#![cfg_attr(target_os = "windows", windows_subsystem = "windows")]
use atomcode_core::session::SessionManager;
use atomcode_daemon::{run_server, ServerOpts};
use atomcode_telemetry::{CliOverride, SessionMode};
const DEFAULT_IDLE_TIMEOUT_SECS: u64 = 30 * 60;
fn parse_daemon_args() -> (String, u16, CliOverride, u64, SessionMode) {
const DEFAULT_HOST: &str = "127.0.0.1";
const DEFAULT_PORT: u16 = 13456;
let mut host: Option<String> = None;
let mut port: Option<u16> = None;
let mut no_telemetry = false;
let mut idle_timeout: Option<u64> = None;
let mut client_mode: Option<String> = None;
let mut args = std::env::args().skip(1);
while let Some(arg) = args.next() {
if arg == "--host" {
if let Some(value) = args.next() {
host = Some(value);
}
continue;
}
if let Some(value) = arg.strip_prefix("--host=") {
host = Some(value.to_string());
continue;
}
if arg == "--port" {
if let Some(value) = args.next() {
port = value.parse().ok();
}
continue;
}
if let Some(value) = arg.strip_prefix("--port=") {
port = value.parse().ok();
continue;
}
if arg == "--no-telemetry" {
no_telemetry = true;
continue;
}
if arg == "--idle-timeout" {
if let Some(value) = args.next() {
idle_timeout = value.parse().ok();
}
continue;
}
if let Some(value) = arg.strip_prefix("--idle-timeout=") {
idle_timeout = value.parse().ok();
continue;
}
if arg == "--client" {
if let Some(value) = args.next() {
client_mode = Some(value);
}
continue;
}
if let Some(value) = arg.strip_prefix("--client=") {
client_mode = Some(value.to_string());
continue;
}
}
let cli_override = if no_telemetry {
CliOverride { disabled: true }
} else {
CliOverride::default()
};
let raw_timeout = idle_timeout
.or_else(|| std::env::var("ATOMCODE_DAEMON_IDLE_TIMEOUT").ok()?.parse().ok())
.unwrap_or(DEFAULT_IDLE_TIMEOUT_SECS);
let timeout = if raw_timeout == 0 { 0 } else { raw_timeout.max(60) };
let mode = match client_mode.as_deref() {
Some("vscode") => SessionMode::Vscode,
Some("webui") => SessionMode::Webui,
Some("atomcode-air") => SessionMode::AtomcodeAir,
_ => SessionMode::Ide,
};
(host.unwrap_or_else(|| DEFAULT_HOST.to_string()), port.unwrap_or(DEFAULT_PORT), cli_override, timeout, mode)
}
#[tokio::main]
async fn main() {
#[cfg(target_os = "windows")]
{
use windows_sys::Win32::System::Console::{AttachConsole, ATTACH_PARENT_PROCESS};
unsafe { AttachConsole(ATTACH_PARENT_PROCESS); }
}
SessionManager::migrate_from_legacy();
let (host, port, cli_override, idle_timeout_secs, startup_mode) = parse_daemon_args();
if let Err(e) = run_server(ServerOpts {
host,
port,
cli_override,
idle_timeout_secs,
startup_mode,
webui_tokens: None,
quiet: false,
working_dir_override: None,
prebound_listener: None,
})
.await
{
eprintln!("Fatal: daemon server error: {e:#}");
std::process::exit(1);
}
}