use std::sync::Arc;
use serde::Deserialize;
use trusty_common::uds::server::RpcRouter;
use crate::daemon::managed_routes::prune::{PruneRequest, PruneWorktreesRequest};
use crate::daemon::managed_routes::{
AdoptExistingRequest, AnswerRequest, ReactivateQuery, RenameRequest, SendInputRequest,
SpawnRequest, activity, cores, delete, fleet, provision_status, prune, reactivate, rebind,
reconcile, rename, residency, supervisor, sync_assets,
};
use crate::daemon::state::DaemonState;
#[derive(Debug, Deserialize)]
pub struct SessionParams {
pub id: String,
}
#[derive(Debug, Deserialize, Default)]
#[serde(default)]
pub struct ListParams {
pub source_id: Option<String>,
pub slim: bool,
}
#[derive(Debug, Deserialize)]
pub struct SendParams {
pub id: String,
pub text: String,
}
#[derive(Debug, Deserialize)]
pub struct AnswerParams {
pub id: String,
pub answer: String,
}
#[derive(Debug, Deserialize)]
pub struct RenameParams {
pub id: String,
pub name: String,
}
#[derive(Debug, Deserialize)]
pub struct DecommissionParams {
pub id: String,
#[serde(default)]
pub record_only: bool,
#[serde(default)]
pub force: bool,
}
#[derive(Debug, Deserialize)]
pub struct DeleteParams {
pub id: String,
#[serde(default)]
pub force: bool,
}
#[derive(Debug, Deserialize, Default)]
#[serde(default)]
pub struct EphemeralParams {
pub dry_run: bool,
}
#[derive(Debug, Deserialize)]
pub struct ReactivateParams {
pub id: String,
#[serde(default)]
pub caller_pane_id: Option<String>,
#[serde(default)]
pub pane_confirmed_dead: bool,
}
#[derive(Debug, Deserialize, Default)]
#[serde(default)]
pub struct NoParams {}
pub fn register(router: RpcRouter, state: &Arc<DaemonState>) -> RpcRouter {
let router = register_fleet_wide(router, state);
let router = register_rebind(router, state);
register_per_session(router, state)
}
#[derive(Debug, Deserialize)]
pub struct RebindParams {
pub id: String,
#[serde(default)]
pub tmux: Option<String>,
}
fn register_rebind(router: RpcRouter, state: &Arc<DaemonState>) -> RpcRouter {
let (one_s, all_s) = (Arc::clone(state), Arc::clone(state));
router
.typed("mpm.managed.rebind", move |req: RebindParams| {
let state = Arc::clone(&one_s);
async move {
rebind::rebind_core(&state, &req.id, req.tmux.as_deref())
.await
.into_rpc()
}
})
.typed("mpm.managed.rebind_all", move |_: NoParams| {
let state = Arc::clone(&all_s);
async move { rebind::rebind_all_core(&state).await.into_rpc() }
})
}
fn register_fleet_wide(router: RpcRouter, state: &Arc<DaemonState>) -> RpcRouter {
macro_rules! st {
() => {
Arc::clone(state)
};
}
let (spawn_s, list_s, adopt_s, prune_s, eph_s) = (st!(), st!(), st!(), st!(), st!());
let (pw_s, rw_s, fleet_s, sa_s) = (st!(), st!(), st!(), st!());
let (residency_s, sup_s) = (st!(), st!());
router
.typed("mpm.managed.spawn", move |req: SpawnRequest| {
let state = Arc::clone(&spawn_s);
async move { cores::spawn_core(&state, req).await.into_rpc() }
})
.typed("mpm.managed.list", move |req: ListParams| {
let state = Arc::clone(&list_s);
async move {
cores::list_core(&state, req.source_id.as_deref(), req.slim)
.await
.into_rpc()
}
})
.typed("mpm.managed.adopt", move |req: AdoptExistingRequest| {
let state = Arc::clone(&adopt_s);
async move { cores::adopt_core(&state, req).await.into_rpc() }
})
.typed("mpm.managed.prune", move |req: PruneRequest| {
let state = Arc::clone(&prune_s);
async move { prune::prune_managed_core(&state, req).await.into_rpc() }
})
.typed(
"mpm.managed.decommission_ephemeral",
move |req: EphemeralParams| {
let state = Arc::clone(&eph_s);
async move {
prune::decommission_ephemeral_core(&state, req.dry_run)
.await
.into_rpc()
}
},
)
.typed(
"mpm.managed.prune_worktrees",
move |req: PruneWorktreesRequest| {
let state = Arc::clone(&pw_s);
async move { prune::prune_worktrees_core(&state, req).await.into_rpc() }
},
)
.typed("mpm.managed.reconcile_worktrees", move |_: NoParams| {
let state = Arc::clone(&rw_s);
async move { reconcile::reconcile_worktrees_core(&state).await.into_rpc() }
})
.typed("mpm.managed.fleet", move |_: NoParams| {
let state = Arc::clone(&fleet_s);
async move { fleet::fleet_core(&state).await.into_rpc() }
})
.typed(
"mpm.managed.register_supervisor",
move |req: crate::session_manager::SupervisorRegistration| {
let state = Arc::clone(&sup_s);
async move {
let verifier = supervisor::LaunchRecordBinding {
root: state.framework_root().to_path_buf(),
};
supervisor::register_supervisor_core(&state, &req, &verifier)
.await
.into_rpc()
}
},
)
.typed(
trusty_common::mpm_rpc::METHOD_RESIDENCY_ACTIVE,
move |_: NoParams| {
let state = Arc::clone(&residency_s);
async move { residency::active_projects_core(&state).await.into_rpc() }
},
)
.typed("mpm.managed.sync_assets_all", move |_: NoParams| {
let state = Arc::clone(&sa_s);
async move {
sync_assets::sync_all_session_assets_core(&state)
.await
.into_rpc()
}
})
}
fn register_per_session(router: RpcRouter, state: &Arc<DaemonState>) -> RpcRouter {
macro_rules! st {
() => {
Arc::clone(state)
};
}
let (get_s, stop_s, rstop_s, rename_s, send_s) = (st!(), st!(), st!(), st!(), st!());
let (ps_s, sa_s, ans_s, ac_s, act_s) = (st!(), st!(), st!(), st!(), st!());
let (res_s, react_s, dec_s, del_s) = (st!(), st!(), st!(), st!());
router
.typed("mpm.managed.get", move |req: SessionParams| {
let state = Arc::clone(&get_s);
async move { cores::get_core(&state, &req.id).await.into_rpc() }
})
.typed("mpm.managed.stop", move |req: SessionParams| {
let state = Arc::clone(&stop_s);
async move { cores::runtime_stop_core(&state, &req.id).await.into_rpc() }
})
.typed("mpm.managed.runtime_stop", move |req: SessionParams| {
let state = Arc::clone(&rstop_s);
async move { cores::runtime_stop_core(&state, &req.id).await.into_rpc() }
})
.typed("mpm.managed.rename", move |req: RenameParams| {
let state = Arc::clone(&rename_s);
async move {
rename::rename_core(&state, &req.id, RenameRequest { name: req.name })
.await
.into_rpc()
}
})
.typed("mpm.managed.send", move |req: SendParams| {
let state = Arc::clone(&send_s);
async move {
cores::send_core(&state, &req.id, SendInputRequest { text: req.text })
.await
.into_rpc()
}
})
.typed("mpm.managed.provision_status", move |req: SessionParams| {
let state = Arc::clone(&ps_s);
async move {
provision_status::provision_status_core(&state, &req.id)
.await
.into_rpc()
}
})
.typed("mpm.managed.sync_assets", move |req: SessionParams| {
let state = Arc::clone(&sa_s);
async move {
sync_assets::sync_session_assets_core(&state, &req.id)
.await
.into_rpc()
}
})
.typed("mpm.managed.answer", move |req: AnswerParams| {
let state = Arc::clone(&ans_s);
async move {
cores::answer_core(&state, &req.id, AnswerRequest { answer: req.answer })
.await
.into_rpc()
}
})
.typed("mpm.managed.attach_cmd", move |req: SessionParams| {
let state = Arc::clone(&ac_s);
async move { cores::attach_cmd_core(&state, &req.id).await.into_rpc() }
})
.typed("mpm.managed.activity", move |req: SessionParams| {
let state = Arc::clone(&act_s);
async move { activity::activity_core(&state, &req.id).await.into_rpc() }
})
.typed("mpm.managed.resume", move |req: SessionParams| {
let state = Arc::clone(&res_s);
async move { cores::resume_core(&state, &req.id).await.into_rpc() }
})
.typed("mpm.managed.reactivate", move |req: ReactivateParams| {
let state = Arc::clone(&react_s);
async move {
let query = ReactivateQuery {
caller_pane_id: req.caller_pane_id,
pane_confirmed_dead: req.pane_confirmed_dead,
};
let outcome = reactivate::reactivate_core(&state, &req.id, &query).await;
outcome.into_rpc()
}
})
.typed(
"mpm.managed.decommission",
move |req: DecommissionParams| {
let state = Arc::clone(&dec_s);
async move {
cores::decommission_core(
&state,
&req.id,
req.record_only,
crate::daemon::managed_routes::dirt_policy(req.force),
)
.await
.into_rpc()
}
},
)
.typed("mpm.managed.delete", move |req: DeleteParams| {
let state = Arc::clone(&del_s);
async move {
delete::delete_core(&state, &req.id, req.force)
.await
.into_rpc()
}
})
}