1pub use crate::mcp_types::AppToolApproval;
7pub use crate::mcp_types::McpServerAuth;
8pub use crate::mcp_types::McpServerConfig;
9pub use crate::mcp_types::McpServerDisabledReason;
10pub use crate::mcp_types::McpServerEnvVar;
11pub use crate::mcp_types::McpServerOAuthConfig;
12pub use crate::mcp_types::McpServerToolConfig;
13pub use crate::mcp_types::McpServerTransportConfig;
14pub use crate::mcp_types::RawMcpServerConfig;
15pub use crate::shell_environment_policy::ShellEnvironmentPolicyToml;
16pub use codex_protocol::config_types::AltScreenMode;
17pub use codex_protocol::config_types::ApprovalsReviewer;
18pub use codex_protocol::config_types::ModeKind;
19pub use codex_protocol::config_types::Personality;
20pub use codex_protocol::config_types::ServiceTier;
21pub use codex_protocol::config_types::WebSearchMode;
22use codex_utils_absolute_path::AbsolutePathBuf;
23use std::collections::BTreeMap;
24use std::collections::HashMap;
25use std::fmt;
26
27use schemars::JsonSchema;
28use serde::Deserialize;
29use serde::Serialize;
30
31pub use crate::tui_keymap::KeybindingSpec;
32pub use crate::tui_keymap::KeybindingsSpec;
33pub use crate::tui_keymap::MAX_FUNCTION_KEY;
34pub use crate::tui_keymap::TuiApprovalKeymap;
35pub use crate::tui_keymap::TuiChatKeymap;
36pub use crate::tui_keymap::TuiComposerKeymap;
37pub use crate::tui_keymap::TuiEditorKeymap;
38pub use crate::tui_keymap::TuiGlobalKeymap;
39pub use crate::tui_keymap::TuiKeymap;
40pub use crate::tui_keymap::TuiListKeymap;
41pub use crate::tui_keymap::TuiPagerKeymap;
42pub use crate::tui_keymap::TuiVimNormalKeymap;
43pub use crate::tui_keymap::TuiVimOperatorKeymap;
44
45pub const DEFAULT_OTEL_ENVIRONMENT: &str = "dev";
46pub const DEFAULT_MEMORIES_MAX_ROLLOUTS_PER_STARTUP: usize = 2;
47pub const DEFAULT_MEMORIES_MAX_ROLLOUT_AGE_DAYS: i64 = 10;
48pub const DEFAULT_MEMORIES_MIN_ROLLOUT_IDLE_HOURS: i64 = 6;
49pub const DEFAULT_MEMORIES_MIN_RATE_LIMIT_REMAINING_PERCENT: i64 = 25;
50pub const DEFAULT_MEMORIES_MAX_RAW_MEMORIES_FOR_CONSOLIDATION: usize = 256;
51pub const DEFAULT_MEMORIES_MAX_UNUSED_DAYS: i64 = 30;
52const MIN_MEMORIES_MAX_RAW_MEMORIES_FOR_CONSOLIDATION: usize = 1;
53const MAX_MEMORIES_MAX_RAW_MEMORIES_FOR_CONSOLIDATION: usize = 4096;
54const MIN_MEMORIES_MAX_ROLLOUTS_PER_STARTUP: usize = 1;
55const MAX_MEMORIES_MAX_ROLLOUTS_PER_STARTUP: usize = 128;
56
57const fn default_enabled() -> bool {
58 true
59}
60
61#[derive(Serialize, Deserialize, Debug, Default, Copy, Clone, PartialEq, Eq, JsonSchema)]
63#[serde(rename_all = "kebab-case")]
64pub enum SessionPickerViewMode {
65 Comfortable,
66 #[default]
67 Dense,
68}
69
70impl SessionPickerViewMode {
71 pub const fn as_str(self) -> &'static str {
72 match self {
73 Self::Comfortable => "comfortable",
74 Self::Dense => "dense",
75 }
76 }
77}
78
79impl fmt::Display for SessionPickerViewMode {
80 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
81 f.write_str(self.as_str())
82 }
83}
84
85#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Eq, JsonSchema)]
87#[serde(rename_all = "kebab-case")]
88pub enum ResumeCwdMode {
89 Current,
91 Session,
93}
94
95impl ResumeCwdMode {
96 pub const fn as_str(self) -> &'static str {
97 match self {
98 Self::Current => "current",
99 Self::Session => "session",
100 }
101 }
102}
103
104#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
106#[serde(rename_all = "lowercase")]
107pub enum AuthCredentialsStoreMode {
108 #[default]
109 File,
111 Keyring,
113 Auto,
115 Ephemeral,
117}
118
119#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
121#[serde(rename_all = "lowercase")]
122pub enum OAuthCredentialsStoreMode {
123 #[default]
128 Auto,
129 File,
132 Keyring,
134}
135
136#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
138#[serde(rename_all = "lowercase")]
139pub enum AuthKeyringBackendKind {
140 Direct,
142 Secrets,
144}
145
146impl Default for AuthKeyringBackendKind {
147 fn default() -> Self {
148 if cfg!(windows) {
149 Self::Secrets
150 } else {
151 Self::Direct
152 }
153 }
154}
155
156#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, JsonSchema)]
157#[serde(rename_all = "kebab-case")]
158pub enum WindowsSandboxModeToml {
159 Elevated,
160 Unelevated,
161}
162
163#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Eq, JsonSchema)]
164#[schemars(deny_unknown_fields)]
165pub struct WindowsToml {
166 pub sandbox: Option<WindowsSandboxModeToml>,
167 pub sandbox_private_desktop: Option<bool>,
170}
171
172#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, JsonSchema)]
173pub enum UriBasedFileOpener {
174 #[serde(rename = "vscode")]
175 VsCode,
176
177 #[serde(rename = "vscode-insiders")]
178 VsCodeInsiders,
179
180 #[serde(rename = "windsurf")]
181 Windsurf,
182
183 #[serde(rename = "cursor")]
184 Cursor,
185
186 #[serde(rename = "none")]
188 None,
189}
190
191#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, JsonSchema)]
193#[serde(default)]
194#[schemars(deny_unknown_fields)]
195pub struct History {
196 pub persistence: HistoryPersistence,
198
199 pub max_bytes: Option<usize>,
202}
203
204#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Default, JsonSchema)]
205#[serde(rename_all = "kebab-case")]
206pub enum HistoryPersistence {
207 #[default]
209 SaveAll,
210 None,
212}
213
214#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, JsonSchema)]
218#[schemars(deny_unknown_fields)]
219pub struct AnalyticsConfigToml {
220 pub enabled: Option<bool>,
222}
223
224#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, JsonSchema)]
225#[schemars(deny_unknown_fields)]
226pub struct FeedbackConfigToml {
227 pub enabled: Option<bool>,
229}
230
231#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, Hash, JsonSchema)]
232#[serde(rename_all = "snake_case")]
233pub enum ToolSuggestDiscoverableType {
234 Connector,
235 Plugin,
236}
237
238#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash, JsonSchema)]
239#[schemars(deny_unknown_fields)]
240pub struct ToolSuggestDiscoverable {
241 #[serde(rename = "type")]
242 pub kind: ToolSuggestDiscoverableType,
243 pub id: String,
244}
245
246#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash, JsonSchema)]
247#[schemars(deny_unknown_fields)]
248pub struct ToolSuggestDisabledTool {
249 #[serde(rename = "type")]
250 pub kind: ToolSuggestDiscoverableType,
251 pub id: String,
252}
253
254impl ToolSuggestDisabledTool {
255 pub fn plugin(id: impl Into<String>) -> Self {
256 Self {
257 kind: ToolSuggestDiscoverableType::Plugin,
258 id: id.into(),
259 }
260 }
261
262 pub fn connector(id: impl Into<String>) -> Self {
263 Self {
264 kind: ToolSuggestDiscoverableType::Connector,
265 id: id.into(),
266 }
267 }
268
269 pub fn normalized(&self) -> Option<Self> {
270 let id = self.id.trim();
271 (!id.is_empty()).then(|| Self {
272 kind: self.kind,
273 id: id.to_string(),
274 })
275 }
276}
277
278#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Default, JsonSchema)]
279#[schemars(deny_unknown_fields)]
280pub struct ToolSuggestConfig {
281 #[serde(default)]
282 pub discoverables: Vec<ToolSuggestDiscoverable>,
283 #[serde(default)]
284 pub disabled_tools: Vec<ToolSuggestDisabledTool>,
285}
286
287#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, JsonSchema)]
289#[schemars(deny_unknown_fields)]
290pub struct MemoriesToml {
291 #[serde(alias = "no_memories_if_mcp_or_web_search")]
293 pub disable_on_external_context: Option<bool>,
294 pub generate_memories: Option<bool>,
296 pub use_memories: Option<bool>,
298 pub dedicated_tools: Option<bool>,
300 #[schemars(range(min = 1, max = 4096))]
302 pub max_raw_memories_for_consolidation: Option<usize>,
303 pub max_unused_days: Option<i64>,
305 pub max_rollout_age_days: Option<i64>,
307 #[schemars(range(min = 1, max = 128))]
309 pub max_rollouts_per_startup: Option<usize>,
310 pub min_rollout_idle_hours: Option<i64>,
312 #[schemars(range(min = 0, max = 100))]
314 pub min_rate_limit_remaining_percent: Option<i64>,
315 pub extract_model: Option<String>,
317 pub consolidation_model: Option<String>,
319}
320
321#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
323pub struct MemoriesConfig {
324 pub disable_on_external_context: bool,
325 pub generate_memories: bool,
326 pub use_memories: bool,
327 pub dedicated_tools: bool,
328 pub max_raw_memories_for_consolidation: usize,
329 pub max_unused_days: i64,
330 pub max_rollout_age_days: i64,
331 pub max_rollouts_per_startup: usize,
332 pub min_rollout_idle_hours: i64,
333 pub min_rate_limit_remaining_percent: i64,
334 pub extract_model: Option<String>,
335 pub consolidation_model: Option<String>,
336}
337
338impl Default for MemoriesConfig {
339 fn default() -> Self {
340 Self {
341 disable_on_external_context: false,
342 generate_memories: true,
343 use_memories: true,
344 dedicated_tools: false,
345 max_raw_memories_for_consolidation: DEFAULT_MEMORIES_MAX_RAW_MEMORIES_FOR_CONSOLIDATION,
346 max_unused_days: DEFAULT_MEMORIES_MAX_UNUSED_DAYS,
347 max_rollout_age_days: DEFAULT_MEMORIES_MAX_ROLLOUT_AGE_DAYS,
348 max_rollouts_per_startup: DEFAULT_MEMORIES_MAX_ROLLOUTS_PER_STARTUP,
349 min_rollout_idle_hours: DEFAULT_MEMORIES_MIN_ROLLOUT_IDLE_HOURS,
350 min_rate_limit_remaining_percent: DEFAULT_MEMORIES_MIN_RATE_LIMIT_REMAINING_PERCENT,
351 extract_model: None,
352 consolidation_model: None,
353 }
354 }
355}
356
357impl From<MemoriesToml> for MemoriesConfig {
358 fn from(toml: MemoriesToml) -> Self {
359 let defaults = Self::default();
360 Self {
361 disable_on_external_context: toml
362 .disable_on_external_context
363 .unwrap_or(defaults.disable_on_external_context),
364 generate_memories: toml.generate_memories.unwrap_or(defaults.generate_memories),
365 use_memories: toml.use_memories.unwrap_or(defaults.use_memories),
366 dedicated_tools: toml.dedicated_tools.unwrap_or(defaults.dedicated_tools),
367 max_raw_memories_for_consolidation: toml
368 .max_raw_memories_for_consolidation
369 .unwrap_or(defaults.max_raw_memories_for_consolidation)
370 .clamp(
371 MIN_MEMORIES_MAX_RAW_MEMORIES_FOR_CONSOLIDATION,
372 MAX_MEMORIES_MAX_RAW_MEMORIES_FOR_CONSOLIDATION,
373 ),
374 max_unused_days: toml
375 .max_unused_days
376 .unwrap_or(defaults.max_unused_days)
377 .clamp(0, 365),
378 max_rollout_age_days: toml
379 .max_rollout_age_days
380 .unwrap_or(defaults.max_rollout_age_days)
381 .clamp(0, 90),
382 max_rollouts_per_startup: toml
383 .max_rollouts_per_startup
384 .unwrap_or(defaults.max_rollouts_per_startup)
385 .clamp(
386 MIN_MEMORIES_MAX_ROLLOUTS_PER_STARTUP,
387 MAX_MEMORIES_MAX_ROLLOUTS_PER_STARTUP,
388 ),
389 min_rollout_idle_hours: toml
390 .min_rollout_idle_hours
391 .unwrap_or(defaults.min_rollout_idle_hours)
392 .clamp(1, 48),
393 min_rate_limit_remaining_percent: toml
394 .min_rate_limit_remaining_percent
395 .unwrap_or(defaults.min_rate_limit_remaining_percent)
396 .clamp(0, 100),
397 extract_model: toml.extract_model,
398 consolidation_model: toml.consolidation_model,
399 }
400 }
401}
402
403#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Default, JsonSchema)]
405#[schemars(deny_unknown_fields)]
406pub struct AppsDefaultConfig {
407 #[serde(default = "default_enabled")]
409 pub enabled: bool,
410
411 #[serde(default, skip_serializing_if = "Option::is_none")]
413 pub approvals_reviewer: Option<ApprovalsReviewer>,
414
415 #[serde(
417 default = "default_enabled",
418 skip_serializing_if = "std::clone::Clone::clone"
419 )]
420 pub destructive_enabled: bool,
421
422 #[serde(
424 default = "default_enabled",
425 skip_serializing_if = "std::clone::Clone::clone"
426 )]
427 pub open_world_enabled: bool,
428
429 #[serde(default, skip_serializing_if = "Option::is_none")]
431 pub default_tools_approval_mode: Option<AppToolApproval>,
432}
433
434#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Default, JsonSchema)]
436#[schemars(deny_unknown_fields)]
437pub struct AppToolConfig {
438 #[serde(default, skip_serializing_if = "Option::is_none")]
440 pub enabled: Option<bool>,
441
442 #[serde(default, skip_serializing_if = "Option::is_none")]
444 pub approval_mode: Option<AppToolApproval>,
445}
446
447#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Default, JsonSchema)]
449#[schemars(deny_unknown_fields)]
450pub struct AppToolsConfig {
451 #[serde(default, flatten)]
453 pub tools: HashMap<String, AppToolConfig>,
454}
455
456#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, JsonSchema)]
458#[schemars(deny_unknown_fields)]
459pub struct AppConfig {
460 #[serde(default = "default_enabled")]
462 pub enabled: bool,
463
464 #[serde(default, skip_serializing_if = "Option::is_none")]
466 pub approvals_reviewer: Option<ApprovalsReviewer>,
467
468 #[serde(default, skip_serializing_if = "Option::is_none")]
470 pub destructive_enabled: Option<bool>,
471
472 #[serde(default, skip_serializing_if = "Option::is_none")]
474 pub open_world_enabled: Option<bool>,
475
476 #[serde(default, skip_serializing_if = "Option::is_none")]
478 pub default_tools_approval_mode: Option<AppToolApproval>,
479
480 #[serde(default, skip_serializing_if = "Option::is_none")]
482 pub default_tools_enabled: Option<bool>,
483
484 #[serde(default, skip_serializing_if = "Option::is_none")]
486 pub tools: Option<AppToolsConfig>,
487}
488
489#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, JsonSchema)]
491#[schemars(deny_unknown_fields)]
492pub struct AppsConfigToml {
493 #[serde(default, rename = "_default", skip_serializing_if = "Option::is_none")]
495 pub default: Option<AppsDefaultConfig>,
496
497 #[serde(default, flatten)]
499 pub apps: HashMap<String, AppConfig>,
500}
501
502#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema)]
505#[serde(rename_all = "kebab-case")]
506pub enum OtelHttpProtocol {
507 Binary,
509 Json,
511}
512
513#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, JsonSchema)]
514#[schemars(deny_unknown_fields)]
515#[serde(rename_all = "kebab-case")]
516pub struct OtelTlsConfig {
517 pub ca_certificate: Option<AbsolutePathBuf>,
518 pub client_certificate: Option<AbsolutePathBuf>,
519 pub client_private_key: Option<AbsolutePathBuf>,
520}
521
522#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema)]
524#[schemars(deny_unknown_fields)]
525#[serde(rename_all = "kebab-case")]
526pub enum OtelExporterKind {
527 None,
528 Statsig,
529 OtlpHttp {
530 endpoint: String,
531 #[serde(default)]
532 headers: HashMap<String, String>,
533 protocol: OtelHttpProtocol,
534 #[serde(default)]
535 tls: Option<OtelTlsConfig>,
536 },
537 OtlpGrpc {
538 endpoint: String,
539 #[serde(default)]
540 headers: HashMap<String, String>,
541 #[serde(default)]
542 tls: Option<OtelTlsConfig>,
543 },
544}
545
546#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, JsonSchema)]
548#[schemars(deny_unknown_fields)]
549pub struct OtelConfigToml {
550 pub log_user_prompt: Option<bool>,
552
553 pub environment: Option<String>,
555
556 pub exporter: Option<OtelExporterKind>,
558
559 pub trace_exporter: Option<OtelExporterKind>,
561
562 pub metrics_exporter: Option<OtelExporterKind>,
564
565 pub span_attributes: Option<BTreeMap<String, String>>,
567
568 pub tracestate: Option<BTreeMap<String, BTreeMap<String, String>>>,
570}
571
572#[derive(Debug, Clone, PartialEq)]
574pub struct OtelConfig {
575 pub log_user_prompt: bool,
576 pub environment: String,
577 pub exporter: OtelExporterKind,
578 pub trace_exporter: OtelExporterKind,
579 pub metrics_exporter: OtelExporterKind,
580 pub span_attributes: BTreeMap<String, String>,
581 pub tracestate: BTreeMap<String, BTreeMap<String, String>>,
582}
583
584impl Default for OtelConfig {
585 fn default() -> Self {
586 OtelConfig {
587 log_user_prompt: false,
588 environment: DEFAULT_OTEL_ENVIRONMENT.to_owned(),
589 exporter: OtelExporterKind::None,
590 trace_exporter: OtelExporterKind::None,
591 metrics_exporter: OtelExporterKind::Statsig,
592 span_attributes: BTreeMap::new(),
593 tracestate: BTreeMap::new(),
594 }
595 }
596}
597
598#[derive(Serialize, Debug, Clone, PartialEq, Eq, Deserialize, JsonSchema)]
599#[serde(untagged)]
600pub enum Notifications {
601 Enabled(bool),
602 Custom(Vec<String>),
603}
604
605impl Default for Notifications {
606 fn default() -> Self {
607 Self::Enabled(true)
608 }
609}
610
611#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, JsonSchema, Default)]
612#[serde(rename_all = "lowercase")]
613pub enum NotificationMethod {
614 #[default]
615 Auto,
616 Osc9,
617 Bel,
618}
619
620impl fmt::Display for NotificationMethod {
621 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
622 match self {
623 NotificationMethod::Auto => write!(f, "auto"),
624 NotificationMethod::Osc9 => write!(f, "osc9"),
625 NotificationMethod::Bel => write!(f, "bel"),
626 }
627 }
628}
629
630#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, JsonSchema, Default)]
631#[serde(rename_all = "lowercase")]
632pub enum NotificationCondition {
633 #[default]
635 Unfocused,
636 Always,
638}
639
640impl fmt::Display for NotificationCondition {
641 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
642 match self {
643 NotificationCondition::Unfocused => write!(f, "unfocused"),
644 NotificationCondition::Always => write!(f, "always"),
645 }
646 }
647}
648
649#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, JsonSchema, Default)]
650#[serde(rename_all = "kebab-case")]
651pub enum TuiPetAnchor {
652 #[default]
654 Composer,
655 ScreenBottom,
657}
658
659#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Default, JsonSchema)]
660#[schemars(deny_unknown_fields)]
661pub struct TuiNotificationSettings {
662 #[serde(default, rename = "notifications")]
665 pub notifications: Notifications,
666
667 #[serde(default, rename = "notification_method")]
670 pub method: NotificationMethod,
671
672 #[serde(default, rename = "notification_condition")]
675 pub condition: NotificationCondition,
676}
677
678#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Default, JsonSchema)]
679#[schemars(deny_unknown_fields)]
680pub struct ModelAvailabilityNuxConfig {
681 #[serde(default, flatten)]
683 pub shown_count: HashMap<String, u32>,
684}
685
686pub const DEFAULT_TERMINAL_RESIZE_REFLOW_FALLBACK_MAX_ROWS: usize = 1_000;
688
689#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, JsonSchema)]
691#[schemars(deny_unknown_fields)]
692pub struct Tui {
693 #[serde(default, flatten)]
694 pub notification_settings: TuiNotificationSettings,
695
696 #[serde(default = "default_true")]
699 pub animations: bool,
700
701 #[serde(default = "default_true")]
704 pub show_tooltips: bool,
705
706 #[serde(default)]
709 pub vim_mode_default: bool,
710
711 #[serde(default)]
714 pub raw_output_mode: bool,
715
716 #[serde(default)]
722 pub alternate_screen: AltScreenMode,
723
724 #[serde(default)]
729 pub status_line: Option<Vec<String>>,
730
731 #[serde(default = "default_true")]
734 pub status_line_use_colors: bool,
735
736 #[serde(default)]
743 pub terminal_title: Option<Vec<String>>,
744
745 #[serde(default)]
750 pub theme: Option<String>,
751
752 #[serde(default)]
756 pub pet: Option<String>,
757
758 #[serde(default)]
762 pub pet_anchor: TuiPetAnchor,
763
764 #[serde(default)]
766 pub session_picker_view: Option<SessionPickerViewMode>,
767
768 #[serde(default)]
771 pub resume_cwd: Option<ResumeCwdMode>,
772
773 #[serde(default)]
778 pub keymap: TuiKeymap,
779
780 #[serde(default)]
782 pub model_availability_nux: ModelAvailabilityNuxConfig,
783
784 #[serde(default)]
788 #[schemars(range(min = 0))]
789 pub terminal_resize_reflow_max_rows: Option<usize>,
790}
791
792const fn default_true() -> bool {
793 true
794}
795
796#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Default, JsonSchema)]
800#[schemars(deny_unknown_fields)]
801pub struct ExternalConfigMigrationPrompts {
802 pub home: Option<bool>,
804 pub home_last_prompted_at: Option<i64>,
806 #[serde(default)]
808 pub projects: BTreeMap<String, bool>,
809 #[serde(default)]
811 pub project_last_prompted_at: BTreeMap<String, i64>,
812}
813
814#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, JsonSchema)]
815#[schemars(deny_unknown_fields)]
816pub struct Notice {
817 pub hide_full_access_warning: Option<bool>,
819 pub hide_world_writable_warning: Option<bool>,
821 pub fast_default_opt_out: Option<bool>,
823 pub hide_rate_limit_model_nudge: Option<bool>,
825 pub hide_gpt5_1_migration_prompt: Option<bool>,
827 #[serde(rename = "hide_gpt-5.1-codex-max_migration_prompt")]
829 pub hide_gpt_5_1_codex_max_migration_prompt: Option<bool>,
830 #[serde(default)]
832 pub model_migrations: BTreeMap<String, String>,
833 #[serde(default)]
835 pub external_config_migration_prompts: ExternalConfigMigrationPrompts,
836}
837
838pub use crate::skills_config::BundledSkillsConfig;
839pub use crate::skills_config::SkillConfig;
840pub use crate::skills_config::SkillsConfig;
841
842#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema)]
843#[schemars(deny_unknown_fields)]
844pub struct PluginConfig {
845 #[serde(default = "default_enabled")]
846 pub enabled: bool,
847
848 #[serde(default, skip_serializing_if = "HashMap::is_empty")]
850 pub mcp_servers: HashMap<String, PluginMcpServerConfig>,
851}
852
853#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema)]
858#[schemars(deny_unknown_fields)]
859pub struct PluginMcpServerConfig {
860 #[serde(default = "default_enabled")]
862 pub enabled: bool,
863
864 #[serde(default, skip_serializing_if = "Option::is_none")]
866 pub default_tools_approval_mode: Option<AppToolApproval>,
867
868 #[serde(default, skip_serializing_if = "Option::is_none")]
870 pub enabled_tools: Option<Vec<String>>,
871
872 #[serde(default, skip_serializing_if = "Option::is_none")]
874 pub disabled_tools: Option<Vec<String>>,
875
876 #[serde(default, skip_serializing_if = "HashMap::is_empty")]
878 pub tools: HashMap<String, McpServerToolConfig>,
879}
880
881impl Default for PluginMcpServerConfig {
882 fn default() -> Self {
883 Self {
884 enabled: true,
885 default_tools_approval_mode: None,
886 enabled_tools: None,
887 disabled_tools: None,
888 tools: HashMap::new(),
889 }
890 }
891}
892
893#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Default, JsonSchema)]
894#[schemars(deny_unknown_fields)]
895pub struct MarketplaceConfig {
896 #[serde(default)]
898 pub last_updated: Option<String>,
899 #[serde(default)]
901 pub last_revision: Option<String>,
902 #[serde(default)]
904 pub source_type: Option<MarketplaceSourceType>,
905 #[serde(default)]
907 pub source: Option<String>,
908 #[serde(default, rename = "ref")]
910 pub ref_name: Option<String>,
911 #[serde(default)]
913 pub sparse_paths: Option<Vec<String>>,
914}
915
916#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, JsonSchema)]
917#[serde(rename_all = "snake_case")]
918pub enum MarketplaceSourceType {
919 Git,
920 Local,
921}
922
923#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, JsonSchema)]
924#[schemars(deny_unknown_fields)]
925pub struct SandboxWorkspaceWrite {
926 #[serde(default)]
927 pub writable_roots: Vec<AbsolutePathBuf>,
928 #[serde(default)]
929 pub network_access: bool,
930 #[serde(default)]
931 pub exclude_tmpdir_env_var: bool,
932 #[serde(default)]
933 pub exclude_slash_tmp: bool,
934}
935
936#[cfg(test)]
937#[path = "types_tests.rs"]
938mod tests;