Skip to main content

systemprompt_cli/commands/infrastructure/services/
mod.rs

1//! `infra services` command group: start, stop, restart, status, cleanup, and
2//! serve.
3//!
4//! Defines the [`ServicesCommands`] clap subcommand tree and the individual
5//! target enums ([`StartTarget`], [`StopTarget`], [`RestartTarget`]); dispatch
6//! is delegated to the sibling implementation modules via [`execute`].
7
8pub mod cleanup;
9mod dispatch;
10mod lifecycle;
11pub mod restart;
12pub mod serve;
13pub mod start;
14mod status;
15mod stop;
16mod types;
17
18use clap::Subcommand;
19use systemprompt_config::ProfileBootstrap;
20
21pub use dispatch::{execute, load_service_configs};
22
23const DEFAULT_API_PORT: u16 = 8080;
24
25pub(super) fn get_api_port() -> u16 {
26    ProfileBootstrap::get().map_or(DEFAULT_API_PORT, |p| p.server.port)
27}
28
29pub(super) fn get_api_addr() -> anyhow::Result<String> {
30    let profile = ProfileBootstrap::get()?;
31    Ok(format!("{}:{}", profile.server.host, profile.server.port))
32}
33
34#[derive(Debug, Clone, Subcommand)]
35pub enum StartTarget {
36    #[command(about = "Start a single agent by name")]
37    Agent { agent: String },
38    #[command(about = "Start a single MCP server by name")]
39    Mcp { server_name: String },
40}
41
42#[derive(Debug, Clone, Subcommand)]
43pub enum StopTarget {
44    #[command(about = "Stop a single agent by name")]
45    Agent {
46        agent: String,
47        #[arg(long, help = "Force stop (SIGKILL)")]
48        force: bool,
49    },
50    #[command(about = "Stop a single MCP server by name")]
51    Mcp {
52        server_name: String,
53        #[arg(long, help = "Force stop (SIGKILL)")]
54        force: bool,
55    },
56}
57
58#[derive(Debug, Subcommand)]
59pub enum ServicesCommands {
60    #[command(
61        about = "Start API, agents, and MCP servers",
62        after_help = "EXAMPLES:\n  systemprompt infra services start\n  systemprompt infra \
63                      services start --api\n  systemprompt infra services start --agents --mcp\n  \
64                      systemprompt infra services start agent <name>"
65    )]
66    Start {
67        #[command(subcommand)]
68        target: Option<StartTarget>,
69
70        #[arg(long, help = "Start all services")]
71        all: bool,
72
73        #[arg(long, help = "Start API server only")]
74        api: bool,
75
76        #[arg(long, help = "Start agents only")]
77        agents: bool,
78
79        #[arg(long, help = "Start MCP servers only")]
80        mcp: bool,
81
82        #[arg(long, help = "Run in foreground (default)")]
83        foreground: bool,
84
85        #[arg(long, help = "Skip database migrations")]
86        skip_migrate: bool,
87
88        #[arg(long, help = "Kill process using the port if occupied")]
89        kill_port_process: bool,
90    },
91
92    #[command(
93        about = "Stop running services gracefully",
94        after_help = "EXAMPLES:\n  systemprompt infra services stop\n  systemprompt infra \
95                      services stop --api\n  systemprompt infra services stop agent <name> \
96                      [--force]"
97    )]
98    Stop {
99        #[command(subcommand)]
100        target: Option<StopTarget>,
101
102        #[arg(long, help = "Stop all services")]
103        all: bool,
104
105        #[arg(long, help = "Stop API server only")]
106        api: bool,
107
108        #[arg(long, help = "Stop agents only")]
109        agents: bool,
110
111        #[arg(long, help = "Stop MCP servers only")]
112        mcp: bool,
113
114        #[arg(long, help = "Force stop (SIGKILL)")]
115        force: bool,
116    },
117
118    #[command(about = "Restart services")]
119    Restart {
120        #[command(subcommand)]
121        target: Option<RestartTarget>,
122
123        #[arg(long, help = "Restart only failed services")]
124        failed: bool,
125
126        #[arg(long, help = "Restart all agents")]
127        agents: bool,
128
129        #[arg(long, help = "Restart all MCP servers")]
130        mcp: bool,
131    },
132
133    #[command(about = "Show detailed service status")]
134    Status {
135        #[arg(long, help = "Show detailed information")]
136        detailed: bool,
137
138        #[arg(long, help = "Output as JSON")]
139        json: bool,
140
141        #[arg(long, help = "Include health check results")]
142        health: bool,
143    },
144
145    #[command(about = "Clean up orphaned processes and stale entries")]
146    Cleanup {
147        #[arg(short = 'y', long, help = "Skip confirmation prompt")]
148        yes: bool,
149
150        #[arg(long, help = "Preview cleanup without executing")]
151        dry_run: bool,
152    },
153
154    #[command(about = "Start API server (automatically starts agents and MCP servers)")]
155    Serve {
156        #[arg(long, help = "Run in foreground mode")]
157        foreground: bool,
158
159        #[arg(long, help = "Kill process using the port if occupied")]
160        kill_port_process: bool,
161    },
162}
163
164#[derive(Debug, Clone, Subcommand)]
165pub enum RestartTarget {
166    #[command(about = "Restart the API server")]
167    Api,
168    #[command(about = "Restart a single agent by name")]
169    Agent { agent: String },
170    #[command(about = "Restart a single MCP server by name")]
171    Mcp {
172        server_name: String,
173        #[arg(long, help = "Rebuild the binary before restarting")]
174        build: bool,
175    },
176}