4runr-os 2.9.43 → 2.9.45

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.
@@ -378,6 +378,7 @@ impl Default for SetupPortalState {
378
378
  impl SetupPortalState {
379
379
  pub fn cycle_option(&mut self, direction: i8) {
380
380
  use GatewayOption::*;
381
+ let prev = self.selected_option.clone();
381
382
  self.selected_option = match (&self.selected_option, direction) {
382
383
  // Forward cycling (Down key, Scroll Down)
383
384
  (LocalBundle, 1) => CloudServer,
@@ -389,6 +390,7 @@ impl SetupPortalState {
389
390
  (CustomUrl, -1) => CloudServer,
390
391
  _ => self.selected_option.clone(),
391
392
  };
393
+ eprintln!("[SETUP-PORTAL] cycle_option direction={} prev={:?} -> new={:?}", direction, prev, self.selected_option);
392
394
  }
393
395
 
394
396
  pub fn reset(&mut self) {
@@ -1799,12 +1801,13 @@ impl App {
1799
1801
  // SETUP PORTAL INPUT HANDLING
1800
1802
  // ============================================================
1801
1803
 
1802
- fn handle_setup_portal_input(&mut self, key: KeyEvent, ws_client: Option<&WebSocketClient>) -> anyhow::Result<bool> {
1804
+ fn handle_setup_portal_input(&mut self, key: KeyEvent, _ws_client: Option<&WebSocketClient>) -> anyhow::Result<bool> {
1805
+ eprintln!("[SETUP-PORTAL] INPUT key={:?} (selected_option={:?})", key.code, self.state.setup_portal.selected_option);
1803
1806
  // Guard: Don't process if already detecting
1804
1807
  if self.state.setup_portal.detecting {
1805
1808
  return Ok(false);
1806
1809
  }
1807
-
1810
+
1808
1811
  match key.code {
1809
1812
  // ESC - Cancel and close portal
1810
1813
  KeyCode::Esc => {
@@ -1824,11 +1827,13 @@ impl App {
1824
1827
 
1825
1828
  // Up/Down - Navigate options (immediate render for responsiveness)
1826
1829
  KeyCode::Up => {
1830
+ eprintln!("[SETUP-PORTAL] KEY Up -> cycle_option(-1)");
1827
1831
  self.state.setup_portal.cycle_option(-1);
1828
1832
  self.request_immediate_render("setup_nav_up");
1829
1833
  }
1830
1834
 
1831
1835
  KeyCode::Down => {
1836
+ eprintln!("[SETUP-PORTAL] KEY Down -> cycle_option(1)");
1832
1837
  self.state.setup_portal.cycle_option(1);
1833
1838
  self.request_immediate_render("setup_nav_down");
1834
1839
  }
@@ -632,12 +632,12 @@ fn main() -> Result<()> {
632
632
  if !app.state.setup_portal.detecting {
633
633
  match mouse.kind {
634
634
  MouseEventKind::ScrollUp => {
635
- // Navigate up (cycle backward)
635
+ eprintln!("[SETUP-PORTAL] MOUSE ScrollUp -> cycle_option(-1)");
636
636
  app.state.setup_portal.cycle_option(-1);
637
637
  app.request_immediate_render("setup_portal_scroll_up");
638
638
  }
639
639
  MouseEventKind::ScrollDown => {
640
- // Navigate down (cycle forward)
640
+ eprintln!("[SETUP-PORTAL] MOUSE ScrollDown -> cycle_option(1)");
641
641
  app.state.setup_portal.cycle_option(1);
642
642
  app.request_immediate_render("setup_portal_scroll_down");
643
643
  }
@@ -144,7 +144,7 @@ fn render_header(f: &mut Frame, area: Rect, state: &AppState) {
144
144
 
145
145
  // Line 1: Brand + version + mode + uptime - Bug 3 fix: Use "4Runr." with dot (matches brand logo)
146
146
  // Use npm package version (2.9.24) - matches package.json
147
- const PACKAGE_VERSION: &str = "2.9.43";
147
+ const PACKAGE_VERSION: &str = "2.9.45";
148
148
  let brand_line = Line::from(vec![
149
149
  Span::styled("4Runr.", Style::default().fg(BRAND_PURPLE).add_modifier(Modifier::BOLD)),
150
150
  Span::styled(" AI AGENT OS", Style::default().fg(BRAND_VIOLET)),
@@ -18,18 +18,19 @@ const ERROR_RED: Color = Color::Rgb(255, 69, 69);
18
18
 
19
19
  /// Render the Setup Portal screen - Full-screen standalone portal
20
20
  pub fn render(f: &mut Frame, state: &AppState) {
21
- // DEBUG: Track render calls
21
+ // DEBUG: Every frame log the selection state used for this draw (no throttle)
22
+ eprintln!("[SETUP-PORTAL] FRAME selected_option={:?}", state.setup_portal.selected_option);
23
+
22
24
  static mut RENDER_COUNT: u64 = 0;
23
25
  unsafe {
24
26
  RENDER_COUNT += 1;
25
- if RENDER_COUNT % 10 == 1 { // Log every 10th render to avoid spam
27
+ if RENDER_COUNT % 10 == 1 {
26
28
  eprintln!("[SETUP-PORTAL] Render #{}", RENDER_COUNT);
27
29
  }
28
30
  }
29
-
31
+
30
32
  let area = f.size();
31
-
32
- // DEBUG: Log terminal size
33
+
33
34
  unsafe {
34
35
  if RENDER_COUNT % 10 == 1 {
35
36
  eprintln!("[SETUP-PORTAL] Terminal size: {}x{}", area.width, area.height);
@@ -175,7 +176,7 @@ fn render_description(f: &mut Frame, area: Rect) {
175
176
  f.render_widget(block, area);
176
177
 
177
178
  let text = Paragraph::new("Choose how you want to connect to a Gateway server.")
178
- .style(Style::default().fg(TEXT_DIM))
179
+ .style(Style::default().fg(TEXT_DIM).bg(BG_PANEL))
179
180
  .alignment(ratatui::layout::Alignment::Center);
180
181
 
181
182
  f.render_widget(text, inner);
@@ -226,8 +227,10 @@ fn render_options_list(f: &mut Frame, area: Rect, state: &AppState) {
226
227
  }
227
228
  }
228
229
 
229
- // CRITICAL: Clear the list area first to prevent duplication
230
- f.render_widget(Clear, area);
230
+ // CRITICAL: Fill entire area with background so every cell is overwritten.
231
+ // Without this, List only paints rows with items; leftover rows show previous frame (duplication).
232
+ let fill = Block::default().style(Style::default().bg(BG_PANEL));
233
+ f.render_widget(fill, area);
231
234
 
232
235
  let options = vec![
233
236
  ("Local Bundle", GatewayOption::LocalBundle),
@@ -239,12 +242,12 @@ fn render_options_list(f: &mut Frame, area: Rect, state: &AppState) {
239
242
  let selected_index = options.iter()
240
243
  .position(|(_, opt)| opt == &state.setup_portal.selected_option)
241
244
  .unwrap_or(0);
242
-
243
- // DEBUG: Log selected index
245
+
246
+ // DEBUG: Every frame - exact state used for list (so we can match what's drawn)
247
+ eprintln!("[SETUP-PORTAL] LIST selected_index={} selected_option={:?}", selected_index, state.setup_portal.selected_option);
248
+
244
249
  unsafe {
245
250
  if LOG_COUNT % 10 == 1 {
246
- eprintln!("[SETUP-PORTAL] Selected index: {}, option: {:?}",
247
- selected_index, state.setup_portal.selected_option);
248
251
  eprintln!("[SETUP-PORTAL] Options count: {}", options.len());
249
252
  }
250
253
  }
@@ -290,19 +293,22 @@ fn render_options_list(f: &mut Frame, area: Rect, state: &AppState) {
290
293
  }
291
294
 
292
295
  fn render_option_details(f: &mut Frame, area: Rect, state: &AppState) {
293
- // DEBUG: Log details rendering
296
+ // DEBUG: Every frame - state used for details panel
297
+ eprintln!("[SETUP-PORTAL] DETAILS selected_option={:?}", state.setup_portal.selected_option);
298
+
294
299
  static mut LOG_COUNT: u64 = 0;
295
300
  unsafe {
296
301
  LOG_COUNT += 1;
297
302
  if LOG_COUNT % 10 == 1 {
298
- eprintln!("[SETUP-PORTAL] render_option_details - area: x={}, y={}, w={}, h={}",
303
+ eprintln!("[SETUP-PORTAL] render_option_details - area: x={}, y={}, w={}, h={}",
299
304
  area.x, area.y, area.width, area.height);
300
- eprintln!("[SETUP-PORTAL] Selected option: {:?}", state.setup_portal.selected_option);
301
305
  }
302
306
  }
303
307
 
304
- // CRITICAL: Clear the details area first to prevent content overlap/corruption
305
- f.render_widget(Clear, area);
308
+ // CRITICAL: Fill entire area with background so every cell is overwritten.
309
+ // Without this, Paragraph may not paint every cell; leftover shows previous option (corruption).
310
+ let fill = Block::default().style(Style::default().bg(BG_PANEL));
311
+ f.render_widget(fill, area);
306
312
 
307
313
  let selected_option = &state.setup_portal.selected_option;
308
314
  let detection_result = &state.setup_portal.detection_result;
@@ -482,7 +488,8 @@ fn render_actions(f: &mut Frame, area: Rect, state: &AppState) {
482
488
  };
483
489
 
484
490
  let paragraph = Paragraph::new(text)
485
- .alignment(ratatui::layout::Alignment::Center);
491
+ .alignment(ratatui::layout::Alignment::Center)
492
+ .style(Style::default().bg(BG_PANEL));
486
493
 
487
494
  f.render_widget(paragraph, inner);
488
495
  }
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "4runr-os",
3
- "version": "2.9.43",
3
+ "version": "2.9.45",
4
4
  "type": "module",
5
- "description": "4Runr AI Agent OS - Secure terminal interface for AI agents. v2.9.43: Release prep. v2.9.42: Reverted Setup Portal to standard Ratatui pattern - simplified rendering to fix content overlap and mixing. ⚠️ Pre-MVP / Development Phase",
5
+ "description": "4Runr AI Agent OS - Secure terminal interface for AI agents. v2.9.45: Setup Portal debug logging for navigation (input/state/frame). v2.9.44: Setup Portal fill-background fix for duplication and corruption. ⚠️ Pre-MVP / Development Phase",
6
6
  "main": "dist/index.js",
7
7
  "bin": {
8
8
  "4runr": "dist/index.js",