#![recursion_limit = "256"]
#[cfg(feature = "profiling-alloc")]
#[allow(unsafe_code)]
mod alloc_counter {
use std::alloc::{GlobalAlloc, Layout, System};
use std::cell::RefCell;
pub struct CountingAllocator;
unsafe impl GlobalAlloc for CountingAllocator {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
increment_alloc(layout.size());
unsafe { System.alloc(layout) }
}
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
increment_dealloc(layout.size());
unsafe { System.dealloc(ptr, layout) }
}
}
#[derive(Clone, Copy)]
struct RawStats {
alloc_count: u64,
alloc_bytes: u64,
dealloc_count: u64,
dealloc_bytes: u64,
}
impl RawStats {
const ZERO: Self = Self {
alloc_count: 0,
alloc_bytes: 0,
dealloc_count: 0,
dealloc_bytes: 0,
};
}
thread_local! {
static STATS: RefCell<RawStats> = const { RefCell::new(RawStats::ZERO) };
}
fn increment_alloc(size: usize) {
STATS.with(|s| {
let mut s = s.borrow_mut();
s.alloc_count += 1;
s.alloc_bytes += size as u64;
});
}
fn increment_dealloc(size: usize) {
STATS.with(|s| {
let mut s = s.borrow_mut();
s.dealloc_count += 1;
s.dealloc_bytes += size as u64;
});
}
pub fn snapshot() -> (u64, u64, u64, u64) {
STATS.with(|s| {
let s = s.borrow();
(
s.alloc_count,
s.alloc_bytes,
s.dealloc_count,
s.dealloc_bytes,
)
})
}
}
#[cfg(feature = "profiling-alloc")]
#[allow(unsafe_code)]
#[global_allocator]
static GLOBAL: alloc_counter::CountingAllocator = alloc_counter::CountingAllocator;
mod acp;
mod agent_setup;
mod bootstrap;
mod channel;
#[cfg(feature = "otel")]
mod circuit_breaker_exporter;
mod cli;
mod commands;
mod daemon;
mod db_url;
mod execution_mode;
mod fleet_session;
mod gateway_spawn;
mod init;
#[cfg(feature = "prometheus")]
mod metrics_export;
#[cfg(feature = "profiling-pyroscope")]
mod pyroscope_push;
#[cfg(feature = "otel")]
mod redacting_span_processor;
mod runner;
mod scheduler;
#[cfg(feature = "scheduler")]
mod scheduler_executor;
#[cfg(feature = "session")]
mod serve;
mod startup_checks;
mod tracing_init;
mod tui_bridge;
mod tui_remote;
#[cfg(feature = "deep-link")]
mod url_scheme;
use clap::Parser;
use cli::Cli;
const MAIN_THREAD_STACK_SIZE: usize = 32 * 1024 * 1024;
fn main() -> anyhow::Result<()> {
std::thread::Builder::new()
.name("zeph-main".into())
.stack_size(MAIN_THREAD_STACK_SIZE)
.spawn(|| {
tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()?
.block_on(Box::pin(runner::run(Cli::parse())))
})?
.join()
.expect("zeph-main thread panicked")
}
#[cfg(test)]
mod tests;