Skip to main content

Fleet

Struct Fleet 

Source
pub struct Fleet {
    surface: Arc<ViewSurface>,
    workspace: Arc<Workspace>,
    config_dir: PathBuf,
    owned_dir: Option<TempDir>,
}
Expand description

A view surface over a stub workspace, plus the seeding a test needs to put a roster in front of it.

Fields§

§surface: Arc<ViewSurface>§workspace: Arc<Workspace>§config_dir: PathBuf

Where the workspace’s store and the CLI’s transcripts live, which a transcript fixture has to write into.

§owned_dir: Option<TempDir>

Declared last, so the directory goes after the store this fixture opened under it has closed - unless a surface is cloned into something that outlives the fleet, which unlinks the file while it is still open.

Implementations§

Source§

impl Fleet

Source

pub fn new(orgs: &[(&str, &[&str])]) -> Result<Self, FixtureError>

A fleet over a config directory of its own, removed with the fleet.

Source

pub fn in_dir( config_dir: &Path, orgs: &[(&str, &[&str])], ) -> Result<Self, FixtureError>

A fleet whose forge.toml declares one project per name under each (org, projects) entry, in the order given. config_dir has to outlive the fleet - the workspace’s store lives under it, and each project’s path is a directory of its own under it.

The project directories are not created. A fixture that makes one itself moves the key project_key answers, because that derivation canonicalises a path that now resolves - and everything the fixture registered before it appeared is registered under a key nothing looks up again. Read project_key before creating one.

Source

pub fn in_dir_with_server( config_dir: &Path, orgs: &[(&str, &[&str])], server: &str, ) -> Result<Self, FixtureError>

Self::in_dir with a [server] block of the caller’s own, for a test that pins what a key DOES rather than that it parses.

Source

pub fn in_dir_with_server_and_env( config_dir: &Path, orgs: &[(&str, &[&str])], server: &str, env: &[(&str, &str)], ) -> Result<Self, FixtureError>

Self::in_dir_with_server with each project’s own [orgs.projects.env], which is the identity a scan’s git and gh children carry - a fixture that pins a lookup needs its own PATH.

Source

pub fn new_with_tts(orgs: &[(&str, &[&str])]) -> Result<Self, FixtureError>

A fleet with [tts] enabled, for a test that drives the voice service: the fixture’s own section stays off so no other test synthesises.

Source

fn open(config_dir: &Path) -> Result<Self, FixtureError>

Source

pub fn surface(&self) -> Arc<ViewSurface> ⓘ

The surface, which keeps the workspace alive on its own.

Source

pub fn workspace(&self) -> Arc<Workspace> ⓘ

The workspace under the fixture, for a test that has to build something FROM it - the transport a binary builds, above all, whose browser relay has to be this workspace’s own.

Source

pub fn arm_dictation(&self, key: &SessionSlot) -> Result<TempDir, FixtureError>

Arm dictation for key: an engine over a temp models directory whose weights are absent, and the seat marked live, so a test can drive a take without hardware, a model or a CLI. The returned directory has to outlive the engine.

Source

pub fn emit(&self, update: SessionUpdate)

Push one update onto the core’s stream, so a test can watch a view react to it without driving a whole session.

Source

pub fn seed_task(&self, task: Task)

Give a project a task, so a fixture can read one back rather than answering with an empty list a reader cannot tell from a missing field.

Source

pub fn emit_and_report(&self, update: SessionUpdate) -> bool

Self::emit, reporting whether a subscriber was there to take it.

false once nothing is listening, which is how a test tells a subscription still attached from one that went with its socket.

Source

pub fn park_slack_draft(&self, key: &SessionSlot, draft: SlackDraft)

Park a Slack draft on key as a blocked Slack call would, so a transport test can answer it from the socket without a session agent driving the tool. The draft’s own id is the one to answer.

Source

pub fn subscriber_count(&self) -> usize

How many subscribers are attached right now, the transport’s own fold included. A test that watches a socket’s subscription arrive and leave reads this rather than asking whether an emit landed: the fold makes every emit land, whether or not a client is there.

Source

pub fn answering_count(&self) -> usize

How many subscribers could answer a prompt right now. The role decides whether the core parks a turn on a reply rather than resolving it Cancelled, and nothing on the wire reports it - so a test that watches a client declare answering reads this.

Source

pub fn set_cli_version(&self, installed: Option<&str>, latest: Option<&str>)

Hold a claude version snapshot, so a view test renders a version line without a real claude --version and npm probe.

Source

pub fn set_fatal_error(&self, error: AppError)

Hold the core’s last fatal, as the boot spawn’s failure records it, so a test can read the home’s encoding without a dying spawn.

Source

pub fn set_user_preferences(&self, preferences: Value)

Hold the CLI’s per-user preferences document, so a view test reads a preference of its own rather than the machine’s.

Source

pub fn start(&self, org: &str, project: &str) -> Result<(), FixtureError>

Give project a live lead session, registering the domain a spawn would.

Source

pub fn add_worker( &self, org: &str, project: &str, label: &str, ) -> Result<(), FixtureError>

Put label under project as a worker that has run before: a persisted row, so it is offered, plus a live entry, so it is not asleep.

Source

pub fn add_despawned_worker( &self, project: &str, label: &str, ) -> Result<(), FixtureError>

A worker label with no live registry entry: the row a despawned worker leaves behind, which is drawn until the label is despawned.

The project’s directory has to exist for the label to be offered at all - worker_row_can_start asks whether the tree it would start in is there.

Source

pub fn add_git_worker( &self, org: &str, project: &str, label: &str, ) -> Result<(), FixtureError>

Self::add_worker for a worker spawned in a git repo, whose tree is the worktree under the project rather than the project root.

The two reads differ, which is the whole point: a fixture that puts every worker in the project’s own tree cannot tell a per-seat read from a per-project one.

Source

pub fn seed_transcript( &self, org: &str, project: &str, label: &str, rows: &[&str], ) -> Result<(), FixtureError>

Write a session’s transcript, where the CLI would have left it, and register slot as the session that owns it. rows are the JSONL lines themselves, so a fixture writes the wire shapes it means.

Source

pub fn seed_asleep_transcript( &self, org: &str, project: &str, label: &str, rows: &[&str], ) -> Result<(), FixtureError>

Self::seed_transcript for a seat nothing is running behind: the id lives in the store’s own row - which is what a wake resumes, and the other place a transcript read is looked up by - and no live entry names it.

Source

fn write_transcript( &self, org: &str, project: &str, label: &str, rows: &[&str], ) -> Result<SessionSlot, FixtureError>

The row file at the path the CLI would have written it to, with the seat resolved; which of the two id sources names it is the caller’s.

Source

pub fn hold_conversation( &self, state: &TransportState, org: &str, project: &str, label: &str, ) -> Result<(), FixtureError>

Hold the seat’s conversation on state, read from the transcript a fixture just seeded.

This is the window a Connected carries, put there by hand: a fixture that wants a seat to answer with a conversation the transport is HANDED holds it this way, rather than leaning on the transport’s own read of the file - which is a sleeping seat’s path, and firing it here would make every held-window test pass through the other source. So it reads the transcript RAW - the shape a Connected carries and a resume answers with - and lets the conversation convert it. Not through ViewSurface::conversation, which converts the task notices on the way out: a fixture built on the converted shape would exercise something production never seeds from, so a defect in the seed’s own conversion could not be seen here.

Source

pub fn install_agent( &self, org: &str, project: &str, label: &str, ) -> UnboundedReceiver<AgentCommand>

Give slot a live agent, which is what makes a view treat the seat as running rather than as one nothing is behind. A stub: nothing answers the commands it is sent, and a caller that holds the receiver it hands back reads what was asked.

Source

pub fn park_terminal_hand_off( &self, slot: &SessionSlot, terminal: u16, ) -> Result<String, String>

Park a terminal hand-off on slot as a blocked terminal__hand_off call would, so a socket test can type through the hand-off’s door.

Source

pub fn answer_terminal_hand_off(&self, id: &str, slot: &SessionSlot)

Answer that parked hand-off with Done, as the dock’s button would.

Source

pub fn seed_queued_prompt( &self, slot: &SessionSlot, uuid: &str, source: PromptSource, text: &str, )

Put a prompt in a seat’s queue exactly as a dispatch leaves it: the row a client attaching mid-queue reads, with no dispatch to drive.

Source

pub fn intercept_dispatch(&self)

Catch every command the core is dispatched, so a test can assert what a view asked for without driving a session.

Source

pub fn dispatched(&self) -> Vec<Command>

The commands caught since the last call.

Source

pub fn fail_spawn(&self, org: &str, project: &str, label: &str, reason: &str)

Give slot the core’s own record of a spawn that failed, as the connection-failure path leaves one.

Source

pub fn seed_test_pending_interaction( &self, slot: &SessionSlot, kind: PendingKind, )

Hold slot on a pending interaction, the way a session that has asked a person for something reads.

Source

pub fn clear_test_pending(&self, slot: &SessionSlot)

Let go of everything parked on slot, which is the half of answering that is the core’s.

Source

pub fn await_login(&self, slot: &SessionSlot)

Hold slot waiting to be let in, the way a session that cannot authenticate reads.

Source

pub fn add_starting_worker( &self, org: &str, project: &str, label: &str, ) -> Result<(), FixtureError>

Put label under project as a worker whose spawn has not connected yet, so its row reads as starting rather than asleep.

Source

pub fn seed_test_prompt_queue( &self, slot: &SessionSlot, kind: PendingKind, count: usize, )

Hold slot on a queue of count unanswered prompts, so a view test can render a depth a session holding several reads.

Source

pub fn advertise( &self, slot: &SessionSlot, commands: Vec<AvailableCommand>, agents: Vec<AvailableAgent>, )

Advertise commands and agents for slot, the way the CLI’s init frame leaves them: what the composer’s / and & triggers read.

Source

pub fn add_task( &self, org: &str, project: &str, subject: &str, owner: &str, artifact: Option<&str>, ) -> Result<(), FixtureError>

Declare a task under project, held by the session labelled owner, with artifact as what it produced.

Source

pub fn add_cron(&self, project: &str, prompt: &str) -> Result<(), FixtureError>

Declare a durable cron under project, firing a day out so a view renders it as a schedule rather than as an overdue one.

Source

pub fn record_session( &self, project: &str, session_id: &str, ) -> Result<(), FixtureError>

Record a transcript row for project, as a session that ran and ended would leave behind: a project whose session is gone but whose history is not.

Source

pub fn seed_view_facts(&self, slot: &SessionSlot, facts: ViewFacts)

Hold facts on slot’s session, as the events that carry them would: the header’s four, the MCP snapshot, the process walk, the monitor set and the sub-agent attribution.

A field left out is a fact the session has not reported, which is its own state rather than an empty one.

Source

fn project_view(&self, project: &str) -> Result<ProjectView, FixtureError>

Source

fn project_key(&self, project: &str) -> Result<ProjectKey, FixtureError>

The registry key for project.

The key is derived from the project’s PATH, and the derivation canonicalises it, so the same project answers a different key before and after its directory exists. in_dir writes the config without creating the project directories, so a fixture that creates one itself gets a key that moves under it: anything registered before it appeared is registered under a key nothing looks up again, and the failure is silent - an empty worker list rather than an error.

Auto Trait Implementations§

§

impl !RefUnwindSafe for Fleet

§

impl !UnwindSafe for Fleet

§

impl Freeze for Fleet

§

impl Send for Fleet

§

impl Sync for Fleet

§

impl Unpin for Fleet

§

impl UnsafeUnpin for Fleet

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
§

impl<T> Any for T
where T: Any,

§

fn into_any(self: Box<T>) -> Box<dyn Any>

§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

§

fn type_name(&self) -> &'static str

§

impl<T> AnySync for T
where T: Any + Send + Sync,

§

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

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
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<S> FromSample<S> for S

§

fn from_sample_(s: S) -> S

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

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
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

impl<T> PolicyExt for T
where T: ?Sized,

§

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
§

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
§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

§

fn to_sample_(self) -> U

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.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

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
§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more