diff --git a/Cargo.toml b/Cargo.toml index 72a4bc6..d388cd9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ members = ["crates/codexchat-core", "crates/codexchat-cli"] resolver = "2" [workspace.package] -version = "0.1.7" +version = "0.1.8" edition = "2024" license = "MIT" authors = ["Dhruv Mars"] diff --git a/crates/codexchat-cli/src/lib.rs b/crates/codexchat-cli/src/lib.rs index 0d13e37..e6a3cfc 100644 --- a/crates/codexchat-cli/src/lib.rs +++ b/crates/codexchat-cli/src/lib.rs @@ -8,7 +8,7 @@ use std::{ use anyhow::{Result, anyhow}; use clap::{Parser, Subcommand}; use codexchat_core::{ - auth::AccountInfo, + auth::{AccountInfo, AuthState}, codex::{CodexClient, CodexClientOptions}, config::AppPaths, history::ThreadStore, @@ -75,6 +75,18 @@ pub async fn current_account(client: &CodexClient) -> Result { client.account_read().await } +fn render_auth_status(account: &AccountInfo) -> String { + match account.auth_state { + Some(AuthState::Connected) => format!("Connected: {}", account.account_label()), + Some(AuthState::SignedOut) => "Signed out".into(), + Some(AuthState::SigningIn) => "Signing in".into(), + Some(AuthState::Expired) => "Auth expired".into(), + Some(AuthState::RateLimited) => "Rate limited".into(), + Some(AuthState::Error) => "Auth error".into(), + None => "Disconnected".into(), + } +} + pub async fn make_client() -> Result { let paths = app_paths()?; let codex_bin = env::var_os("CODEXCHAT_CODEX_BIN") @@ -163,11 +175,7 @@ async fn run_auth_command(command: AuthCommand) -> Result<()> { } AuthCommand::Status => { let account = current_account(&client).await?; - if account.is_connected() { - println!("Connected: {}", account.account_label()); - } else { - println!("Disconnected"); - } + println!("{}", render_auth_status(&account)); Ok(()) } } @@ -281,8 +289,11 @@ async fn run_models_command() -> Result<()> { mod tests { use clap::Parser; - use crate::{AuthCommand, Cli, Command, choose_model}; - use codexchat_core::types::{AppConfig, ModelDescriptor}; + use crate::{AuthCommand, Cli, Command, choose_model, render_auth_status}; + use codexchat_core::{ + auth::{AccountInfo, AuthState}, + types::{AppConfig, ModelDescriptor}, + }; #[test] fn parses_chat_and_auth_commands() { @@ -350,4 +361,62 @@ mod tests { "gpt-5.4" ); } + + #[test] + fn renders_specific_auth_status_messages() { + assert_eq!( + render_auth_status(&AccountInfo { + auth_state: Some(AuthState::Connected), + auth_mode: Some("chatgpt".into()), + email: Some("user@example.com".into()), + plan_type: Some("plus".into()), + requires_openai_auth: true, + }), + "Connected: user@example.com (plus)" + ); + + assert_eq!( + render_auth_status(&AccountInfo { + auth_state: Some(AuthState::SignedOut), + auth_mode: None, + email: None, + plan_type: None, + requires_openai_auth: true, + }), + "Signed out" + ); + + assert_eq!( + render_auth_status(&AccountInfo { + auth_state: Some(AuthState::Expired), + auth_mode: None, + email: None, + plan_type: None, + requires_openai_auth: true, + }), + "Auth expired" + ); + + assert_eq!( + render_auth_status(&AccountInfo { + auth_state: Some(AuthState::RateLimited), + auth_mode: None, + email: None, + plan_type: None, + requires_openai_auth: true, + }), + "Rate limited" + ); + + assert_eq!( + render_auth_status(&AccountInfo { + auth_state: Some(AuthState::Error), + auth_mode: None, + email: None, + plan_type: None, + requires_openai_auth: true, + }), + "Auth error" + ); + } } diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index a5d7ba3..e985699 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,11 @@ # @dhruv2mars/codexchat +## 0.1.8 + +### Patch Changes + +- Show clear auth status text for signed-out users on fresh installs. + ## 0.1.7 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index 864999f..caaddc4 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@dhruv2mars/codexchat", - "version": "0.1.7", + "version": "0.1.8", "description": "ChatGPT terminal app with official Codex bridge", "type": "module", "bin": {