Skip to content
Open
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 .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@ jobs:

- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, llvm-tools-preview
components: rustfmt, clippy, llvm-tools-preview

- name: cargo fmt --check (optional)
- name: cargo fmt --check
run: cargo fmt --check
continue-on-error: true

- name: cargo clippy
run: cargo clippy --locked --all-targets -- -D warnings

- uses: taiki-e/install-action@v2
with:
Expand Down
68 changes: 32 additions & 36 deletions src/commands.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::collections::{BTreeMap, HashMap};
use std::path::PathBuf;
use std::path::{Path, PathBuf};
use std::sync::{Arc, Mutex};

use crate::auth::acquire_api_key;
Expand Down Expand Up @@ -946,7 +946,7 @@ fn known_model_id(models: &[CatalogModel], id: &str) -> bool {

fn save_model_slot(
existing: Option<crate::config::Config>,
path: &PathBuf,
path: &Path,
slot: &str,
id: &str,
) -> Result<i32, String> {
Expand Down Expand Up @@ -988,7 +988,7 @@ fn known_agent(name: &str) -> Result<String, String> {
}
}

fn save_agent_model(path: &PathBuf, agent: &str, id: &str) -> Result<i32, String> {
fn save_agent_model(path: &Path, agent: &str, id: &str) -> Result<i32, String> {
let agent = known_agent(agent)?;
let mut cfg = load_config_if_present(path).ok_or_else(no_key_error)?;
let id = catalog_model_id(id);
Expand All @@ -1008,7 +1008,7 @@ fn save_agent_model(path: &PathBuf, agent: &str, id: &str) -> Result<i32, String
Ok(0)
}

fn save_agent_account(path: &PathBuf, agent: &str, profile: &str) -> Result<i32, String> {
fn save_agent_account(path: &Path, agent: &str, profile: &str) -> Result<i32, String> {
let agent = known_agent(agent)?;
let mut cfg = load_config_if_present(path).ok_or_else(no_key_error)?;
if !cfg.profiles.contains_key(profile) {
Expand All @@ -1024,7 +1024,7 @@ fn save_agent_account(path: &PathBuf, agent: &str, profile: &str) -> Result<i32,
Ok(0)
}

fn save_agent_key(path: &PathBuf, agent: &str, key: &str) -> Result<i32, String> {
fn save_agent_key(path: &Path, agent: &str, key: &str) -> Result<i32, String> {
let agent = known_agent(agent)?;
let mut cfg = load_config_if_present(path).ok_or_else(no_key_error)?;
cfg.agent_binding_mut(&agent).api_key = Some(key.to_string());
Expand Down Expand Up @@ -1323,7 +1323,7 @@ fn run_whoami(parsed: &ParsedArgs, env: &BTreeMap<String, String>) -> Result<i32
fn print_config_status(
parsed: &ParsedArgs,
env: &BTreeMap<String, String>,
path: &PathBuf,
path: &Path,
) -> Result<(), String> {
let cfg = load_config_if_present(path).unwrap_or_default();
let profile = cfg.profiles.get(&cfg.active_profile);
Expand Down Expand Up @@ -1469,7 +1469,7 @@ fn settings_tab_names() -> Vec<String> {
tabs
}

fn tool_command_for(path: &PathBuf, id: &str) -> String {
fn tool_command_for(path: &Path, id: &str) -> String {
let cfg = load_config_if_present(path);
resolve_tool(cfg.as_ref(), id)
.map(|t| t.command)
Expand All @@ -1480,7 +1480,7 @@ fn tool_command_for(path: &PathBuf, id: &str) -> String {
fn config_settings_frame(
parsed: &ParsedArgs,
env: &BTreeMap<String, String>,
path: &PathBuf,
path: &Path,
online: bool,
cache: &mut CreditsCache,
tab: usize,
Expand Down Expand Up @@ -1553,7 +1553,7 @@ fn config_settings_frame(
fn fill_general_settings(
rows: &mut Vec<crate::tui::SettingRow>,
kinds: &mut Vec<Option<SettingKind>>,
path: &PathBuf,
path: &Path,
parsed: &ParsedArgs,
env: &BTreeMap<String, String>,
profile: Option<&Profile>,
Expand Down Expand Up @@ -1689,7 +1689,7 @@ fn fill_general_settings(
fn fill_agent_settings(
rows: &mut Vec<crate::tui::SettingRow>,
kinds: &mut Vec<Option<SettingKind>>,
path: &PathBuf,
path: &Path,
env: &BTreeMap<String, String>,
profile: Option<&Profile>,
id: &'static str,
Expand Down Expand Up @@ -1982,7 +1982,7 @@ fn slot_current_opt(profile: Option<&Profile>, slot: &str) -> String {
fn config_settings_loop(
parsed: &ParsedArgs,
env: &BTreeMap<String, String>,
path: &PathBuf,
path: &Path,
) -> Result<i32, String> {
let mut cache = CreditsCache::fresh();
let mut tab = 0usize;
Expand Down Expand Up @@ -2029,7 +2029,7 @@ fn config_settings_loop(
fn config_edit_row(
parsed: &ParsedArgs,
env: &BTreeMap<String, String>,
path: &PathBuf,
path: &Path,
kind: SettingKind,
) -> Result<i32, String> {
match kind {
Expand Down Expand Up @@ -2406,7 +2406,7 @@ fn config_reset_row(path: &std::path::Path, kind: SettingKind) -> Result<i32, St
fn config_menu_loop_legacy(
parsed: &ParsedArgs,
env: &BTreeMap<String, String>,
path: &PathBuf,
path: &Path,
) -> Result<i32, String> {
let items = vec![
"Switch key".into(),
Expand Down Expand Up @@ -2535,10 +2535,10 @@ fn run_config(parsed: &ParsedArgs, env: &BTreeMap<String, String>) -> Result<i32
}

fn catalog_lookup_enabled(env: &BTreeMap<String, String>) -> bool {
match env.get("ANYR_NO_CATALOG").map(|s| s.as_str()) {
Some("1" | "true" | "TRUE" | "yes") => false,
_ => true,
}
!matches!(
env.get("ANYR_NO_CATALOG").map(|s| s.as_str()),
Some("1" | "true" | "TRUE" | "yes")
)
}

struct ResolvedModel {
Expand Down Expand Up @@ -3138,7 +3138,7 @@ fn key_pick_label(row: &crate::http::RemoteKey, current: bool) -> String {
fn stored_api_key(
parsed: &ParsedArgs,
env: &BTreeMap<String, String>,
path: &PathBuf,
path: &Path,
) -> Option<String> {
let existing = load_config_if_present(path);
let profile = existing
Expand Down Expand Up @@ -3196,7 +3196,7 @@ fn agent_binding_detail(cfg: &crate::config::Config, id: &str, signed_in: bool)
/// `signed_in` gates the launch group exactly like the old dialog did.
#[cfg(feature = "native")]
fn launcher_palette(
path: &PathBuf,
path: &Path,
parsed: &ParsedArgs,
env: &BTreeMap<String, String>,
credits: &mut CreditsCache,
Expand Down Expand Up @@ -3273,7 +3273,7 @@ fn launcher_palette(
/// Non-native twin of `launcher_palette` — same rows, plain inline entries.
#[cfg(not(feature = "native"))]
fn launcher_palette(
path: &PathBuf,
path: &Path,
parsed: &ParsedArgs,
env: &BTreeMap<String, String>,
_credits: &mut CreditsCache,
Expand Down Expand Up @@ -3561,7 +3561,7 @@ fn push_agent_configure_entries(
));
}

fn install_agent_dialog(path: &PathBuf, env: &BTreeMap<String, String>) -> Result<i32, String> {
fn install_agent_dialog(path: &Path, env: &BTreeMap<String, String>) -> Result<i32, String> {
let missing = missing_agents(env, |id| tool_command_for(path, id));
if missing.is_empty() {
println!(
Expand Down Expand Up @@ -3593,19 +3593,15 @@ fn install_agent_dialog(path: &PathBuf, env: &BTreeMap<String, String>) -> Resul
Ok(0)
}

fn persist_tool_command(path: &PathBuf, id: &str, command: &str) -> Result<(), String> {
fn persist_tool_command(path: &Path, id: &str, command: &str) -> Result<(), String> {
let mut cfg = load_config_if_present(path).unwrap_or_default();
let mut tool = resolve_tool(Some(&cfg), id)?;
tool.command = command.to_string();
cfg.tools.insert(id.to_string(), tool);
write_config(&cfg, path)
}

fn launcher_last_tool(
path: &PathBuf,
parsed: &ParsedArgs,
env: &BTreeMap<String, String>,
) -> String {
fn launcher_last_tool(path: &Path, parsed: &ParsedArgs, env: &BTreeMap<String, String>) -> String {
let cfg = load_config_if_present(path).unwrap_or_default();
let profile = cfg.profiles.get(&cfg.active_profile);
cfg.last_tool
Expand All @@ -3620,7 +3616,7 @@ fn launcher_last_tool(
})
}

fn launcher_signed_in(path: &PathBuf, parsed: &ParsedArgs, env: &BTreeMap<String, String>) -> bool {
fn launcher_signed_in(path: &Path, parsed: &ParsedArgs, env: &BTreeMap<String, String>) -> bool {
stored_api_key(parsed, env, path).is_some()
}

Expand Down Expand Up @@ -3741,7 +3737,7 @@ fn launcher_dispatch(
action: &str,
parsed: &ParsedArgs,
env: &BTreeMap<String, String>,
path: &PathBuf,
path: &Path,
) -> Result<LauncherNext, String> {
if action == "Quit" || action.starts_with("Quit") {
return Ok(LauncherNext::Exit(0));
Expand Down Expand Up @@ -3868,7 +3864,7 @@ fn launcher_dispatch(
fn switch_agent_model(
parsed: &ParsedArgs,
env: &BTreeMap<String, String>,
path: &PathBuf,
path: &Path,
agent: &str,
) -> Result<LauncherNext, String> {
if agent.is_empty() {
Expand All @@ -3889,7 +3885,7 @@ fn switch_agent_model(
fn bind_agent_model(
parsed: &ParsedArgs,
env: &BTreeMap<String, String>,
path: &PathBuf,
path: &Path,
agent: &str,
) -> Result<i32, String> {
let existing = load_config_if_present(path);
Expand All @@ -3911,7 +3907,7 @@ fn bind_agent_model(
fn switch_agent_account(
_parsed: &ParsedArgs,
_env: &BTreeMap<String, String>,
path: &PathBuf,
path: &Path,
agent: &str,
) -> Result<LauncherNext, String> {
if agent.is_empty() {
Expand All @@ -3925,7 +3921,7 @@ fn switch_agent_account(
Ok(LauncherNext::Continue)
}

fn bind_agent_account(path: &PathBuf, agent: &str) -> Result<i32, String> {
fn bind_agent_account(path: &Path, agent: &str) -> Result<i32, String> {
let cfg = load_config_if_present(path).unwrap_or_default();
let mut names: Vec<String> = cfg.profiles.keys().cloned().collect();
names.sort();
Expand Down Expand Up @@ -3960,7 +3956,7 @@ fn bind_agent_account(path: &PathBuf, agent: &str) -> Result<i32, String> {
fn switch_agent_key(
parsed: &ParsedArgs,
env: &BTreeMap<String, String>,
path: &PathBuf,
path: &Path,
agent: &str,
) -> Result<LauncherNext, String> {
if agent.is_empty() {
Expand All @@ -3981,7 +3977,7 @@ fn switch_agent_key(
fn bind_agent_key(
parsed: &ParsedArgs,
env: &BTreeMap<String, String>,
path: &PathBuf,
path: &Path,
agent: &str,
) -> Result<i32, String> {
let (_keys_path, cfg, base, api_key) = keys_credential(parsed, env)?;
Expand Down Expand Up @@ -4024,7 +4020,7 @@ fn bind_agent_key(
fn launch_agent_picker(
parsed: &ParsedArgs,
env: &BTreeMap<String, String>,
path: &PathBuf,
path: &Path,
) -> Result<LauncherNext, String> {
if !launcher_signed_in(path, parsed, env) {
eprintln!(
Expand Down
2 changes: 1 addition & 1 deletion src/help.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::path::Path;
use crate::VERSION;

thread_local! {
static INVOKED_BIN: RefCell<String> = RefCell::new(String::new());
static INVOKED_BIN: RefCell<String> = const { RefCell::new(String::new()) };
}

const LAUNCH_HELP_BODY: &str = "\
Expand Down
1 change: 1 addition & 0 deletions src/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,7 @@ mod tests {
}

/// Helper mirroring the server's getKeyPrefix() shape for tests.
#[allow(non_snake_case)]
fn getKeyPrefixStyleMask(head: &str, tail: &str) -> String {
format!("{head}...{tail}")
}
Expand Down
19 changes: 2 additions & 17 deletions src/spawn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const CLAUDE_EFFORT_TOKENS: &[(&str, i64)] = &[
("max", 32000),
];

#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone, Default, PartialEq)]
pub struct ToolConfig {
pub command: String,
pub base_url_env: String,
Expand All @@ -34,21 +34,6 @@ pub struct ToolConfig {
pub extra: BTreeMap<String, YamlValue>,
}

impl Default for ToolConfig {
fn default() -> Self {
Self {
command: String::new(),
base_url_env: String::new(),
auth_env: String::new(),
model_env: None,
base_suffix: String::new(),
enable_gateway_model_discovery: false,
shadow_env: None,
extra: BTreeMap::new(),
}
}
}

impl ToolConfig {
pub fn merge(&mut self, over: &ToolConfig) {
if !over.command.is_empty() {
Expand Down Expand Up @@ -1177,7 +1162,7 @@ mod tests {
let mut env = BTreeMap::new();
let mut routing = crate::config::RoutingConstraints::default();
apply_routing_env(&mut env, &routing, "claude");
assert!(env.get("CLAUDE_CODE_EXTRA_BODY").is_none());
assert!(!env.contains_key("CLAUDE_CODE_EXTRA_BODY"));
routing.set_exacto(true);
routing.set_require_tools(true);
routing.set_require_1m(true);
Expand Down
2 changes: 1 addition & 1 deletion src/term.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ const MARK_PNG: &[u8] = include_bytes!("../assets/mark.png");
const B64: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

fn base64_encode(bytes: &[u8]) -> String {
let mut out = String::with_capacity((bytes.len() + 2) / 3 * 4);
let mut out = String::with_capacity(bytes.len().div_ceil(3) * 4);
for chunk in bytes.chunks(3) {
let a = chunk[0] as u32;
let b = chunk.get(1).copied().unwrap_or(0) as u32;
Expand Down
2 changes: 1 addition & 1 deletion src/tui/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ pub fn render_picker(frame: &mut Frame, state: &PickerState) {
ListItem::new(Line::from(vec![
Span::styled(if i == state.cursor { "❯ " } else { " " }, theme::accent()),
Span::styled(item_icon(label), item_icon_style(label)),
Span::styled(format!("{label}"), style),
Span::styled(label.to_string(), style),
]))
})
.collect();
Expand Down
4 changes: 2 additions & 2 deletions src/upgrade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::channel::{
parse_releases_html, release_asset_url, releases_http_error, select_latest_release_with_asset,
Channel, Release, GITHUB_EXPANDED_ASSETS_PREFIX, GITHUB_RELEASES_API, GITHUB_RELEASES_HTML,
};
use crate::config::{resolve_config_path, write_config, Config};
use crate::config::{resolve_config_path, write_config};
use crate::http::{http_get_github, http_get_web};
use crate::key::load_config_if_present;
use crate::parse::{get_string_flag, ParsedArgs};
Expand Down Expand Up @@ -180,7 +180,7 @@ fn resolve_channel(parsed: &ParsedArgs, env: &BTreeMap<String, String>) -> Resul
/// Persist `channel:` so future auto-updates follow the switched track.
fn persist_channel(channel: Channel, env: &BTreeMap<String, String>) -> Result<bool, String> {
let path = resolve_config_path(None, env);
let mut cfg = load_config_if_present(&path).unwrap_or_else(Config::default);
let mut cfg = load_config_if_present(&path).unwrap_or_default();
let next = channel.as_str().to_string();
let changed = cfg.channel.as_deref() != Some(next.as_str());
if !changed && cfg.channel.is_some() {
Expand Down
Loading