4runr-os 2.9.41 → 2.9.44

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.
@@ -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.41";
147
+ const PACKAGE_VERSION: &str = "2.9.44";
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)),
@@ -175,7 +175,7 @@ fn render_description(f: &mut Frame, area: Rect) {
175
175
  f.render_widget(block, area);
176
176
 
177
177
  let text = Paragraph::new("Choose how you want to connect to a Gateway server.")
178
- .style(Style::default().fg(TEXT_DIM))
178
+ .style(Style::default().fg(TEXT_DIM).bg(BG_PANEL))
179
179
  .alignment(ratatui::layout::Alignment::Center);
180
180
 
181
181
  f.render_widget(text, inner);
@@ -226,8 +226,10 @@ fn render_options_list(f: &mut Frame, area: Rect, state: &AppState) {
226
226
  }
227
227
  }
228
228
 
229
- // CRITICAL: Clear the list area first to prevent duplication
230
- f.render_widget(Clear, area);
229
+ // CRITICAL: Fill entire area with background so every cell is overwritten.
230
+ // Without this, List only paints rows with items; leftover rows show previous frame (duplication).
231
+ let fill = Block::default().style(Style::default().bg(BG_PANEL));
232
+ f.render_widget(fill, area);
231
233
 
232
234
  let options = vec![
233
235
  ("Local Bundle", GatewayOption::LocalBundle),
@@ -301,8 +303,10 @@ fn render_option_details(f: &mut Frame, area: Rect, state: &AppState) {
301
303
  }
302
304
  }
303
305
 
304
- // CRITICAL: Clear the details area first to prevent content overlap/corruption
305
- f.render_widget(Clear, area);
306
+ // CRITICAL: Fill entire area with background so every cell is overwritten.
307
+ // Without this, Paragraph may not paint every cell; leftover shows previous option (corruption).
308
+ let fill = Block::default().style(Style::default().bg(BG_PANEL));
309
+ f.render_widget(fill, area);
306
310
 
307
311
  let selected_option = &state.setup_portal.selected_option;
308
312
  let detection_result = &state.setup_portal.detection_result;
@@ -408,58 +412,22 @@ fn render_option_details(f: &mut Frame, area: Rect, state: &AppState) {
408
412
  .border_style(Style::default().fg(TEXT_DIM))
409
413
  .style(Style::default().bg(BG_PANEL));
410
414
 
411
- // CRITICAL: Render block first to clear and establish boundaries
412
- let inner = block.inner(area);
415
+ // CRITICAL: Use the standard Ratatui pattern - Paragraph with .block()
416
+ // This is more reliable than rendering Block and Paragraph separately
417
+ let paragraph = Paragraph::new(content)
418
+ .block(block)
419
+ .wrap(Wrap { trim: true })
420
+ .style(Style::default().bg(BG_PANEL)); // Ensure background fills the block
413
421
 
414
- // CRITICAL: Validate inner area to prevent index out of bounds panic
415
- // Ratatui panics if area coordinates exceed terminal buffer
422
+ // Validate area before rendering
416
423
  let terminal_size = f.size();
417
- let safe_inner = Rect {
418
- x: inner.x.min(terminal_size.width.saturating_sub(1)),
419
- y: inner.y.min(terminal_size.height.saturating_sub(1)),
420
- width: inner.width.min(terminal_size.width.saturating_sub(inner.x)),
421
- height: inner.height.min(terminal_size.height.saturating_sub(inner.y)),
422
- };
423
-
424
- // DEBUG: Log block inner area
425
- unsafe {
426
- if LOG_COUNT % 10 == 1 {
427
- eprintln!("[SETUP-PORTAL] Block outer: x={}, y={}, w={}, h={}",
428
- area.x, area.y, area.width, area.height);
429
- eprintln!("[SETUP-PORTAL] Block inner (original): x={}, y={}, w={}, h={}",
430
- inner.x, inner.y, inner.width, inner.height);
431
- eprintln!("[SETUP-PORTAL] Terminal size: {}x{}", terminal_size.width, terminal_size.height);
432
- eprintln!("[SETUP-PORTAL] Block inner (safe): x={}, y={}, w={}, h={}",
433
- safe_inner.x, safe_inner.y, safe_inner.width, safe_inner.height);
434
-
435
- // Warn if we had to clamp
436
- if inner.x != safe_inner.x || inner.y != safe_inner.y ||
437
- inner.width != safe_inner.width || inner.height != safe_inner.height {
438
- eprintln!("[SETUP-PORTAL] ⚠️ WARNING: Inner area was clamped to fit terminal bounds!");
439
- }
440
- }
441
- }
442
-
443
- // Validate area before rendering block
444
424
  if area.width == 0 || area.height == 0 ||
445
425
  area.x >= terminal_size.width || area.y >= terminal_size.height {
446
- eprintln!("[SETUP-PORTAL] ⚠️ ERROR: Invalid block area, skipping render");
447
- return;
448
- }
449
-
450
- f.render_widget(block, area);
451
-
452
- // Validate safe_inner before rendering paragraph
453
- if safe_inner.width == 0 || safe_inner.height == 0 {
454
- eprintln!("[SETUP-PORTAL] ⚠️ ERROR: Invalid inner area (zero size), skipping paragraph render");
426
+ eprintln!("[SETUP-PORTAL] ⚠️ ERROR: Invalid area, skipping render");
455
427
  return;
456
428
  }
457
429
 
458
- // Then render paragraph content only within the safe inner area
459
- let paragraph = Paragraph::new(content)
460
- .wrap(Wrap { trim: true });
461
-
462
- f.render_widget(paragraph, safe_inner);
430
+ f.render_widget(paragraph, area);
463
431
  }
464
432
 
465
433
  fn render_error_box(f: &mut Frame, area: Rect, state: &AppState) {
@@ -518,7 +486,8 @@ fn render_actions(f: &mut Frame, area: Rect, state: &AppState) {
518
486
  };
519
487
 
520
488
  let paragraph = Paragraph::new(text)
521
- .alignment(ratatui::layout::Alignment::Center);
489
+ .alignment(ratatui::layout::Alignment::Center)
490
+ .style(Style::default().bg(BG_PANEL));
522
491
 
523
492
  f.render_widget(paragraph, inner);
524
493
  }
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "4runr-os",
3
- "version": "2.9.41",
3
+ "version": "2.9.44",
4
4
  "type": "module",
5
- "description": "4Runr AI Agent OS - Secure terminal interface for AI agents. v2.9.41: Fixed Setup Portal index out of bounds panic - added bounds validation and clamping for safe area rendering. Added comprehensive debug logging for Setup Portal rendering diagnostics. v2.9.40: Fixed Setup Portal rendering. ⚠️ Pre-MVP / Development Phase",
5
+ "description": "4Runr AI Agent OS - Secure terminal interface for AI agents. v2.9.44: Setup Portal navigation fix - fill background before List/details to fix duplication and character corruption. v2.9.43: Release prep. ⚠️ Pre-MVP / Development Phase",
6
6
  "main": "dist/index.js",
7
7
  "bin": {
8
8
  "4runr": "dist/index.js",