Skip to main content

PtyHandle

Struct PtyHandle 

Source
pub struct PtyHandle { /* private fields */ }
Expand description

Handle to a PTY

Implementations§

Source§

impl PtyHandle

Source

pub fn new(rows: u16, cols: u16) -> Result<Self>

Create a new PTY with the specified size

Source

pub async fn spawn_command(&self, cmd: CommandBuilder) -> Result<()>

Spawn a command in the PTY

Source

pub async fn write(&self, data: &[u8]) -> Result<()>

Write data to the PTY

Source

pub async fn read(&self) -> Result<Vec<u8>>

Read data from the PTY with timeout

Source

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

Resize the PTY

Source

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

Get the current PTY size

Source

pub fn is_running(&self) -> bool

Check if child process is running

Source

pub async fn read_with_timeout(&self, timeout_ms: u64) -> Result<Vec<u8>>

Read data from PTY with timeout (for testing)

Source

pub async fn spawn_claude( &self, prompt: &str, working_dir: &Path, max_turns: Option<u32>, ) -> Result<()>

Spawn Claude Code in the PTY with –dangerously-skip-permissions flag

This method launches Claude CLI in a PTY session for true parallel multi-agent execution. Each call creates an independent Claude process that can run concurrently with others.

§Arguments
  • prompt - The prompt/instruction to send to Claude
  • working_dir - Working directory for the Claude session
  • max_turns - Maximum number of conversation turns (default: 1 for single task)
§Example
use ai_session::core::pty::PtyHandle;
use std::path::Path;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let pty = PtyHandle::new(24, 80)?;
    pty.spawn_claude("Create a hello world function", Path::new("/tmp"), Some(3)).await?;
     
    // Read output with timeout
    let output = pty.read_with_timeout(30000).await?;
    println!("Claude output: {}", String::from_utf8_lossy(&output));
    Ok(())
}
Source

pub async fn spawn_claude_and_wait( &self, prompt: &str, working_dir: &Path, max_turns: Option<u32>, timeout_ms: u64, ) -> Result<String>

Spawn Claude Code and wait for completion, returning the output

This is a convenience method that spawns Claude, waits for it to finish, and returns the collected output.

§Arguments
  • prompt - The prompt/instruction to send to Claude
  • working_dir - Working directory for the Claude session
  • max_turns - Maximum number of conversation turns
  • timeout_ms - Timeout in milliseconds to wait for completion
Source

pub async fn spawn_claude_with_session( &self, prompt: &str, working_dir: &Path, session_id: &str, max_turns: Option<u32>, ) -> Result<()>

Spawn Claude Code with a specific session ID for later resumption

This method allows you to specify a session ID that can be used later with resume_claude to continue the conversation.

§Arguments
  • prompt - The prompt/instruction to send to Claude
  • working_dir - Working directory for the Claude session
  • session_id - UUID to use as the Claude session ID
  • max_turns - Maximum number of conversation turns
§Example
use ai_session::core::pty::PtyHandle;
use std::path::Path;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let pty = PtyHandle::new(24, 80)?;
    let session_id = "2c4e029f-3411-442a-b24c-33001c78cd14";

    // Start a new session with specific ID
    pty.spawn_claude_with_session(
        "Create a hello world function",
        Path::new("/tmp"),
        session_id,
        Some(3),
    ).await?;

    // Later, resume the same session
    let pty2 = PtyHandle::new(24, 80)?;
    pty2.resume_claude(session_id, Path::new("/tmp")).await?;
    Ok(())
}
Source

pub async fn resume_claude( &self, session_id: &str, working_dir: &Path, ) -> Result<()>

Resume a Claude Code session by session ID

This method resumes a previous Claude conversation using the session ID that was used when the session was created.

§Arguments
  • session_id - The Claude session ID to resume
  • working_dir - Working directory for the Claude session
§Example
use ai_session::core::pty::PtyHandle;
use std::path::Path;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let pty = PtyHandle::new(24, 80)?;

    // Resume a previous session
    pty.resume_claude(
        "2c4e029f-3411-442a-b24c-33001c78cd14",
        Path::new("/tmp"),
    ).await?;

    Ok(())
}
Source

pub async fn resume_claude_with_prompt( &self, session_id: &str, prompt: &str, working_dir: &Path, max_turns: Option<u32>, ) -> Result<()>

Resume a Claude Code session interactively with a new prompt

This method resumes a previous Claude conversation and sends a new prompt.

§Arguments
  • session_id - The Claude session ID to resume
  • prompt - New prompt to send to the resumed session
  • working_dir - Working directory for the Claude session
  • max_turns - Maximum number of conversation turns

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<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> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync>

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

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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, 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<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