use std::sync::{Arc, Weak};
use crate::daemon::state::DaemonState;
use crate::session_manager::SessionRecord;
use crate::session_manager::relaunch::RuntimeRelauncher;
pub(crate) struct DaemonRelauncher {
state: Weak<DaemonState>,
}
impl DaemonRelauncher {
pub(crate) fn new(state: &Arc<DaemonState>) -> Self {
Self {
state: Arc::downgrade(state),
}
}
}
#[async_trait::async_trait]
impl RuntimeRelauncher for DaemonRelauncher {
async fn relaunch(&self, record: &SessionRecord) -> Result<(), String> {
let Some(state) = self.state.upgrade() else {
return Err("the daemon state is gone, so no runtime could be started".to_owned());
};
let mgr = state.session_manager().await;
let workspace = record
.workspace_path
.clone()
.unwrap_or_else(|| record.cwd.clone());
let tmux = mgr.tmux_driver();
let gh_env = super::lifecycle::resolve_gh_env(&state, &workspace).await;
let adapter = crate::runtime::build_adapter(
record.runtime,
tmux.clone(),
None,
state.framework_root(),
);
let granted = state.grant_resume_of(record);
spawn_resume_into_owned_pane(&mgr, adapter.as_ref(), record, &workspace, &gh_env).map_err(
|e| {
state.revoke_resume_grant(granted);
format!("runtime adapter spawn_resume failed: {e}")
},
)?;
match super::launch_verify::record_resume_outcome(&mgr, tmux.as_ref(), record, &workspace)
.await
{
Some(msg) => Err(msg),
None => Ok(()),
}
}
}
pub(crate) fn spawn_resume_into_owned_pane(
mgr: &crate::session_manager::SessionManager,
adapter: &dyn crate::runtime::RuntimeAdapter,
record: &SessionRecord,
workspace: &std::path::Path,
gh_env: &[(String, String)],
) -> Result<(), String> {
let pane_id = mgr
.owned_pane(&record.id, record)
.map_err(|e| e.to_string())?;
adapter
.spawn_resume(
&record.tmux_name,
Some(&pane_id),
workspace,
&record.task,
record.claude_session_id.as_deref(),
&record.id.to_string(),
gh_env,
)
.map_err(|e| e.to_string())
}
pub async fn install_auto_relauncher(state: &Arc<DaemonState>) {
let mgr = state.session_manager().await;
mgr.install_relauncher(Arc::new(DaemonRelauncher::new(state)));
}
#[cfg(test)]
#[path = "auto_relaunch_tests.rs"]
mod tests;