Skip to content

Commit 6f59c6a

Browse files
committed
Merge remote-tracking branch 'origin/main' into resume
# Conflicts: # src/tui/app.rs
2 parents 764b632 + 684397e commit 6f59c6a

14 files changed

Lines changed: 353 additions & 28 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ Thumbs.db
3939

4040
# AI coding tools
4141
.opencode/
42+
.sisyphus/
4243

4344
# Per-repo aoe config (created by `aoe init`, should be committed per-repo by users)
4445
# Ignored here since this is the aoe tool repo itself

AGENTS.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@
6363
- Commit messages: use conventional commit prefixes (`feat:`, `fix:`, `docs:`, `refactor:`).
6464
- PRs: include a clear “what/why”, how you tested (`cargo test`, plus any manual tmux/TUI checks), and screenshots/recordings for UI changes.
6565

66+
## Git Configuration
67+
68+
- Do not modify git configuration (e.g., `.gitconfig`, `.git/config`, `git config` commands) without explicit user approval.
69+
- The one exception: adding a new remote to fetch a contributor's fork during PR code review is allowed without asking.
70+
6671
## Local Data & Configuration Tips
6772

6873
- Runtime config/data location:

docs/guides/configuration.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,17 @@ All settings below can also be edited from the TUI settings screen (press `s` or
3737
| `AGENT_OF_EMPIRES_PROFILE` | Default profile to use |
3838
| `AGENT_OF_EMPIRES_DEBUG` | Enable debug logging (`1` to enable) |
3939

40+
## Theme
41+
42+
```toml
43+
[theme]
44+
name = "phosphor" # phosphor, tokyo-night-storm, catppuccin-latte
45+
```
46+
47+
| Option | Default | Description |
48+
|--------|---------|-------------|
49+
| `name` | `"phosphor"` | TUI color theme. Available: `phosphor` (default green), `tokyo-night-storm` (dark blue/purple), `catppuccin-latte` (light pastel). |
50+
4051
## Session
4152

4253
```toml

src/session/profile_config.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,4 +703,27 @@ mod tests {
703703
Some(TmuxMouseMode::Enabled)
704704
);
705705
}
706+
707+
#[test]
708+
fn test_merge_configs_with_theme_override() {
709+
let global = Config::default();
710+
let profile = ProfileConfig {
711+
theme: Some(ThemeConfigOverride {
712+
name: Some("tokyo-night".to_string()),
713+
}),
714+
..Default::default()
715+
};
716+
let merged = merge_configs(global, &profile);
717+
assert_eq!(merged.theme.name, "tokyo-night");
718+
}
719+
720+
#[test]
721+
fn test_merge_configs_theme_inherits_when_not_overridden() {
722+
let mut global = Config::default();
723+
global.theme.name = "catppuccin-latte".to_string();
724+
725+
let profile = ProfileConfig::default();
726+
let merged = merge_configs(global, &profile);
727+
assert_eq!(merged.theme.name, "catppuccin-latte");
728+
}
706729
}

src/tui/app.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use std::path::PathBuf;
77
use std::time::Duration;
88

99
use super::home::{HomeView, TerminalMode};
10+
use super::styles::load_theme;
1011
use super::styles::Theme;
1112
use crate::session::{get_update_settings, load_config, save_config, Storage};
1213
use crate::tmux::AvailableTools;
@@ -78,10 +79,17 @@ impl App {
7879
pub fn new(profile: &str, available_tools: AvailableTools) -> Result<Self> {
7980
let storage = Storage::new(profile)?;
8081
let mut home = HomeView::new(storage, available_tools)?;
81-
let theme = Theme::default();
8282

8383
// Check if we need to show welcome or changelog dialogs
8484
let mut config = load_config()?.unwrap_or_default();
85+
86+
// Load theme from config, defaulting to phosphor if empty
87+
let theme_name = if config.theme.name.is_empty() {
88+
"phosphor"
89+
} else {
90+
&config.theme.name
91+
};
92+
let theme = load_theme(theme_name);
8593
let current_version = env!("CARGO_PKG_VERSION").to_string();
8694

8795
if !config.app_state.has_seen_welcome {
@@ -106,6 +114,11 @@ impl App {
106114
})
107115
}
108116

117+
pub fn set_theme(&mut self, name: &str) {
118+
self.theme = load_theme(name);
119+
self.needs_redraw = true;
120+
}
121+
109122
pub async fn run(
110123
&mut self,
111124
terminal: &mut Terminal<CrosstermBackend<std::io::Stdout>>,
@@ -352,6 +365,9 @@ impl App {
352365
}
353366
}
354367
}
368+
Action::SetTheme(name) => {
369+
self.set_theme(&name);
370+
}
355371
}
356372
Ok(())
357373
}
@@ -564,6 +580,7 @@ pub enum Action {
564580
SwitchProfile(String),
565581
EditFile(PathBuf),
566582
StopSession(String),
583+
SetTheme(String),
567584
}
568585

569586
#[cfg(test)]

src/tui/components/preview.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ impl Preview {
6363
if sandbox.enabled {
6464
info_lines.push(Line::from(vec![
6565
Span::styled("Sandbox: ", Style::default().fg(theme.dimmed)),
66-
Span::styled(&sandbox.container_name, Style::default().fg(Color::Magenta)),
66+
Span::styled(&sandbox.container_name, Style::default().fg(theme.sandbox)),
6767
]));
6868
}
6969
}
@@ -194,7 +194,7 @@ impl Preview {
194194
]));
195195
info_lines.push(Line::from(vec![
196196
Span::styled("Branch: ", Style::default().fg(theme.dimmed)),
197-
Span::styled(&wt_info.branch, Style::default().fg(Color::Cyan)),
197+
Span::styled(&wt_info.branch, Style::default().fg(theme.branch)),
198198
]));
199199
info_lines.push(Line::from(vec![
200200
Span::styled("Main: ", Style::default().fg(theme.dimmed)),
@@ -214,9 +214,9 @@ impl Preview {
214214
Span::styled(
215215
managed_text,
216216
Style::default().fg(if wt_info.managed_by_aoe {
217-
Color::Green
217+
theme.worktree_managed
218218
} else {
219-
Color::Yellow
219+
theme.worktree_manual
220220
}),
221221
),
222222
]));

src/tui/dialogs/new_session/render.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ impl NewSessionDialog {
357357
if let Some(error) = &self.error_message {
358358
let error_text = format!("✗ Error: {}", error);
359359
let error_paragraph = Paragraph::new(error_text)
360-
.style(Style::default().fg(Color::Red))
360+
.style(Style::default().fg(theme.error))
361361
.wrap(Wrap { trim: true });
362362
frame.render_widget(error_paragraph, chunks[hint_chunk]);
363363
} else {

src/tui/diff/render.rs

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use ratatui::{
44
layout::{Constraint, Direction, Layout, Rect},
5-
style::{Color, Modifier, Style},
5+
style::{Modifier, Style},
66
text::{Line, Span},
77
widgets::{
88
Block, Borders, Clear, List, ListItem, Padding, Paragraph, Scrollbar, ScrollbarOrientation,
@@ -98,9 +98,15 @@ impl DiffView {
9898
Style::default().fg(theme.dimmed),
9999
),
100100
Span::styled(" ", Style::default()),
101-
Span::styled(format!("+{}", additions), Style::default().fg(Color::Green)),
101+
Span::styled(
102+
format!("+{}", additions),
103+
Style::default().fg(theme.diff_add),
104+
),
102105
Span::styled(" ", Style::default()),
103-
Span::styled(format!("-{}", deletions), Style::default().fg(Color::Red)),
106+
Span::styled(
107+
format!("-{}", deletions),
108+
Style::default().fg(theme.diff_delete),
109+
),
104110
]);
105111

106112
frame.render_widget(Paragraph::new(header), inner);
@@ -147,12 +153,12 @@ impl DiffView {
147153
let is_selected = i == self.selected_file;
148154

149155
let status_color = match file.status {
150-
FileStatus::Added => Color::Green,
151-
FileStatus::Modified => Color::Yellow,
152-
FileStatus::Deleted => Color::Red,
153-
FileStatus::Renamed => Color::Cyan,
154-
FileStatus::Copied => Color::Cyan,
155-
FileStatus::Untracked => Color::Gray,
156+
FileStatus::Added => theme.diff_add,
157+
FileStatus::Modified => theme.diff_modified,
158+
FileStatus::Deleted => theme.diff_delete,
159+
FileStatus::Renamed => theme.diff_header,
160+
FileStatus::Copied => theme.diff_header,
161+
FileStatus::Untracked => theme.dimmed,
156162
};
157163

158164
let style = if is_selected {
@@ -239,13 +245,13 @@ impl DiffView {
239245
);
240246
lines.push(Line::from(Span::styled(
241247
header,
242-
Style::default().fg(Color::Cyan),
248+
Style::default().fg(theme.diff_header),
243249
)));
244250

245251
for line in &hunk.lines {
246252
let (prefix, style) = match line.tag {
247-
ChangeTag::Delete => ("-", Style::default().fg(Color::Red)),
248-
ChangeTag::Insert => ("+", Style::default().fg(Color::Green)),
253+
ChangeTag::Delete => ("-", Style::default().fg(theme.diff_delete)),
254+
ChangeTag::Insert => ("+", Style::default().fg(theme.diff_add)),
249255
ChangeTag::Equal => (" ", Style::default().fg(theme.dimmed)),
250256
};
251257

@@ -330,7 +336,7 @@ impl DiffView {
330336
let content = if let Some(ref error) = self.error_message {
331337
Line::from(Span::styled(error, Style::default().fg(theme.error)))
332338
} else if let Some(ref success) = self.success_message {
333-
Line::from(Span::styled(success, Style::default().fg(Color::Green)))
339+
Line::from(Span::styled(success, Style::default().fg(theme.diff_add)))
334340
} else {
335341
Line::from(vec![
336342
Span::styled("j/k", Style::default().fg(theme.accent)),
@@ -495,7 +501,7 @@ impl DiffView {
495501
)));
496502
for (key, desc) in keys {
497503
lines.push(Line::from(vec![
498-
Span::styled(format!(" {:14}", key), Style::default().fg(Color::Yellow)),
504+
Span::styled(format!(" {:14}", key), Style::default().fg(theme.help_key)),
499505
Span::styled(desc, Style::default().fg(theme.text)),
500506
]));
501507
}

src/tui/home/input.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,15 @@ impl HomeView {
3535
self.settings_view = None;
3636
self.confirm_dialog = None;
3737
self.settings_close_confirm = false;
38+
// Revert theme to saved config (undo any preview)
39+
if let Ok(config) = resolve_config(self.storage.profile()) {
40+
let theme_name = if config.theme.name.is_empty() {
41+
"phosphor".to_string()
42+
} else {
43+
config.theme.name
44+
};
45+
return Some(Action::SetTheme(theme_name));
46+
}
3847
return None;
3948
}
4049
}
@@ -44,11 +53,22 @@ impl HomeView {
4453
// Handle settings view (full-screen takeover)
4554
if let Some(ref mut settings) = self.settings_view {
4655
match settings.handle_key(key) {
47-
SettingsAction::Continue => return None,
56+
SettingsAction::Continue => {
57+
return None;
58+
}
4859
SettingsAction::Close => {
4960
self.settings_view = None;
5061
// Refresh config-dependent state in case settings changed
5162
self.refresh_from_config();
63+
// Reload theme from saved config
64+
if let Ok(config) = resolve_config(self.storage.profile()) {
65+
let theme_name = if config.theme.name.is_empty() {
66+
"phosphor".to_string()
67+
} else {
68+
config.theme.name
69+
};
70+
return Some(Action::SetTheme(theme_name));
71+
}
5272
return None;
5373
}
5474
SettingsAction::UnsavedChangesWarning => {
@@ -61,6 +81,9 @@ impl HomeView {
6181
self.settings_close_confirm = true;
6282
return None;
6383
}
84+
SettingsAction::PreviewTheme(name) => {
85+
return Some(Action::SetTheme(name));
86+
}
6487
}
6588
}
6689

src/tui/home/render.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -297,15 +297,15 @@ impl HomeView {
297297
if let Some(wt_info) = &inst.worktree_info {
298298
line_spans.push(Span::styled(
299299
format!(" {}", wt_info.branch),
300-
Style::default().fg(Color::Cyan),
300+
Style::default().fg(theme.branch),
301301
));
302302
}
303303
if inst.is_sandboxed() {
304304
match self.view_mode {
305305
ViewMode::Agent => {
306306
line_spans.push(Span::styled(
307307
" [sandbox]",
308-
Style::default().fg(Color::Magenta),
308+
Style::default().fg(theme.sandbox),
309309
));
310310
}
311311
ViewMode::Terminal => {
@@ -315,7 +315,7 @@ impl HomeView {
315315
TerminalMode::Host => " [host]",
316316
};
317317
line_spans
318-
.push(Span::styled(mode_text, Style::default().fg(Color::Magenta)));
318+
.push(Span::styled(mode_text, Style::default().fg(theme.sandbox)));
319319
}
320320
}
321321
}

0 commit comments

Comments
 (0)