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.
- package/apps/gateway/dist/apps/gateway/src/index.js +14 -4
- package/apps/gateway/dist/apps/gateway/src/index.js.map +1 -1
- package/apps/gateway/dist/apps/gateway/src/metrics/monitoring-detail.d.ts +18 -0
- package/apps/gateway/dist/apps/gateway/src/metrics/monitoring-detail.d.ts.map +1 -0
- package/apps/gateway/dist/apps/gateway/src/metrics/monitoring-detail.js +117 -0
- package/apps/gateway/dist/apps/gateway/src/metrics/monitoring-detail.js.map +1 -0
- package/apps/gateway/dist/apps/gateway/src/middleware/log-capture.d.ts +2 -0
- package/apps/gateway/dist/apps/gateway/src/middleware/log-capture.d.ts.map +1 -0
- package/apps/gateway/dist/apps/gateway/src/middleware/log-capture.js +54 -0
- package/apps/gateway/dist/apps/gateway/src/middleware/log-capture.js.map +1 -0
- package/apps/gateway/dist/apps/gateway/src/routes/monitoring.d.ts +15 -0
- package/apps/gateway/dist/apps/gateway/src/routes/monitoring.d.ts.map +1 -0
- package/apps/gateway/dist/apps/gateway/src/routes/monitoring.js +164 -0
- package/apps/gateway/dist/apps/gateway/src/routes/monitoring.js.map +1 -0
- package/apps/gateway/package-lock.json +204 -353
- package/apps/gateway/src/index.ts +27 -8
- package/apps/gateway/src/metrics/monitoring-detail.ts +162 -0
- package/apps/gateway/src/middleware/log-capture.ts +70 -0
- package/apps/gateway/src/routes/monitoring.ts +298 -0
- package/dist/gateway-client.d.ts +2 -0
- package/dist/gateway-client.d.ts.map +1 -1
- package/dist/gateway-client.js +22 -0
- package/dist/gateway-client.js.map +1 -1
- package/dist/tui-handlers.js +498 -0
- package/dist/tui-handlers.js.map +1 -1
- package/mk3-tui/src/app/render_scheduler.rs +111 -112
- package/mk3-tui/src/app.rs +1078 -295
- package/mk3-tui/src/debug_log.rs +131 -124
- package/mk3-tui/src/io/mod.rs +63 -66
- package/mk3-tui/src/io/protocol.rs +14 -15
- package/mk3-tui/src/io/stdio.rs +31 -32
- package/mk3-tui/src/io/ws.rs +25 -32
- package/mk3-tui/src/main.rs +774 -212
- package/mk3-tui/src/monitoring/mod.rs +428 -0
- package/mk3-tui/src/screens/mod.rs +53 -39
- package/mk3-tui/src/storage/cache.rs +221 -224
- package/mk3-tui/src/storage/mod.rs +5 -6
- package/mk3-tui/src/ui/agent_builder.rs +1148 -922
- package/mk3-tui/src/ui/agent_list.rs +344 -295
- package/mk3-tui/src/ui/boot.rs +145 -148
- package/mk3-tui/src/ui/connection_portal.rs +121 -98
- package/mk3-tui/src/ui/help.rs +340 -284
- package/mk3-tui/src/ui/layout.rs +966 -803
- package/mk3-tui/src/ui/mod.rs +1 -1
- package/mk3-tui/src/ui/portal_monitoring.rs +1027 -147
- package/mk3-tui/src/ui/run_manager.rs +784 -764
- package/mk3-tui/src/ui/safe_viewport.rs +236 -235
- package/mk3-tui/src/ui/settings.rs +414 -362
- package/mk3-tui/src/ui/setup_portal.rs +158 -101
- package/mk3-tui/src/websocket.rs +315 -308
- package/package.json +2 -2
package/mk3-tui/src/debug_log.rs
CHANGED
|
@@ -1,124 +1,131 @@
|
|
|
1
|
-
//! File-based debug logger for Setup Portal.
|
|
2
|
-
//! When SETUP_PORTAL_DEBUG=1 or SETUP_PORTAL_DEBUG_FILE is set, all inputs and render state
|
|
3
|
-
//! are written to a file so you can capture the full trace when reproducing the navigation bug.
|
|
4
|
-
//!
|
|
5
|
-
//! Usage:
|
|
6
|
-
//! set SETUP_PORTAL_DEBUG_FILE=setup-portal-debug.log
|
|
7
|
-
//! mk3-tui (or 4r)
|
|
8
|
-
//! Then open Setup Portal (windowed), reproduce the bug, exit. Inspect setup-portal-debug.log.
|
|
9
|
-
|
|
10
|
-
use std::io::Write;
|
|
11
|
-
use std::sync::Mutex;
|
|
12
|
-
use std::sync::OnceLock;
|
|
13
|
-
use std::time::{SystemTime, UNIX_EPOCH};
|
|
14
|
-
|
|
15
|
-
fn enabled() -> bool {
|
|
16
|
-
std::env::var("SETUP_PORTAL_DEBUG").as_deref() == Ok("1")
|
|
17
|
-
|| std::env::var("SETUP_PORTAL_DEBUG_FILE").is_ok()
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
fn path() -> String {
|
|
21
|
-
std::env::var("SETUP_PORTAL_DEBUG_FILE")
|
|
22
|
-
.unwrap_or_else(|_| "setup-portal-debug.log".to_string())
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
static FILE: OnceLock<Mutex<Option<std::io::BufWriter<std::fs::File>>>> = OnceLock::new();
|
|
26
|
-
|
|
27
|
-
fn ensure_open() -> bool {
|
|
28
|
-
if !enabled() {
|
|
29
|
-
return false;
|
|
30
|
-
}
|
|
31
|
-
let mutex = FILE.get_or_init(|| Mutex::new(None));
|
|
32
|
-
let mut guard = mutex.lock().unwrap();
|
|
33
|
-
if guard.is_none() {
|
|
34
|
-
let path = path();
|
|
35
|
-
match std::fs::OpenOptions::new()
|
|
36
|
-
.create(true)
|
|
37
|
-
.append(true)
|
|
38
|
-
.open(&path)
|
|
39
|
-
{
|
|
40
|
-
Ok(file_handle) => {
|
|
41
|
-
// Resolve full path so user always knows where the log is
|
|
42
|
-
let full_path: String = std::path::Path::new(&path)
|
|
43
|
-
.canonicalize()
|
|
44
|
-
.map(|p| p.display().to_string())
|
|
45
|
-
.or_else(|_|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
let
|
|
55
|
-
let
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
let _ =
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
.
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
log(&msg);
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
1
|
+
//! File-based debug logger for Setup Portal.
|
|
2
|
+
//! When SETUP_PORTAL_DEBUG=1 or SETUP_PORTAL_DEBUG_FILE is set, all inputs and render state
|
|
3
|
+
//! are written to a file so you can capture the full trace when reproducing the navigation bug.
|
|
4
|
+
//!
|
|
5
|
+
//! Usage:
|
|
6
|
+
//! set SETUP_PORTAL_DEBUG_FILE=setup-portal-debug.log
|
|
7
|
+
//! mk3-tui (or 4r)
|
|
8
|
+
//! Then open Setup Portal (windowed), reproduce the bug, exit. Inspect setup-portal-debug.log.
|
|
9
|
+
|
|
10
|
+
use std::io::Write;
|
|
11
|
+
use std::sync::Mutex;
|
|
12
|
+
use std::sync::OnceLock;
|
|
13
|
+
use std::time::{SystemTime, UNIX_EPOCH};
|
|
14
|
+
|
|
15
|
+
fn enabled() -> bool {
|
|
16
|
+
std::env::var("SETUP_PORTAL_DEBUG").as_deref() == Ok("1")
|
|
17
|
+
|| std::env::var("SETUP_PORTAL_DEBUG_FILE").is_ok()
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
fn path() -> String {
|
|
21
|
+
std::env::var("SETUP_PORTAL_DEBUG_FILE")
|
|
22
|
+
.unwrap_or_else(|_| "setup-portal-debug.log".to_string())
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
static FILE: OnceLock<Mutex<Option<std::io::BufWriter<std::fs::File>>>> = OnceLock::new();
|
|
26
|
+
|
|
27
|
+
fn ensure_open() -> bool {
|
|
28
|
+
if !enabled() {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
let mutex = FILE.get_or_init(|| Mutex::new(None));
|
|
32
|
+
let mut guard = mutex.lock().unwrap();
|
|
33
|
+
if guard.is_none() {
|
|
34
|
+
let path = path();
|
|
35
|
+
match std::fs::OpenOptions::new()
|
|
36
|
+
.create(true)
|
|
37
|
+
.append(true)
|
|
38
|
+
.open(&path)
|
|
39
|
+
{
|
|
40
|
+
Ok(file_handle) => {
|
|
41
|
+
// Resolve full path so user always knows where the log is
|
|
42
|
+
let full_path: String = std::path::Path::new(&path)
|
|
43
|
+
.canonicalize()
|
|
44
|
+
.map(|p| p.display().to_string())
|
|
45
|
+
.or_else(|_| {
|
|
46
|
+
std::env::current_dir().map(|cwd| cwd.join(&path).display().to_string())
|
|
47
|
+
})
|
|
48
|
+
.unwrap_or_else(|_| path.clone());
|
|
49
|
+
let _ = writeln!(
|
|
50
|
+
std::io::stderr(),
|
|
51
|
+
"[SETUP_PORTAL_DEBUG] Log file: {}",
|
|
52
|
+
full_path
|
|
53
|
+
);
|
|
54
|
+
let mut w = std::io::BufWriter::new(file_handle);
|
|
55
|
+
let banner = format!(
|
|
56
|
+
"{} === Setup Portal debug log opened: {} ===\n",
|
|
57
|
+
timestamp(),
|
|
58
|
+
full_path
|
|
59
|
+
);
|
|
60
|
+
let _ = w.write_all(banner.as_bytes());
|
|
61
|
+
let _ = w.flush();
|
|
62
|
+
*guard = Some(w);
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
Err(e) => {
|
|
66
|
+
let _ = writeln!(
|
|
67
|
+
std::io::stderr(),
|
|
68
|
+
"[SETUP_PORTAL_DEBUG] Failed to open \"{}\": {}",
|
|
69
|
+
path,
|
|
70
|
+
e
|
|
71
|
+
);
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
true
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
fn log_raw(msg: &str) {
|
|
80
|
+
if !enabled() {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if !ensure_open() {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
let mutex = FILE.get().unwrap();
|
|
87
|
+
let mut guard = mutex.lock().unwrap();
|
|
88
|
+
if let Some(ref mut w) = *guard {
|
|
89
|
+
let _ = w.write_all(msg.as_bytes());
|
|
90
|
+
let _ = w.write_all(b"\n");
|
|
91
|
+
let _ = w.flush();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
fn timestamp() -> String {
|
|
96
|
+
SystemTime::now()
|
|
97
|
+
.duration_since(UNIX_EPOCH)
|
|
98
|
+
.map(|d| format!("{}.{:03}", d.as_secs(), d.subsec_millis()))
|
|
99
|
+
.unwrap_or_else(|_| "?.???".to_string())
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/// Log a line with timestamp. Call from main or setup_portal when debug file is enabled.
|
|
103
|
+
pub fn log(msg: &str) {
|
|
104
|
+
log_raw(&format!("{} {}", timestamp(), msg));
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/// Log screen switch (enter/leave Setup Portal).
|
|
108
|
+
pub fn log_screen(from: &str, to: &str) {
|
|
109
|
+
log(&format!("SCREEN {} -> {}", from, to));
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/// Log an input event (key, mouse, resize).
|
|
113
|
+
pub fn log_input(kind: &str, detail: &str) {
|
|
114
|
+
log(&format!("INPUT {} {}", kind, detail));
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/// Log render state (dims, rects, selected option). Throttled by caller.
|
|
118
|
+
pub fn log_render(msg: &str) {
|
|
119
|
+
log(&format!("RENDER {}", msg));
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/// Log flicker-debug: when we clear and when we finish draw (to correlate with visible flicker).
|
|
123
|
+
/// Writes to debug file when SETUP_PORTAL_DEBUG or SETUP_PORTAL_DEBUG_FILE is set.
|
|
124
|
+
pub fn log_flicker_debug(event: &str, detail: &str) {
|
|
125
|
+
let msg = format!("FLICKER {} {}", event, detail);
|
|
126
|
+
log(&msg);
|
|
127
|
+
// Also to stderr when file debug enabled, so "4r 2> setup-debug.log" captures it
|
|
128
|
+
if enabled() {
|
|
129
|
+
let _ = writeln!(std::io::stderr(), "[SETUP_PORTAL_DEBUG] {}", msg);
|
|
130
|
+
}
|
|
131
|
+
}
|
package/mk3-tui/src/io/mod.rs
CHANGED
|
@@ -1,66 +1,63 @@
|
|
|
1
|
-
mod protocol;
|
|
2
|
-
mod stdio;
|
|
3
|
-
mod ws;
|
|
4
|
-
|
|
5
|
-
use crate::app::{App, Message};
|
|
6
|
-
use anyhow::Result;
|
|
7
|
-
use serde_json;
|
|
8
|
-
use std::io::Write;
|
|
9
|
-
use std::sync::mpsc;
|
|
10
|
-
use std::thread;
|
|
11
|
-
|
|
12
|
-
pub struct IoHandler {
|
|
13
|
-
receiver: mpsc::Receiver<Message>,
|
|
14
|
-
#[allow(dead_code)]
|
|
15
|
-
sender: mpsc::Sender<String>,
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
impl IoHandler {
|
|
19
|
-
pub fn new() -> Result<Self> {
|
|
20
|
-
let (_tx, rx) = mpsc::channel();
|
|
21
|
-
let (cmd_tx, _cmd_rx) = mpsc::channel();
|
|
22
|
-
|
|
23
|
-
// DO NOT spawn any IO threads that read from stdin!
|
|
24
|
-
// The TUI needs exclusive access to stdin for keyboard input.
|
|
25
|
-
// Future: use WebSocket or named pipe for backend communication.
|
|
26
|
-
|
|
27
|
-
// Command sender thread (writes to stdout, but doesn't block stdin)
|
|
28
|
-
thread::spawn(move || {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
1
|
+
mod protocol;
|
|
2
|
+
mod stdio;
|
|
3
|
+
mod ws;
|
|
4
|
+
|
|
5
|
+
use crate::app::{App, Message};
|
|
6
|
+
use anyhow::Result;
|
|
7
|
+
use serde_json;
|
|
8
|
+
use std::io::Write;
|
|
9
|
+
use std::sync::mpsc;
|
|
10
|
+
use std::thread;
|
|
11
|
+
|
|
12
|
+
pub struct IoHandler {
|
|
13
|
+
receiver: mpsc::Receiver<Message>,
|
|
14
|
+
#[allow(dead_code)]
|
|
15
|
+
sender: mpsc::Sender<String>,
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
impl IoHandler {
|
|
19
|
+
pub fn new() -> Result<Self> {
|
|
20
|
+
let (_tx, rx) = mpsc::channel();
|
|
21
|
+
let (cmd_tx, _cmd_rx) = mpsc::channel();
|
|
22
|
+
|
|
23
|
+
// DO NOT spawn any IO threads that read from stdin!
|
|
24
|
+
// The TUI needs exclusive access to stdin for keyboard input.
|
|
25
|
+
// Future: use WebSocket or named pipe for backend communication.
|
|
26
|
+
|
|
27
|
+
// Command sender thread (writes to stdout, but doesn't block stdin)
|
|
28
|
+
thread::spawn(move || loop {
|
|
29
|
+
match _cmd_rx.recv() {
|
|
30
|
+
Ok(cmd) => {
|
|
31
|
+
let cmd_json = serde_json::json!({
|
|
32
|
+
"type": "command",
|
|
33
|
+
"text": cmd
|
|
34
|
+
});
|
|
35
|
+
if let Ok(json_str) = serde_json::to_string(&cmd_json) {
|
|
36
|
+
println!("{}", json_str);
|
|
37
|
+
let _ = std::io::stdout().flush();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
Err(_) => break,
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
Ok(Self {
|
|
45
|
+
receiver: rx,
|
|
46
|
+
sender: cmd_tx,
|
|
47
|
+
})
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
pub fn update(&mut self, app: &mut App) -> Result<()> {
|
|
51
|
+
// Non-blocking receive
|
|
52
|
+
while let Ok(message) = self.receiver.try_recv() {
|
|
53
|
+
app.update(message);
|
|
54
|
+
}
|
|
55
|
+
Ok(())
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
#[allow(dead_code)]
|
|
59
|
+
pub fn send_command(&mut self, cmd: String) -> Result<()> {
|
|
60
|
+
self.sender.send(cmd)?;
|
|
61
|
+
Ok(())
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
use crate::app::Message;
|
|
2
|
-
use anyhow::Result;
|
|
3
|
-
use std::sync::mpsc;
|
|
4
|
-
|
|
5
|
-
#[allow(dead_code)]
|
|
6
|
-
pub trait Protocol: Send {
|
|
7
|
-
fn run(&mut self) -> Result<()>;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
#[allow(dead_code)]
|
|
11
|
-
pub struct ProtocolContext {
|
|
12
|
-
pub message_tx: mpsc::Sender<Message>,
|
|
13
|
-
pub command_rx: mpsc::Receiver<String>,
|
|
14
|
-
}
|
|
15
|
-
|
|
1
|
+
use crate::app::Message;
|
|
2
|
+
use anyhow::Result;
|
|
3
|
+
use std::sync::mpsc;
|
|
4
|
+
|
|
5
|
+
#[allow(dead_code)]
|
|
6
|
+
pub trait Protocol: Send {
|
|
7
|
+
fn run(&mut self) -> Result<()>;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
#[allow(dead_code)]
|
|
11
|
+
pub struct ProtocolContext {
|
|
12
|
+
pub message_tx: mpsc::Sender<Message>,
|
|
13
|
+
pub command_rx: mpsc::Receiver<String>,
|
|
14
|
+
}
|
package/mk3-tui/src/io/stdio.rs
CHANGED
|
@@ -1,32 +1,31 @@
|
|
|
1
|
-
use crate::app::Message;
|
|
2
|
-
use crate::io::protocol::Protocol;
|
|
3
|
-
use anyhow::Result;
|
|
4
|
-
use std::sync::mpsc;
|
|
5
|
-
|
|
6
|
-
#[allow(dead_code)]
|
|
7
|
-
pub struct StdioProtocol {
|
|
8
|
-
#[allow(dead_code)]
|
|
9
|
-
message_tx: mpsc::Sender<Message>,
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
impl StdioProtocol {
|
|
13
|
-
#[allow(dead_code)]
|
|
14
|
-
pub fn new(message_tx: mpsc::Sender<Message>) -> Result<Self> {
|
|
15
|
-
Ok(Self { message_tx })
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
impl Protocol for StdioProtocol {
|
|
20
|
-
fn run(&mut self) -> Result<()> {
|
|
21
|
-
// DO NOT read from stdin here!
|
|
22
|
-
// The TUI needs stdin for keyboard input via crossterm.
|
|
23
|
-
// This protocol is a no-op for now.
|
|
24
|
-
// In the future, we can use a named pipe or socket for IPC.
|
|
25
|
-
|
|
26
|
-
// Just sleep forever to keep the thread alive
|
|
27
|
-
loop {
|
|
28
|
-
std::thread::sleep(std::time::Duration::from_secs(3600));
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
1
|
+
use crate::app::Message;
|
|
2
|
+
use crate::io::protocol::Protocol;
|
|
3
|
+
use anyhow::Result;
|
|
4
|
+
use std::sync::mpsc;
|
|
5
|
+
|
|
6
|
+
#[allow(dead_code)]
|
|
7
|
+
pub struct StdioProtocol {
|
|
8
|
+
#[allow(dead_code)]
|
|
9
|
+
message_tx: mpsc::Sender<Message>,
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
impl StdioProtocol {
|
|
13
|
+
#[allow(dead_code)]
|
|
14
|
+
pub fn new(message_tx: mpsc::Sender<Message>) -> Result<Self> {
|
|
15
|
+
Ok(Self { message_tx })
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
impl Protocol for StdioProtocol {
|
|
20
|
+
fn run(&mut self) -> Result<()> {
|
|
21
|
+
// DO NOT read from stdin here!
|
|
22
|
+
// The TUI needs stdin for keyboard input via crossterm.
|
|
23
|
+
// This protocol is a no-op for now.
|
|
24
|
+
// In the future, we can use a named pipe or socket for IPC.
|
|
25
|
+
|
|
26
|
+
// Just sleep forever to keep the thread alive
|
|
27
|
+
loop {
|
|
28
|
+
std::thread::sleep(std::time::Duration::from_secs(3600));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
package/mk3-tui/src/io/ws.rs
CHANGED
|
@@ -1,32 +1,25 @@
|
|
|
1
|
-
use crate::app::Message;
|
|
2
|
-
use crate::io::protocol::Protocol;
|
|
3
|
-
use anyhow::Result;
|
|
4
|
-
use std::sync::mpsc;
|
|
5
|
-
|
|
6
|
-
#[allow(dead_code)]
|
|
7
|
-
pub struct WsProtocol {
|
|
8
|
-
url: String,
|
|
9
|
-
message_tx: mpsc::Sender<Message>,
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
impl WsProtocol {
|
|
13
|
-
#[allow(dead_code)]
|
|
14
|
-
pub fn new(
|
|
15
|
-
url
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
fn run(&mut self) -> Result<()> {
|
|
27
|
-
// This will be implemented with tokio runtime
|
|
28
|
-
// For now, return error to fallback to stdio
|
|
29
|
-
anyhow::bail!("WebSocket not yet implemented, use stdio");
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
1
|
+
use crate::app::Message;
|
|
2
|
+
use crate::io::protocol::Protocol;
|
|
3
|
+
use anyhow::Result;
|
|
4
|
+
use std::sync::mpsc;
|
|
5
|
+
|
|
6
|
+
#[allow(dead_code)]
|
|
7
|
+
pub struct WsProtocol {
|
|
8
|
+
url: String,
|
|
9
|
+
message_tx: mpsc::Sender<Message>,
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
impl WsProtocol {
|
|
13
|
+
#[allow(dead_code)]
|
|
14
|
+
pub fn new(url: String, message_tx: mpsc::Sender<Message>) -> Result<Self> {
|
|
15
|
+
Ok(Self { url, message_tx })
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
impl Protocol for WsProtocol {
|
|
20
|
+
fn run(&mut self) -> Result<()> {
|
|
21
|
+
// This will be implemented with tokio runtime
|
|
22
|
+
// For now, return error to fallback to stdio
|
|
23
|
+
anyhow::bail!("WebSocket not yet implemented, use stdio");
|
|
24
|
+
}
|
|
25
|
+
}
|