fix: v2.5.9 — Vietnamese in the terminal on macOS, every slash command, the right Claude account

Issue #62: a tmux client whose LC_ALL/LC_CTYPE/LANG names no UTF-8 prints `_`
for every non-ASCII character, and a macOS LaunchAgent starts the dashboard
with no locale at all — Vietnamese text and Claude Code's logo came out as
underscores in every browser terminal.

- shell-path.js: ensureUtf8Locale() defaults LC_CTYPE (en_US.UTF-8 on macOS,
  C.UTF-8 elsewhere) at start, before any tmux call; an explicit LC_ALL and
  Windows are left alone
- RunSetup.tsx: the `/` list now offers Claude Code's bundled skills
  (/code-review, /security-review, /simplify, /loop…) and newer built-ins, and
  every enabled plugin's commands and skills as /<plugin>:<name>
- Claude login decided by the TOKEN's owner (GET /api/oauth/profile, cached
  per token), not by .claude.json: a running session can leave the
  credentials store holding one account's token under another account's
  name. The Profiles modal, its Check quota and the status-bar quota now show
  the account requests are really billed to and warn on the mismatch; a
  switch saves the outgoing token into its OWNER's profile (credentials only)
  instead of overwriting the profile .claude.json names; saving a profile
  while they disagree is refused (EMISMATCH); a saved profile holding another
  account's token reports EWRONGACCOUNT instead of that account's usage
- Running Claude Code sessions follow a switch on their own (they re-read the
  credentials store when it changes), so the "close your sessions first"
  warning is gone
This commit is contained in:
2026-10-07 11:18:10 +07:00
parent 7543b8d62a
commit 8fdda66893
24 changed files with 504 additions and 59 deletions
+2 -1
View File
@@ -263,7 +263,8 @@
"title": "Claude Code profiles",
"openButton": "Switch profile",
"subtitle": "A profile is one Anthropic account - its own quota. Switching swaps only the login (credentials + account identity); skills, subagents, memory, plugins, marketplaces, MCP servers and settings all stay exactly as they are.",
"warning": "Close your running Claude Code sessions before switching - a live session rewrites the config on exit and would put the old account back.",
"warning": "Running Claude Code sessions follow a switch on their own: they pick up the new login within about 30 seconds.",
"mismatch": "The login in use belongs to {{owner}}, but Claude Code's config names {{config}}. Requests are billed to {{owner}}. Switch to the account you want to fix this.",
"activeLabel": "Logged in now",
"noActive": "No Claude account is logged in on this machine.",
"unsavedActive": "This account is not saved as a profile yet - save it, otherwise you cannot switch away without losing its credentials.",
+1
View File
@@ -79,6 +79,7 @@
"quotaRefreshing": "Refreshing…",
"quotaExpired": "Token expired: use Claude Code once so it refreshes",
"quotaFailed": "Could not read the quota",
"quotaWrongAccount": "This sign-in belongs to another Claude account: log in as this account and save it again",
"quotaActive": "in use",
"quotaProfileExpired": "Sign-in expired: use Check quota in Claude Code → Profiles to refresh it",
"quotaSignInExpires": "Sign-in expires in {{time}}",
+2 -1
View File
@@ -258,7 +258,8 @@
"title": "Profile Claude Code",
"openButton": "Đổi profile",
"subtitle": "Mỗi profile là một tài khoản Anthropic - quota riêng. Khi đổi, chỉ phần đăng nhập (credentials + danh tính tài khoản) được hoán đổi; skills, subagent, memory, plugin, marketplace, MCP server và settings vẫn giữ nguyên.",
"warning": "Hãy đóng các phiên Claude Code đang chạy trước khi đổi - phiên đang chạy sẽ ghi lại config khi thoát và đưa tài khoản cũ quay về.",
"warning": "Các phiên Claude Code đang chạy tự đi theo khi đổi: chúng nhận đăng nhập mới trong khoảng 30 giây.",
"mismatch": "Đăng nhập đang dùng thuộc tài khoản {{owner}}, nhưng config của Claude Code lại ghi {{config}}. Mọi request đang tính vào {{owner}}. Bấm Chuyển sang đúng tài khoản bạn muốn để sửa.",
"activeLabel": "Đang đăng nhập",
"noActive": "Chưa có tài khoản Claude nào đăng nhập trên máy này.",
"unsavedActive": "Tài khoản này chưa được lưu thành profile - hãy lưu lại, nếu không sẽ không thể đổi sang profile khác mà không mất credentials của nó.",
+1
View File
@@ -79,6 +79,7 @@
"quotaRefreshing": "Đang làm mới…",
"quotaExpired": "Token đã hết hạn: dùng Claude Code một lần để nó tự làm mới",
"quotaFailed": "Không đọc được quota",
"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",
"quotaProfileExpired": "Đăng nhập đã hết hạn: bấm Kiểm tra quota trong Claude Code → Profiles để làm mới",
"quotaSignInExpires": "Đăng nhập hết hạn sau {{time}}",