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,235 +1,236 @@
1
- use ratatui::prelude::*;
2
- use std::env;
3
-
4
- /// Render mode: Local (full borders) vs Browser (no outer borders)
5
- #[derive(Debug, Clone, Copy, PartialEq)]
6
- #[allow(dead_code)]
7
- pub enum RenderMode {
8
- Local, // Full borders, rich UI
9
- Browser, // No outer borders, larger margins
10
- }
11
-
12
- impl RenderMode {
13
- pub fn detect() -> Self {
14
- // Allow explicit override
15
- if let Ok(mode) = env::var("TUI_RENDER_MODE") {
16
- match mode.to_lowercase().as_str() {
17
- "local" => return RenderMode::Local,
18
- "browser" | "web" => return RenderMode::Browser,
19
- _ => {}
20
- }
21
- }
22
-
23
- // Auto-detect
24
- if is_cloudshell_mode() {
25
- RenderMode::Browser
26
- } else {
27
- RenderMode::Local
28
- }
29
- }
30
- }
31
-
32
- /// Safe viewport configuration from environment variables
33
- #[derive(Debug, Clone)]
34
- pub struct SafeViewportConfig {
35
- pub margin_x: u16,
36
- pub margin_y: u16,
37
- pub guard_right: u16,
38
- pub guard_bottom: u16,
39
- }
40
-
41
- impl Default for SafeViewportConfig {
42
- fn default() -> Self {
43
- let render_mode = RenderMode::detect();
44
-
45
- match render_mode {
46
- RenderMode::Browser => Self {
47
- margin_x: env::var("TUI_MARGIN_X")
48
- .ok()
49
- .and_then(|v| v.parse().ok())
50
- .unwrap_or(2),
51
- margin_y: env::var("TUI_MARGIN_Y")
52
- .ok()
53
- .and_then(|v| v.parse().ok())
54
- .unwrap_or(1),
55
- guard_right: env::var("TUI_GUARD_RIGHT")
56
- .ok()
57
- .and_then(|v| v.parse().ok())
58
- .unwrap_or(6), // Was 4, increase to 6
59
- guard_bottom: env::var("TUI_GUARD_BOTTOM")
60
- .ok()
61
- .and_then(|v| v.parse().ok())
62
- .unwrap_or(3), // Was 2, increase to 3
63
- },
64
- RenderMode::Local => Self {
65
- margin_x: env::var("TUI_MARGIN_X")
66
- .ok()
67
- .and_then(|v| v.parse().ok())
68
- .unwrap_or(0), // Was 1, no margin needed locally
69
- margin_y: env::var("TUI_MARGIN_Y")
70
- .ok()
71
- .and_then(|v| v.parse().ok())
72
- .unwrap_or(0),
73
- guard_right: env::var("TUI_GUARD_RIGHT")
74
- .ok()
75
- .and_then(|v| v.parse().ok())
76
- .unwrap_or(1), // Minimal guard
77
- guard_bottom: env::var("TUI_GUARD_BOTTOM")
78
- .ok()
79
- .and_then(|v| v.parse().ok())
80
- .unwrap_or(1),
81
- },
82
- }
83
- }
84
- }
85
-
86
- /// Detect if running in CloudShell/browser terminal
87
- pub fn is_cloudshell_mode() -> bool {
88
- // AWS CloudShell
89
- env::var("AWS_EXECUTION_ENV").is_ok()
90
- || env::var("CLOUDSHELL").is_ok()
91
- // Google Cloud Shell
92
- || env::var("CLOUD_SHELL").is_ok()
93
- || env::var("DEVSHELL_PROJECT_ID").is_ok()
94
- // Azure Cloud Shell
95
- || env::var("ACC_CLOUD").is_ok()
96
- // Generic web terminal indicators
97
- || env::var("TUI_WEB").map(|v| v == "1").unwrap_or(false)
98
- || env::var("TERM_PROGRAM").map(|v| v.contains("xterm.js")).unwrap_or(false)
99
- // SSH through web console (likely browser-based)
100
- || (env::var("SSH_CONNECTION").is_ok() && env::var("DISPLAY").is_err())
101
- }
102
-
103
- /// Safe viewport calculation result
104
- #[derive(Debug, Clone)]
105
- #[allow(dead_code)]
106
- pub struct SafeViewport {
107
- pub canvas_cols: u16,
108
- pub canvas_rows: u16,
109
- pub safe_cols: u16,
110
- pub safe_rows: u16,
111
- pub safe_rect: Rect,
112
- pub config: SafeViewportConfig,
113
- pub render_mode: RenderMode,
114
- }
115
-
116
- impl SafeViewport {
117
- /// Calculate safe viewport from terminal size
118
- pub fn new(full_area: Rect) -> Self {
119
- let render_mode = RenderMode::detect();
120
- let config = SafeViewportConfig::default();
121
-
122
- let canvas_cols = full_area.width;
123
- let canvas_rows = full_area.height;
124
-
125
- // Calculate safe area with margins and guards
126
- // Hard rule: never draw on last column/row
127
- let left_margin = config.margin_x;
128
- let right_margin = config.margin_x + config.guard_right;
129
- let top_margin = config.margin_y;
130
- let bottom_margin = config.margin_y + config.guard_bottom;
131
-
132
- let safe_x = full_area.x + left_margin;
133
- let safe_y = full_area.y + top_margin;
134
- let safe_w = full_area.width
135
- .saturating_sub(left_margin + right_margin)
136
- .max(1);
137
- let safe_h = full_area.height
138
- .saturating_sub(top_margin + bottom_margin)
139
- .max(1);
140
-
141
- let safe_rect = Rect {
142
- x: safe_x,
143
- y: safe_y,
144
- width: safe_w,
145
- height: safe_h,
146
- };
147
-
148
- Self {
149
- canvas_cols,
150
- canvas_rows,
151
- safe_cols: safe_w,
152
- safe_rows: safe_h,
153
- safe_rect,
154
- config,
155
- render_mode,
156
- }
157
- }
158
-
159
- /// Check if terminal is too small for minimum requirements
160
- pub fn is_too_small(&self, required_cols: u16, required_rows: u16) -> bool {
161
- self.safe_cols < required_cols || self.safe_rows < required_rows
162
- }
163
-
164
- /// Validate a rectangle before rendering
165
- #[allow(dead_code)]
166
- pub fn validate_rect(&self, rect: Rect, min_w: u16, min_h: u16, name: &str) -> RectValidation {
167
- // Check minimum size
168
- if rect.width < min_w || rect.height < min_h {
169
- return RectValidation::Invalid {
170
- reason: format!(
171
- "{}: size {}x{} below minimum {}x{}",
172
- name, rect.width, rect.height, min_w, min_h
173
- ),
174
- };
175
- }
176
-
177
- // Check bounds: rect must fit within safe_rect (using ABSOLUTE coordinates)
178
- let max_x = rect.x + rect.width;
179
- let max_y = rect.y + rect.height;
180
- let safe_max_x = self.safe_rect.x + self.safe_rect.width; // FIXED: use absolute bound
181
- let safe_max_y = self.safe_rect.y + self.safe_rect.height; // FIXED: use absolute bound
182
-
183
- if max_x > safe_max_x {
184
- return RectValidation::Invalid {
185
- reason: format!(
186
- "{}: right edge {} exceeds safe bound {}",
187
- name, max_x, safe_max_x
188
- ),
189
- };
190
- }
191
-
192
- if max_y > safe_max_y {
193
- return RectValidation::Invalid {
194
- reason: format!(
195
- "{}: bottom edge {} exceeds safe bound {}",
196
- name, max_y, safe_max_y
197
- ),
198
- };
199
- }
200
-
201
- // Clamp to safe bounds
202
- let clamped = rect.intersection(self.safe_rect);
203
-
204
- if clamped.width == 0 || clamped.height == 0 {
205
- return RectValidation::Invalid {
206
- reason: format!("{}: clamped rect has zero size", name),
207
- };
208
- }
209
-
210
- RectValidation::Valid(clamped)
211
- }
212
- }
213
-
214
- #[derive(Debug, Clone)]
215
- #[allow(dead_code)]
216
- pub enum RectValidation {
217
- Valid(Rect),
218
- Invalid { reason: String },
219
- }
220
-
221
- impl RectValidation {
222
- #[allow(dead_code)]
223
- pub fn is_valid(&self) -> bool {
224
- matches!(self, RectValidation::Valid(_))
225
- }
226
-
227
- #[allow(dead_code)]
228
- pub fn unwrap_or_default(self) -> Rect {
229
- match self {
230
- RectValidation::Valid(rect) => rect,
231
- RectValidation::Invalid { .. } => Rect::default(),
232
- }
233
- }
234
- }
235
-
1
+ use ratatui::prelude::*;
2
+ use std::env;
3
+
4
+ /// Render mode: Local (full borders) vs Browser (no outer borders)
5
+ #[derive(Debug, Clone, Copy, PartialEq)]
6
+ #[allow(dead_code)]
7
+ pub enum RenderMode {
8
+ Local, // Full borders, rich UI
9
+ Browser, // No outer borders, larger margins
10
+ }
11
+
12
+ impl RenderMode {
13
+ pub fn detect() -> Self {
14
+ // Allow explicit override
15
+ if let Ok(mode) = env::var("TUI_RENDER_MODE") {
16
+ match mode.to_lowercase().as_str() {
17
+ "local" => return RenderMode::Local,
18
+ "browser" | "web" => return RenderMode::Browser,
19
+ _ => {}
20
+ }
21
+ }
22
+
23
+ // Auto-detect
24
+ if is_cloudshell_mode() {
25
+ RenderMode::Browser
26
+ } else {
27
+ RenderMode::Local
28
+ }
29
+ }
30
+ }
31
+
32
+ /// Safe viewport configuration from environment variables
33
+ #[derive(Debug, Clone)]
34
+ pub struct SafeViewportConfig {
35
+ pub margin_x: u16,
36
+ pub margin_y: u16,
37
+ pub guard_right: u16,
38
+ pub guard_bottom: u16,
39
+ }
40
+
41
+ impl Default for SafeViewportConfig {
42
+ fn default() -> Self {
43
+ let render_mode = RenderMode::detect();
44
+
45
+ match render_mode {
46
+ RenderMode::Browser => Self {
47
+ margin_x: env::var("TUI_MARGIN_X")
48
+ .ok()
49
+ .and_then(|v| v.parse().ok())
50
+ .unwrap_or(2),
51
+ margin_y: env::var("TUI_MARGIN_Y")
52
+ .ok()
53
+ .and_then(|v| v.parse().ok())
54
+ .unwrap_or(1),
55
+ guard_right: env::var("TUI_GUARD_RIGHT")
56
+ .ok()
57
+ .and_then(|v| v.parse().ok())
58
+ .unwrap_or(6), // Was 4, increase to 6
59
+ guard_bottom: env::var("TUI_GUARD_BOTTOM")
60
+ .ok()
61
+ .and_then(|v| v.parse().ok())
62
+ .unwrap_or(3), // Was 2, increase to 3
63
+ },
64
+ RenderMode::Local => Self {
65
+ margin_x: env::var("TUI_MARGIN_X")
66
+ .ok()
67
+ .and_then(|v| v.parse().ok())
68
+ .unwrap_or(0), // Was 1, no margin needed locally
69
+ margin_y: env::var("TUI_MARGIN_Y")
70
+ .ok()
71
+ .and_then(|v| v.parse().ok())
72
+ .unwrap_or(0),
73
+ guard_right: env::var("TUI_GUARD_RIGHT")
74
+ .ok()
75
+ .and_then(|v| v.parse().ok())
76
+ .unwrap_or(1), // Minimal guard
77
+ guard_bottom: env::var("TUI_GUARD_BOTTOM")
78
+ .ok()
79
+ .and_then(|v| v.parse().ok())
80
+ .unwrap_or(1),
81
+ },
82
+ }
83
+ }
84
+ }
85
+
86
+ /// Detect if running in CloudShell/browser terminal
87
+ pub fn is_cloudshell_mode() -> bool {
88
+ // AWS CloudShell
89
+ env::var("AWS_EXECUTION_ENV").is_ok()
90
+ || env::var("CLOUDSHELL").is_ok()
91
+ // Google Cloud Shell
92
+ || env::var("CLOUD_SHELL").is_ok()
93
+ || env::var("DEVSHELL_PROJECT_ID").is_ok()
94
+ // Azure Cloud Shell
95
+ || env::var("ACC_CLOUD").is_ok()
96
+ // Generic web terminal indicators
97
+ || env::var("TUI_WEB").map(|v| v == "1").unwrap_or(false)
98
+ || env::var("TERM_PROGRAM").map(|v| v.contains("xterm.js")).unwrap_or(false)
99
+ // SSH through web console (likely browser-based)
100
+ || (env::var("SSH_CONNECTION").is_ok() && env::var("DISPLAY").is_err())
101
+ }
102
+
103
+ /// Safe viewport calculation result
104
+ #[derive(Debug, Clone)]
105
+ #[allow(dead_code)]
106
+ pub struct SafeViewport {
107
+ pub canvas_cols: u16,
108
+ pub canvas_rows: u16,
109
+ pub safe_cols: u16,
110
+ pub safe_rows: u16,
111
+ pub safe_rect: Rect,
112
+ pub config: SafeViewportConfig,
113
+ pub render_mode: RenderMode,
114
+ }
115
+
116
+ impl SafeViewport {
117
+ /// Calculate safe viewport from terminal size
118
+ pub fn new(full_area: Rect) -> Self {
119
+ let render_mode = RenderMode::detect();
120
+ let config = SafeViewportConfig::default();
121
+
122
+ let canvas_cols = full_area.width;
123
+ let canvas_rows = full_area.height;
124
+
125
+ // Calculate safe area with margins and guards
126
+ // Hard rule: never draw on last column/row
127
+ let left_margin = config.margin_x;
128
+ let right_margin = config.margin_x + config.guard_right;
129
+ let top_margin = config.margin_y;
130
+ let bottom_margin = config.margin_y + config.guard_bottom;
131
+
132
+ let safe_x = full_area.x + left_margin;
133
+ let safe_y = full_area.y + top_margin;
134
+ let safe_w = full_area
135
+ .width
136
+ .saturating_sub(left_margin + right_margin)
137
+ .max(1);
138
+ let safe_h = full_area
139
+ .height
140
+ .saturating_sub(top_margin + bottom_margin)
141
+ .max(1);
142
+
143
+ let safe_rect = Rect {
144
+ x: safe_x,
145
+ y: safe_y,
146
+ width: safe_w,
147
+ height: safe_h,
148
+ };
149
+
150
+ Self {
151
+ canvas_cols,
152
+ canvas_rows,
153
+ safe_cols: safe_w,
154
+ safe_rows: safe_h,
155
+ safe_rect,
156
+ config,
157
+ render_mode,
158
+ }
159
+ }
160
+
161
+ /// Check if terminal is too small for minimum requirements
162
+ pub fn is_too_small(&self, required_cols: u16, required_rows: u16) -> bool {
163
+ self.safe_cols < required_cols || self.safe_rows < required_rows
164
+ }
165
+
166
+ /// Validate a rectangle before rendering
167
+ #[allow(dead_code)]
168
+ pub fn validate_rect(&self, rect: Rect, min_w: u16, min_h: u16, name: &str) -> RectValidation {
169
+ // Check minimum size
170
+ if rect.width < min_w || rect.height < min_h {
171
+ return RectValidation::Invalid {
172
+ reason: format!(
173
+ "{}: size {}x{} below minimum {}x{}",
174
+ name, rect.width, rect.height, min_w, min_h
175
+ ),
176
+ };
177
+ }
178
+
179
+ // Check bounds: rect must fit within safe_rect (using ABSOLUTE coordinates)
180
+ let max_x = rect.x + rect.width;
181
+ let max_y = rect.y + rect.height;
182
+ let safe_max_x = self.safe_rect.x + self.safe_rect.width; // FIXED: use absolute bound
183
+ let safe_max_y = self.safe_rect.y + self.safe_rect.height; // FIXED: use absolute bound
184
+
185
+ if max_x > safe_max_x {
186
+ return RectValidation::Invalid {
187
+ reason: format!(
188
+ "{}: right edge {} exceeds safe bound {}",
189
+ name, max_x, safe_max_x
190
+ ),
191
+ };
192
+ }
193
+
194
+ if max_y > safe_max_y {
195
+ return RectValidation::Invalid {
196
+ reason: format!(
197
+ "{}: bottom edge {} exceeds safe bound {}",
198
+ name, max_y, safe_max_y
199
+ ),
200
+ };
201
+ }
202
+
203
+ // Clamp to safe bounds
204
+ let clamped = rect.intersection(self.safe_rect);
205
+
206
+ if clamped.width == 0 || clamped.height == 0 {
207
+ return RectValidation::Invalid {
208
+ reason: format!("{}: clamped rect has zero size", name),
209
+ };
210
+ }
211
+
212
+ RectValidation::Valid(clamped)
213
+ }
214
+ }
215
+
216
+ #[derive(Debug, Clone)]
217
+ #[allow(dead_code)]
218
+ pub enum RectValidation {
219
+ Valid(Rect),
220
+ Invalid { reason: String },
221
+ }
222
+
223
+ impl RectValidation {
224
+ #[allow(dead_code)]
225
+ pub fn is_valid(&self) -> bool {
226
+ matches!(self, RectValidation::Valid(_))
227
+ }
228
+
229
+ #[allow(dead_code)]
230
+ pub fn unwrap_or_default(self) -> Rect {
231
+ match self {
232
+ RectValidation::Valid(rect) => rect,
233
+ RectValidation::Invalid { .. } => Rect::default(),
234
+ }
235
+ }
236
+ }