use std::path::PathBuf;
use chrono::Utc;
use tracing::{info, warn};
use super::manager::{ManagedError, SessionManager};
use super::record::{ManagedSessionId, ManagedSessionState, SessionRecord};
impl SessionManager {
#[allow(clippy::too_many_arguments)]
pub async fn create_with_id(
&self,
id: ManagedSessionId,
task: String,
cwd: Option<PathBuf>,
name_hint: Option<String>,
workspace_path: Option<PathBuf>,
repo_url: Option<String>,
branch: Option<String>,
runtime: crate::runtime::RuntimeKind,
ephemeral: bool,
owned: bool,
) -> Result<SessionRecord, ManagedError> {
let cwd = cwd.unwrap_or_else(|| dirs::home_dir().unwrap_or_else(|| PathBuf::from("/tmp")));
let github_project = repo_url
.as_deref()
.and_then(trusty_common::github_path::parse_github_path)
.map(|gh| gh.repo);
let tmux_name = self
.resolve_session_name(
name_hint.as_deref(),
github_project.as_deref(),
&cwd,
|_| false,
)
.await?;
self.create_with_resolved_name(
id,
tmux_name,
task,
cwd,
workspace_path,
repo_url,
branch,
runtime,
ephemeral,
owned,
)
.await
}
#[allow(clippy::too_many_arguments)]
pub(crate) async fn create_with_reserved_name(
&self,
id: ManagedSessionId,
reserved_name: String,
task: String,
cwd: Option<PathBuf>,
workspace_path: Option<PathBuf>,
repo_url: Option<String>,
branch: Option<String>,
runtime: crate::runtime::RuntimeKind,
ephemeral: bool,
owned: bool,
) -> Result<SessionRecord, ManagedError> {
let cwd = cwd.unwrap_or_else(|| dirs::home_dir().unwrap_or_else(|| PathBuf::from("/tmp")));
self.create_with_resolved_name(
id,
reserved_name,
task,
cwd,
workspace_path,
repo_url,
branch,
runtime,
ephemeral,
owned,
)
.await
}
#[allow(clippy::too_many_arguments)]
async fn create_with_resolved_name(
&self,
id: ManagedSessionId,
tmux_name: String,
task: String,
cwd: PathBuf,
workspace_path: Option<PathBuf>,
repo_url: Option<String>,
branch: Option<String>,
runtime: crate::runtime::RuntimeKind,
ephemeral: bool,
owned: bool,
) -> Result<SessionRecord, ManagedError> {
let workdir = cwd.to_string_lossy().to_string();
self.tmux
.create_session(&tmux_name, &workdir)
.map_err(|e| ManagedError::TmuxUnavailable(e.to_string()))?;
let mut tmux_guard =
super::session_guard::TmuxSessionGuard::new(tmux_name.clone(), self.tmux.clone());
let mut correlation = crate::driver::SessionCorrelation::new();
if let Some(ref ws) = workspace_path {
correlation = correlation.with_worktree(ws.clone());
}
if let Some(ref b) = branch {
correlation = correlation.with_branch(b.clone());
}
let record = SessionRecord {
id,
tmux_name: tmux_name.clone(),
cwd,
task,
state: ManagedSessionState::Provisioning,
created_at: Utc::now(),
last_activity_at: None,
workspace_path,
repo_url,
branch,
pending_decision: None,
proposed_default: None,
correlation,
runtime,
ephemeral,
workspace_owned: owned,
source_id: None,
claude_session_id: None,
scrollback_path: None,
last_cwd: None,
};
if let Err(e) = self.store.write().await.upsert(record.clone()).await {
warn!(
id = %id,
name = %tmux_name,
"registry upsert failed; rolling back (reaping) the orphaned tmux session: {e}"
);
return Err(ManagedError::from(e));
}
tmux_guard.disarm();
info!(id = %id, name = %tmux_name, runtime = %runtime.as_str(), "managed session created");
Ok(record)
}
}