orchflow_core/manager/handlers/
terminal.rs

1use crate::error::Result;
2use crate::manager::Manager;
3use serde_json::Value;
4
5pub async fn send_keys(manager: &Manager, pane_id: &str, keys: &str) -> Result<Value> {
6    // Get pane
7    let pane = manager
8        .state_manager
9        .get_pane(pane_id)
10        .await
11        .ok_or_else(|| {
12            crate::error::OrchflowError::NotFound(format!("Pane not found: {pane_id}"))
13        })?;
14
15    // Send keys to backend
16    if let Some(backend_id) = &pane.backend_id {
17        manager.mux_backend.send_keys(backend_id, keys).await?;
18    }
19
20    Ok(serde_json::json!({
21        "status": "ok",
22        "pane_id": pane_id
23    }))
24}
25
26pub async fn run_command(manager: &Manager, pane_id: &str, command: &str) -> Result<Value> {
27    // Get pane
28    let pane = manager
29        .state_manager
30        .get_pane(pane_id)
31        .await
32        .ok_or_else(|| {
33            crate::error::OrchflowError::NotFound(format!("Pane not found: {pane_id}"))
34        })?;
35
36    // Send command with newline
37    if let Some(backend_id) = &pane.backend_id {
38        let command_with_newline = format!("{command}\n");
39        manager
40            .mux_backend
41            .send_keys(backend_id, &command_with_newline)
42            .await?;
43    }
44
45    // Emit event
46    manager.emit_event(crate::manager::Event::CommandExecuted {
47        pane_id: pane_id.to_string(),
48        command: command.to_string(),
49    });
50
51    // Record in command history if available
52    if let Some(history) = &manager.command_history {
53        let _ = history.add_command(&pane.session_id, command).await;
54    }
55
56    Ok(serde_json::json!({
57        "status": "ok",
58        "pane_id": pane_id,
59        "command": command
60    }))
61}
62
63pub async fn get_pane_output(
64    manager: &Manager,
65    pane_id: &str,
66    lines: Option<u32>,
67) -> Result<Value> {
68    // Get pane
69    let pane = manager
70        .state_manager
71        .get_pane(pane_id)
72        .await
73        .ok_or_else(|| {
74            crate::error::OrchflowError::NotFound(format!("Pane not found: {pane_id}"))
75        })?;
76
77    // Capture output from backend
78    let output = if let Some(backend_id) = &pane.backend_id {
79        manager.mux_backend.capture_pane(backend_id).await?
80    } else {
81        String::new()
82    };
83
84    // Limit lines if requested
85    let output = if let Some(line_count) = lines {
86        let lines: Vec<&str> = output.lines().collect();
87        let start = lines.len().saturating_sub(line_count as usize);
88        lines[start..].join("\n")
89    } else {
90        output
91    };
92
93    Ok(serde_json::json!({
94        "status": "ok",
95        "pane_id": pane_id,
96        "output": output
97    }))
98}