Skip to content

Commit 34d5827

Browse files
committed
fix: resolve CI formatting and notify-rust linux build errors
1 parent 54cf9da commit 34d5827

8 files changed

Lines changed: 549 additions & 50 deletions

File tree

Cargo.lock

Lines changed: 401 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,16 @@ serde_json = "1"
2828
libc = "0.2"
2929
pulldown-cmark = "0.12"
3030
syntect = { version = "5", default-features = false, features = ["default-fancy"] }
31-
notify-rust = { version = "4.16", default-features = false }
3231
nucleo = "0.5"
3332
thiserror = "2"
3433
tokio = { version = "1", features = ["macros", "rt-multi-thread", "sync", "time"] }
3534

35+
[target.'cfg(all(unix, not(target_os = "macos")))'.dependencies]
36+
notify-rust = { version = "4.16", default-features = false, features = ["z"] }
37+
38+
[target.'cfg(target_os = "macos")'.dependencies]
39+
notify-rust = { version = "4.16", default-features = false }
40+
3641
[dev-dependencies]
3742
pretty_assertions = "1"
3843

src/app/session_picker.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,13 @@ impl SessionPickerState {
210210
}
211211
}
212212

213-
result.push((entry.clone(), repo_indices, title_indices, dir_indices, is_live));
213+
result.push((
214+
entry.clone(),
215+
repo_indices,
216+
title_indices,
217+
dir_indices,
218+
is_live,
219+
));
214220
}
215221

216222
result
@@ -301,7 +307,13 @@ mod tests {
301307

302308
assert_eq!(picker.live_session_ids, live_ids);
303309
assert_eq!(picker.total_count(), 2);
304-
assert_eq!(picker.selected_entry().as_ref().map(|e| e.session_id.as_str()), Some("new"));
310+
assert_eq!(
311+
picker
312+
.selected_entry()
313+
.as_ref()
314+
.map(|e| e.session_id.as_str()),
315+
Some("new")
316+
);
305317

306318
let visible = picker.visible_entries(10);
307319
let (entry0, repo0, title0, dir0, live0) = &visible[0];

src/data/poller.rs

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,28 @@ pub fn poll_once() -> anyhow::Result<PollSnapshot> {
121121
.into_iter()
122122
.filter_map(|e| e.tui_pid)
123123
.collect();
124+
125+
let serve_sessions_by_port: HashMap<u16, Vec<String>> = std::thread::scope(|s| {
126+
let mut handles = Vec::new();
127+
for serve_process in &serve_processes {
128+
let port = serve_process.port;
129+
handles.push((
130+
port,
131+
s.spawn(move || fetch_recent_serve_session_ids(port).unwrap_or_default()),
132+
));
133+
}
134+
let mut results = HashMap::new();
135+
for (port, handle) in handles {
136+
results.insert(port, handle.join().unwrap_or_default());
137+
}
138+
results
139+
});
140+
124141
for serve_process in serve_processes {
125-
for serve_session_id in
126-
fetch_recent_serve_session_ids(serve_process.port).unwrap_or_default()
142+
for serve_session_id in serve_sessions_by_port
143+
.get(&serve_process.port)
144+
.cloned()
145+
.unwrap_or_default()
127146
{
128147
if seen.contains(&serve_session_id) {
129148
continue;
@@ -242,7 +261,10 @@ pub fn poll_once() -> anyhow::Result<PollSnapshot> {
242261
continue;
243262
};
244263
let cwd = if session.directory.as_os_str().is_empty() {
245-
if let Some(proj) = projects.iter().find(|project| project.id == session.project_id) {
264+
if let Some(proj) = projects
265+
.iter()
266+
.find(|project| project.id == session.project_id)
267+
{
246268
proj.worktree.clone()
247269
} else {
248270
continue;
@@ -257,7 +279,9 @@ pub fn poll_once() -> anyhow::Result<PollSnapshot> {
257279
status: reader.get_session_status(&managed_id)?,
258280
process_pid: None,
259281
model: reader.get_session_model(&managed_id)?,
260-
preview: reader.get_last_message_preview(&managed_id)?.map(|preview| preview.text),
282+
preview: reader
283+
.get_last_message_preview(&managed_id)?
284+
.map(|preview| preview.text),
261285
time_updated: Some(session.time_updated),
262286
has_children: reader.has_child_sessions(&managed_id)?,
263287
children: collect_children(&reader, &managed_id, 2)?,
@@ -303,7 +327,7 @@ fn collect_children(
303327

304328
fn fetch_recent_serve_session_ids(port: u16) -> anyhow::Result<Vec<String>> {
305329
let client = reqwest::blocking::Client::builder()
306-
.timeout(Duration::from_secs(1))
330+
.timeout(Duration::from_millis(200))
307331
.build()?;
308332
let response = client
309333
.get(format!("http://localhost:{port}/session"))

src/terminal/manager.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -440,9 +440,7 @@ impl PtyManager {
440440
// Managed sessions have an authoritative serve_port set at
441441
// spawn time — a Serve discovery may report a different port
442442
// when multiple serves share the same DB.
443-
if discovered.serve_port.is_some()
444-
&& summary.origin != SessionOrigin::Managed
445-
{
443+
if discovered.serve_port.is_some() && summary.origin != SessionOrigin::Managed {
446444
summary.serve_port = discovered.serve_port;
447445
}
448446
} else {

src/ui/message_picker.rs

Lines changed: 58 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
use ratatui::{
2+
Frame,
23
layout::{Constraint, Layout, Rect},
34
style::{Color, Modifier, Style},
45
text::{Line, Span},
56
widgets::{Block, Borders, Cell, Paragraph, Row, Table, Wrap},
6-
Frame,
77
};
88

9-
use crate::{
10-
app::message_picker::MessagePickerState,
11-
ui::sidebar::relative_time_from_updated,
12-
};
9+
use crate::{app::message_picker::MessagePickerState, ui::sidebar::relative_time_from_updated};
1310

1411
pub fn render_message_picker(frame: &mut Frame, picker: &mut MessagePickerState, area: Rect) {
1512
let block = Block::default()
@@ -31,19 +28,21 @@ pub fn render_message_picker(frame: &mut Frame, picker: &mut MessagePickerState,
3128
])
3229
.areas(inner);
3330

34-
let [table_area, preview_area] = Layout::vertical([
35-
Constraint::Percentage(55),
36-
Constraint::Percentage(45),
37-
])
38-
.areas(body_area);
31+
let [table_area, preview_area] =
32+
Layout::vertical([Constraint::Percentage(55), Constraint::Percentage(45)]).areas(body_area);
3933

4034
let search_line = Line::from(vec![
41-
Span::styled(" Search: ", Style::default().fg(Color::Cyan).add_modifier(Modifier::BOLD)),
35+
Span::styled(
36+
" Search: ",
37+
Style::default()
38+
.fg(Color::Cyan)
39+
.add_modifier(Modifier::BOLD),
40+
),
4241
Span::raw(&picker.query),
4342
Span::styled("█", Style::default().fg(Color::Cyan)),
4443
]);
4544
frame.render_widget(Paragraph::new(search_line), search_area);
46-
45+
4746
// Render empty spacer
4847
frame.render_widget(Paragraph::new(""), spacer_area);
4948

@@ -64,15 +63,21 @@ pub fn render_message_picker(frame: &mut Frame, picker: &mut MessagePickerState,
6463
let header = Row::new(vec![
6564
Cell::from(Span::styled(
6665
"Session",
67-
Style::default().add_modifier(Modifier::BOLD).fg(Color::Cyan),
66+
Style::default()
67+
.add_modifier(Modifier::BOLD)
68+
.fg(Color::Cyan),
6869
)),
6970
Cell::from(Span::styled(
7071
"Message",
71-
Style::default().add_modifier(Modifier::BOLD).fg(Color::Cyan),
72+
Style::default()
73+
.add_modifier(Modifier::BOLD)
74+
.fg(Color::Cyan),
7275
)),
7376
Cell::from(Span::styled(
7477
"Time",
75-
Style::default().add_modifier(Modifier::BOLD).fg(Color::Cyan),
78+
Style::default()
79+
.add_modifier(Modifier::BOLD)
80+
.fg(Color::Cyan),
7681
)),
7782
]);
7883

@@ -81,30 +86,49 @@ pub fn render_message_picker(frame: &mut Frame, picker: &mut MessagePickerState,
8186
.enumerate()
8287
.map(|(i, (entry, title_idx, text_idx))| {
8388
let is_selected = i + picker.scroll_offset == picker.selected;
84-
89+
8590
// Session Title Styling
8691
let (title_normal, title_highlight) = if is_selected {
87-
(Style::default().fg(Color::White).bg(Color::DarkGray).add_modifier(Modifier::BOLD), selected_matched_style)
92+
(
93+
Style::default()
94+
.fg(Color::White)
95+
.bg(Color::DarkGray)
96+
.add_modifier(Modifier::BOLD),
97+
selected_matched_style,
98+
)
8899
} else {
89-
(Style::default().fg(Color::Cyan).add_modifier(Modifier::BOLD), matched_style)
100+
(
101+
Style::default()
102+
.fg(Color::Cyan)
103+
.add_modifier(Modifier::BOLD),
104+
matched_style,
105+
)
90106
};
91107

92108
// Message Preview Styling (dimmer)
93109
let (text_normal, text_highlight) = if is_selected {
94-
(Style::default().fg(Color::White).bg(Color::DarkGray), selected_matched_style)
110+
(
111+
Style::default().fg(Color::White).bg(Color::DarkGray),
112+
selected_matched_style,
113+
)
95114
} else {
96115
(Style::default().fg(Color::DarkGray), matched_style)
97116
};
98-
117+
99118
// Time Styling
100119
let time_style = if is_selected {
101120
Style::default().fg(Color::White).bg(Color::DarkGray)
102121
} else {
103122
Style::default().fg(Color::DarkGray)
104123
};
105124

106-
let title_cell = Cell::from(highlight_text(&entry.session_title, title_idx, title_normal, title_highlight));
107-
125+
let title_cell = Cell::from(highlight_text(
126+
&entry.session_title,
127+
title_idx,
128+
title_normal,
129+
title_highlight,
130+
));
131+
108132
// Truncate text for the table view so it doesn't wrap awkwardly
109133
let max_text_len = 100; // Arbitrary max length for the preview column
110134
let display_text = if entry.compact_text.chars().count() > max_text_len {
@@ -114,9 +138,14 @@ pub fn render_message_picker(frame: &mut Frame, picker: &mut MessagePickerState,
114138
} else {
115139
entry.compact_text.clone()
116140
};
117-
118-
let text_cell = Cell::from(highlight_text(&display_text, text_idx, text_normal, text_highlight));
119-
141+
142+
let text_cell = Cell::from(highlight_text(
143+
&display_text,
144+
text_idx,
145+
text_normal,
146+
text_highlight,
147+
));
148+
120149
let time = relative_time_from_updated(Some(entry.time_created));
121150
let time_cell = Cell::from(Span::styled(time, time_style));
122151

@@ -156,7 +185,10 @@ pub fn render_message_picker(frame: &mut Frame, picker: &mut MessagePickerState,
156185
);
157186
} else {
158187
frame.render_widget(
159-
Paragraph::new(Span::styled("No matching messages.", Style::default().fg(Color::DarkGray))),
188+
Paragraph::new(Span::styled(
189+
"No matching messages.",
190+
Style::default().fg(Color::DarkGray),
191+
)),
160192
preview_inner,
161193
);
162194
}

src/ui/session_picker.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ pub fn render_session_picker(frame: &mut Frame, picker: &mut SessionPickerState,
5555
let header = Row::new(vec![
5656
Cell::from(Span::styled(
5757
"",
58-
Style::default().add_modifier(Modifier::BOLD).fg(Color::Cyan),
58+
Style::default()
59+
.add_modifier(Modifier::BOLD)
60+
.fg(Color::Cyan),
5961
)),
6062
Cell::from(Span::styled(
6163
"Repo",

tests/managed.rs

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,7 @@ fn apply_poll_snapshot_updates_via_serve_pid() {
553553
#[test]
554554
fn manager_can_attach_arbitrary_session_reuses_existing() {
555555
let mut manager = PtyManager::default();
556-
556+
557557
// First, Poller discovers an active session in the background and registers it
558558
manager.apply_poll_snapshot(PollSnapshot {
559559
sessions: vec![DiscoveredSessionInfo {
@@ -571,11 +571,11 @@ fn manager_can_attach_arbitrary_session_reuses_existing() {
571571
source: DiscoverySource::Serve,
572572
}],
573573
});
574-
574+
575575
assert_eq!(manager.len(), 1);
576576
let summary_before = manager.sessions().items()[0].clone();
577577
assert_eq!(summary_before.origin, SessionOrigin::Discovered);
578-
578+
579579
// User tries to attach to it via the Session Picker UI
580580
manager
581581
.attach_arbitrary_session(
@@ -590,13 +590,28 @@ fn manager_can_attach_arbitrary_session_reuses_existing() {
590590
.unwrap();
591591

592592
// The manager should REUSE the existing discovered entry, not create a second one.
593-
assert_eq!(manager.len(), 1, "Should reuse existing session instead of duplicating");
594-
593+
assert_eq!(
594+
manager.len(),
595+
1,
596+
"Should reuse existing session instead of duplicating"
597+
);
598+
595599
let summary_after = manager.selected_summary().unwrap();
596600
assert_eq!(summary_after.session_id.as_deref(), Some("sess_existing"));
597-
assert_eq!(summary_after.title, "Existing Attached", "Should update title");
598-
assert_eq!(summary_after.status, SessionStatus::Working, "Should update status");
599-
assert_eq!(summary_after.origin, SessionOrigin::Managed, "Should upgrade origin to Managed");
601+
assert_eq!(
602+
summary_after.title, "Existing Attached",
603+
"Should update title"
604+
);
605+
assert_eq!(
606+
summary_after.status,
607+
SessionStatus::Working,
608+
"Should update status"
609+
);
610+
assert_eq!(
611+
summary_after.origin,
612+
SessionOrigin::Managed,
613+
"Should upgrade origin to Managed"
614+
);
600615
assert!(manager.active_session().is_some(), "Should attach PTY");
601616
}
602617

@@ -612,7 +627,7 @@ fn manager_apply_poll_snapshot_matches_unresolved_managed_session() {
612627
None, // missing session_id
613628
SessionOrigin::Managed,
614629
Some(123),
615-
Some(122), // serve_pid
630+
Some(122), // serve_pid
616631
Some(4001), // serve_port
617632
None,
618633
None,
@@ -643,10 +658,18 @@ fn manager_apply_poll_snapshot_matches_unresolved_managed_session() {
643658
assert_eq!(manager.len(), 1, "Should not duplicate");
644659
let summary = manager.sessions().items()[0].clone();
645660
assert_eq!(summary.id, id);
646-
assert_eq!(summary.session_id.as_deref(), Some("sess_guessed"), "Should adopt the guessed ID");
661+
assert_eq!(
662+
summary.session_id.as_deref(),
663+
Some("sess_guessed"),
664+
"Should adopt the guessed ID"
665+
);
647666
assert_eq!(summary.title, "Guessed Title");
648667
assert_eq!(summary.status, SessionStatus::Idle);
649-
assert_eq!(summary.origin, SessionOrigin::Managed, "Should stay managed");
668+
assert_eq!(
669+
summary.origin,
670+
SessionOrigin::Managed,
671+
"Should stay managed"
672+
);
650673
}
651674

652675
#[test]
@@ -760,7 +783,9 @@ fn session_id_match_takes_priority_over_serve_port() {
760783
#[test]
761784
fn test_specific_session_status() {
762785
let reader = opencode_multiplexer::data::db::reader::DbReader::open_default().unwrap();
763-
let status = reader.get_session_status("ses_225490e46ffeDsv1XQ4g7jhPmq").unwrap();
786+
let status = reader
787+
.get_session_status("ses_225490e46ffeDsv1XQ4g7jhPmq")
788+
.unwrap();
764789
println!("STATUS: {:?}", status);
765790
// assert!(false); // to see output
766791
}

0 commit comments

Comments
 (0)