//! `spectra open`: sign in to Radar (spec ยง8.3). The owner's CLI signs a //! request for a one-time link with the owner's key; the link, valid for a //! minute, opens a level-2 browser session. use super::identity::{owner_home, recorded_owner}; use super::{ui, Ctx}; use anyhow::{bail, Context, Result}; use spectra_core::ledger::Ledger; use spectra_mcp::client::Client; use std::path::PathBuf; pub async fn open(ctx: &Ctx, owner_home_flag: Option, launch: bool) -> Result { let socket = ctx.socket(); if !Client::alive(&socket).await { bail!("Spectra is not serving {} (spectra serve)", ctx.data.display()); } let home = owner_home(ctx, owner_home_flag); let ledger = Ledger::open_read_only(&ctx.db()?).await?; let owner = recorded_owner(&ledger, &home).await?; let r = Client::new(&socket, Some(owner)).send("POST", "/radar/link", &[], Vec::new()).await?; if r.status != 200 { bail!("the daemon refused the sign-in: {}", String::from_utf8_lossy(&r.body)); } let url = r.json()?.get("url").and_then(|u| u.as_str()).map(String::from).context("no link in the answer")?; println!("{} {}", ui::done("Signed"), ui::subject("a one-time link to Radar, good for a minute")); println!(" {}", ui::id(&url)); if launch && std::process::Command::new("xdg-open") .arg(&url) .stdout(std::process::Stdio::null()) .stderr(std::process::Stdio::null()) .spawn() .is_ok() { println!(" {} {}", ui::note(), ui::dim("opened in your browser")); } Ok(0) }