From e3decc491af820ab4ea172dc6562262972c9868e Mon Sep 17 00:00:00 2001 From: Kingsword Date: Mon, 17 Aug 2026 18:40:35 +0800 Subject: [PATCH] fix(tui): use platform-specific config path in login prompt --- packages/zcode-tui/src/index.ts | 8 +++++--- src/model-access.ts | 6 ++++++ test/model-access.test.ts | 8 +++++++- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/packages/zcode-tui/src/index.ts b/packages/zcode-tui/src/index.ts index 0840ba1..aeee016 100644 --- a/packages/zcode-tui/src/index.ts +++ b/packages/zcode-tui/src/index.ts @@ -1,7 +1,7 @@ import { spawn } from "node:child_process"; import { appendFileSync } from "node:fs"; -import { readConfiguredModelAccess } from "../../../src/model-access.ts"; +import { readConfiguredModelAccess, userConfigPathHint } from "../../../src/model-access.ts"; import { availableUpdateVersion, readStartupUpdate, @@ -664,12 +664,13 @@ class ZCodeTui { } private updateLoginWarning(): void { + const configPath = userConfigPathHint(); this.loginWarning.setText( this.loginRequired ? this.theme.warning("Model access is not configured.") : "" ); this.loginHelp.setText( this.loginRequired - ? this.theme.warning("Run /login, or configure a custom provider in ~/.zcode/cli/config.json.") + ? this.theme.warning(`Run /login, or configure a custom provider in ${configPath}.`) : "" ); } @@ -2798,8 +2799,9 @@ class ZCodeTui { const command = selected?.payload as SelectionCommand | undefined; if (!command?.command) return; if (command.command === customProviderHelpCommand) { + const configPath = userConfigPathHint(); this.addNotice( - "Custom providers do not require login. Copy config.example.json to ~/.zcode/cli/config.json, " + `Custom providers do not require login. Copy config.example.json to ${configPath}, ` + "set provider kind, baseURL, apiKey and model IDs, then run /new. " + "See README: Custom provider without login.", "muted" diff --git a/src/model-access.ts b/src/model-access.ts index 3b43108..550c1f7 100644 --- a/src/model-access.ts +++ b/src/model-access.ts @@ -61,6 +61,12 @@ export function userConfigPath( return path.join(configuredHome || fallbackHome, ".zcode", "cli", "config.json"); } +export function userConfigPathHint(platform: NodeJS.Platform = process.platform): string { + return platform === "win32" + ? "%USERPROFILE%\\.zcode\\cli\\config.json" + : "~/.zcode/cli/config.json"; +} + export async function ensureUserConfig( env: NodeJS.ProcessEnv = process.env ): Promise { diff --git a/test/model-access.test.ts b/test/model-access.test.ts index 1ba8412..f8a0a14 100644 --- a/test/model-access.test.ts +++ b/test/model-access.test.ts @@ -3,7 +3,7 @@ import { mkdtemp, mkdir, rm, writeFile } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; -import { readConfiguredModelAccess, userConfigPath } from "../src/model-access.ts"; +import { readConfiguredModelAccess, userConfigPath, userConfigPathHint } from "../src/model-access.ts"; const temporaryDirectories: string[] = []; @@ -20,6 +20,12 @@ async function temporaryHome(): Promise { } describe("configured model access", () => { + test("formats the config path hint for each supported platform", () => { + expect(userConfigPathHint("linux")).toBe("~/.zcode/cli/config.json"); + expect(userConfigPathHint("darwin")).toBe("~/.zcode/cli/config.json"); + expect(userConfigPathHint("win32")).toBe("%USERPROFILE%\\.zcode\\cli\\config.json"); + }); + test("detects an internally consistent custom provider", async () => { const home = await temporaryHome(); const env = { HOME: home, USERPROFILE: home };