Repository navigation
zcode-cli 3.8.1-24
Show the workspace directory beside the turn timer in the TUI status footer
-
Show the workspace directory beside the turn timer in the TUI status footer (tell concurrently open sessions apart) (
packages/zcode-tui/src/turn-status.ts,packages/zcode-tui/src/index.ts,packages/zcode-tui/src/welcome-banner.ts,test/turn-status.test.ts).- Why: the current directory was previously shown only in the welcome banner; once a long session scrolls the banner off screen, several concurrently open zcode TUI instances can no longer be told apart. The directory now lives on the turn status line (the line that carries the turn timer), always visible right next to the timer and refreshing along with it.
- What changed: (1)
welcome-banner.tsexports the home-prefix-abbreviatingdisplayWorkspace()logic asabbreviateWorkspaceDirectory()(banner and timer line now share one abbreviation rule); (2)turn-status.tsaddsturnStatusDirectoryText()-- the workspace directory abbreviated to~form, and when it exceeds the 24-column budget (TURN_STATUS_DIRECTORY_MAX_COLUMNS) it is truncated from the head while keeping the tail (the distinguishing part of concurrently open sessions is mostly the project name at the end of the path); the 24-column budget leaves room for the right-side Goal status on 80-column terminals (measured: timer + directory + compact Goal coexist at 80 columns; narrower terminals prioritize timer + directory); (3)index.tsupdateTurnStatus()appends the directory text (muted style,─separator) to the right of the timer text, and the directory shows alone when there is no timer content; the directory text is sanitized viasanitizeTerminalTextand cached (cwd does not change within a process lifetime,??=computes it once); (4) 3 new test cases (same abbreviation as the banner, head-truncation keeping the tail over budget, wide-character directory truncated without breaking characters). - Verification: full
bun test639 pass / 0 fail (78 files);tsc --noEmitpasses; multi-width rendering measured at 100 / 80 / 60 columns confirms the expected layout; after thebuild:tuirebuild, the@zcode/tuicopy inside vendor is refreshed in sync (matches the build output).
-
Fix the TUI showing the previous account's username after switching accounts: the identity display now refreshes unconditionally after login, and logins whose identity cannot be attributed clear stale snapshots when the API key changes (
src/identity.ts,packages/zcode-tui/src/index.ts,test/identity.test.ts,test/login-flow.test.ts,README.md,README_zh_hans.md,README_zh_hant.md).- Why: users reported that after switching accounts and logging in again, the TUI banner and status bar still showed the old account's username. Investigation confirmed two root causes -- (1) session layer:
setLoginRequiredrefreshed the identity display only whenloginRequiredflipped from true to false; when switching accounts while already logged in, that state stays false, sorefreshLoginIdentitynever fired and the old name persisted until the TUI was restarted; (2) data layer: the display name is read from the vault'soauth:<provider>:user_infosnapshot; the Z.AI OAuth login flow rewrites that snapshot with the new account's user object on every login (runtimesaveZaiLoginCredentials, confirmed by reverse engineering), but BigModel OAuth and the two API-key login variants only write the new API key into config.json and never touch the snapshot (reverse engineering confirmed the runtime has zero references tooauth:bigmodel:*keys; that entry in the local vault is a leftover from the uninstalled ZCode Desktop) -- after switching to another BigModel account, the name in the snapshot belongs to the old account and a restart does not fix it, and the CLI has no way to obtain the new account's username (the token exchange happens entirely inside the runtime process, and the live fetch endpoint is blocked by a WAF, see the previous entry). - What changed: (1)
src/identity.tsaddsreadProviderApiKeySnapshot()(snapshots the zai / bigmodel providers' config API keys before login) andclearIdentitiesWithChangedKeys(before)(after login, a provider whose key changed has itsuser_infosnapshot deleted because it can no longer be attributed to the current account; returns the cleared list); (2) the TUI'ssetLoginRequirednow callsrefreshLoginIdentity()on every invocation (no longer only on state flips -- switching accounts while logged in also refreshes), andrefreshLoginIdentitycompares values (early-returns when kind + label are unchanged, avoiding a redraw on every result); (3) newisLoginWithoutIdentityRefresh()detecting the three non-attributable login commands (/login bigmodel-coding-planand the two-api-keyvariants; Z.AI OAuth excluded because it rewrites the snapshot itself);submit()snapshots the keys beforesubmitPromptfor such commands and calls the newclearStaleIdentityAfterLogin()afterhandleResult: key changed -> clear the snapshot, refresh the display, and hint thatzcode identity set <name>can pin the new name; key unchanged (re-login to the same account) -> keep the current name; (4) 7 new test cases (5 in identity: snapshot only includes vault-backed providers, a key change clears the snapshot while preserving neighboring entries, an unchanged key keeps it, a zai key change also clears, no snapshot is a no-op; 2 in login-flow: positive and negative cases of the predicate); fullbun test636 pass / 0 fail (78 files),typecheckpasses; rebuilt withbuild:launcher+build:tui, and the@zcode/tuicopy inside vendor is refreshed in sync. - Scope note: this fix guarantees "the old account's name no longer shows after a switch" (a Z.AI switch shows the new name directly; a BigModel / API key switch falls back to the masked API key with a hint to pin the new name manually) -- obtaining the new BigModel username during login is a structural limitation of the upstream runtime (the token never touches disk); showing it automatically requires upstream support and is out of scope for this fix.
- Why: users reported that after switching accounts and logging in again, the TUI banner and status bar still showed the old account's username. Investigation confirmed two root causes -- (1) session layer:
-
New
zcode identitysubcommand: view / manually sync the signed-in identity display name (fixes the TUI showing a stale username after a rename) (newsrc/identity.ts,src/usage.ts,src/launcher.ts, newtest/identity.test.ts).- Why: the user renamed their account on bigmodel.cn, but the TUI banner and status bar kept the old name. Investigation confirmed the root cause -- the display name is read from the encrypted
oauth:bigmodel:user_infosnapshot (containing username / displayName) in the machine-wide shared credential vault~/.zcode/v2/credentials.json; that snapshot was written when ZCode Desktop (which shares the vault with the CLI) logged in via OAuth, and nothing has refreshed it since: Desktop is uninstalled, and the official runtime's bigmodel login flow (reverse engineered from vendor/zcode.cjs) only writes the exchanged API key into~/.zcode/cli/config.jsonand never the vault's user_info -- so even re-runningzcode logincannot clear the old name. Fetching the latest username from the server in real time is not dependable: the primary endpointGET bigmodel.cn/api/biz/customer/getCustomerInfo(the same one used by the web profile page and the runtime login chainGhr->Uhr) is currently blocked by an Aliyun WAF challenge from this machine both directly and via proxy (200 + empty body +acw_tccookie), and the monitor domain has no user-info endpoint. Hence a manual sync command as the only reliable refresh path. - What changed: (1)
src/usage.tsaddsencryptCredential()-- the dual ofdecryptCredential()(enc:v1:AES-256-GCM, random 12-byte IV, 16-byte tag, three base64url segments, key derivation identical to the runtime), letting the CLI write back credentials the runtime can read; (2) newsrc/identity.ts--zcode identityshows the active provider's identity (OAuth account name or masked API key, with the same read priority as the TUI's login-identity.ts mirror; the package dependency direction forbids importing it the other way, hence the standalone implementation);zcode identity set <name>rewrites the active provider's user_info snapshot username + displayName (theoauth:active_providermarker first, falling back to the config.model.main prefix, default bigmodel), preserving other fields such as id / avatarUrl and neighboring vault entries (login_attribution etc.), and creating the entry when no snapshot exists;zcode identity cleardeletes the snapshot and falls back to the API-key display; the name is capped at 64 characters,setis rejected for non-OAuth providers, and the vault is written back with 0600 permissions; (3)launcher.tswires the identity route after the stats route; (4) newtest/identity.test.tswith 13 cases (encrypt/decrypt round trip + random IV, command argument dispatch, the three snapshot read priorities, set preserving fields / creating an entry / two rejection classes, show / clear / no-op / missing state). Rebuilt withbun run build:launcher; fullbun test630 pass / 0 fail (78 files). Live check:zcode identityoutputsProvider: bigmodel / Identity: signed in as <old name>(reproducing the issue); the vault is shared globally, and afterseta new TUI session picks it up immediately. - Scope note:
identity setis a local display-name sync and does not change the server-side account; if the WAF ever allows the live endpoint, automatic refresh could be filed separately (not filed now -- live fetching is unusable in production today, and automatic refresh would silently fail and fall back to the stale snapshot, adding complexity for nothing). - Version note: these changes were originally recorded under the 3.8.1-23 entry, but v3.8.1-23 had already been published as a GitHub Release (2026-09-04, whose notes do not include these two items); after committing, the version was bumped 3.8.1-23 -> 3.8.1-24 and both items were relocated into this entry (the 3.8.1-23 entry was restored to its published form); VERSION, package.json, the test/update.test.ts assertion, and the three READMEs' badges and install-URL asset names were updated in sync.
- Why: the user renamed their account on bigmodel.cn, but the TUI banner and status bar kept the old name. Investigation confirmed the root cause -- the display name is read from the encrypted
Install
npm install -g https://github.com/xhqing/zcode-cli/releases/download/v3.8.1-24/zcode-cli-3.8.1-24.tgz