diff --git a/src/main.rs b/src/main.rs
index 72ab771..8173d5e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,175 +1,175 @@
 mod cli;
 mod daemon;
 mod globals;
 mod webui;
 
 use crate::cli::Args;
 use clap::{Parser, Subcommand};
 use clap_verbosity_flag::{LogLevel, Verbosity};
 use macros_rs::{str, string, then};
 
 fn validate_id_script(s: &str) -> Result<Args, String> {
     if let Ok(id) = s.parse::<usize>() {
         Ok(Args::Id(id))
     } else {
         Ok(Args::Script(s.to_owned()))
     }
 }
 
 #[derive(Copy, Clone, Debug, Default)]
 struct NoneLevel;
 impl LogLevel for NoneLevel {
     fn default() -> Option<log::Level> { None }
 }
 
 #[derive(Parser)]
 #[command(version = str!(cli::get_version(false)))]
 struct Cli {
     #[command(subcommand)]
     command: Commands,
     #[clap(flatten)]
     verbose: Verbosity<NoneLevel>,
 }
 
 #[derive(Subcommand)]
 enum Daemon {
     /// Reset process index
     #[command(alias = "clean")]
     Reset,
     /// Stop daemon
     #[command(alias = "kill")]
     Stop,
     /// Restart daemon
     #[command(alias = "restart", alias = "start")]
     Restore {
         /// Daemon api
         #[arg(long)]
         api: bool,
         /// WebUI using api
         #[arg(long)]
         webui: bool,
     },
     /// Check daemon
     #[command(alias = "info", alias = "status")]
     Health {
         /// Format output
         #[arg(long, default_value_t = string!("default"))]
         format: String,
     },
 }
 
 // add pmc restore command
 #[derive(Subcommand)]
 enum Commands {
     /// Start/Restart a process
     #[command(alias = "restart")]
     Start {
         /// Process name
         #[arg(long)]
         name: Option<String>,
         #[clap(value_parser = validate_id_script)]
         args: Option<Args>,
         /// Watch to reload path
         #[arg(long)]
         watch: Option<String>,
         /// Server
         #[arg(short, long, default_value_t = string!("internal"))]
         server: String,
     },
 
     /// Stop/Kill a process
     #[command(alias = "kill")]
     Stop {
         id: usize,
         /// Server
         #[arg(short, long, default_value_t = string!("internal"))]
         server: String,
     },
 
     /// Stop then remove a process
     #[command(alias = "rm")]
     Remove {
         id: usize,
         /// Server
         #[arg(short, long, default_value_t = string!("internal"))]
         server: String,
     },
 
     /// Get env of a process
     #[command(alias = "cmdline")]
     Env {
         id: usize,
         /// Server
         #[arg(short, long, default_value_t = string!("internal"))]
         server: String,
     },
 
     /// Get information of a process
     #[command(alias = "info")]
     Details {
         id: usize,
         /// Format output
         #[arg(long, default_value_t = string!("default"))]
         format: String,
         /// Server
         #[arg(short, long, default_value_t = string!("internal"))]
         server: String,
     },
 
     /// List all processes
     #[command(alias = "ls")]
     List {
         /// Format output
         #[arg(long, default_value_t = string!("default"))]
         format: String,
         /// Server
         #[arg(short, long, default_value_t = string!("all"))]
         server: String,
     },
 
     /// Get logs from a process
     Logs {
         id: usize,
         #[arg(long, default_value_t = 15, help = "")]
         lines: usize,
         /// Server
         #[arg(short, long, default_value_t = string!("internal"))]
         server: String,
     },
 
     /// Daemon management
     Daemon {
         #[command(subcommand)]
         command: Daemon,
     },
 }
 
 fn main() {
     let cli = Cli::parse();
     let mut env = env_logger::Builder::new();
     let level = cli.verbose.log_level_filter();
 
     globals::init();
     env.filter_level(level).init();
 
     match &cli.command {
         Commands::Start { name, args, watch, server } => cli::start(name, args, watch, server),
         Commands::Stop { id, server } => cli::stop(id, server),
         Commands::Remove { id, server } => cli::remove(id, server),
         Commands::Env { id, server } => cli::env(id, server),
         Commands::Details { id, format, server } => cli::info(id, format, server),
         Commands::List { format, server } => cli::list(format, server),
         Commands::Logs { id, lines, server } => cli::logs(id, lines, server),
 
         Commands::Daemon { command } => match command {
             Daemon::Stop => daemon::stop(),
             Daemon::Reset => daemon::reset(),
             Daemon::Health { format } => daemon::health(format),
-            Daemon::Restore { api, webui } => daemon::restart(api, webui, level.as_str() != "ERROR"),
+            Daemon::Restore { api, webui } => daemon::restart(api, webui, level.as_str() != "OFF"),
         },
     };
 
     if !matches!(&cli.command, Commands::Daemon { .. }) {
-        then!(!daemon::pid::exists(), daemon::start(false));
+        then!(!daemon::pid::exists(), daemon::restart(&false, &false, false));
     }
 }
diff --git a/src/process/mod.rs b/src/process/mod.rs
index 4b50cd3..b99ab6b 100644
--- a/src/process/mod.rs
+++ b/src/process/mod.rs
@@ -1,523 +1,523 @@
 use crate::{
     config,
     config::structs::Server,
     file, helpers,
     service::{run, stop, ProcessMetadata},
 };
 
 use std::{
     env,
     path::PathBuf,
     sync::{Arc, Mutex},
 };
 
 use chrono::serde::ts_milliseconds;
 use chrono::{DateTime, Utc};
 use global_placeholders::global;
 use macros_rs::{crashln, string, ternary, then};
 use psutil::process;
 use serde::{Deserialize, Serialize};
 use serde_json::{json, Value};
 use std::collections::{BTreeMap, HashMap};
 use utoipa::ToSchema;
 
 #[derive(Serialize, Deserialize, ToSchema)]
 pub struct ItemSingle {
     pub info: Info,
     pub stats: Stats,
     pub watch: Watch,
     pub log: Log,
     pub raw: Raw,
 }
 
 #[derive(Serialize, Deserialize, ToSchema)]
 pub struct Info {
     pub id: usize,
     pub pid: i64,
     pub name: String,
     pub status: String,
     #[schema(value_type = String, example = "/path")]
     pub path: PathBuf,
     pub uptime: String,
     pub command: String,
 }
 
 #[derive(Serialize, Deserialize, ToSchema)]
 pub struct Stats {
     pub restarts: u64,
     pub start_time: i64,
     pub cpu_percent: Option<f32>,
     pub memory_usage: Option<MemoryInfo>,
 }
 
 #[derive(Serialize, Deserialize, ToSchema)]
 pub struct MemoryInfo {
     pub rss: u64,
     pub vms: u64,
 }
 
 #[derive(Serialize, Deserialize, ToSchema)]
 pub struct Log {
     pub out: String,
     pub error: String,
 }
 
 #[derive(Serialize, Deserialize, ToSchema)]
 pub struct Raw {
     pub running: bool,
     pub crashed: bool,
     pub crashes: u64,
 }
 
 #[derive(Serialize, ToSchema)]
 pub struct ProcessItem {
     pid: i64,
     id: usize,
     cpu: String,
     mem: String,
     name: String,
     restarts: u64,
     status: String,
     uptime: String,
     #[schema(example = "/path")]
     watch_path: String,
     #[schema(value_type = String, example = "2000-01-01T01:00:00.000Z")]
     start_time: DateTime<Utc>,
 }
 
 #[derive(Clone)]
 pub struct ProcessWrapper {
     pub id: usize,
     pub runner: Arc<Mutex<Runner>>,
 }
 
 #[derive(Clone, Debug, Deserialize, Serialize)]
 pub struct Process {
     pub id: usize,
     pub pid: i64,
     pub name: String,
     pub path: PathBuf,
     pub script: String,
     pub env: HashMap<String, String>,
     #[serde(with = "ts_milliseconds")]
     pub started: DateTime<Utc>,
     pub restarts: u64,
     pub running: bool,
     pub crash: Crash,
     pub watch: Watch,
 }
 
 #[derive(Clone, Debug, Deserialize, Serialize)]
 pub struct Crash {
     pub crashed: bool,
     pub value: u64,
 }
 
 #[derive(Clone, Debug, Deserialize, Serialize, ToSchema)]
 pub struct Watch {
     pub enabled: bool,
     #[schema(example = "/path")]
     pub path: String,
     pub hash: String,
 }
 
 #[derive(Clone, Debug, Deserialize, Serialize)]
 pub struct Runner {
     pub id: id::Id,
     #[serde(skip)]
     pub remote: Option<Remote>,
     pub list: BTreeMap<usize, Process>,
 }
 
 #[derive(Clone, Debug)]
 pub struct Remote {
     address: String,
     token: Option<String>,
     pub config: RemoteConfig,
 }
 
 #[derive(Clone, Debug, Deserialize)]
 pub struct RemoteConfig {
     pub shell: String,
     pub args: Vec<String>,
     pub log_path: String,
 }
 
 pub enum Status {
     Offline,
     Running,
 }
 
 impl Status {
     pub fn to_bool(&self) -> bool {
         match self {
             Status::Offline => false,
             Status::Running => true,
         }
     }
 }
 
 impl Runner {
     pub fn new() -> Self { dump::read() }
 
     pub fn connect(name: String, Server { address, token }: Server, verbose: bool) -> Option<Self> {
-        let remote_config = match config::from(&address, token.as_deref()) {
+        let remote_config = match config::from(&address.trim_end_matches('/'), token.as_deref()) {
             Ok(config) => config,
             Err(err) => {
                 log::error!("{err}");
                 return None;
             }
         };
 
-        if let Ok(dump) = dump::from(&address, token.as_deref()) {
+        if let Ok(dump) = dump::from(&address.trim_end_matches('/'), token.as_deref()) {
             then!(verbose, println!("{} Fetched remote (name={name}, address={address})", *helpers::SUCCESS));
             Some(Runner {
                 remote: Some(Remote {
                     token,
                     address: string!(address),
                     config: remote_config,
                 }),
                 ..dump
             })
         } else {
             None
         }
     }
 
     pub fn start(&mut self, name: &String, command: &String, path: PathBuf, watch: &Option<String>) -> &mut Self {
         if let Some(remote) = &self.remote {
             if let Err(err) = http::create(remote, name, command, path, watch) {
                 crashln!("{} Failed to start create {name}\nError: {:#?}", *helpers::FAIL, err);
             };
         } else {
             let id = self.id.next();
             let config = config::read().runner;
             let crash = Crash { crashed: false, value: 0 };
 
             let watch = match watch {
                 Some(watch) => Watch {
                     enabled: true,
                     path: string!(watch),
                     hash: hash::create(file::cwd().join(watch)),
                 },
                 None => Watch {
                     enabled: false,
                     path: string!(""),
                     hash: string!(""),
                 },
             };
 
             let pid = run(ProcessMetadata {
                 args: config.args,
                 name: name.clone(),
                 shell: config.shell,
                 command: command.clone(),
                 log_path: config.log_path,
             });
 
             self.list.insert(
                 id,
                 Process {
                     id,
                     pid,
                     path,
                     watch,
                     crash,
                     restarts: 0,
                     running: true,
                     name: name.clone(),
                     started: Utc::now(),
                     script: command.clone(),
                     env: env::vars().collect(),
                 },
             );
         }
 
         return self;
     }
 
     pub fn restart(&mut self, id: usize, dead: bool) -> &mut Self {
         if let Some(remote) = &self.remote {
             if let Err(err) = http::restart(remote, id) {
                 crashln!("{} Failed to start process {id}\nError: {:#?}", *helpers::FAIL, err);
             };
         } else {
             let process = self.process(id);
             let config = config::read().runner;
             let Process { path, script, name, .. } = process.clone();
 
             if let Err(err) = std::env::set_current_dir(&process.path) {
                 crashln!("{} Failed to set working directory {:?}\nError: {:#?}", *helpers::FAIL, path, err);
             };
 
             stop(process.pid);
             process.running = false;
             process.crash.crashed = false;
 
             process.pid = run(ProcessMetadata {
                 args: config.args,
                 name: name.clone(),
                 shell: config.shell,
                 log_path: config.log_path,
                 command: script.to_string(),
             });
 
             process.running = true;
             process.started = Utc::now();
 
             then!(!dead, process.crash.value = 0);
             then!(dead, process.restarts += 1);
         }
 
         return self;
     }
 
     pub fn remove(&mut self, id: usize) {
         if let Some(remote) = &self.remote {
             if let Err(err) = http::remove(remote, id) {
                 crashln!("{} Failed to stop remove {id}\nError: {:#?}", *helpers::FAIL, err);
             };
         } else {
             self.stop(id);
             self.list.remove(&id);
             dump::write(&self);
         }
     }
 
     pub fn set_id(&mut self, id: id::Id) {
         self.id = id;
         self.id.next();
         dump::write(&self);
     }
 
     pub fn set_status(&mut self, id: usize, status: Status) {
         self.process(id).running = status.to_bool();
         dump::write(&self);
     }
 
     pub fn items(&mut self) -> BTreeMap<usize, Process> { self.list.clone() }
     pub fn items_mut(&mut self) -> &mut BTreeMap<usize, Process> { &mut self.list }
 
     pub fn save(&self) { then!(self.remote.is_none(), dump::write(&self)) }
     pub fn count(&mut self) -> usize { self.list().count() }
     pub fn is_empty(&self) -> bool { self.list.is_empty() }
     pub fn exists(&mut self, id: usize) -> bool { self.list.contains_key(&id) }
     pub fn info(&mut self, id: usize) -> Option<&Process> { self.list.get(&id) }
     pub fn list<'l>(&'l mut self) -> impl Iterator<Item = (&'l usize, &'l mut Process)> { self.list.iter_mut().map(|(k, v)| (k, v)) }
     pub fn process(&mut self, id: usize) -> &mut Process { self.list.get_mut(&id).unwrap_or_else(|| crashln!("{} Process ({id}) not found", *helpers::FAIL)) }
 
     pub fn get(self, id: usize) -> ProcessWrapper {
         ProcessWrapper {
             id,
             runner: Arc::new(Mutex::new(self)),
         }
     }
 
     pub fn set_crashed(&mut self, id: usize) -> &mut Self {
         self.process(id).crash.crashed = true;
         return self;
     }
 
     pub fn new_crash(&mut self, id: usize) -> &mut Self {
         self.process(id).crash.value += 1;
         return self;
     }
 
     pub fn stop(&mut self, id: usize) -> &mut Self {
         if let Some(remote) = &self.remote {
             if let Err(err) = http::stop(remote, id) {
                 crashln!("{} Failed to stop process {id}\nError: {:#?}", *helpers::FAIL, err);
             };
         } else {
             let process = self.process(id);
             stop(process.pid);
             process.running = false;
             process.crash.crashed = false;
             process.crash.value = 0;
         }
 
         return self;
     }
 
     pub fn rename(&mut self, id: usize, name: String) -> &mut Self {
         if let Some(remote) = &self.remote {
             if let Err(err) = http::rename(remote, id, name) {
                 crashln!("{} Failed to rename process {id}\nError: {:#?}", *helpers::FAIL, err);
             };
         } else {
             self.process(id).name = name;
         }
 
         return self;
     }
 
     pub fn watch(&mut self, id: usize, path: &str, enabled: bool) -> &mut Self {
         let process = self.process(id);
         process.watch = Watch {
             enabled,
             path: string!(path),
             hash: ternary!(enabled, hash::create(process.path.join(path)), string!("")),
         };
 
         return self;
     }
 
     pub fn json(&mut self) -> Value {
         let mut processes: Vec<ProcessItem> = Vec::new();
 
         for (id, item) in self.items() {
             let mut memory_usage: Option<MemoryInfo> = None;
             let mut cpu_percent: Option<f32> = None;
 
             if let Ok(mut process) = process::Process::new(item.pid as u32) {
                 let mem_info_psutil = process.memory_info().ok();
 
                 cpu_percent = process.cpu_percent().ok();
                 memory_usage = Some(MemoryInfo {
                     rss: mem_info_psutil.as_ref().unwrap().rss(),
                     vms: mem_info_psutil.as_ref().unwrap().vms(),
                 });
             }
 
             let cpu_percent = match cpu_percent {
                 Some(percent) => format!("{:.2}%", percent),
                 None => string!("0.00%"),
             };
 
             let memory_usage = match memory_usage {
                 Some(usage) => helpers::format_memory(usage.rss),
                 None => string!("0b"),
             };
 
             let status = if item.running {
                 string!("online")
             } else {
                 match item.crash.crashed {
                     true => string!("crashed"),
                     false => string!("stopped"),
                 }
             };
 
             processes.push(ProcessItem {
                 id,
                 status,
                 pid: item.pid,
                 cpu: cpu_percent,
                 mem: memory_usage,
                 restarts: item.restarts,
                 name: item.name.clone(),
                 start_time: item.started,
                 watch_path: item.watch.path.clone(),
                 uptime: helpers::format_duration(item.started),
             });
         }
 
         json!(processes)
     }
 }
 
 impl ProcessWrapper {
     pub fn stop(&mut self) {
         let runner_arc = Arc::clone(&self.runner);
         let mut runner = runner_arc.lock().unwrap();
         runner.stop(self.id).save();
     }
 
     pub fn watch(&mut self, path: &str) {
         let runner_arc = Arc::clone(&self.runner);
         let mut runner = runner_arc.lock().unwrap();
         runner.watch(self.id, path, true).save();
     }
 
     pub fn disable_watch(&mut self) {
         let runner_arc = Arc::clone(&self.runner);
         let mut runner = runner_arc.lock().unwrap();
         runner.watch(self.id, "", false).save();
     }
 
     pub fn rename(&mut self, name: String) {
         let runner_arc = Arc::clone(&self.runner);
         let mut runner = runner_arc.lock().unwrap();
         runner.rename(self.id, name).save();
     }
 
     pub fn restart(&mut self) {
         let runner_arc = Arc::clone(&self.runner);
         let mut runner = runner_arc.lock().unwrap();
         runner.restart(self.id, false).save();
     }
 
     pub fn crashed(&mut self) {
         let runner_arc = Arc::clone(&self.runner);
         let mut runner = runner_arc.lock().unwrap();
         runner.new_crash(self.id).save();
         runner.restart(self.id, true).save();
     }
 
     pub fn json(&mut self) -> Value {
         let runner_arc = Arc::clone(&self.runner);
         let mut runner = runner_arc.lock().unwrap();
 
         let item = runner.process(self.id);
         let config = config::read().runner;
 
         let mut memory_usage: Option<MemoryInfo> = None;
         let mut cpu_percent: Option<f32> = None;
 
         if let Ok(mut process) = process::Process::new(item.pid as u32) {
             let mem_info_psutil = process.memory_info().ok();
 
             cpu_percent = process.cpu_percent().ok();
             memory_usage = Some(MemoryInfo {
                 rss: mem_info_psutil.as_ref().unwrap().rss(),
                 vms: mem_info_psutil.as_ref().unwrap().vms(),
             });
         }
 
         let status = if item.running {
             string!("online")
         } else {
             match item.crash.crashed {
                 true => string!("crashed"),
                 false => string!("stopped"),
             }
         };
 
         json!(ItemSingle {
             info: Info {
                 status,
                 id: item.id,
                 pid: item.pid,
                 name: item.name.clone(),
                 path: item.path.clone(),
                 uptime: helpers::format_duration(item.started),
                 command: format!("{} {} '{}'", config.shell, config.args.join(" "), item.script.clone()),
             },
             stats: Stats {
                 cpu_percent,
                 memory_usage,
                 restarts: item.restarts,
                 start_time: item.started.timestamp_millis(),
             },
             watch: Watch {
                 enabled: item.watch.enabled,
                 hash: item.watch.hash.clone(),
                 path: item.watch.path.clone(),
             },
             log: Log {
                 out: global!("pmc.logs.out", item.name.as_str()),
                 error: global!("pmc.logs.error", item.name.as_str()),
             },
             raw: Raw {
                 running: item.running,
                 crashed: item.crash.crashed,
                 crashes: item.crash.value,
             }
         })
     }
 }
 
 pub mod dump;
 pub mod hash;
 pub mod http;
 pub mod id;