4runr-os 2.5.0 → 2.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -682,17 +682,20 @@ impl App {
682
682
  }
683
683
 
684
684
  /// Close all overlays and popups (return to base screen)
685
+ #[allow(dead_code)]
685
686
  pub fn close_all_overlays(&mut self) {
686
687
  self.state.navigation.close_all();
687
688
  self.request_render("close_all");
688
689
  }
689
690
 
690
691
  /// Get the currently visible screen
692
+ #[allow(dead_code)]
691
693
  pub fn current_screen(&self) -> &Screen {
692
694
  self.state.navigation.current_screen()
693
695
  }
694
696
 
695
697
  /// Check if we're on the base screen (no overlays/popups)
698
+ #[allow(dead_code)]
696
699
  pub fn is_on_base_screen(&self) -> bool {
697
700
  self.state.navigation.is_on_base()
698
701
  }
@@ -187,14 +187,17 @@ fn main() -> Result<()> {
187
187
  let _ = cache.update_agents(cache_agents);
188
188
  }
189
189
 
190
- // Update agent list state and open AgentList overlay
190
+ // Update agent list state
191
191
  app.state.agent_list.agents = agents;
192
192
  app.state.agent_list.selected_index = 0;
193
193
  app.state.agent_list.detail_view = None;
194
194
 
195
+ // Only open AgentList overlay if we're on Main screen (not during boot)
195
196
  use crate::screens::Screen;
196
- app.push_overlay(Screen::AgentList);
197
- app.request_render("agent_list_opened");
197
+ if app.state.navigation.current_screen() == &Screen::Main {
198
+ app.push_overlay(Screen::AgentList);
199
+ app.request_render("agent_list_opened");
200
+ }
198
201
  }
199
202
  } else {
200
203
  app.add_log(format!("✓ [{}] Success", short_id));
@@ -50,6 +50,7 @@ impl Screen {
50
50
  }
51
51
 
52
52
  /// Returns the screen name for display
53
+ #[allow(dead_code)]
53
54
  pub fn name(&self) -> &str {
54
55
  match self {
55
56
  Screen::Boot => "Boot",
@@ -143,12 +144,14 @@ impl NavigationState {
143
144
  }
144
145
 
145
146
  /// Close all overlays and popups (return to base screen)
147
+ #[allow(dead_code)]
146
148
  pub fn close_all(&mut self) {
147
149
  self.overlay_stack.clear();
148
150
  self.popup_stack.clear();
149
151
  }
150
152
 
151
153
  /// Check if we're currently on the base screen (no overlays/popups)
154
+ #[allow(dead_code)]
152
155
  pub fn is_on_base(&self) -> bool {
153
156
  self.overlay_stack.is_empty() && self.popup_stack.is_empty()
154
157
  }
@@ -121,6 +121,7 @@ impl Cache {
121
121
  }
122
122
 
123
123
  /// Add a single agent
124
+ #[allow(dead_code)]
124
125
  pub fn add_agent(&mut self, agent: AgentData) -> Result<(), std::io::Error> {
125
126
  self.data.agents.push(agent);
126
127
  self.data.last_updated = Self::now();
@@ -128,6 +129,7 @@ impl Cache {
128
129
  }
129
130
 
130
131
  /// Remove an agent by name
132
+ #[allow(dead_code)]
131
133
  pub fn remove_agent(&mut self, name: &str) -> Result<(), std::io::Error> {
132
134
  self.data.agents.retain(|a| a.name != name);
133
135
  self.data.last_updated = Self::now();
@@ -137,11 +139,13 @@ impl Cache {
137
139
  // === Run Operations ===
138
140
 
139
141
  /// Get all cached runs
142
+ #[allow(dead_code)]
140
143
  pub fn get_runs(&self) -> Vec<RunData> {
141
144
  self.data.runs.clone()
142
145
  }
143
146
 
144
147
  /// Update runs cache
148
+ #[allow(dead_code)]
145
149
  pub fn update_runs(&mut self, runs: Vec<RunData>) -> Result<(), std::io::Error> {
146
150
  self.data.runs = runs;
147
151
  self.data.last_updated = Self::now();
@@ -149,6 +153,7 @@ impl Cache {
149
153
  }
150
154
 
151
155
  /// Add a single run
156
+ #[allow(dead_code)]
152
157
  pub fn add_run(&mut self, run: RunData) -> Result<(), std::io::Error> {
153
158
  self.data.runs.push(run);
154
159
  self.data.last_updated = Self::now();
@@ -156,6 +161,7 @@ impl Cache {
156
161
  }
157
162
 
158
163
  /// Update a run by ID
164
+ #[allow(dead_code)]
159
165
  pub fn update_run(&mut self, id: &str, run: RunData) -> Result<(), std::io::Error> {
160
166
  if let Some(existing) = self.data.runs.iter_mut().find(|r| r.id == id) {
161
167
  *existing = run;
@@ -173,6 +179,7 @@ impl Cache {
173
179
  }
174
180
 
175
181
  /// Update system status cache
182
+ #[allow(dead_code)]
176
183
  pub fn update_system_status(&mut self, status: SystemStatusData) -> Result<(), std::io::Error> {
177
184
  self.data.system_status = Some(status);
178
185
  self.data.last_updated = Self::now();
@@ -182,22 +189,26 @@ impl Cache {
182
189
  // === Cache Management ===
183
190
 
184
191
  /// Get cache age in seconds
192
+ #[allow(dead_code)]
185
193
  pub fn get_age(&self) -> u64 {
186
194
  Self::now().saturating_sub(self.data.last_updated)
187
195
  }
188
196
 
189
197
  /// Check if cache is stale (older than threshold)
198
+ #[allow(dead_code)]
190
199
  pub fn is_stale(&self, threshold_secs: u64) -> bool {
191
200
  self.get_age() > threshold_secs
192
201
  }
193
202
 
194
203
  /// Clear all cached data
204
+ #[allow(dead_code)]
195
205
  pub fn clear(&mut self) -> Result<(), std::io::Error> {
196
206
  self.data = CacheData::default();
197
207
  self.save_to_file()
198
208
  }
199
209
 
200
210
  /// Get cache data reference
211
+ #[allow(dead_code)]
201
212
  pub fn data(&self) -> &CacheData {
202
213
  &self.data
203
214
  }
@@ -3,4 +3,4 @@
3
3
 
4
4
  pub mod cache;
5
5
 
6
- pub use cache::{Cache, CacheData};
6
+ pub use cache::Cache;
@@ -7,6 +7,7 @@ use crate::app::AppState;
7
7
 
8
8
  // === 4RUNR BRAND COLORS (matching layout.rs) ===
9
9
  const BRAND_PURPLE: Color = Color::Rgb(138, 43, 226);
10
+ #[allow(dead_code)]
10
11
  const BRAND_VIOLET: Color = Color::Rgb(148, 103, 189);
11
12
  const CYBER_CYAN: Color = Color::Rgb(0, 255, 255);
12
13
  const NEON_GREEN: Color = Color::Rgb(57, 255, 20);
@@ -108,7 +109,7 @@ struct CostEstimate {
108
109
  is_free: bool,
109
110
  }
110
111
 
111
- fn calculate_cost(provider: &str, model: &str, max_tokens: u32) -> CostEstimate {
112
+ fn calculate_cost(provider: &str, model: &str, _max_tokens: u32) -> CostEstimate {
112
113
  let pricing = get_model_pricing(provider, model);
113
114
  let is_free = pricing.input_cost == 0.0 && pricing.output_cost == 0.0;
114
115
 
@@ -57,9 +57,8 @@ fn render_list_view(f: &mut Frame, area: Rect, state: &AppState) {
57
57
  .border_style(Style::default().fg(TEXT_MUTED))
58
58
  .style(Style::default().bg(BG_PANEL));
59
59
 
60
- f.render_widget(content_block, chunks[1]);
61
-
62
60
  let table_area = content_block.inner(chunks[1]);
61
+ f.render_widget(content_block, chunks[1]);
63
62
 
64
63
  if state.agent_list.agents.is_empty() {
65
64
  // Show "No agents" message
@@ -146,7 +145,6 @@ fn render_detail_popup(f: &mut Frame, area: Rect, state: &AppState) {
146
145
  }
147
146
 
148
147
  fn render_agent_detail(f: &mut Frame, area: Rect, agent: &AgentInfo) {
149
- use ratatui::layout::{Constraint, Direction, Layout};
150
148
 
151
149
  // Calculate popup size (70% width, 80% height, centered)
152
150
  let popup_width = (area.width * 70 / 100).max(50);
@@ -181,9 +179,8 @@ fn render_agent_detail(f: &mut Frame, area: Rect, agent: &AgentInfo) {
181
179
  .border_style(Style::default().fg(CYBER_CYAN))
182
180
  .style(Style::default().bg(BG_PANEL));
183
181
 
184
- f.render_widget(detail_block, popup_area);
185
-
186
182
  let inner = detail_block.inner(popup_area);
183
+ f.render_widget(detail_block, popup_area);
187
184
 
188
185
  // Create detail text
189
186
  let mut detail_lines = vec![
@@ -138,8 +138,9 @@ fn render_command_list(f: &mut Frame, area: Rect) {
138
138
 
139
139
  let nav_list = List::new(nav_items);
140
140
 
141
+ let nav_inner = nav_block.inner(chunks[0]);
141
142
  f.render_widget(nav_block, chunks[0]);
142
- f.render_widget(nav_list, nav_block.inner(chunks[0]));
143
+ f.render_widget(nav_list, nav_inner);
143
144
 
144
145
  // Local Commands section
145
146
  let local_block = Block::default()
@@ -158,8 +159,9 @@ fn render_command_list(f: &mut Frame, area: Rect) {
158
159
 
159
160
  let local_list = List::new(local_items);
160
161
 
162
+ let local_inner = local_block.inner(chunks[1]);
161
163
  f.render_widget(local_block, chunks[1]);
162
- f.render_widget(local_list, local_block.inner(chunks[1]));
164
+ f.render_widget(local_list, local_inner);
163
165
 
164
166
  // WebSocket Commands section
165
167
  let ws_block = Block::default()
@@ -181,8 +183,9 @@ fn render_command_list(f: &mut Frame, area: Rect) {
181
183
 
182
184
  let ws_list = List::new(ws_items);
183
185
 
186
+ let ws_inner = ws_block.inner(chunks[2]);
184
187
  f.render_widget(ws_block, chunks[2]);
185
- f.render_widget(ws_list, ws_block.inner(chunks[2]));
188
+ f.render_widget(ws_list, ws_inner);
186
189
  }
187
190
 
188
191
  fn render_command_details(f: &mut Frame, area: Rect) {
@@ -242,11 +245,12 @@ fn render_command_details(f: &mut Frame, area: Rect) {
242
245
  ]),
243
246
  ];
244
247
 
248
+ let desc_inner = desc_block.inner(chunks[0]);
245
249
  f.render_widget(desc_block, chunks[0]);
246
250
  f.render_widget(
247
251
  Paragraph::new(desc_text)
248
252
  .wrap(Wrap { trim: false }),
249
- desc_block.inner(chunks[0])
253
+ desc_inner
250
254
  );
251
255
 
252
256
  // Screen controls
@@ -300,10 +304,11 @@ fn render_command_details(f: &mut Frame, area: Rect) {
300
304
  ]),
301
305
  ];
302
306
 
307
+ let controls_inner = controls_block.inner(chunks[1]);
303
308
  f.render_widget(controls_block, chunks[1]);
304
309
  f.render_widget(
305
310
  Paragraph::new(controls_text)
306
311
  .wrap(Wrap { trim: false }),
307
- controls_block.inner(chunks[1])
312
+ controls_inner
308
313
  );
309
314
  }
@@ -120,7 +120,7 @@ fn render_header(f: &mut Frame, area: Rect, state: &AppState) {
120
120
 
121
121
  // Line 1: Brand + version + uptime - Bug 3 fix: Use "4Runr." with dot (matches brand logo)
122
122
  // Use npm package version (2.3.5) - matches package.json
123
- const PACKAGE_VERSION: &str = "2.5.0";
123
+ const PACKAGE_VERSION: &str = "2.5.2";
124
124
  let brand_line = Line::from(vec![
125
125
  Span::styled("4Runr.", Style::default().fg(BRAND_PURPLE).add_modifier(Modifier::BOLD)),
126
126
  Span::styled(" AI AGENT OS", Style::default().fg(BRAND_VIOLET)),
@@ -7,8 +7,10 @@ pub mod run_manager;
7
7
  pub mod safe_viewport;
8
8
  pub mod settings;
9
9
 
10
- // Re-export screen states
10
+ // Re-export screen states (used in app.rs)
11
+ #[allow(dead_code)]
11
12
  pub use agent_builder::AgentBuilderState;
13
+ #[allow(dead_code)]
12
14
  pub use run_manager::RunManagerState;
15
+ #[allow(dead_code)]
13
16
  pub use settings::SettingsState;
14
-
@@ -31,9 +31,11 @@ pub struct RunManagerState {
31
31
  pub sort: RunSort,
32
32
 
33
33
  /// Loading state
34
+ #[allow(dead_code)]
34
35
  pub loading: bool,
35
36
 
36
37
  /// Last refresh time
38
+ #[allow(dead_code)]
37
39
  pub last_refresh: Option<std::time::Instant>,
38
40
 
39
41
  /// Detailed view state (None = list view, Some(index) = detail view)
@@ -61,10 +63,12 @@ pub struct RunInfo {
61
63
 
62
64
  #[derive(Debug, Clone, PartialEq)]
63
65
  pub enum RunStatus {
66
+ #[allow(dead_code)]
64
67
  Pending,
65
68
  Running,
66
69
  Completed,
67
70
  Failed,
71
+ #[allow(dead_code)]
68
72
  Cancelled,
69
73
  }
70
74
 
@@ -73,11 +73,14 @@ pub enum WsClientMessage {
73
73
  Event(EventMessage),
74
74
  Error(String),
75
75
  ConnectionLost,
76
+ #[allow(dead_code)]
76
77
  Reconnecting,
78
+ #[allow(dead_code)]
77
79
  ReconnectFailed(String),
78
80
  }
79
81
 
80
82
  pub struct WebSocketClient {
83
+ #[allow(dead_code)]
81
84
  url: String,
82
85
  tx: mpsc::UnboundedSender<WsMessage>,
83
86
  rx: Arc<Mutex<mpsc::UnboundedReceiver<WsClientMessage>>>,
@@ -211,6 +214,7 @@ impl WebSocketClient {
211
214
  }
212
215
 
213
216
  /// Retry pending commands after reconnection
217
+ #[allow(dead_code)]
214
218
  pub fn retry_pending_commands(&self) -> Result<Vec<String>> {
215
219
  let mut pending = self.pending_commands.lock().unwrap();
216
220
  let mut retried_ids = Vec::new();
@@ -239,6 +243,7 @@ impl WebSocketClient {
239
243
  }
240
244
 
241
245
  /// Clear pending commands (e.g., on explicit disconnect)
246
+ #[allow(dead_code)]
242
247
  pub fn clear_pending_commands(&self) {
243
248
  self.pending_commands.lock().unwrap().clear();
244
249
  }
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "4runr-os",
3
- "version": "2.5.0",
3
+ "version": "2.5.2",
4
4
  "type": "module",
5
- "description": "4Runr AI Agent OS - Secure terminal interface for AI agents. v2.5.0: NEW professional help popup interface, NEW Agent List viewer with detail popup for agent.list command. Enhanced UX with clean navigation and organized displays. Built with Rust + Ratatui. ⚠️ Pre-MVP / Development Phase",
5
+ "description": "4Runr AI Agent OS - Secure terminal interface for AI agents. v2.5.2: Fixed loading screen being overshadowed by agent list during boot. Resolved all compilation warnings. Professional help popup interface, Agent List viewer with detail popup. Enhanced UX with clean navigation. Built with Rust + Ratatui. ⚠️ Pre-MVP / Development Phase",
6
6
  "main": "dist/index.js",
7
7
  "bin": {
8
8
  "4runr": "dist/index.js",