Skip to main content

PtyShell

Struct PtyShell 

Source
pub struct PtyShell {
    pub last_command: String,
    pub output_buffer: String,
    pub command_running: bool,
    pub last_exit_code: Option<i32>,
    pub output_truncated: bool,
    pub last_returned_hash: Option<u64>,
    pub attach_hint: Option<String>,
    /* private fields */
}
Expand description

Real PTY-based interactive shell

Uses portable-pty for true pseudo-terminal functionality, enabling proper handling of interactive programs like sudo, vim, etc.

Fields§

§last_command: String

Last command executed

§output_buffer: String

Accumulated output buffer

§command_running: bool

Whether a command is currently running

§last_exit_code: Option<i32>

Exit code of the last completed foreground command, parsed from the prompt marker (──➤<nonce>:<code>). None until a command finishes, and reset to None while one is running.

§output_truncated: bool

Flag for output truncation

§last_returned_hash: Option<u64>

Hash of the last rendered output we shipped to the caller. Used by the delta path in status_check to elide repeats when the screen is idle.

§attach_hint: Option<String>

Optional command a human can run to attach to the same terminal session.

Implementations§

Source§

impl PtyShell

Source

pub fn new(initial_dir: &Path, restricted_mode: bool) -> Result<Self>

Create a new PTY shell session

§Arguments
  • initial_dir - Starting directory for the shell
  • restricted_mode - Whether to use bash restricted mode (-r)
§Returns

A new PtyShell instance with an active bash session

Source

pub fn clear_to_run(&mut self, max_wait_secs: f32) -> Result<bool>

Drain any pending output and, if a previous command still seems to be running, send a Ctrl-C to flush it. Mirrors wcgw’s clear_to_run so a new command never inherits stale prompt fragments or a half-typed line.

Returns true if the shell looks idle (prompt seen), false if it still wouldn’t yield after the Ctrl-C — caller may want to reset.

Source

pub fn send_command(&mut self, command: &str) -> Result<()>

Send a command to the shell and start reading output

Source

pub fn collect_scrollback(&self, lines: usize) -> String

Return up to lines recent lines from the scrollback ring, oldest first. When older lines were evicted or a long unterminated line was clipped, a [winx: …] notice is prepended so the caller knows the scrollback is incomplete rather than silently receiving less than asked.

Source

pub fn fingerprint(text: &str) -> u64

Hash arbitrary rendered output into a u64 dedup key.

Source

pub fn read_output(&mut self, timeout_secs: f32) -> Result<(String, bool)>

Read output from the PTY with timeout

Returns (output, is_complete) tuple where is_complete indicates whether the command has finished (prompt detected)

Source

pub fn poll_output_nonblocking(&mut self) -> bool

Non-blocking drain of whatever the reader thread has already queued.

Unlike read_output, this never sleeps: it consumes every chunk currently available, updates prompt/completion state, and returns immediately. prune_finished_shells uses it so the global background-shell lock is never held across a blocking 100ms read_output. Returns true if the command has completed (prompt seen or PTY closed).

Source

pub fn send_interrupt(&mut self) -> Result<()>

Send Ctrl+C (interrupt) to the PTY

Source

pub fn send_eof(&mut self) -> Result<()>

Send Ctrl+D (EOF) to the PTY

Source

pub fn send_suspend(&mut self) -> Result<()>

Send Ctrl+Z (suspend) to the PTY

Source

pub fn send_text(&mut self, text: &str) -> Result<()>

Send text directly to the PTY (for interactive input)

Source

pub fn send_bytes(&mut self, bytes: &[u8]) -> Result<()>

Send raw bytes directly to the PTY.

Source

pub fn send_special_key(&mut self, key: &str) -> Result<()>

Send a special key sequence

Source

pub fn live_snapshot(&self, max_lines: usize) -> Vec<String>

Snapshot the live terminal screen — a stable, consolidated view of what a human would currently see, with cursor moves/redraws applied and ANSI stripped. max_lines of 0 returns the full screen buffer. This is the foundation for piloting interactive TUIs (the claude CLI, vim, …).

Source

pub fn live_in_alt_screen(&self) -> bool

Whether the live terminal is currently on the alternate screen buffer (a full-screen app like vim/htop/less is running).

Source

pub fn live_cursor_position(&self) -> (u16, u16)

Cursor position (row, col) on the live screen (0-based), so a piloting agent knows where focus is in a menu/form. (0, 0) if the lock is poisoned.

Source

pub fn live_snapshot_diff( &self, max_lines: usize, threshold: usize, ) -> ScreenUpdate

Diff the live screen against what the client last saw, returning only the changed lines when the change is small (huge token savings over many polls). Updates the baseline as a side effect. See ScreenUpdate.

Source

pub fn resize(&mut self, cols: u16, rows: u16) -> Result<()>

Resize the terminal

Source

pub fn get_size(&self) -> (u16, u16)

Get current terminal size

Source

pub fn is_alive(&mut self) -> bool

Check if the shell is still alive

Trait Implementations§

Source§

impl Debug for PtyShell

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Drop for PtyShell

Source§

fn drop(&mut self)

Kill and reap the shell child so it doesn’t leak.

std::process::Child::drop neither kills nor waits, so without this every dropped shell (reset_shell, background-shell prune/remove) would leak a live bash process — soon a zombie — plus the reader thread blocked in read(). Killing the child closes the PTY slave, which makes the reader’s read() return EOF so the thread terminates on its own. Best-effort.

Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more