feat: refresh web console theme

This commit is contained in:
Nathan Flurry 2026-01-25 03:33:34 -08:00
parent 0fbf6272b1
commit 1fcae6ed76
34 changed files with 5037 additions and 748 deletions

View file

@ -98,6 +98,9 @@ enum AgentsCommand {
enum CredentialsCommand {
/// Extract credentials using local discovery rules.
Extract(CredentialsExtractArgs),
/// Output credentials as environment variable assignments.
#[command(name = "extract-env")]
ExtractEnv(CredentialsExtractEnvArgs),
}
#[derive(Subcommand, Debug)]
@ -239,6 +242,17 @@ struct CredentialsExtractArgs {
reveal: bool,
}
#[derive(Args, Debug)]
struct CredentialsExtractEnvArgs {
/// Prefix each line with "export " for shell sourcing.
#[arg(long, short = 'e')]
export: bool,
#[arg(long, short = 'd')]
home_dir: Option<PathBuf>,
#[arg(long, short = 'n')]
no_oauth: bool,
}
#[derive(Debug, Error)]
enum CliError {
#[error("missing --token or --no-token for server mode")]
@ -455,6 +469,33 @@ fn run_credentials(command: &CredentialsCommand) -> Result<(), CliError> {
write_stdout_line(&pretty)?;
Ok(())
}
CredentialsCommand::ExtractEnv(args) => {
let mut options = CredentialExtractionOptions::new();
if let Some(home_dir) = args.home_dir.clone() {
options.home_dir = Some(home_dir);
}
if args.no_oauth {
options.include_oauth = false;
}
let credentials = extract_all_credentials(&options);
let prefix = if args.export { "export " } else { "" };
if let Some(cred) = &credentials.anthropic {
write_stdout_line(&format!("{}ANTHROPIC_API_KEY={}", prefix, cred.api_key))?;
write_stdout_line(&format!("{}CLAUDE_API_KEY={}", prefix, cred.api_key))?;
}
if let Some(cred) = &credentials.openai {
write_stdout_line(&format!("{}OPENAI_API_KEY={}", prefix, cred.api_key))?;
write_stdout_line(&format!("{}CODEX_API_KEY={}", prefix, cred.api_key))?;
}
for (provider, cred) in &credentials.other {
let var_name = format!("{}_API_KEY", provider.to_uppercase().replace('-', "_"));
write_stdout_line(&format!("{}{}={}", prefix, var_name, cred.api_key))?;
}
Ok(())
}
}
}

View file

@ -76,6 +76,7 @@ pub fn build_router(state: AppState) -> Router {
let shared = Arc::new(state);
let mut v1_router = Router::new()
.route("/health", get(get_health))
.route("/agents", get(list_agents))
.route("/agents/:agent/install", post(install_agent))
.route("/agents/:agent/modes", get(get_agent_modes))
@ -107,6 +108,7 @@ pub fn build_router(state: AppState) -> Router {
#[derive(OpenApi)]
#[openapi(
paths(
get_health,
install_agent,
get_agent_modes,
list_agents,
@ -125,6 +127,7 @@ pub fn build_router(state: AppState) -> Router {
AgentModesResponse,
AgentInfo,
AgentListResponse,
HealthResponse,
CreateSessionRequest,
CreateSessionResponse,
MessageRequest,
@ -153,6 +156,7 @@ pub fn build_router(state: AppState) -> Router {
)
),
tags(
(name = "meta", description = "Service metadata"),
(name = "agents", description = "Agent management"),
(name = "sessions", description = "Session management")
)
@ -1202,12 +1206,6 @@ fn extract_token(headers: &HeaderMap) -> Option<String> {
}
}
if let Some(value) = headers.get("x-sandbox-token") {
if let Ok(value) = value.to_str() {
return Some(value.to_string());
}
}
None
}
@ -1249,6 +1247,12 @@ pub struct AgentListResponse {
pub agents: Vec<AgentInfo>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, JsonSchema)]
#[serde(rename_all = "camelCase")]
pub struct HealthResponse {
pub status: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, JsonSchema)]
#[serde(rename_all = "camelCase")]
pub struct CreateSessionRequest {
@ -1390,6 +1394,18 @@ async fn get_agent_modes(
Ok(Json(AgentModesResponse { modes }))
}
#[utoipa::path(
get,
path = "/v1/health",
responses((status = 200, body = HealthResponse)),
tag = "meta"
)]
async fn get_health() -> Json<HealthResponse> {
Json(HealthResponse {
status: "ok".to_string(),
})
}
#[utoipa::path(
get,
path = "/v1/agents",