1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct Config {
7 pub analysis: AnalysisConfig,
8 pub generation: GenerationConfig,
9 pub output: OutputConfig,
10 pub telemetry: TelemetryConfig,
11 #[serde(default)]
12 pub agent: AgentConfig,
13 #[serde(default)]
15 pub syncable_auth: SyncableAuth,
16}
17
18#[derive(Debug, Clone, Serialize, Deserialize)]
20pub struct AnalysisConfig {
21 pub include_dev_dependencies: bool,
22 pub deep_analysis: bool,
23 pub ignore_patterns: Vec<String>,
24 pub max_file_size: usize,
25}
26
27#[derive(Debug, Clone, Serialize, Deserialize)]
29pub struct GenerationConfig {
30 pub dockerfile: DockerfileConfig,
31 pub compose: ComposeConfig,
32 pub terraform: TerraformConfig,
33}
34
35#[derive(Debug, Clone, Serialize, Deserialize)]
37pub struct DockerfileConfig {
38 pub base_image_override: Option<String>,
39 pub use_multi_stage: bool,
40 pub optimize_for_size: bool,
41 pub include_health_check: bool,
42}
43
44#[derive(Debug, Clone, Serialize, Deserialize)]
46pub struct ComposeConfig {
47 pub version: String,
48 pub include_database: bool,
49 pub include_redis: bool,
50}
51
52#[derive(Debug, Clone, Serialize, Deserialize)]
54pub struct TerraformConfig {
55 pub provider: String,
56 pub include_networking: bool,
57 pub include_monitoring: bool,
58}
59
60#[derive(Debug, Clone, Serialize, Deserialize)]
62pub struct OutputConfig {
63 pub format: OutputFormat,
64 pub overwrite_existing: bool,
65 pub create_backup: bool,
66}
67
68#[derive(Debug, Clone, Serialize, Deserialize)]
69pub enum OutputFormat {
70 Files,
71 Stdout,
72 Json,
73}
74
75#[derive(Debug, Clone, Serialize, Deserialize)]
77pub struct TelemetryConfig {
78 pub enabled: bool,
79}
80
81#[derive(Debug, Clone, Serialize, Deserialize, Default)]
83pub struct AgentConfig {
84 #[serde(skip_serializing_if = "Option::is_none")]
86 pub openai_api_key: Option<String>,
87 #[serde(skip_serializing_if = "Option::is_none")]
89 pub anthropic_api_key: Option<String>,
90 #[serde(skip_serializing_if = "Option::is_none")]
92 pub bedrock: Option<BedrockConfig>,
93 #[serde(skip_serializing_if = "Option::is_none")]
95 pub bedrock_configured: Option<bool>,
96 #[serde(default = "default_provider")]
98 pub default_provider: String,
99 #[serde(skip_serializing_if = "Option::is_none")]
101 pub default_model: Option<String>,
102
103 #[serde(default, skip_serializing_if = "HashMap::is_empty")]
106 pub profiles: HashMap<String, Profile>,
107 #[serde(skip_serializing_if = "Option::is_none")]
109 pub active_profile: Option<String>,
110
111 #[serde(default, skip_serializing_if = "HashMap::is_empty")]
113 pub openai_profiles: HashMap<String, OpenAIProfile>,
114 #[serde(skip_serializing_if = "Option::is_none")]
115 pub openai_active_profile: Option<String>,
116 #[serde(default, skip_serializing_if = "HashMap::is_empty")]
117 pub anthropic_profiles: HashMap<String, AnthropicProfile>,
118 #[serde(skip_serializing_if = "Option::is_none")]
119 pub anthropic_active_profile: Option<String>,
120 #[serde(default, skip_serializing_if = "HashMap::is_empty")]
121 pub bedrock_profiles: HashMap<String, BedrockConfig>,
122 #[serde(skip_serializing_if = "Option::is_none")]
123 pub bedrock_active_profile: Option<String>,
124}
125
126#[derive(Debug, Clone, Serialize, Deserialize, Default)]
128pub struct Profile {
129 #[serde(skip_serializing_if = "Option::is_none")]
131 pub description: Option<String>,
132 #[serde(skip_serializing_if = "Option::is_none")]
134 pub default_provider: Option<String>,
135 #[serde(skip_serializing_if = "Option::is_none")]
137 pub default_model: Option<String>,
138 #[serde(skip_serializing_if = "Option::is_none")]
140 pub openai: Option<OpenAIProfile>,
141 #[serde(skip_serializing_if = "Option::is_none")]
143 pub anthropic: Option<AnthropicProfile>,
144 #[serde(skip_serializing_if = "Option::is_none")]
146 pub bedrock: Option<BedrockConfig>,
147}
148
149#[derive(Debug, Clone, Serialize, Deserialize, Default)]
151pub struct OpenAIProfile {
152 pub api_key: String,
154 #[serde(skip_serializing_if = "Option::is_none")]
156 pub description: Option<String>,
157 #[serde(skip_serializing_if = "Option::is_none")]
159 pub default_model: Option<String>,
160}
161
162#[derive(Debug, Clone, Serialize, Deserialize, Default)]
164pub struct AnthropicProfile {
165 pub api_key: String,
167 #[serde(skip_serializing_if = "Option::is_none")]
169 pub description: Option<String>,
170 #[serde(skip_serializing_if = "Option::is_none")]
172 pub default_model: Option<String>,
173}
174
175#[derive(Debug, Clone, Serialize, Deserialize, Default)]
177pub struct BedrockConfig {
178 #[serde(skip_serializing_if = "Option::is_none")]
180 pub region: Option<String>,
181 #[serde(skip_serializing_if = "Option::is_none")]
183 pub profile: Option<String>,
184 #[serde(skip_serializing_if = "Option::is_none")]
186 pub access_key_id: Option<String>,
187 #[serde(skip_serializing_if = "Option::is_none")]
189 pub secret_access_key: Option<String>,
190 #[serde(skip_serializing_if = "Option::is_none")]
192 pub bearer_token: Option<String>,
193 #[serde(skip_serializing_if = "Option::is_none")]
195 pub default_model: Option<String>,
196}
197
198#[derive(Debug, Clone, Serialize, Deserialize, Default)]
200pub struct SyncableAuth {
201 #[serde(skip_serializing_if = "Option::is_none")]
203 pub access_token: Option<String>,
204 #[serde(skip_serializing_if = "Option::is_none")]
206 pub refresh_token: Option<String>,
207 #[serde(skip_serializing_if = "Option::is_none")]
209 pub expires_at: Option<u64>,
210 #[serde(skip_serializing_if = "Option::is_none")]
212 pub user_email: Option<String>,
213}
214
215fn default_provider() -> String {
216 "openai".to_string()
217}
218
219impl Default for Config {
220 fn default() -> Self {
221 Self {
222 analysis: AnalysisConfig {
223 include_dev_dependencies: false,
224 deep_analysis: true,
225 ignore_patterns: vec![
226 "node_modules".to_string(),
227 ".git".to_string(),
228 "target".to_string(),
229 "build".to_string(),
230 ],
231 max_file_size: 1024 * 1024, },
233 generation: GenerationConfig {
234 dockerfile: DockerfileConfig {
235 base_image_override: None,
236 use_multi_stage: true,
237 optimize_for_size: true,
238 include_health_check: true,
239 },
240 compose: ComposeConfig {
241 version: "3.8".to_string(),
242 include_database: false,
243 include_redis: false,
244 },
245 terraform: TerraformConfig {
246 provider: "docker".to_string(),
247 include_networking: true,
248 include_monitoring: false,
249 },
250 },
251 output: OutputConfig {
252 format: OutputFormat::Files,
253 overwrite_existing: false,
254 create_backup: true,
255 },
256 telemetry: TelemetryConfig { enabled: true },
257 agent: AgentConfig::default(),
258 syncable_auth: SyncableAuth::default(),
259 }
260 }
261}