4runr-os 2.9.51 → 2.9.52

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.51";
147
+ const PACKAGE_VERSION: &str = "2.9.52";
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)),
@@ -150,10 +150,7 @@ fn render_content(f: &mut Frame, area: Rect, state: &mut AppState, render_id: u6
150
150
  render_option_details(f, chunks[1], state, render_id);
151
151
  }
152
152
 
153
- fn render_options_list(f: &mut Frame, area: Rect, state: &mut AppState, render_id: u64) {
154
- let fill = Block::default().style(Style::default().bg(BG_PANEL));
155
- f.render_widget(fill, area);
156
-
153
+ fn render_options_list(f: &mut Frame, area: Rect, state: &mut AppState, _render_id: u64) {
157
154
  let options = vec![
158
155
  ("Local Bundle", GatewayOption::LocalBundle),
159
156
  ("4Runr Server", GatewayOption::CloudServer),
@@ -161,7 +158,7 @@ fn render_options_list(f: &mut Frame, area: Rect, state: &mut AppState, render_i
161
158
  ];
162
159
 
163
160
  let selected_option = &state.setup_portal.selected_option;
164
- let selected_index = options.iter()
161
+ let _selected_index = options.iter()
165
162
  .position(|(_, opt)| opt == selected_option)
166
163
  .unwrap_or(0);
167
164
 
@@ -185,24 +182,26 @@ fn render_options_list(f: &mut Frame, area: Rect, state: &mut AppState, render_i
185
182
  })
186
183
  .collect();
187
184
 
185
+ // CRITICAL: Render block first, then fill inner, then list to ensure full paint
188
186
  let block = Block::default()
189
187
  .borders(Borders::ALL)
190
188
  .title(" Gateway Options ")
191
189
  .border_style(Style::default().fg(CYBER_CYAN))
192
190
  .style(Style::default().bg(BG_PANEL));
193
191
 
194
- // STATELESS: Render list without ListState so only our item styling (► + color) shows selection.
195
- // This removes any second source of highlight that could drift from selected_option.
196
- let list = List::new(items).block(block);
197
- f.render_widget(list, area);
192
+ let inner = block.inner(area);
193
+ f.render_widget(block, area);
194
+
195
+ // Fill inner area
196
+ let fill = Block::default().style(Style::default().bg(BG_PANEL));
197
+ f.render_widget(fill, inner);
198
+
199
+ // STATELESS: Render list without ListState so only our item styling (► + color) shows selection
200
+ let list = List::new(items).style(Style::default().bg(BG_PANEL));
201
+ f.render_widget(list, inner);
198
202
  }
199
203
 
200
204
  fn render_option_details(f: &mut Frame, area: Rect, state: &AppState, _render_id: u64) {
201
- // CRITICAL: Fill entire area with background so every cell is overwritten.
202
- // Without this, Paragraph may not paint every cell; leftover shows previous option (corruption).
203
- let fill = Block::default().style(Style::default().bg(BG_PANEL));
204
- f.render_widget(fill, area);
205
-
206
205
  let selected_option = &state.setup_portal.selected_option;
207
206
  let detection_result = &state.setup_portal.detection_result;
208
207
 
@@ -288,28 +287,33 @@ fn render_option_details(f: &mut Frame, area: Rect, state: &AppState, _render_id
288
287
  ),
289
288
  };
290
289
 
291
- // Use Block to properly contain and clear the area
290
+ // CRITICAL: Render Block first (clears its area), then Paragraph separately to force full paint
292
291
  let block = Block::default()
293
292
  .title(title)
294
293
  .borders(Borders::ALL)
295
294
  .border_style(Style::default().fg(TEXT_DIM))
296
295
  .style(Style::default().bg(BG_PANEL));
297
296
 
298
- // CRITICAL: Use the standard Ratatui pattern - Paragraph with .block()
299
- // This is more reliable than rendering Block and Paragraph separately
297
+ let inner = block.inner(area);
298
+ f.render_widget(block, area);
299
+
300
+ // Fill the inner area with background explicitly
301
+ let fill = Block::default().style(Style::default().bg(BG_PANEL));
302
+ f.render_widget(fill, inner);
303
+
304
+ // Now render paragraph (content only, no block)
300
305
  let paragraph = Paragraph::new(content)
301
- .block(block)
302
306
  .wrap(Wrap { trim: true })
303
- .style(Style::default().bg(BG_PANEL)); // Ensure background fills the block
307
+ .style(Style::default().bg(BG_PANEL));
304
308
 
305
309
  // Validate area before rendering
306
310
  let terminal_size = f.size();
307
- if area.width == 0 || area.height == 0 ||
308
- area.x >= terminal_size.width || area.y >= terminal_size.height {
311
+ if inner.width == 0 || inner.height == 0 ||
312
+ inner.x >= terminal_size.width || inner.y >= terminal_size.height {
309
313
  return;
310
314
  }
311
315
 
312
- f.render_widget(paragraph, area);
316
+ f.render_widget(paragraph, inner);
313
317
  }
314
318
 
315
319
  fn render_error_box(f: &mut Frame, area: Rect, state: &AppState) {
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "4runr-os",
3
- "version": "2.9.51",
3
+ "version": "2.9.52",
4
4
  "type": "module",
5
- "description": "4Runr AI Agent OS - Secure terminal interface for AI agents. v2.9.51: Setup Portal - no clear on nav (no flicker), removed debug logs. v2.9.50: Clear only when selection changed. ⚠️ Pre-MVP / Development Phase",
5
+ "description": "4Runr AI Agent OS - Secure terminal interface for AI agents. v2.9.52: Setup Portal - block+fill+widget render (no flicker, no corruption). v2.9.51: No clear on nav, removed debug logs. ⚠️ Pre-MVP / Development Phase",
6
6
  "main": "dist/index.js",
7
7
  "bin": {
8
8
  "4runr": "dist/index.js",