Skip to main content

LoopCtx

Struct LoopCtx 

Source
pub struct LoopCtx {
Show 48 fields pub config: Config, pub model_name: String, pub agent: AgentClient, pub runtime_factory: AgentRuntimeFactory, pub bg_manager: BgRuntimeManager, pub foreground_runtime_id: RuntimeId, pub runtime_event_tx: UnboundedSender<RuntimeEvent>, pub runtime_event_rx: UnboundedReceiver<RuntimeEvent>, pub working_dir: PathBuf, pub previous_dir: Option<PathBuf>, pub recent_dirs: Vec<PathBuf>, pub history: History, pub input_rx: UnboundedReceiver<InputEvent>, pub commands: CommandRegistry, pub session_manager: SessionManager, pub current_session: Session, pub update_hint: Arc<Mutex<Option<String>>>, pub monitor_warning: Arc<Mutex<Option<CodingPlanWarning>>>, pub monitor_last_check_at: Option<Instant>, pub usage_slot: Arc<Mutex<Option<UsageInfo>>>, pub usage_last_check_at: Option<Instant>, pub monitor_last_sync_seen: Option<SystemTime>, pub wake_rx: Receiver<()>, pub wake_tx: Sender<()>, pub oauth_event_rx: UnboundedReceiver<OauthEvent>, pub oauth_event_tx: UnboundedSender<OauthEvent>, pub reader: Option<ReaderHandle>, pub upgrade_tx: UnboundedSender<UpgradeEvent>, pub upgrade_rx: UnboundedReceiver<UpgradeEvent>, pub plugin_job_tx: UnboundedSender<PluginJobEvent>, pub plugin_job_rx: UnboundedReceiver<PluginJobEvent>, pub pending_new_issue: Option<NewIssueDraft>, pub pending_run_codingplan: bool, pub pending_open_provider_wizard: bool, pub mcp_registry: Option<Arc<McpRegistry>>, pub mcp_connect_rx: Option<UnboundedReceiver<McpConnectEvent>>, pub mcp_reload: Option<McpReloadProgress>, pub lsp_connect_rx: Option<UnboundedReceiver<LspConnectEvent>>, pub telemetry: Arc<Telemetry>, pub worktree_original_dir: Option<PathBuf>, pub custom_commands: CustomCommandRegistry, pub skill_registry: Arc<RwLock<SkillRegistry>>, pub caps: TerminalCaps, pub replay_on_start: Option<Session>, pub file_index: FileIndex, pub current_session_id: Option<SessionId>, pub clipboard_check: Arc<Mutex<ClipboardCheckState>>, pub is_plain_renderer: bool,
}
Expand description

Bag of handles passed into the loop.

Fields§

§config: Config§model_name: String§agent: AgentClient§runtime_factory: AgentRuntimeFactory§bg_manager: BgRuntimeManager§foreground_runtime_id: RuntimeId§runtime_event_tx: UnboundedSender<RuntimeEvent>§runtime_event_rx: UnboundedReceiver<RuntimeEvent>§working_dir: PathBuf§previous_dir: Option<PathBuf>§recent_dirs: Vec<PathBuf>

Recently visited project directories, most recent first (max 5). Persisted to ~/.atomcode/recent_dirs.txt. Drives the /cd picker when invoked with no argument and is updated whenever the working directory changes (via slash command or agent tool).

§history: History§input_rx: UnboundedReceiver<InputEvent>§commands: CommandRegistry§session_manager: SessionManager§current_session: Session

Session actively being accumulated. Updated on TurnComplete / TurnCancelled (both carry the latest messages slice), saved to disk via session_manager on the same events so /resume after a quit sees the conversation. Replaced wholesale when the user resumes another session via /resume + SessionPicker.

§update_hint: Arc<Mutex<Option<String>>>

Shared “new version available” hint. Populated by the detached version-check task spawned from run(); read by build_status on each redraw. None = no hint (either check still pending, network failed silently, or already up to date).

§monitor_warning: Arc<Mutex<Option<CodingPlanWarning>>>

Shared CodingPlan drift-monitor warning slot. Written by the detached check task (see monitor::spawn_check); read by build_status on each redraw. Takes precedence over update_hint so a drift warning isn’t buried by an upgrade banner. Cleared when /codingplan persists a fresh config (re-sync resets the hint state).

§monitor_last_check_at: Option<Instant>

Last time a monitor check was fired this session. Pre-turn triggers respect monitor::CHECK_COOLDOWN (15 min) against this timestamp; startup + /model switch bypass the cooldown. None = no check has run yet this session.

§usage_slot: Arc<Mutex<Option<UsageInfo>>>

CodingPlan token-usage snapshot. Populated by usage_monitor::spawn_check at startup and after each TurnComplete (30s cooldown). Read on every redraw to construct the right-aligned usage hint when usage_percent ≥ 80% and the current model is on a CodingPlan provider.

§usage_last_check_at: Option<Instant>

Last time usage_monitor::spawn_check was invoked. Used to enforce usage_monitor::USAGE_COOLDOWN on TurnComplete-triggered refreshes. None = no check has run yet this session.

§monitor_last_sync_seen: Option<SystemTime>

Last-observed timestamp from the shared CodingPlan sync marker (~/.atomcode/codingplan_sync.json). On every user input we re-read it; a change means ANOTHER atomcode process (e.g. a second terminal) just ran /codingplan and the server is now in sync with the on-disk config. We then hot-reload config from disk + clear the stale drift warning. Without this, Terminal A’s “CodingPlan 模型列表更新” hint would stick forever after Terminal B ran the fix.

§wake_rx: Receiver<()>

Wake signal from background tasks (version check + CodingPlan drift monitor). One () sent when any task needs the event loop to repaint so a freshly-computed hint/warning appears without waiting for the user’s next keystroke. Bounded at 1 — overlapping wakes coalesce since the redraw is idempotent.

§wake_tx: Sender<()>

Sender side of wake_rx. Cloned into every spawned check task so /model switches, pre-turn triggers, and the like can wake the event loop after updating monitor_warning.

§oauth_event_rx: UnboundedReceiver<OauthEvent>

Receiver for OauthEvents emitted by the QR-fast-path onboarding poll thread (see event_loop::oauth_poll). One event arrives per spawned poll task (Authorized or Failed). The tokio::select! arm that reads this channel closes the wizard modal + flips pending_run_codingplan on Authorized, or surfaces the failure reason in scrollback on Failed.

§oauth_event_tx: UnboundedSender<OauthEvent>

Sender cloned into each spawned poll task.

§reader: Option<ReaderHandle>

Control handle for the crossterm reader thread — Some in raw-mode TTY sessions, None in pipe mode. Used by child-process handoffs (OAuth login, future /shell) to pause+resume event consumption so our reader doesn’t race the child for stdin bytes.

§upgrade_tx: UnboundedSender<UpgradeEvent>

Sender used by /upgrade to report streaming progress/failure events from the detached upgrade task. Cloned into the task at spawn time; kept here so the receiver in the loop outlives any number of upgrades (no reconstructing on each invocation).

§upgrade_rx: UnboundedReceiver<UpgradeEvent>

Consumed in the main select! so upgrade progress is rendered alongside agent events.

§plugin_job_tx: UnboundedSender<PluginJobEvent>

Long-lived channel for /plugin marketplace add|update and /plugin install. Each invocation spawns a blocking task that does the git clone/pull and pushes a PluginJobEvent here when done. Mirrors the upgrade_tx/rx layout so the event loop only has to add a single select! arm. Unbounded — events are tiny terminal results.

§plugin_job_rx: UnboundedReceiver<PluginJobEvent>§pending_new_issue: Option<NewIssueDraft>

Signal channel from the /issue wizard modal back to the event loop. The wizard’s Enter handler can’t touch App directly (modals only see LoopCtx), so it stores the collected title + body here, returns Close, and the event loop’s post-close branch POSTs the issue to AtomGit and echoes the URL of the newly-created issue back into the conversation.

§pending_run_codingplan: bool

Set by OnboardingWizard (step 3, Setup) when the user picks option 0 (Set up CodingPlan). The event loop drains this on modal close and runs the full CodingPlan setup flow (login if needed → claim → fetch models → register providers). Needs raw-mode suspend/resume, something modals can’t drive themselves. Same pattern as pending_new_issue.

§pending_open_provider_wizard: bool

Set by OnboardingWizard (step 3, Setup) when the user picks option 1 (Configure manually). The event loop drains this on modal close and swaps in ProviderWizard::MainMenu — a Modal-to-Modal transition that needs mutable active_modal access only the event loop has.

§mcp_registry: Option<Arc<McpRegistry>>

MCP server registry for /mcp status display. None when no MCP servers are configured or all failed to connect.

§mcp_connect_rx: Option<UnboundedReceiver<McpConnectEvent>>

Channel for receiving MCP connection status events (Connected/Failed). Events are rendered into scrollback as they arrive during startup.

§mcp_reload: Option<McpReloadProgress>

When /mcp reload is invoked, we track progress until every configured server reports Connected/Failed, then emit a one-line summary.

§lsp_connect_rx: Option<UnboundedReceiver<LspConnectEvent>>

Channel for receiving LSP connection status events (Started / Failed / Warning). Same plumbing as mcp_connect_rx — wired in TUI mode so the manager’s start failures land in scrollback as ✗ LSP server 'rust-analyzer' for .rs failed: ... instead of leaking to stderr and printing inside the input box.

§telemetry: Arc<Telemetry>

Telemetry handle — used to emit UseCommand at each slash dispatch.

§worktree_original_dir: Option<PathBuf>

Original working dir before /worktree create, for /worktree done.

§custom_commands: CustomCommandRegistry

User-defined custom commands loaded from ~/.atomcode/commands/ and <project>/.atomcode/commands/. Queried by the slash-command dispatcher as a fallback when the entered name doesn’t match a built-in command.

§skill_registry: Arc<RwLock<SkillRegistry>>

Loaded skills (.claude/skills/*/SKILL.md, etc.). Same Arc the agent loop holds, so reload(...) there is visible here without extra plumbing. Used by the slash-command palette to surface user-invocable skills, and by the dispatcher to expand /skill_name [args] into a SendMessage.

§caps: TerminalCaps

Snapshot of the terminal’s rendering capabilities. Probed once at startup in lib.rs; threaded into App::new so UiState knows whether to use Unicode or ASCII fallbacks for the spinner glyph and ellipsis. Same value as RetainedRenderer was constructed with — single source of truth.

§replay_on_start: Option<Session>

Session loaded by the CLI auto-continue path (atomcode -c / --continue). Replayed into scrollback AND restored into the agent’s model context via AgentCommand::SetMessages on first run_loop entry, then dropped — matching /resume behaviour.

§file_index: FileIndex

Lazy file/dir index for @-mention popup. Built on first @ keystroke via FileIndex::filter; session-life cache.

§current_session_id: Option<SessionId>

Active session id once /resume has loaded one. Required by the /rename slash command to know which session file to update.

§clipboard_check: Arc<Mutex<ClipboardCheckState>>

Cached “clipboard currently holds an image” flag, with a short TTL so the right-aligned Image in clipboard · ctrl+v to paste hint stays current without thrashing the system clipboard on every redraw. Refreshed lazily inside build_status.

§is_plain_renderer: bool

true when the TUI was launched with PlainRenderer (CI / pipe / non-TTY). The onboarding wizard checks this — plain mode can’t run interactive multi-step flows, so first-run falls through to the existing “no provider configured” status hint.

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> 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> 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> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: 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: 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, 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