Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions packages/zcode-tui/src/index.ts
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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}.`)
: ""
);
}
Expand Down Expand Up @@ -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"
Expand Down
6 changes: 6 additions & 0 deletions src/model-access.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<UserConfigBootstrapResult> {
Expand Down
8 changes: 7 additions & 1 deletion test/model-access.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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[] = [];

Expand All @@ -20,6 +20,12 @@ async function temporaryHome(): Promise<string> {
}

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 };
Expand Down