4runr-os 2.1.48 → 2.1.49

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.
@@ -282,8 +282,9 @@ impl App {
282
282
  match key.code {
283
283
  // Typing - ALL characters go to command input (with debounce)
284
284
  KeyCode::Char(c) => {
285
- self.state.command_input.push(c);
285
+ // CRITICAL: Always set focused when typing to show cursor
286
286
  self.state.command_focused = true;
287
+ self.state.command_input.push(c);
287
288
  // Debounce: schedule render after delay
288
289
  self.input_debounce = Some(Instant::now());
289
290
  // Don't render immediately - let debounce handle it
@@ -40,6 +40,9 @@ fn render_separator(f: &mut Frame, area: Rect) {
40
40
  }
41
41
 
42
42
  pub fn render(f: &mut Frame, state: &AppState) {
43
+ // CRITICAL: Hide cursor by default at start of each render
44
+ // Only show it when explicitly set in render_command_box
45
+ // This prevents cursor from appearing in wrong places (like operations log)
43
46
  let full_area = f.size();
44
47
  f.render_widget(Clear, full_area);
45
48
 
@@ -598,13 +601,14 @@ fn render_command_box(f: &mut Frame, area: Rect, state: &AppState) {
598
601
  // Just use spacing for visual separation
599
602
 
600
603
  // Command prompt - Use ASCII > instead of Unicode ▶
601
- let cursor = if state.command_focused || !state.command_input.is_empty() { "_" } else { "_" };
604
+ // Note: We show a visual cursor character "_" in the text, but the real cursor
605
+ // position is handled separately below
602
606
  let prompt_line = Line::from(vec![
603
607
  Span::styled("> ", Style::default().fg(BRAND_PURPLE)), // ASCII > instead of Unicode ▶
604
608
  Span::styled("4runr", Style::default().fg(BRAND_VIOLET).add_modifier(Modifier::BOLD)),
605
609
  Span::styled(": ", Style::default().fg(TEXT_DIM)), // ASCII : instead of Unicode ›
606
610
  Span::styled(&state.command_input, Style::default().fg(TEXT_PRIMARY)),
607
- Span::styled(cursor, Style::default().fg(CYBER_CYAN)),
611
+ Span::styled("_", Style::default().fg(CYBER_CYAN)), // Visual cursor indicator
608
612
  ]);
609
613
  f.render_widget(Paragraph::new(prompt_line), Rect {
610
614
  x: bar_area.x, y: bar_area.y + 1, width: bar_area.width, height: 1
@@ -623,12 +627,26 @@ fn render_command_box(f: &mut Frame, area: Rect, state: &AppState) {
623
627
  x: bar_area.x, y: bar_area.y + 2, width: bar_area.width, height: 1
624
628
  });
625
629
 
626
- // Cursor position when focused
627
- if state.command_focused {
628
- let cursor_x = bar_area.x + 8 + state.command_input.len() as u16; // +8 for "> 4runr: "
630
+ // CRITICAL FIX: Only set cursor position when user is actively typing
631
+ // This prevents cursor from appearing in wrong places (operations log, etc.)
632
+ // IMPORTANT: In Ratatui, set_cursor() shows the cursor, so we only call it here
633
+ if state.command_focused || !state.command_input.is_empty() {
634
+ // Calculate correct cursor position: "> 4runr: " = 9 chars
635
+ let prompt_len = 9u16; // "> 4runr: " = 9 characters ("> " + "4runr" + ": " = 2+5+2 = 9)
636
+ let input_len = state.command_input.len() as u16;
637
+ let cursor_x = bar_area.x + prompt_len + input_len;
629
638
  let cursor_y = bar_area.y + 1;
630
- f.set_cursor(cursor_x.min(bar_area.x + bar_area.width - 1), cursor_y);
639
+
640
+ // Ensure cursor doesn't go beyond the safe area (respects 15% margin)
641
+ let max_x = (bar_area.x + bar_area.width).saturating_sub(1);
642
+ let final_x = cursor_x.min(max_x);
643
+
644
+ // Only set cursor if we're actually at the input field
645
+ // This prevents cursor from appearing elsewhere (operations log, etc.)
646
+ f.set_cursor(final_x, cursor_y);
631
647
  }
648
+ // IMPORTANT: If not focused and no input, we don't call set_cursor()
649
+ // This keeps the cursor hidden (hidden at start of main loop)
632
650
  }
633
651
 
634
652
  fn render_too_small(f: &mut Frame, viewport: &SafeViewport) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "4runr-os",
3
- "version": "2.1.48",
3
+ "version": "2.1.49",
4
4
  "type": "module",
5
5
  "description": "4Runr AI Agent OS - Interactive terminal for managing AI agents",
6
6
  "main": "dist/index.js",