Skip to main content

TmuxManager

Struct TmuxManager 

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

Manage tmux sessions for agent tasks.

Implementations§

Source§

impl TmuxManager

Source

pub fn new() -> Self

Source

pub fn session_name(&self, project: &str, task_id: &str) -> String

Session name for a task: orch-{project}-{task_id}.

The project name is derived from the repo slug (e.g. owner/repo → repo). This prevents collisions between projects with the same issue number.

Source

pub async fn create_session( &self, repo: &str, task_id: &str, working_dir: &str, command: &str, env_vars: &[(&str, &str)], ) -> Result<String>

Create a new tmux session for a task and run a command in it.

Environment variables in env_vars are injected into the session via tmux new-session -e KEY=VALUE — they are not written to disk.

The session is detached — the agent runs in the background. Returns the session name.

Note: GH_TOKEN is passed here via -e like all other env vars. Do NOT use create_session_detached + set_env + create_window to avoid exposing secrets in process args — that creates a 2-window session which breaks all tmux monitoring (completion detection, output capture, silence detection) because they target the default window (the idle shell), not the agent window. See the revert of PR #2903.

Source

pub async fn session_exists(&self, session: &str) -> bool

Check if a session exists.

Source

pub async fn kill_session(&self, session: &str) -> Result<()>

Kill a session.

Source

pub async fn capture_pane(&self, session: &str, lines: i32) -> Result<String>

Capture the current pane content (last N lines).

Returns Ok(String::new()) if the session or pane is not found — this is an expected teardown race when the session was cleaned up between the caller’s is_session_active() check and this capture.

Source

pub async fn is_session_active(&self, session: &str) -> bool

Check if the process in a session’s pane is still running. Returns false if the session doesn’t exist or the pane has no active process.

Source

pub async fn session_blocks_dispatch(&self, session: &str) -> bool

Return whether a session should block a new dispatch.

Dead tmux sessions with the same name are cleaned up eagerly so they do not block reclaim/re-dispatch loops or cause new-session name collisions.

Source

pub async fn session_blocks_dispatch_from_map( &self, session: &str, session_map: &HashMap<String, bool>, ) -> bool

Batch variant of session_blocks_dispatch that uses a pre-fetched session map.

session_map is the result of batch_session_active(). Sessions absent from the map do not exist (→ no block). Sessions present with alive=true block dispatch. Sessions present with alive=false have a dead pane and are cleaned up eagerly.

Source

pub async fn batch_session_active(&self) -> HashMap<String, bool>

Get pane_dead status for all sessions in a single tmux call.

Returns a map from session name → alive (true = alive, false = dead/missing). Uses list-panes -a to avoid one subprocess per session.

Source

pub async fn list_sessions(&self) -> Result<Vec<Session>>

List all orch-prefixed sessions with metadata including creation time.

Source

pub async fn kill_stale_sessions(&self, before_timestamp: u64) -> Result<usize>

Kill all orch-prefixed sessions created before a given timestamp. Returns the number of sessions killed.

Source

pub async fn wait_for_sessions_dead( &self, sessions: &[String], poll_interval: Duration, timeout: Duration, ) -> usize

Wait for multiple sessions to be fully dead (no longer exist). Polls every poll_interval up to timeout. Returns the number of sessions that were still alive after timeout.

Source

pub async fn wait_for_completion( &self, session: &str, poll_interval: Duration, ) -> Result<String>

Wait for a session to finish (pane process exits). Returns the captured output from the last N lines.

Source

pub async fn snapshot(&self) -> Vec<(Session, bool)>

Snapshot all orch-prefixed sessions — for engine tick monitoring.

Returns a vector of (Session, alive) so callers can operate on the actual session name instead of reconstructing one from repo+task_id.

Uses batch_session_active() internally to fetch all pane-dead statuses in a single subprocess call instead of one call per session (N+1 → 2).

Source

pub async fn unset_env(&self, session: &str, key: &str) -> Result<()>

Unset (remove) an environment variable from a tmux session.

Source

pub async fn unset_global_env(&self, key: &str) -> Result<()>

Unset (remove) an environment variable from the tmux global environment.

Uses: tmux set-environment -gu <key>

Trait Implementations§

Source§

impl Clone for TmuxManager

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. 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<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
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> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

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

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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