codetether_agent/plugin_marketplace/
hot_load.rs1use anyhow::Result;
4use std::path::Path;
5use std::process::Command;
6
7#[derive(Debug)]
9pub struct LoadedPlugin {
10 pub name: String,
11 pub pid: u32,
12 pub endpoint: String,
13 pub capabilities: Vec<String>,
14}
15
16pub fn start_plugin(name: &str, binary_path: &Path, port: u16) -> Result<LoadedPlugin> {
18 let child = Command::new(binary_path)
19 .env("MCP_PORT", port.to_string())
20 .env("PLUGIN_NAME", name)
21 .spawn()?;
22 let pid = child.id();
23 tracing::info!(name, pid, port, "Plugin MCP server started");
24 Ok(LoadedPlugin {
25 name: name.to_string(),
26 pid,
27 endpoint: format!("http://127.0.0.1:{port}"),
28 capabilities: Vec::new(),
29 })
30}
31
32pub fn stop_plugin(plugin: &LoadedPlugin) -> Result<()> {
34 tracing::info!(name = %plugin.name, pid = %plugin.pid, "Stopping plugin");
35 #[cfg(unix)]
36 {
37 if plugin.pid > i32::MAX as u32 {
38 anyhow::bail!("Invalid PID: {}", plugin.pid);
39 }
40 let ret = unsafe { libc::kill(plugin.pid as i32, libc::SIGTERM) };
41 if ret != 0 {
42 anyhow::bail!(
43 "Failed to send SIGTERM to plugin {}: errno {}",
44 plugin.name,
45 ret
46 );
47 }
48 }
49 Ok(())
50}