systemprompt_cli/commands/admin/setup/
mod.rs1pub mod ai_config;
9pub mod catalog;
10mod common;
11mod docker;
12mod docker_compose;
13mod docker_database;
14mod postgres;
15mod profile;
16mod profile_sections;
17mod secrets;
18mod types;
19mod wizard;
20mod wizard_dry_run;
21mod wizard_prompts;
22
23use crate::shared::CommandOutput;
24use anyhow::Result;
25use clap::Args;
26
27pub use secrets::SecretsData;
28pub use types::*;
29
30#[derive(Debug, Args)]
31#[expect(
32 clippy::struct_excessive_bools,
33 reason = "each bool is an independent clap CLI flag, not a state machine"
34)]
35pub struct SetupArgs {
36 #[arg(
37 short,
38 long,
39 help = "Target environment name (e.g., dev, staging, prod)"
40 )]
41 pub environment: Option<String>,
42
43 #[arg(
44 long,
45 help = "Use Docker for PostgreSQL (default: use existing installation)"
46 )]
47 pub docker: bool,
48
49 #[arg(
50 long,
51 env = "SYSTEMPROMPT_DB_HOST",
52 default_value = "localhost",
53 help = "PostgreSQL host"
54 )]
55 pub db_host: String,
56
57 #[arg(
58 long,
59 env = "SYSTEMPROMPT_DB_PORT",
60 default_value = "5432",
61 help = "PostgreSQL port"
62 )]
63 pub db_port: u16,
64
65 #[arg(
66 long,
67 env = "SYSTEMPROMPT_DB_USER",
68 help = "PostgreSQL user (default: systemprompt_`<env>`)"
69 )]
70 pub db_user: Option<String>,
71
72 #[arg(
73 long,
74 env = "SYSTEMPROMPT_DB_PASSWORD",
75 help = "PostgreSQL password (auto-generated if not provided)"
76 )]
77 pub db_password: Option<String>,
78
79 #[arg(
80 long,
81 env = "SYSTEMPROMPT_DB_NAME",
82 help = "PostgreSQL database name (default: systemprompt_`<env>`)"
83 )]
84 pub db_name: Option<String>,
85
86 #[arg(long, env = "GEMINI_API_KEY", help = "Google AI (Gemini) API key")]
87 pub gemini_key: Option<String>,
88
89 #[arg(long, env = "ANTHROPIC_API_KEY", help = "Anthropic (Claude) API key")]
90 pub anthropic_key: Option<String>,
91
92 #[arg(long, env = "OPENAI_API_KEY", help = "OpenAI (GPT) API key")]
93 pub openai_key: Option<String>,
94
95 #[arg(long, env = "GITHUB_TOKEN", help = "GitHub token (optional)")]
96 pub github_token: Option<String>,
97
98 #[arg(
99 long,
100 env = "SYSTEMPROMPT_DEFAULT_PROVIDER",
101 help = "Provider to make the default (gemini | anthropic | openai); must have a key. \
102 In interactive mode the selected provider is used instead."
103 )]
104 pub default_provider: Option<String>,
105
106 #[arg(long, help = "Run database migrations after setup")]
107 pub migrate: bool,
108
109 #[arg(
110 long,
111 conflicts_with = "migrate",
112 help = "Skip migrations (non-interactive default)"
113 )]
114 pub no_migrate: bool,
115
116 #[arg(long, help = "Preview setup without creating files or making changes")]
117 pub dry_run: bool,
118
119 #[arg(short = 'y', long, help = "Skip confirmation prompts")]
120 pub yes: bool,
121
122 #[arg(
123 long,
124 help = "Overwrite existing profile/secrets files (default: preserve them)"
125 )]
126 pub force: bool,
127}
128
129impl SetupArgs {
130 pub fn effective_db_user(&self, env_name: &str) -> String {
131 self.db_user
132 .clone()
133 .unwrap_or_else(|| format!("systemprompt_{}", env_name))
134 }
135
136 pub fn effective_db_name(&self, env_name: &str) -> String {
137 self.db_name
138 .clone()
139 .unwrap_or_else(|| format!("systemprompt_{}", env_name))
140 }
141
142 pub const fn has_ai_provider(&self) -> bool {
143 self.gemini_key.is_some() || self.anthropic_key.is_some() || self.openai_key.is_some()
144 }
145}
146
147pub async fn execute(args: SetupArgs, config: &crate::CliConfig) -> Result<CommandOutput> {
148 wizard::execute(args, config).await
149}