Skip to main content

Module protocol

Module protocol 

Source
Expand description

Command + SessionUpdate channel envelopes between a view and forge-workspace. A view dispatches Commands; workspace per-session tasks emit SessionUpdates back through the workspace’s fan-out.

§Dual Command shape (deliberate)

Two Command enums exist in the workspace: this one, keyed by SessionSlot, and forge_primitives::AgentCommand, keyed by session_id: String. They overlap on variant names (Prompt, Cancel, SetMode, …) but serve different boundary layers:

  • forge_workspace::protocol::Command is the view ↔ workspace envelope. SessionSlot routing, App-level variants (SpawnProject), the workspace-internal Respond* cluster.
  • forge_primitives::AgentCommand is the workspace ↔ agent envelope. session_id-keyed, raw shapes the AgentHandle dispatcher recognises.

Collapsing them would force the AgentHandle dispatcher to handle App-level variants it has no business in (SpawnProject is a workspace concern; SessionSlot is a routing concern; neither belongs in the agent layer). The current split keeps each envelope minimal at its respective boundary. The translation happens in session_task::execute_command_via_handle.

Re-exports§

use std::path::PathBuf; 🔒
use forge_agent::client::SessionLaunchSettings; 🔒
use forge_primitives::cloud::service_status::ServiceSeverity; 🔒
use forge_primitives::error::AppError; 🔒
use forge_primitives::permission::PermissionMode; 🔒
use forge_primitives::permission_interaction::PermissionOutcome; 🔒
use forge_primitives::permission_interaction::PermissionRequest; 🔒
use forge_primitives::plugins::PluginUpdateRun; 🔒
use forge_primitives::plugins::PluginUpdateTrigger; 🔒
use forge_primitives::plugins::PluginsCliActionSuccess; 🔒
use forge_primitives::plugins::PluginsInventorySnapshot; 🔒
use forge_primitives::question::QuestionOutcome; 🔒
use forge_primitives::question::QuestionRequest; 🔒
use forge_primitives::review::ReviewStatus; 🔒
use forge_primitives::review::ReviewThread; 🔒
use forge_primitives::runtime::AvailableModel; 🔒
use forge_primitives::runtime::CurrentModel; 🔒
use forge_primitives::runtime::ModeState; 🔒
use forge_primitives::runtime::TerminalReason; 🔒
use forge_primitives::ImageAttachment; 🔒
use forge_primitives::McpOperationError; 🔒
use forge_primitives::McpServerStatus; 🔒
use forge_primitives::Message; 🔒
use forge_primitives::SessionId; 🔒
use serde::Deserialize; 🔒
use serde::Deserialize; 🔒
use serde::Serialize; 🔒
use serde::Serialize; 🔒
use tokio::sync::oneshot; 🔒
use uuid::Uuid; 🔒
use crate::SessionSlot; 🔒
use crate::mcp::peers::types::WrappedPrompt; 🔒

Structs§

QueuedPrompt
One prompt waiting in the CLI’s queue, as a view reads it.
WorkerSpawnReply
Synchronous return from Command::SpawnWorker - the session_id that the new worker was issued and the tag value applied. Threaded back to the calling agents__spawn Tool impl via the oneshot receiver so the LLM sees {session_id, tag} in the tool result.

Enums§

Command
Command envelope: a view -> forge-workspace.
DespawnResult
Outcome of a Command::DespawnWorker, sent back to the calling agents__despawn Tool via the command’s respond oneshot.
DictateOutcome
What one finished dictation take produced. Plain data rather than forge_dictate::Outcome: a view words the notices, so it gets the observations and keeps the crate’s error shapes.
DispatchError
Errors from the dispatch boundary. UnknownSession and SessionClosed are returned by Workspace::dispatch; NoActiveSession is for a caller with no slot to name.
NoticeSeverity
How loudly a SessionUpdate::Notice reads.
PendingAsk
What a seat is held on, as the core kept it: the prompt a view that attached late has no other way to read.
PendingInteractionSlot
One pending interaction response slot. Workspace stores these keyed by tool_id in DomainSession.pending_interactions. Command::RespondPermission / RespondQuestion look up the matching slot and send the outcome down the oneshot.
PromptSource
Who dispatched a prompt, for a queued row’s label.
RankMove
Where the user moved a row in its queue.
SessionChoice
Which session a worker spawn landed on, as the spawn tool reports it.
SessionUpdate
Update envelope: forge-workspace -> a view.
SpawnRole
The role a caller states for a spawn: a project’s lead, or a worker named by its label.
TurnErrorClass
Coarse classification of a turn-level error message. The classifier itself lives in forge-agent’s translate::error_handling; this enum is the wire shape it produces.
WorkerStatusAction
Mutation kind for a SessionUpdate::WorkerStatusChanged event. Added and StatusChanged carry a fresh WorkerStatus snapshot; Removed carries the last-known snapshot for symmetry but a view’s reducer treats it as a delete.
WorktreeDisposition
What has happened to a worker’s git worktree as of the SessionUpdate::WorkerStatusChanged event carrying it. Only the agents__despawn path ever removes one. Among the spawn rollbacks, the dividing line is Connected: one that fires before the subprocess connected reports Self::Absent, because claude never ran to create a worktree, while a rollback after Connected (a failed tag-write) reports Self::untouched, because by then the worktree is on disk. Every other emitter reports Self::untouched.

Functions§

no_signal_reads_as_negative_infinity 🔒
Read a no-signal peak - a level’s, or the one a no_audio outcome carries - taking null as no signal rather than as a decode failure.
unanswerable
A reply channel for a command that carries none.