diff --git a/packages/server/src/server/agent/providers/claude-agent.ts b/packages/server/src/server/agent/providers/claude-agent.ts index 8030e534f..67cea73f0 100644 --- a/packages/server/src/server/agent/providers/claude-agent.ts +++ b/packages/server/src/server/agent/providers/claude-agent.ts @@ -1144,6 +1144,7 @@ export class ClaudeAgentClient implements AgentClient { const resolvedBinary = (await findExecutable("claude")) ?? "not found"; const available = await this.isAvailable(); const version = await resolveClaudeVersion(this.runtimeSettings); + const auth = available ? await resolveClaudeAuth(this.runtimeSettings) : null; let modelsValue = "Not checked"; let status = formatDiagnosticStatus(available); @@ -1164,6 +1165,7 @@ export class ClaudeAgentClient implements AgentClient { diagnostic: formatProviderDiagnostic("Claude Code", [ { label: "Binary", value: resolvedBinary }, ...(version ? [{ label: "Version", value: version }] : []), + ...(auth ? [{ label: "Auth", value: auth }] : []), { label: "Models", value: modelsValue }, { label: "Status", value: status }, ]), @@ -1210,6 +1212,57 @@ async function resolveClaudeVersion( } } +async function resolveClaudeAuth( + runtimeSettings?: ProviderRuntimeSettings, +): Promise { + const command = runtimeSettings?.command; + + try { + let stdout: string; + if (command?.mode === "replace") { + const result = await execCommand( + command.argv[0]!, + [...command.argv.slice(1), "auth", "status"], + { timeout: 5_000 }, + ); + stdout = result.stdout; + } else { + const executable = await findExecutable("claude"); + if (!executable) { + return null; + } + const result = await execCommand(executable, ["auth", "status"], { timeout: 5_000 }); + stdout = result.stdout; + } + + const parsed: unknown = JSON.parse(stdout); + if (!parsed || typeof parsed !== "object") { + return null; + } + const record = parsed as Record; + if (record.loggedIn !== true) { + return "Not logged in"; + } + + const parts: string[] = []; + if (typeof record.authMethod === "string" && record.authMethod) { + parts.push(record.authMethod); + } + if (typeof record.subscriptionType === "string" && record.subscriptionType) { + parts.push(record.subscriptionType); + } + if (typeof record.email === "string" && record.email) { + parts.push(record.email); + } else if (typeof record.orgName === "string" && record.orgName) { + parts.push(record.orgName); + } + + return parts.length > 0 ? parts.join(" ยท ") : "Logged in"; + } catch { + return null; + } +} + function extractContextWindowSize(modelUsage: unknown): number | undefined { if (!modelUsage || typeof modelUsage !== "object") { return undefined;