1use crate::daemon::{self, DaemonOpts, DEFAULT_DAEMON_PORT};
2use crate::mcp::{self, DEFAULT_MCP_BIND};
3use clap::Subcommand;
4
5#[derive(Subcommand, Debug)]
6pub enum ServiceAction {
7 Start {
9 #[arg(long)]
11 force: bool,
12 #[arg(long, default_value_t = DEFAULT_DAEMON_PORT)]
14 daemon_port: u16,
15 #[arg(long, default_value = DEFAULT_MCP_BIND)]
17 mcp_bind: String,
18 },
19 Stop,
21 Status,
23 Doctor,
25}
26
27pub async fn handle(action: &ServiceAction, qpu_enabled: bool) {
28 match action {
29 ServiceAction::Start {
30 force,
31 daemon_port,
32 mcp_bind,
33 } => {
34 let daemon_opts = DaemonOpts {
35 dev: true,
36 port: *daemon_port,
37 net_mode: "unmetered".to_string(),
38 energy_mode: "unlimited".to_string(),
39 workers: 1,
40 compute_swarm: false,
41 empty_graph: true,
42 };
43
44 println!("Starting Qualia local dev stack...");
45 if let Err(err) = daemon::start_service(&daemon_opts, *force) {
46 eprintln!("Daemon start failed: {err}");
47 std::process::exit(1);
48 }
49
50 if let Err(err) = mcp::start_background(mcp_bind, qpu_enabled, *force) {
51 eprintln!("MCP start failed: {err}");
52 let _ = daemon::stop_service();
53 std::process::exit(1);
54 }
55
56 println!("Local dev stack ready:");
57 println!(" graph daemon : http://127.0.0.1:{daemon_port}");
58 println!(" MCP surface : tcp://{mcp_bind}");
59 println!(" run tests : node docs/tests/run-headless.mjs --mode both");
60 }
61 ServiceAction::Stop => {
62 let daemon_err = daemon::stop_service().err();
63 let mcp_err = mcp::stop_background().err();
64 if let Some(err) = daemon_err {
65 eprintln!("Daemon stop: {err}");
66 }
67 if let Some(err) = mcp_err {
68 eprintln!("MCP stop: {err}");
69 }
70 }
71 ServiceAction::Status => {
72 println!("daemon:");
73 let _ = daemon::print_status();
74 println!("mcp:");
75 let _ = mcp::print_status();
76 }
77 ServiceAction::Doctor => {
78 println!("=== daemon ===");
79 let _ = daemon::print_doctor(DEFAULT_DAEMON_PORT);
80 println!();
81 println!("=== mcp ===");
82 let _ = mcp::print_doctor();
83 println!();
84 println!("=== quick start ===");
85 println!(" qualia-cli service start");
86 println!(" qualia-cli mcp serve --transport stdio # for IDE MCP clients");
87 println!(" node docs/tests/run-headless.mjs --mode both");
88 }
89 }
90}