webterm_agent/models/
pty_activity.rs1use crate::models::agent_error::AgentError;
2use crate::models::pty_activity_reader::PtyActivityReader;
3use pty_process::{Command, OwnedWritePty, Pty, Size};
4use tokio::io::AsyncWriteExt;
5use tokio::sync::Mutex;
6use webterm_core::types::ActivityId;
7
8pub struct PtyActivity {
9 _pty_reader: PtyActivityReader,
11 pty_writer: Mutex<OwnedWritePty>,
12}
13
14impl PtyActivity {
15 pub async fn new(activity_id: ActivityId, command: &str) -> Result<Self, AgentError> {
16 let pty = Pty::new()?;
17 let mut command = Command::new(command);
18 command.env("TERM", "xterm-256color");
19 command.spawn(&pty.pts().unwrap())?;
20 let (pty_reader, pty_writer) = pty.into_split();
21 let pty_writer = Mutex::new(pty_writer);
22 Ok(PtyActivity {
23 pty_writer,
24 _pty_reader: PtyActivityReader::new(activity_id, pty_reader),
25 })
26 }
27
28 pub async fn resize(&self, cols: u16, rows: u16) -> Result<(), AgentError> {
29 self.pty_writer.lock().await.resize(Size::new(cols, rows))?;
30 Ok(())
31 }
32
33 pub async fn write(&self, data: &[u8]) -> Result<(), AgentError> {
34 self.pty_writer.lock().await.write_all(data).await?;
35 Ok(())
36 }
37
38 pub async fn shutdown(&self) -> Result<(), AgentError> {
39 self.pty_writer.lock().await.shutdown().await?;
40 Ok(())
41 }
42}