Skip to content

Commit d61283c

Browse files
committed
♻️ Split Studio reducer into focused submodules
Extract event handlers from the monolithic reduce function into specialized modules organized by domain: - agent.rs: Agent response events (started, progress, complete, streaming) - content.rs: Content updates and file staging operations - git.rs: Git status, file selection, and staging notifications - settings.rs: Preset, gitmoji, emoji, and amend mode settings - ui.rs: Notifications, scrolling, edit mode, and clipboard Also refactor handle_project_config_command into smaller helper functions and make TaskType Copy for more ergonomic handling.
1 parent bebffef commit d61283c

File tree

10 files changed

+618
-412
lines changed

10 files changed

+618
-412
lines changed

src/commands.rs

Lines changed: 74 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -299,16 +299,13 @@ pub fn handle_project_config_command(
299299
print
300300
);
301301

302-
// Set up a header to explain what's happening
303302
println!("\n{}", "✨ Project Configuration".bright_magenta().bold());
304303

305-
// If print-only mode, just display the current project config if it exists
306304
if print {
307305
print_project_config();
308306
return Ok(());
309307
}
310308

311-
// Start with existing project config or empty config (NOT the full personal config)
312309
let mut config = Config::load_project_config().unwrap_or_else(|_| Config {
313310
default_provider: String::new(),
314311
providers: HashMap::new(),
@@ -322,9 +319,38 @@ pub fn handle_project_config_command(
322319
is_project_config: true,
323320
});
324321

325-
// Track what we're changing
326322
let mut changes_made = false;
327323

324+
// Apply provider settings
325+
let provider_name = apply_provider_settings(
326+
&mut config,
327+
common,
328+
model,
329+
fast_model,
330+
token_limit,
331+
param,
332+
&mut changes_made,
333+
)?;
334+
335+
// Apply common settings
336+
apply_common_settings(&mut config, common, subagent_timeout, &mut changes_made)?;
337+
338+
// Display result
339+
display_project_config_result(&config, changes_made, &provider_name)?;
340+
341+
Ok(())
342+
}
343+
344+
/// Apply provider-related settings to config
345+
fn apply_provider_settings(
346+
config: &mut Config,
347+
common: &CommonParams,
348+
model: Option<String>,
349+
fast_model: Option<String>,
350+
token_limit: Option<usize>,
351+
param: Option<Vec<String>>,
352+
changes_made: &mut bool,
353+
) -> anyhow::Result<String> {
328354
// Apply provider change
329355
if let Some(provider_str) = &common.provider {
330356
let provider: Provider = provider_str.parse().map_err(|_| {
@@ -337,16 +363,15 @@ pub fn handle_project_config_command(
337363

338364
if config.default_provider != provider.name() {
339365
config.default_provider = provider.name().to_string();
340-
// Ensure provider entry exists
341366
config
342367
.providers
343368
.entry(provider.name().to_string())
344369
.or_default();
345-
changes_made = true;
370+
*changes_made = true;
346371
}
347372
}
348373

349-
// Get provider name to use (from CLI or existing default)
374+
// Get provider name to use
350375
let provider_name = common
351376
.provider
352377
.clone()
@@ -359,109 +384,115 @@ pub fn handle_project_config_command(
359384
})
360385
.unwrap_or_else(|| Provider::default().name().to_string());
361386

362-
// Ensure provider config entry exists if we're setting model/fast_model/token_limit/params
387+
// Ensure provider config entry exists if setting model options
363388
if model.is_some() || fast_model.is_some() || token_limit.is_some() || param.is_some() {
364389
config.providers.entry(provider_name.clone()).or_default();
365390
}
366391

367-
// Apply model change
392+
// Apply model settings
368393
if let Some(m) = model
369-
&& let Some(provider_config) = config.providers.get_mut(&provider_name)
370-
&& provider_config.model != m
394+
&& let Some(pc) = config.providers.get_mut(&provider_name)
395+
&& pc.model != m
371396
{
372-
provider_config.model = m;
373-
changes_made = true;
397+
pc.model = m;
398+
*changes_made = true;
374399
}
375400

376-
// Apply fast model change
377401
if let Some(fm) = fast_model
378-
&& let Some(provider_config) = config.providers.get_mut(&provider_name)
379-
&& provider_config.fast_model != Some(fm.clone())
402+
&& let Some(pc) = config.providers.get_mut(&provider_name)
403+
&& pc.fast_model != Some(fm.clone())
380404
{
381-
provider_config.fast_model = Some(fm);
382-
changes_made = true;
405+
pc.fast_model = Some(fm);
406+
*changes_made = true;
383407
}
384408

385-
// Apply token limit
386409
if let Some(limit) = token_limit
387-
&& let Some(provider_config) = config.providers.get_mut(&provider_name)
388-
&& provider_config.token_limit != Some(limit)
410+
&& let Some(pc) = config.providers.get_mut(&provider_name)
411+
&& pc.token_limit != Some(limit)
389412
{
390-
provider_config.token_limit = Some(limit);
391-
changes_made = true;
413+
pc.token_limit = Some(limit);
414+
*changes_made = true;
392415
}
393416

394-
// Apply additional params
395417
if let Some(params) = param
396-
&& let Some(provider_config) = config.providers.get_mut(&provider_name)
418+
&& let Some(pc) = config.providers.get_mut(&provider_name)
397419
{
398420
let additional_params = parse_additional_params(&params);
399-
if provider_config.additional_params != additional_params {
400-
provider_config.additional_params = additional_params;
401-
changes_made = true;
421+
if pc.additional_params != additional_params {
422+
pc.additional_params = additional_params;
423+
*changes_made = true;
402424
}
403425
}
404426

405-
// Apply gitmoji setting
427+
Ok(provider_name)
428+
}
429+
430+
/// Apply common settings (gitmoji, instructions, preset, timeout)
431+
fn apply_common_settings(
432+
config: &mut Config,
433+
common: &CommonParams,
434+
subagent_timeout: Option<u64>,
435+
changes_made: &mut bool,
436+
) -> anyhow::Result<()> {
406437
if let Some(use_gitmoji) = common.resolved_gitmoji()
407438
&& config.use_gitmoji != use_gitmoji
408439
{
409440
config.use_gitmoji = use_gitmoji;
410-
changes_made = true;
441+
*changes_made = true;
411442
}
412443

413-
// Apply instructions
414444
if let Some(instr) = &common.instructions
415445
&& config.instructions != *instr
416446
{
417447
config.instructions.clone_from(instr);
418-
changes_made = true;
448+
*changes_made = true;
419449
}
420450

421-
// Apply preset
422451
if let Some(preset) = &common.preset {
423452
let preset_library = get_instruction_preset_library();
424453
if preset_library.get_preset(preset).is_some() {
425454
if config.instruction_preset != *preset {
426455
config.instruction_preset.clone_from(preset);
427-
changes_made = true;
456+
*changes_made = true;
428457
}
429458
} else {
430459
return Err(anyhow!("Invalid preset: {}", preset));
431460
}
432461
}
433462

434-
// Apply subagent timeout
435463
if let Some(timeout) = subagent_timeout
436464
&& config.subagent_timeout_secs != timeout
437465
{
438466
config.subagent_timeout_secs = timeout;
439-
changes_made = true;
467+
*changes_made = true;
440468
}
441469

470+
Ok(())
471+
}
472+
473+
/// Display the result of project config command
474+
fn display_project_config_result(
475+
config: &Config,
476+
changes_made: bool,
477+
_provider_name: &str,
478+
) -> anyhow::Result<()> {
442479
if changes_made {
443-
// Save to project config file (only contains what we set)
444480
config.save_as_project_config()?;
445481
ui::print_success("Project configuration created/updated successfully.");
446482
println!();
447-
448-
// Print a notice about API keys not being stored in project config
449483
println!(
450484
"{}",
451485
"Note: API keys are never stored in project configuration files."
452486
.yellow()
453487
.italic()
454488
);
455489
println!();
456-
457-
// Print the newly created/updated config
458490
println!("{}", "Current project configuration:".bright_cyan().bold());
459-
print_configuration(&config);
491+
print_configuration(config);
460492
} else {
461493
println!("{}", "No changes made to project configuration.".yellow());
462494
println!();
463495

464-
// Check if a project config exists and show it if found
465496
if let Ok(project_config) = Config::load_project_config() {
466497
println!("{}", "Current project configuration:".bright_cyan().bold());
467498
print_configuration(&project_config);
@@ -474,7 +505,6 @@ pub fn handle_project_config_command(
474505
);
475506
}
476507
}
477-
478508
Ok(())
479509
}
480510

src/common.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@ pub struct CommonParams {
2828
conflicts_with = "no_gitmoji",
2929
action = clap::ArgAction::SetTrue
3030
)]
31-
gitmoji_flag: bool,
31+
pub gitmoji_flag: bool,
3232

3333
/// Disable Gitmoji
3434
#[arg(long = "no-gitmoji", help = "Disable Gitmoji", action = clap::ArgAction::SetTrue)]
35-
no_gitmoji: bool,
35+
pub no_gitmoji: bool,
3636

3737
/// Internal: resolved gitmoji value (Some(true), Some(false), or None)
3838
#[arg(skip)]

src/studio/events.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ pub enum StudioEvent {
218218
// ═══════════════════════════════════════════════════════════════════════════════
219219

220220
/// Types of agent tasks
221-
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
221+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
222222
pub enum TaskType {
223223
Commit,
224224
Review,

0 commit comments

Comments
 (0)