supercode-cli 0.5.11

Volter Harness — a lightweight, fully-customizable AI coding agent CLI in Rust. Any model via OpenRouter; natively continues Claude Code and Codex sessions.
//! Native adapter for OpenRouter's documented PKCE flow. Credentials are saved
//! by the CLI's existing login path, never by this module.
use anyhow::{bail, Context, Result};
use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine};
use sha2::{Digest, Sha256};
use std::time::Duration;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use url::Url;

const API: &str = "https://openrouter.ai/api/v1/auth/keys";

fn random_token() -> Result<String> {
    let mut bytes = [0u8; 32];
    getrandom::getrandom(&mut bytes).map_err(|_| anyhow::anyhow!("OS randomness unavailable"))?;
    Ok(URL_SAFE_NO_PAD.encode(bytes))
}
fn authorization_url(verifier: &str, callback: Option<&str>) -> Result<Url> {
    let mut url = Url::parse("https://openrouter.ai/auth")?;
    {
        let mut params = url.query_pairs_mut();
        params.append_pair(
            "code_challenge",
            &URL_SAFE_NO_PAD.encode(Sha256::digest(verifier)),
        );
        params.append_pair("code_challenge_method", "S256");
        params.append_pair("key_label", "Volter Harness");
        if let Some(callback) = callback {
            params.append_pair("callback_url", callback);
        }
    }
    Ok(url)
}

pub async fn authorize(headless: bool) -> Result<String> {
    let verifier = random_token()?;
    let code = if headless {
        let url = authorization_url(&verifier, None)?;
        eprintln!("Open this URL, authorize Volter Harness, then paste the authorization code:\n{url}");
        crate::hidden_input::read_hidden_line().context("reading authorization code")?
    } else {
        let listener = tokio::net::TcpListener::bind("127.0.0.1:0")
            .await
            .context("opening OAuth callback listener; use --oauth --headless over SSH")?;
        let path = format!("/callback/{}", random_token()?);
        let callback = format!("http://127.0.0.1:{}{path}", listener.local_addr()?.port());
        let url = authorization_url(&verifier, Some(&callback))?;
        eprintln!("Authorize Volter Harness in your browser:\n{url}");
        open_browser(url.as_str());
        tokio::time::timeout(Duration::from_secs(600), receive_callback(&listener, &path))
            .await
            .context("OpenRouter sign-in timed out; run login again")??
    };
    if code.trim().is_empty() || code.len() > 4096 {
        bail!("invalid authorization code");
    }
    exchange(API, code.trim(), &verifier).await
}

fn open_browser(url: &str) {
    #[cfg(target_os = "macos")]
    let command = Some(("open", vec![url]));
    #[cfg(target_os = "linux")]
    let command = Some(("xdg-open", vec![url]));
    #[cfg(target_os = "windows")]
    let command = Some(("rundll32", vec!["url.dll,FileProtocolHandler", url]));
    #[cfg(not(any(target_os = "macos", target_os = "linux", target_os = "windows")))]
    let command: Option<(&str, Vec<&str>)> = None;
    if let Some((program, args)) = command {
        // URL remains visible if no desktop opener exists. Never invoke a shell.
        let _ = std::process::Command::new(program)
            .args(args)
            .stdin(std::process::Stdio::null())
            .stdout(std::process::Stdio::null())
            .stderr(std::process::Stdio::null())
            .spawn();
    }
}

fn callback_code(target: &str, path: &str) -> Result<Option<String>> {
    if !target.starts_with('/') || target.starts_with("//") {
        return Ok(None);
    }
    let url = Url::parse(&format!("http://localhost{target}"))?;
    if url.path() != path {
        return Ok(None);
    }
    if url.query_pairs().any(|(name, _)| name == "error") {
        bail!("OpenRouter authorization was declined");
    }
    let codes: Vec<_> = url
        .query_pairs()
        .filter(|(name, _)| name == "code")
        .map(|(_, code)| code.into_owned())
        .collect();
    if codes.len() != 1 || codes[0].is_empty() || codes[0].len() > 4096 {
        bail!("OpenRouter callback has no unique authorization code");
    }
    Ok(Some(codes[0].clone()))
}

async fn receive_callback(listener: &tokio::net::TcpListener, path: &str) -> Result<String> {
    loop {
        let (mut stream, _) = listener.accept().await?;
        let mut bytes = Vec::new();
        let read = tokio::time::timeout(Duration::from_secs(5), async {
            let mut byte = [0u8; 1];
            while bytes.len() < 8192 {
                if stream.read(&mut byte).await? == 0 {
                    break;
                }
                bytes.push(byte[0]);
                if bytes.ends_with(b"\r\n\r\n") {
                    break;
                }
            }
            Ok::<_, std::io::Error>(())
        })
        .await;
        if !matches!(read, Ok(Ok(()))) {
            continue;
        }
        let request = String::from_utf8_lossy(&bytes);
        let mut line = request
            .lines()
            .next()
            .unwrap_or_default()
            .split_whitespace();
        let method = line.next();
        let target = line.next().unwrap_or_default();
        let result = if method == Some("GET") {
            callback_code(target, path)
        } else {
            Ok(None)
        };
        let (status, message) = match &result {
            Ok(Some(_)) => (
                "200 OK",
                "Authorization received. Return to Volter Harness to finish signing in.",
            ),
            Ok(None) => ("404 Not Found", "Unknown callback."),
            Err(_) => (
                "400 Bad Request",
                "Authorization failed. Return to Volter Harness.",
            ),
        };
        let response = format!("HTTP/1.1 {status}\r\nContent-Type: text/plain\r\nCache-Control: no-store\r\nReferrer-Policy: no-referrer\r\nConnection: close\r\nContent-Length: {}\r\n\r\n{message}", message.len());
        let _ = stream.write_all(response.as_bytes()).await;
        if let Some(code) = result? {
            return Ok(code);
        }
    }
}

async fn exchange(endpoint: &str, code: &str, verifier: &str) -> Result<String> {
    let client = reqwest::Client::builder()
        .redirect(reqwest::redirect::Policy::none())
        .timeout(Duration::from_secs(30))
        .build()?;
    let response = client
        .post(endpoint)
        .json(&serde_json::json!({
            "code": code, "code_verifier": verifier, "code_challenge_method": "S256"
        }))
        .send()
        .await
        .context("OpenRouter authorization exchange failed")?;
    if !response.status().is_success() {
        // Responses may contain sensitive values. Report only status, never body.
        bail!(
            "OpenRouter authorization exchange returned HTTP {}; run login again",
            response.status()
        );
    }
    let body: serde_json::Value = response
        .json()
        .await
        .context("invalid OpenRouter authorization response")?;
    let key = body
        .get("key")
        .and_then(|value| value.as_str())
        .filter(|key| {
            (8..=4096).contains(&key.len())
                && key
                    .bytes()
                    .all(|b| b.is_ascii_alphanumeric() || b == b'-' || b == b'_')
        })
        .context("OpenRouter returned no valid API key")?;
    Ok(key.to_owned())
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn pkce_uses_rfc7636_s256_vector() {
        let url = authorization_url("dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk", None).unwrap();
        assert!(url
            .query_pairs()
            .any(|(k, v)| k == "code_challenge"
                && v == "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM"));
        assert!(!url.query_pairs().any(|(k, _)| k == "callback_url"));
        assert_eq!(random_token().unwrap().len(), 43);
    }
    #[test]
    fn callback_requires_exact_attempt_and_unique_code() {
        assert_eq!(
            callback_code("/callback/wrong?code=secret", "/callback/right").unwrap(),
            None
        );
        assert_eq!(
            callback_code("/callback/right?code=a%2Bb", "/callback/right").unwrap(),
            Some("a+b".into())
        );
        assert!(callback_code("/callback/right?code=a&code=b", "/callback/right").is_err());
        assert!(callback_code("/callback/right?error=denied", "/callback/right").is_err());
    }
    #[tokio::test]
    async fn callback_listener_accepts_code_without_reflecting_it() {
        let listener = tokio::net::TcpListener::bind("127.0.0.1:0").await.unwrap();
        let addr = listener.local_addr().unwrap();
        let task =
            tokio::spawn(async move { receive_callback(&listener, "/callback/attempt").await });
        let response = reqwest::get(format!("http://{addr}/callback/attempt?code=private-code"))
            .await
            .unwrap();
        assert!(!response.text().await.unwrap().contains("private-code"));
        assert_eq!(task.await.unwrap().unwrap(), "private-code");
    }
    #[test]
    fn login_flags_reject_ambiguous_credential_sources() {
        use clap::Parser;
        assert!(
            crate::Cli::try_parse_from(["supercode", "login", "--oauth", "--headless"]).is_ok()
        );
        assert!(crate::Cli::try_parse_from(["supercode", "login", "--headless"]).is_err());
        assert!(crate::Cli::try_parse_from([
            "supercode",
            "login",
            "--oauth",
            "--api-key",
            "secret"
        ])
        .is_err());
        assert!(crate::Cli::try_parse_from([
            "supercode",
            "login",
            "--oauth",
            "--base-url",
            "https://other.example"
        ])
        .is_err());
    }

    #[tokio::test]
    #[ignore = "requires the owned OpenRouter World"]
    async fn world_exchange_is_single_use_and_key_reaches_model_api() {
        let endpoint =
            std::env::var("OPENROUTER_TWIN_URL").expect("run through the OpenRouter World");
        let verifier = random_token().unwrap();
        let client = reqwest::Client::new();
        // Twin's fixture authorization door seeds a real stored one-use code.
        let result: serde_json::Value = client.post(format!("{endpoint}/api/v1/auth/authorize"))
            .json(&serde_json::json!({ "callback_url": "http://localhost/callback",
                "code_challenge": URL_SAFE_NO_PAD.encode(Sha256::digest(&verifier)), "code_challenge_method": "S256" }))
            .send().await.unwrap().error_for_status().unwrap().json().await.unwrap();
        let code = result["data"]["code"].as_str().unwrap();
        let url = format!("{endpoint}/api/v1/auth/keys");
        assert!(exchange(&url, code, "wrong-verifier").await.is_err());
        let key = exchange(&url, code, &verifier).await.unwrap();
        assert!(exchange(&url, code, &verifier).await.is_err());
        let reply = client.post(format!("{endpoint}/api/v1/chat/completions"))
            .bearer_auth(key).json(&serde_json::json!({"model":"openai/gpt-4o","messages":[{"role":"user","content":"synthetic credential probe"}]}))
            .send().await.unwrap();
        assert!(reply.status().is_success());
    }
}