//! Layout use cases (ARCHITECTURE §6, §7, L4). //! //! The terminal layout of a tab is a pure [`domain::LayoutTree`] (a recursive //! spreadsheet-like grid). Its mutating operations (`split`/`merge`/`resize`/ //! `move`/`set_session`) are **pure functions** that live in the domain; this //! module is the thin application orchestration that: //! //! - resolves the project root (via the [`domain::ports::ProjectStore`]), //! - reads/writes the tree from/to `.ideai/layout.json` (via the //! [`domain::ports::FileSystem`] port — so the layout *travels with the //! project*, including on remote hosts, ARCHITECTURE §7.3, §9.1), //! - publishes [`domain::DomainEvent::LayoutChanged`] on every mutation. //! //! ## Layout ↔ terminal session binding (L3 ↔ L4) //! //! A [`domain::LeafCell`] carries `Option`. When the UI opens a //! terminal in a cell, it calls `OpenTerminal` (L3) — which mints the //! `SessionId` — then records that id in the hosting leaf through the //! `SetSession` layout operation here. The layout is the single source of truth //! for *which cell hosts which session*; the live PTY handle stays in L3's //! `TerminalSessions` registry, keyed by that same `SessionId`. mod management; mod reconcile; mod snapshot; mod store; mod usecases; pub use management::{ CreateLayout, CreateLayoutInput, CreateLayoutOutput, DeleteLayout, DeleteLayoutInput, DeleteLayoutOutput, LayoutInfo, ListLayouts, ListLayoutsInput, ListLayoutsOutput, RenameLayout, RenameLayoutInput, SetActiveLayout, SetActiveLayoutInput, }; pub use reconcile::{ReconcileLayouts, ReconcileLayoutsInput, ReconcileLayoutsOutput}; pub use snapshot::{ SnapshotRunningAgents, SnapshotRunningAgentsInput, SnapshotRunningAgentsOutput, }; pub(crate) use store::{persist_doc, resolve_doc}; pub use store::{LayoutKind, LayoutsDoc, NamedLayout, LAYOUTS_FILE}; pub use usecases::{ LayoutOperation, LoadLayout, LoadLayoutInput, LoadLayoutOutput, MutateLayout, MutateLayoutInput, MutateLayoutOutput, };