defect_cli/session_open.rs
1//! Logic for opening a local session — a neutral helper shared by the interactive REPL
2//! (`repl`) and the single-shot (`oneshot`) paths.
3//!
4//! Both frontend paths execute files and commands directly on the local machine: fs and
5//! shell both use the local backend, and the frontend is marked [`Frontend::Cli`]. They
6//! depend on this module at the same level, not on each other — this avoids making
7//! oneshot depend on the repl module (which would tie oneshot to the `repl` feature).
8
9use std::path::Path;
10use std::sync::Arc;
11
12use agent_client_protocol_schema::SessionId;
13use defect_agent::session::{AgentCore, Frontend, Session, new_session_id};
14use defect_tools::{LocalFsBackend, LocalShellBackend};
15
16/// Opens a session running directly on the local machine (both fs and shell use local
17/// backends, frontend is `Cli`).
18/// `resume = Some(id)` resumes that session; otherwise creates a new one.
19///
20/// # Errors
21///
22/// Returns an error if `load_session` / `create_session` fails (session does not exist,
23/// duplicate id, cwd unavailable, etc.).
24pub async fn open_session(
25 agent: &Arc<dyn AgentCore>,
26 cwd: &Path,
27 resume: Option<SessionId>,
28) -> anyhow::Result<Arc<dyn Session>> {
29 let fs = Arc::new(LocalFsBackend::new(cwd.to_path_buf()));
30 let shell = Arc::new(LocalShellBackend::new());
31 match resume {
32 Some(id) => agent
33 .load_session(id, fs, shell, Frontend::Cli)
34 .await
35 .map_err(|e| anyhow::anyhow!("load_session failed: {e}")),
36 None => {
37 let session_id = SessionId::new(new_session_id());
38 agent
39 .create_session(
40 session_id,
41 cwd.to_path_buf(),
42 Vec::new(),
43 fs,
44 shell,
45 Frontend::Cli,
46 )
47 .await
48 .map_err(|e| anyhow::anyhow!("create_session failed: {e}"))
49 }
50 }
51}