mielin_cells/debug/
remote.rs

1//! Remote debugging support
2
3use crate::CellError;
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct DebuggerConfig {
9    pub listen_address: String,
10    pub port: u16,
11    pub max_sessions: usize,
12    pub session_timeout_secs: u64,
13}
14
15impl Default for DebuggerConfig {
16    fn default() -> Self {
17        Self {
18            listen_address: "127.0.0.1".to_string(),
19            port: 9229,
20            max_sessions: 10,
21            session_timeout_secs: 3600,
22        }
23    }
24}
25
26#[derive(Debug, Clone, Serialize, Deserialize)]
27pub enum DebugCommand {
28    Pause,
29    Resume,
30    StepOver,
31    StepInto,
32    StepOut,
33    SetBreakpoint { location: String },
34    RemoveBreakpoint { id: u64 },
35    Evaluate { expression: String },
36    GetStackFrame,
37    GetVariables,
38}
39
40#[derive(Debug, Clone, Serialize, Deserialize)]
41pub struct DebugSession {
42    pub session_id: [u8; 16],
43    pub agent_id: [u8; 16],
44    pub created_at: u64,
45    pub last_activity: u64,
46    pub paused: bool,
47}
48
49#[derive(Debug)]
50pub struct RemoteDebugger {
51    #[allow(dead_code)]
52    config: DebuggerConfig,
53    sessions: HashMap<[u8; 16], DebugSession>,
54}
55
56impl RemoteDebugger {
57    pub fn new(config: DebuggerConfig) -> Self {
58        Self {
59            config,
60            sessions: HashMap::new(),
61        }
62    }
63
64    pub fn create_session(&mut self, agent_id: [u8; 16]) -> Result<[u8; 16], CellError> {
65        use rand::Rng;
66        let mut rng = rand::rng();
67        let mut session_id = [0u8; 16];
68        rng.fill(&mut session_id);
69
70        let now = std::time::SystemTime::now()
71            .duration_since(std::time::UNIX_EPOCH)
72            .map_err(|_| CellError::InvalidState("Time error".to_string()))?
73            .as_secs();
74
75        self.sessions.insert(
76            session_id,
77            DebugSession {
78                session_id,
79                agent_id,
80                created_at: now,
81                last_activity: now,
82                paused: false,
83            },
84        );
85
86        Ok(session_id)
87    }
88
89    pub fn close_session(&mut self, session_id: &[u8; 16]) -> bool {
90        self.sessions.remove(session_id).is_some()
91    }
92
93    pub fn get_session(&self, session_id: &[u8; 16]) -> Option<&DebugSession> {
94        self.sessions.get(session_id)
95    }
96
97    pub fn handle_command(
98        &mut self,
99        session_id: &[u8; 16],
100        _command: &DebugCommand,
101    ) -> Result<String, CellError> {
102        if let Some(session) = self.sessions.get_mut(session_id) {
103            let now = std::time::SystemTime::now()
104                .duration_since(std::time::UNIX_EPOCH)
105                .map_err(|_| CellError::InvalidState("Time error".to_string()))?
106                .as_secs();
107            session.last_activity = now;
108            Ok("Command executed".to_string())
109        } else {
110            Err(CellError::InvalidState("Session not found".to_string()))
111        }
112    }
113}
114
115#[cfg(test)]
116mod tests {
117    use super::*;
118
119    #[test]
120    fn test_remote_debugger() {
121        let config = DebuggerConfig::default();
122        let mut debugger = RemoteDebugger::new(config);
123
124        let agent_id = [1u8; 16];
125        let session_id = debugger.create_session(agent_id).expect("Failed");
126
127        assert!(debugger.get_session(&session_id).is_some());
128
129        let closed = debugger.close_session(&session_id);
130        assert!(closed);
131    }
132}