4runr-os 2.10.39 → 2.10.41

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.
Files changed (51) hide show
  1. package/apps/gateway/dist/apps/gateway/src/index.js +14 -4
  2. package/apps/gateway/dist/apps/gateway/src/index.js.map +1 -1
  3. package/apps/gateway/dist/apps/gateway/src/metrics/monitoring-detail.d.ts +18 -0
  4. package/apps/gateway/dist/apps/gateway/src/metrics/monitoring-detail.d.ts.map +1 -0
  5. package/apps/gateway/dist/apps/gateway/src/metrics/monitoring-detail.js +117 -0
  6. package/apps/gateway/dist/apps/gateway/src/metrics/monitoring-detail.js.map +1 -0
  7. package/apps/gateway/dist/apps/gateway/src/middleware/log-capture.d.ts +2 -0
  8. package/apps/gateway/dist/apps/gateway/src/middleware/log-capture.d.ts.map +1 -0
  9. package/apps/gateway/dist/apps/gateway/src/middleware/log-capture.js +54 -0
  10. package/apps/gateway/dist/apps/gateway/src/middleware/log-capture.js.map +1 -0
  11. package/apps/gateway/dist/apps/gateway/src/routes/monitoring.d.ts +15 -0
  12. package/apps/gateway/dist/apps/gateway/src/routes/monitoring.d.ts.map +1 -0
  13. package/apps/gateway/dist/apps/gateway/src/routes/monitoring.js +164 -0
  14. package/apps/gateway/dist/apps/gateway/src/routes/monitoring.js.map +1 -0
  15. package/apps/gateway/package-lock.json +204 -353
  16. package/apps/gateway/src/index.ts +27 -8
  17. package/apps/gateway/src/metrics/monitoring-detail.ts +162 -0
  18. package/apps/gateway/src/middleware/log-capture.ts +70 -0
  19. package/apps/gateway/src/routes/monitoring.ts +298 -0
  20. package/dist/gateway-client.d.ts +2 -0
  21. package/dist/gateway-client.d.ts.map +1 -1
  22. package/dist/gateway-client.js +22 -0
  23. package/dist/gateway-client.js.map +1 -1
  24. package/dist/tui-handlers.js +498 -0
  25. package/dist/tui-handlers.js.map +1 -1
  26. package/mk3-tui/src/app/render_scheduler.rs +111 -112
  27. package/mk3-tui/src/app.rs +1078 -295
  28. package/mk3-tui/src/debug_log.rs +131 -124
  29. package/mk3-tui/src/io/mod.rs +63 -66
  30. package/mk3-tui/src/io/protocol.rs +14 -15
  31. package/mk3-tui/src/io/stdio.rs +31 -32
  32. package/mk3-tui/src/io/ws.rs +25 -32
  33. package/mk3-tui/src/main.rs +774 -212
  34. package/mk3-tui/src/monitoring/mod.rs +428 -0
  35. package/mk3-tui/src/screens/mod.rs +53 -39
  36. package/mk3-tui/src/storage/cache.rs +221 -224
  37. package/mk3-tui/src/storage/mod.rs +5 -6
  38. package/mk3-tui/src/ui/agent_builder.rs +1148 -922
  39. package/mk3-tui/src/ui/agent_list.rs +344 -295
  40. package/mk3-tui/src/ui/boot.rs +145 -148
  41. package/mk3-tui/src/ui/connection_portal.rs +121 -98
  42. package/mk3-tui/src/ui/help.rs +340 -284
  43. package/mk3-tui/src/ui/layout.rs +966 -803
  44. package/mk3-tui/src/ui/mod.rs +1 -1
  45. package/mk3-tui/src/ui/portal_monitoring.rs +1027 -147
  46. package/mk3-tui/src/ui/run_manager.rs +784 -764
  47. package/mk3-tui/src/ui/safe_viewport.rs +236 -235
  48. package/mk3-tui/src/ui/settings.rs +414 -362
  49. package/mk3-tui/src/ui/setup_portal.rs +158 -101
  50. package/mk3-tui/src/websocket.rs +315 -308
  51. package/package.json +2 -2
@@ -1,148 +1,145 @@
1
- use crate::app::AppState;
2
- use ratatui::prelude::*;
3
- use ratatui::widgets::{Block, Borders, Gauge, Paragraph};
4
-
5
- // Color constants matching the TUI palette (exact match from layout.rs)
6
- const BRAND_PURPLE: Color = Color::Rgb(138, 43, 226);
7
- #[allow(dead_code)]
8
- const BRAND_VIOLET: Color = Color::Rgb(148, 103, 189);
9
- const CYBER_CYAN: Color = Color::Rgb(0, 255, 255);
10
- const NEON_GREEN: Color = Color::Rgb(57, 255, 20);
11
- const TEXT_PRIMARY: Color = Color::Rgb(230, 230, 240);
12
- const TEXT_DIM: Color = Color::Rgb(100, 100, 120);
13
- #[allow(dead_code)]
14
- const TEXT_MUTED: Color = Color::Rgb(60, 60, 80);
15
- const BG_PANEL: Color = Color::Rgb(18, 18, 25);
16
-
17
- /// Exact logo from requirements (monospace, preserve spacing)
18
- const LOGO: &str = r#"██╗ ██╗██████╗ ██╗ ██╗███╗ ██╗██████╗ ██████╗ ███████╗
19
- ██║ ██║██╔══██╗██║ ██║████╗ ██║██╔══██╗ ██╔═══██╗██╔════╝
20
- ███████║██████╔╝██║ ██║██╔██╗ ██║██████╔╝ ██║ ██║███████╗
21
- ╚════██║██╔══██╗██║ ██║██║╚██╗██║██╔══██╗ ██║ ██║╚════██║
22
- ██║██║ ██║╚██████╔╝██║ ╚████║██║ ██║ ╚██████╔╝███████║
23
- ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝"#;
24
-
25
- pub fn render_boot(f: &mut Frame, area: Rect, state: &AppState) {
26
- // Clear background
27
- f.render_widget(
28
- Block::default().style(Style::default().bg(BG_PANEL)),
29
- area,
30
- );
31
-
32
- // Fixed layout: logo stays at fixed position, elements below it
33
- let logo_height: u16 = 6; // Logo is 6 lines
34
- let boot_logs_height: u16 = 5; // Fixed height for logs (not dynamic)
35
- let progress_height: u16 = 3;
36
-
37
- // Logo starts at a fixed position from top (about 1/4 down the screen)
38
- let logo_start_y: u16 = area.height / 4;
39
-
40
- // === LOGO (centered horizontally, fixed vertical position) ===
41
- let logo_lines: Vec<&str> = LOGO.lines().collect();
42
- let logo_width: u16 = logo_lines.iter().map(|l| l.len()).max().unwrap_or(0) as u16;
43
- // Center horizontally: (area.width - logo_width) / 2
44
- let logo_x: u16 = area.x + (area.width.saturating_sub(logo_width)) / 2;
45
-
46
- for (i, line) in logo_lines.iter().enumerate() {
47
- let line_y = logo_start_y + i as u16;
48
- if line_y < area.height {
49
- // Center each line within the available width
50
- let line_rect = Rect {
51
- x: logo_x,
52
- y: line_y,
53
- width: logo_width.min(area.width.saturating_sub(logo_x)),
54
- height: 1,
55
- };
56
- f.render_widget(
57
- Paragraph::new(*line)
58
- .style(Style::default().fg(BRAND_PURPLE))
59
- .alignment(Alignment::Center), // Center alignment for perfect centering
60
- line_rect,
61
- );
62
- }
63
- }
64
-
65
- let current_y = logo_start_y + logo_height + 2;
66
-
67
- // === BOOT LOGS ===
68
- if !state.boot_lines.is_empty() && current_y < area.height {
69
- // Center logs horizontally
70
- let logs_width: u16 = (area.width * 60 / 100).min(area.width.saturating_sub(40)); // 60% width, safe margins
71
- let logs_x: u16 = area.x + (area.width.saturating_sub(logs_width)) / 2;
72
-
73
- let logs_area = Rect {
74
- x: logs_x,
75
- y: current_y,
76
- width: logs_width,
77
- height: boot_logs_height,
78
- };
79
-
80
- let mut log_text = String::new();
81
- for line in state.boot_lines.iter() {
82
- log_text.push_str(line);
83
- log_text.push('\n');
84
- }
85
-
86
- f.render_widget(
87
- Paragraph::new(log_text.trim())
88
- .style(Style::default().fg(TEXT_PRIMARY))
89
- .alignment(Alignment::Center), // Center logs too
90
- logs_area,
91
- );
92
- }
93
-
94
- let current_y = current_y + boot_logs_height + 2;
95
-
96
- // === PROGRESS BAR ===
97
- if current_y < area.height {
98
- // Center progress bar horizontally
99
- let progress_width: u16 = (area.width * 60 / 100).min(area.width.saturating_sub(40));
100
- let progress_x: u16 = area.x + (area.width.saturating_sub(progress_width)) / 2;
101
-
102
- let progress_area = Rect {
103
- x: progress_x,
104
- y: current_y,
105
- width: progress_width,
106
- height: 3,
107
- };
108
-
109
- let progress_label = if state.boot_done {
110
- "System Ready"
111
- } else {
112
- "Booting..."
113
- };
114
-
115
- f.render_widget(
116
- Gauge::default()
117
- .block(
118
- Block::default()
119
- .borders(Borders::NONE)
120
- .title(progress_label)
121
- .title_style(Style::default().fg(CYBER_CYAN))
122
- )
123
- .gauge_style(Style::default().fg(NEON_GREEN))
124
- .percent(state.boot_progress as u16)
125
- .label(format!("{}%", state.boot_progress)),
126
- progress_area,
127
- );
128
- }
129
-
130
- let current_y = current_y + progress_height + 2;
131
-
132
- // === FOOTER: "Press any key to continue" (only when boot done) ===
133
- if state.boot_done && current_y < area.height {
134
- let footer_area = Rect {
135
- x: area.x,
136
- y: current_y,
137
- width: area.width,
138
- height: 1,
139
- };
140
-
141
- f.render_widget(
142
- Paragraph::new("Press any key to continue...")
143
- .style(Style::default().fg(TEXT_DIM))
144
- .alignment(Alignment::Center),
145
- footer_area,
146
- );
147
- }
148
- }
1
+ use crate::app::AppState;
2
+ use ratatui::prelude::*;
3
+ use ratatui::widgets::{Block, Borders, Gauge, Paragraph};
4
+
5
+ // Color constants matching the TUI palette (exact match from layout.rs)
6
+ const BRAND_PURPLE: Color = Color::Rgb(138, 43, 226);
7
+ #[allow(dead_code)]
8
+ const BRAND_VIOLET: Color = Color::Rgb(148, 103, 189);
9
+ const CYBER_CYAN: Color = Color::Rgb(0, 255, 255);
10
+ const NEON_GREEN: Color = Color::Rgb(57, 255, 20);
11
+ const TEXT_PRIMARY: Color = Color::Rgb(230, 230, 240);
12
+ const TEXT_DIM: Color = Color::Rgb(100, 100, 120);
13
+ #[allow(dead_code)]
14
+ const TEXT_MUTED: Color = Color::Rgb(60, 60, 80);
15
+ const BG_PANEL: Color = Color::Rgb(18, 18, 25);
16
+
17
+ /// Exact logo from requirements (monospace, preserve spacing)
18
+ const LOGO: &str = r#"██╗ ██╗██████╗ ██╗ ██╗███╗ ██╗██████╗ ██████╗ ███████╗
19
+ ██║ ██║██╔══██╗██║ ██║████╗ ██║██╔══██╗ ██╔═══██╗██╔════╝
20
+ ███████║██████╔╝██║ ██║██╔██╗ ██║██████╔╝ ██║ ██║███████╗
21
+ ╚════██║██╔══██╗██║ ██║██║╚██╗██║██╔══██╗ ██║ ██║╚════██║
22
+ ██║██║ ██║╚██████╔╝██║ ╚████║██║ ██║ ╚██████╔╝███████║
23
+ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝"#;
24
+
25
+ pub fn render_boot(f: &mut Frame, area: Rect, state: &AppState) {
26
+ // Clear background
27
+ f.render_widget(Block::default().style(Style::default().bg(BG_PANEL)), area);
28
+
29
+ // Fixed layout: logo stays at fixed position, elements below it
30
+ let logo_height: u16 = 6; // Logo is 6 lines
31
+ let boot_logs_height: u16 = 5; // Fixed height for logs (not dynamic)
32
+ let progress_height: u16 = 3;
33
+
34
+ // Logo starts at a fixed position from top (about 1/4 down the screen)
35
+ let logo_start_y: u16 = area.height / 4;
36
+
37
+ // === LOGO (centered horizontally, fixed vertical position) ===
38
+ let logo_lines: Vec<&str> = LOGO.lines().collect();
39
+ let logo_width: u16 = logo_lines.iter().map(|l| l.len()).max().unwrap_or(0) as u16;
40
+ // Center horizontally: (area.width - logo_width) / 2
41
+ let logo_x: u16 = area.x + (area.width.saturating_sub(logo_width)) / 2;
42
+
43
+ for (i, line) in logo_lines.iter().enumerate() {
44
+ let line_y = logo_start_y + i as u16;
45
+ if line_y < area.height {
46
+ // Center each line within the available width
47
+ let line_rect = Rect {
48
+ x: logo_x,
49
+ y: line_y,
50
+ width: logo_width.min(area.width.saturating_sub(logo_x)),
51
+ height: 1,
52
+ };
53
+ f.render_widget(
54
+ Paragraph::new(*line)
55
+ .style(Style::default().fg(BRAND_PURPLE))
56
+ .alignment(Alignment::Center), // Center alignment for perfect centering
57
+ line_rect,
58
+ );
59
+ }
60
+ }
61
+
62
+ let current_y = logo_start_y + logo_height + 2;
63
+
64
+ // === BOOT LOGS ===
65
+ if !state.boot_lines.is_empty() && current_y < area.height {
66
+ // Center logs horizontally
67
+ let logs_width: u16 = (area.width * 60 / 100).min(area.width.saturating_sub(40)); // 60% width, safe margins
68
+ let logs_x: u16 = area.x + (area.width.saturating_sub(logs_width)) / 2;
69
+
70
+ let logs_area = Rect {
71
+ x: logs_x,
72
+ y: current_y,
73
+ width: logs_width,
74
+ height: boot_logs_height,
75
+ };
76
+
77
+ let mut log_text = String::new();
78
+ for line in state.boot_lines.iter() {
79
+ log_text.push_str(line);
80
+ log_text.push('\n');
81
+ }
82
+
83
+ f.render_widget(
84
+ Paragraph::new(log_text.trim())
85
+ .style(Style::default().fg(TEXT_PRIMARY))
86
+ .alignment(Alignment::Center), // Center logs too
87
+ logs_area,
88
+ );
89
+ }
90
+
91
+ let current_y = current_y + boot_logs_height + 2;
92
+
93
+ // === PROGRESS BAR ===
94
+ if current_y < area.height {
95
+ // Center progress bar horizontally
96
+ let progress_width: u16 = (area.width * 60 / 100).min(area.width.saturating_sub(40));
97
+ let progress_x: u16 = area.x + (area.width.saturating_sub(progress_width)) / 2;
98
+
99
+ let progress_area = Rect {
100
+ x: progress_x,
101
+ y: current_y,
102
+ width: progress_width,
103
+ height: 3,
104
+ };
105
+
106
+ let progress_label = if state.boot_done {
107
+ "System Ready"
108
+ } else {
109
+ "Booting..."
110
+ };
111
+
112
+ f.render_widget(
113
+ Gauge::default()
114
+ .block(
115
+ Block::default()
116
+ .borders(Borders::NONE)
117
+ .title(progress_label)
118
+ .title_style(Style::default().fg(CYBER_CYAN)),
119
+ )
120
+ .gauge_style(Style::default().fg(NEON_GREEN))
121
+ .percent(state.boot_progress as u16)
122
+ .label(format!("{}%", state.boot_progress)),
123
+ progress_area,
124
+ );
125
+ }
126
+
127
+ let current_y = current_y + progress_height + 2;
128
+
129
+ // === FOOTER: "Press any key to continue" (only when boot done) ===
130
+ if state.boot_done && current_y < area.height {
131
+ let footer_area = Rect {
132
+ x: area.x,
133
+ y: current_y,
134
+ width: area.width,
135
+ height: 1,
136
+ };
137
+
138
+ f.render_widget(
139
+ Paragraph::new("Press any key to continue...")
140
+ .style(Style::default().fg(TEXT_DIM))
141
+ .alignment(Alignment::Center),
142
+ footer_area,
143
+ );
144
+ }
145
+ }