Skip to main content

remowt_client/
shell.rs

1use anyhow::{anyhow, Result};
2use bifrostlink::declarative::RemoteEndpoints as _;
3use bifrostlink::Remote;
4use remowt_endpoints::pty::{PtyClient, ShellId};
5use remowt_link_shared::{Address, BifConfig};
6
7use crate::forwarded::RemowtStream;
8use crate::Remowt;
9
10pub struct RemowtShell {
11	pub id: ShellId,
12	pub stream: RemowtStream,
13	remote: Remote<BifConfig>,
14}
15impl RemowtShell {
16	pub fn resizer(&self) -> RemowtShellResizer {
17		RemowtShellResizer {
18			remote: self.remote.clone(),
19			id: self.id,
20		}
21	}
22}
23
24#[derive(Clone)]
25pub struct RemowtShellResizer {
26	remote: Remote<BifConfig>,
27	id: ShellId,
28}
29
30impl RemowtShellResizer {
31	pub async fn resize(&self, cols: u16, rows: u16) -> Result<()> {
32		PtyClient::wrap(self.remote.clone())
33			.resize(self.id, cols, rows)
34			.await?
35			.map_err(|e| anyhow!("failed to resize remote shell: {e}"))
36	}
37}
38
39impl Remowt {
40	pub async fn open_shell(
41		&self,
42		term: &str,
43		cols: u16,
44		rows: u16,
45		escalate: bool,
46	) -> Result<RemowtShell> {
47		let (forwarded, path) = self.bind_runtime_unix("shell").await?;
48		let client: PtyClient<BifConfig> = if escalate {
49			self.run0_endpoints().await?
50		} else {
51			self.endpoints()
52		};
53		let id = client
54			.open_shell(path, term.to_owned(), cols, rows)
55			.await?
56			.map_err(|e| anyhow!("agent failed to open shell: {e}"))?;
57		let stream = forwarded.accept().await?;
58
59		Ok(RemowtShell {
60			id,
61			stream,
62			remote: self.0.rpc.remote(Address::Agent),
63		})
64	}
65}