Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions crates/freshell-freshagent/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,13 @@ pub struct FreshAgentState {
/// unchanged (terminal-mode routes 503 instead of touching a registry
/// that was never given to them).
pub(crate) terminal_registry: Option<freshell_terminal::TerminalRegistry>,
/// Read-only session-identity lookup (in production: the WS-side
/// TerminalIdentityRegistry behind the freshell-terminal
/// SessionIdentityLookup seam, wired by freshell-server). Powers the
/// identity arm of the REST D7 live-session guard. `None` (unwired)
/// narrows the guard to the registry-row arm.
pub(crate) session_identity:
Option<Arc<dyn freshell_terminal::registry::SessionIdentityLookup>>,
/// paneId -> terminal pane record (Slice 1 `mode:'shell'` terminals
/// created via `POST /api/tabs`). Disjoint from `panes` (fresh-agent-only)
/// and `content_panes` (browser/editor) -- a pane id appears in exactly
Expand Down Expand Up @@ -238,6 +245,7 @@ impl FreshAgentState {
opencode: Arc::new(tokio::sync::Mutex::new(None)),
sessions_revision: Arc::new(AtomicI64::new(0)),
terminal_registry: None,
session_identity: None,
terminal_panes: Arc::new(Mutex::new(HashMap::new())),
content_panes: Arc::new(Mutex::new(HashMap::new())),
tabs: Arc::new(Mutex::new(HashMap::new())),
Expand Down Expand Up @@ -388,6 +396,20 @@ impl FreshAgentState {
self
}

/// D7 live-session guard (REST rung): wire in the read-only
/// session-identity lookup (in production the WS-side
/// `TerminalIdentityRegistry`, injected by `freshell-server`'s `main.rs`)
/// so `spawn_terminal_pane` can probe the identity arm of
/// [`freshell_terminal::TerminalRegistry::live_session_owner`]. Unwired
/// (`None`), the guard degrades to the registry-row arm only.
pub fn with_session_identity(
mut self,
identity: Arc<dyn freshell_terminal::registry::SessionIdentityLookup>,
) -> Self {
self.session_identity = Some(identity);
self
}

/// SESSION-09 fix-forward: replace this state's own `sessions_revision`
/// counter with a SHARED one -- in production, `freshell-server` wires
/// this to the SAME `Arc<AtomicI64>` as `freshell_ws::WsState::sessions_revision`
Expand Down Expand Up @@ -1257,6 +1279,17 @@ fn fail_json(status: StatusCode, message: String) -> Response {
.into_response()
}

/// `fail_json` + a machine-readable code, matching how the WS side keys
/// errors (`error["code"] == "RESTORE_UNAVAILABLE"`). Envelope is additive:
/// `{status:"error", code, message}`.
pub(crate) fn fail_json_code(status: StatusCode, code: &str, message: String) -> Response {
(
status,
Json(json!({ "status": "error", "code": code, "message": message })),
)
.into_response()
}

/// The error status the original maps serve failures to (`agentRouteErrorStatus`): a
/// bounded cold-start failure / transport error is a 5xx; everything else 500 here.
fn serve_error_status(err: &ServeError) -> StatusCode {
Expand Down
Loading
Loading