pub use super::cloud::{
CloudConfig, CloudStateConfig, GitAuthMethod, GitAuthStateMethod, GitRemoteConfig,
GitRemoteStateConfig,
};
use super::truncation;
use std::path::PathBuf;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum ReviewDepth {
#[default]
Standard,
Comprehensive,
Security,
Incremental,
}
impl ReviewDepth {
pub(crate) fn from_str(s: &str) -> Option<Self> {
match s.to_lowercase().as_str() {
"standard" | "default" | "normal" => Some(Self::Standard),
"comprehensive" | "thorough" | "full" => Some(Self::Comprehensive),
"security" | "secure" | "security-focused" => Some(Self::Security),
"incremental" | "diff" | "changed" => Some(Self::Incremental),
_ => None,
}
}
pub(crate) const fn description(self) -> &'static str {
match self {
Self::Standard => "Balanced review covering functionality, quality, and security",
Self::Comprehensive => "In-depth analysis with priority-ordered checks",
Self::Security => "Security-focused analysis emphasizing OWASP Top 10",
Self::Incremental => "Focused review of changed files only (git diff)",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Verbosity {
Quiet = 0,
Normal = 1,
Verbose = 2,
Full = 3,
Debug = 4,
}
impl From<u8> for Verbosity {
fn from(v: u8) -> Self {
match v {
0 => Self::Quiet,
1 => Self::Normal,
2 => Self::Verbose,
3 => Self::Full,
_ => Self::Debug,
}
}
}
impl Verbosity {
pub(crate) fn truncate_limit(self, content_type: &str) -> usize {
truncation::get_limit(self as u8, content_type)
}
pub(crate) const fn is_debug(self) -> bool {
matches!(self, Self::Debug)
}
pub(crate) const fn is_verbose(self) -> bool {
matches!(self, Self::Verbose | Self::Full | Self::Debug)
}
pub(crate) const fn show_tool_input(self) -> bool {
!matches!(self, Self::Quiet)
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq)]
pub struct BehavioralFlags {
pub(crate) interactive: bool,
pub(crate) auto_detect_stack: bool,
pub(crate) strict_validation: bool,
}
#[derive(Debug, Clone, Copy, Default, PartialEq)]
pub struct FeatureFlags {
pub(crate) checkpoint_enabled: bool,
pub(crate) force_universal_prompt: bool,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Config {
pub(crate) developer_agent: Option<String>,
pub(crate) reviewer_agent: Option<String>,
pub(crate) developer_cmd: Option<String>,
pub(crate) reviewer_cmd: Option<String>,
pub(crate) commit_cmd: Option<String>,
pub(crate) developer_model: Option<String>,
pub(crate) reviewer_model: Option<String>,
pub(crate) developer_provider: Option<String>,
pub(crate) reviewer_provider: Option<String>,
pub(crate) reviewer_json_parser: Option<String>,
pub(crate) features: FeatureFlags,
pub(crate) developer_iters: u32,
pub(crate) reviewer_reviews: u32,
pub(crate) fast_check_cmd: Option<String>,
pub(crate) full_check_cmd: Option<String>,
pub(crate) behavior: BehavioralFlags,
pub(crate) prompt_path: PathBuf,
pub(crate) user_templates_dir: Option<PathBuf>,
pub(crate) developer_context: u8,
pub(crate) reviewer_context: u8,
pub(crate) verbosity: Verbosity,
pub(crate) review_depth: ReviewDepth,
pub(crate) isolation_mode: bool,
pub(crate) git_user_name: Option<String>,
pub(crate) git_user_email: Option<String>,
pub(crate) show_streaming_metrics: bool,
pub(crate) review_format_retries: u32,
pub max_dev_continuations: Option<u32>,
pub max_xsd_retries: Option<u32>,
pub max_same_agent_retries: Option<u32>,
pub max_commit_residual_retries: Option<u32>,
pub execution_history_limit: usize,
pub(crate) cloud: CloudConfig,
}
impl Config {
#[must_use]
pub const fn user_templates_dir(&self) -> Option<&std::path::PathBuf> {
self.user_templates_dir.as_ref()
}
#[must_use]
pub fn test_default() -> Self {
Self {
developer_agent: Some("codex".to_string()),
reviewer_agent: Some("codex".to_string()),
developer_cmd: None,
reviewer_cmd: None,
commit_cmd: None,
developer_model: None,
reviewer_model: None,
developer_provider: None,
reviewer_provider: None,
reviewer_json_parser: None,
features: FeatureFlags {
checkpoint_enabled: true,
force_universal_prompt: false,
},
developer_iters: 0,
reviewer_reviews: 0,
fast_check_cmd: None,
full_check_cmd: None,
behavior: BehavioralFlags {
interactive: false,
auto_detect_stack: false,
strict_validation: false,
},
prompt_path: PathBuf::from(".agent/last_prompt.txt"),
user_templates_dir: None,
developer_context: 0,
reviewer_context: 0,
verbosity: Verbosity::Quiet,
review_depth: ReviewDepth::Standard,
isolation_mode: true,
git_user_name: Some("Test".to_string()),
git_user_email: Some("test@example.com".to_string()),
show_streaming_metrics: false,
review_format_retries: 5,
max_dev_continuations: Some(2),
max_xsd_retries: Some(10),
max_same_agent_retries: Some(2),
max_commit_residual_retries: Some(10),
execution_history_limit: 1000,
cloud: CloudConfig::disabled(),
}
}
#[must_use]
pub fn with_isolation_mode(self, isolation_mode: bool) -> Self {
Self {
isolation_mode,
..self
}
}
#[must_use]
pub fn with_developer_iters(self, iters: u32) -> Self {
Self {
developer_iters: iters,
..self
}
}
#[must_use]
pub fn with_reviewer_reviews(self, reviews: u32) -> Self {
Self {
reviewer_reviews: reviews,
..self
}
}
#[must_use]
pub fn with_auto_detect_stack(self, auto_detect: bool) -> Self {
Self {
behavior: BehavioralFlags {
auto_detect_stack: auto_detect,
..self.behavior
},
..self
}
}
#[must_use]
pub fn with_verbosity(self, verbosity: Verbosity) -> Self {
Self { verbosity, ..self }
}
#[must_use]
pub fn with_review_depth(self, review_depth: ReviewDepth) -> Self {
Self {
review_depth,
..self
}
}
#[must_use]
pub fn with_developer_agent(self, agent: String) -> Self {
Self {
developer_agent: Some(agent),
..self
}
}
#[must_use]
pub fn with_reviewer_agent(self, agent: String) -> Self {
Self {
reviewer_agent: Some(agent),
..self
}
}
}
impl Default for Config {
fn default() -> Self {
super::loader::default_config()
}
}