Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions crates/treq-napi/src/dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,40 @@ pub fn dispatch(command: &str, args: Value) -> Result<Value, String> {
serde_json::to_value(result).map_err(|e| e.to_string())
}

// ── Remote SSH ───────────────────────────────────────────────────
"list_ssh_hosts" => {
let hosts = treq_lib::core::remote::list_configured_hosts()?;
serde_json::to_value(hosts).map_err(|e| e.to_string())
}

"check_ssh_host" => {
let host = get_str(&args, "host")?;
let readiness = treq_lib::core::remote::check_readiness(&host)?;
serde_json::to_value(readiness).map_err(|e| e.to_string())
}

"remote_probe_repo" => {
let host = get_str(&args, "host")?;
let path = get_str(&args, "path")?;
let probe = treq_lib::core::remote::probe_repo(&host, &path)?;
serde_json::to_value(probe).map_err(|e| e.to_string())
}

"remote_clone_repo" => {
let host = get_str(&args, "host")?;
let repo_url = get_str(&args, "repoUrl")?;
let destination = get_str(&args, "destination")?;
let repo = treq_lib::core::remote::clone_repo(&host, &repo_url, &destination)?;
serde_json::to_value(repo).map_err(|e| e.to_string())
}

"remote_open_repo" => {
let host = get_str(&args, "host")?;
let path = get_str(&args, "path")?;
let repo = treq_lib::core::remote::open_repo(&host, &path);
serde_json::to_value(repo).map_err(|e| e.to_string())
}

// ── Tauri-runtime-only: silent no-ops ─────────────────────────────
"pty_create_session"
| "pty_session_exists"
Expand Down
2 changes: 2 additions & 0 deletions src-tauri/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub mod file_watcher;
pub mod filesystem;
pub mod pending_review;
pub mod pty_commands;
pub mod remote;
pub mod session;
pub mod settings;
pub mod workspace;
Expand All @@ -18,6 +19,7 @@ pub use file_watcher::*;
pub use filesystem::*;
pub use pending_review::*;
pub use pty_commands::*;
pub use remote::*;
pub use session::*;
pub use settings::*;
pub use workspace::*;
18 changes: 16 additions & 2 deletions src-tauri/src/commands/pty_commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub fn pty_create_session(
shell: Option<String>,
initial_command: Option<String>,
suppress_echo_for: Option<String>,
remote_host: Option<String>,
) -> Result<(), String> {
log::debug!(
"pty_create_session: session_id={}, working_dir={:?}, shell={:?}, initial_command_present={}, suppress_echo_for_present={}",
Expand All @@ -23,10 +24,22 @@ pub fn pty_create_session(
let sid = session_id.clone();
let event_name = format!("pty-data-{}", sid);

pty_manager.create_session(
let (shell, shell_args, working_dir, initial_command) = if let Some(host) = remote_host {
let (program, args) = crate::core::remote::build_ssh_shell_command(
&host,
working_dir.as_deref(),
initial_command.as_deref(),
)?;
(Some(program), args, None, None)
} else {
(shell, Vec::new(), working_dir, initial_command)
};

let result = pty_manager.create_session(
session_id,
working_dir,
shell,
shell_args,
initial_command,
suppress_echo_for,
Box::new(move |data| {
Expand All @@ -39,7 +52,8 @@ pub fn pty_create_session(
);
}
}),
)
);
result
}

#[tauri::command]
Expand Down
51 changes: 51 additions & 0 deletions src-tauri/src/commands/remote.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use crate::core::remote::{self, RemoteReadiness, RemoteRepoProbe, RemoteRepository, SshHost};

#[tauri::command]
pub fn list_ssh_hosts() -> Result<Vec<SshHost>, String> {
remote::list_configured_hosts()
}

#[tauri::command]
pub async fn check_ssh_host(host: String) -> Result<RemoteReadiness, String> {
tauri::async_runtime::spawn_blocking(move || remote::check_readiness(&host))
.await
.map_err(|e| format!("Failed to join check_ssh_host task: {e}"))?
}

#[tauri::command]
pub async fn remote_probe_repo(host: String, path: String) -> Result<RemoteRepoProbe, String> {
tauri::async_runtime::spawn_blocking(move || remote::probe_repo(&host, &path))
.await
.map_err(|e| format!("Failed to join remote_probe_repo task: {e}"))?
}

#[tauri::command]
pub async fn remote_clone_repo(
host: String,
repo_url: String,
destination: String,
) -> Result<RemoteRepository, String> {
tauri::async_runtime::spawn_blocking(move || remote::clone_repo(&host, &repo_url, &destination))
.await
.map_err(|e| format!("Failed to join remote_clone_repo task: {e}"))?
}

#[tauri::command]
pub fn remote_open_repo(host: String, path: String) -> Result<RemoteRepository, String> {
Ok(remote::open_repo(&host, &path))
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn remote_open_repo_returns_remote_identity() {
let repo = remote_open_repo("devbox".to_string(), "/srv/project".to_string()).unwrap();

assert_eq!(repo.host, "devbox");
assert_eq!(repo.path, "/srv/project");
assert_eq!(repo.display_name, "devbox:project");
assert_eq!(repo.repo_uri, "ssh://devbox/srv/project");
}
}
1 change: 1 addition & 0 deletions src-tauri/src/core/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod app;
pub mod changes;
pub mod commits;
pub mod remote;
pub mod repo;
pub mod workspaces;
pub use app::*;
Expand Down
Loading
Loading