pub struct ShellSessionRegistry {
shells: Mutex<HashMap<String, ShellEntry>>,
status_map: Mutex<HashMap<String, Arc<Mutex<ShellStatusInfo>>>>,
status_order: Mutex<VecDeque<String>>,
}Fields§
§shells: Mutex<HashMap<String, ShellEntry>>§status_map: Mutex<HashMap<String, Arc<Mutex<ShellStatusInfo>>>>§status_order: Mutex<VecDeque<String>>Implementations§
Source§impl ShellSessionRegistry
impl ShellSessionRegistry
pub fn new() -> Arc<Self> ⓘ
pub(crate) fn register_full( &self, shell_id: String, stop_tx: Sender<()>, stdin_tx: Option<UnboundedSender<String>>, status: Arc<Mutex<ShellStatusInfo>>, ) -> Vec<String>
Sourcefn prune_exited_statuses(&self) -> Vec<String>
fn prune_exited_statuses(&self) -> Vec<String>
Evict oldest EXITED status entries beyond MAX_EXITED_STATUS. Running
shells are always retained (their status is read live via ShellStatus).
Also drops any order-queue ids whose status entry is already gone.
Returns the shell_ids actually evicted (status entry removed) so the
caller can purge their broker-side persisted history too.
Sourcepub fn stop(&self, shell_id: &str) -> bool
pub fn stop(&self, shell_id: &str) -> bool
Request stop of a running shell. Returns false if unknown or already exited. Dropping the stdin_tx here closes the relay channel → ChildStdin drops → child sees EOF, unblocking any stdin-reading process before the kill.
Sourcefn remove(&self, shell_id: &str)
fn remove(&self, shell_id: &str)
Called by the runner on natural exit (stdout/stderr closed). Removes the shells entry (dropping stdin_tx → child gets stdin EOF). Status entry is intentionally kept so ShellStatus can query the final exit code/line count.
Sourcepub fn resolve_stdin(
&self,
shell_id: &str,
) -> Result<UnboundedSender<String>, ShellInputFailure>
pub fn resolve_stdin( &self, shell_id: &str, ) -> Result<UnboundedSender<String>, ShellInputFailure>
Resolve where a ShellInput write should go, distinguishing two
failure modes:
Ok(tx)— running with captured stdinErr(StdinNotCaptured)— running but created without capture_stdinErr(NotRunning)— unknown id or already exited
Sourcepub fn get_status(&self, shell_id: &str) -> ShellStatusInfo
pub fn get_status(&self, shell_id: &str) -> ShellStatusInfo
Return a snapshot of the shell’s status. Returns running: false if unknown.
Existing, documented contract for POST /api/v1/shell/status (the MCP
ShellStatus tool) — do not change: an agent calling this for an id
it doesn’t recognize expects a plain “not running” answer, not an error.
Sourcepub(crate) fn get_status_if_known(
&self,
shell_id: &str,
) -> Option<ShellStatusInfo>
pub(crate) fn get_status_if_known( &self, shell_id: &str, ) -> Option<ShellStatusInfo>
Like Self::get_status, but None when no entry exists at all —
distinguishing “genuinely unknown” from “known, and not running.”
Needed by the shellstatus RPC command (unlike the MCP tool above,
which is fine collapsing “unknown” into “not running”): register_full
only runs after the runner task spawns the child process, but
shell_node_create is published to the frontend BEFORE that task is
even scheduled (handle_shell_create in server/mod.rs). A caller that
checks status immediately after seeing shell_node_create can race
ahead of registration — reagent P1 on PR #2770: collapsing that race
window into running: false was indistinguishable from a genuinely
already-exited shell, so a fast, still-registering, genuinely LIVE
shell (e.g. a real task dev) could be shown as failed in the
Activity Dock for its entire run.
Sourcepub fn list_active(&self) -> Vec<ShellSummary>
pub fn list_active(&self) -> Vec<ShellSummary>
List every currently-RUNNING shell across all blocks — the Swarm
pane’s data source for its per-agent long-running-process rows
(SPEC_SWARM_LONG_RUNNING_PROCESS_ROWS_2026_07_20). Unfiltered, like
subagent.ListActive/ListDispatches — the Swarm pane fetches once
and groups by block_id client-side in buildTree(), rather than
one RPC per tracked agent block. Exited shells are intentionally
excluded: Phase 1’s scope is “what’s happening now,” not a shell
history view.
Trait Implementations§
Source§impl Default for ShellSessionRegistry
impl Default for ShellSessionRegistry
Source§fn default() -> ShellSessionRegistry
fn default() -> ShellSessionRegistry
Auto Trait Implementations§
impl !Freeze for ShellSessionRegistry
impl !RefUnwindSafe for ShellSessionRegistry
impl !UnwindSafe for ShellSessionRegistry
impl Send for ShellSessionRegistry
impl Sync for ShellSessionRegistry
impl Unpin for ShellSessionRegistry
impl UnsafeUnpin for ShellSessionRegistry
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
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.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.§impl<T> DowncastSync for T
impl<T> DowncastSync for T
impl<A, B, T> HttpServerConnExec<A, B> for Twhere
B: Body,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
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