Extract conch_remote crate for mobile support#68
Conversation
Covers workspace restructuring (conch_remote extraction, conch_mobile crate), purpose-built mobile frontend, iCloud config sync, iOS platform constraints, and phased delivery plan.
Rewrite conch_tauri/src/remote/mod.rs to delegate all SSH, SFTP, transfer, tunnel, and config operations to conch_remote instead of local module implementations. Key changes: - Add TauriRemoteCallbacks implementing RemoteCallbacks trait, bridging host key and password prompts to Tauri events - Add desktop_remote_paths() for platform path configuration - Move PendingPrompts to Arc<Mutex<>> for shared access from callbacks - Simplify ssh_connect/ssh_quick_connect by removing prompt bridge spawn tasks (~60 lines each) in favor of callbacks pattern - Update tunnel_start to pass callbacks + paths to TunnelManager - Update all config commands to use conch_remote::config::save_config with explicit config_dir path - Update all SFTP/transfer commands to delegate to conch_remote - Delete 6 old module files (ssh.rs, sftp.rs, config.rs, known_hosts.rs, transfer.rs, tunnel.rs) totaling ~2400 lines - Remove direct russh/russh-keys/russh-sftp/ssh-key/base64 deps from conch_tauri Cargo.toml (now transitive via conch_remote) - Add 2 new tests (pending_prompts_new_is_empty, desktop_remote_paths_populated) All 234 workspace tests pass. Net: -2407 lines.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f85462ca92
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| #[cfg(target_os = "ios")] | ||
| let effective_proxy: Option<String> = None; |
There was a problem hiding this comment.
Reject proxied iOS SSH sessions instead of bypassing the proxy
On target_os = "ios" this hardcodes effective_proxy to None, so the return Err("Proxy connections are not supported on iOS") branch below is unreachable and client::connect(...) runs even when server.proxy_command or proxy_jump is configured. Any mobile SSH session that depends on a bastion/ProxyCommand will now silently ignore that setting and fail with a misleading direct-connection error.
Useful? React with 👍 / 👎.
| #[cfg(target_os = "ios")] | ||
| let effective_proxy: Option<String> = None; |
There was a problem hiding this comment.
Reject proxied iOS tunnels instead of connecting directly
The tunnel path has the same issue as interactive SSH: on iOS we force effective_proxy to None, so the unsupported-proxy error at lines 252-255 can never fire and connect_for_tunnel attempts a direct TCP connection instead. Tunnels that require ProxyJump/ProxyCommand will therefore be broken on mobile and report the wrong failure mode.
Useful? React with 👍 / 👎.
| let key_paths: Vec<PathBuf> = if let Some(path) = explicit_key_path { | ||
| vec![expand_tilde(path)] | ||
| } else { | ||
| let home = dirs::home_dir().unwrap_or_default(); | ||
| let ssh_dir = home.join(".ssh"); | ||
| vec![ | ||
| ssh_dir.join("id_ed25519"), | ||
| ssh_dir.join("id_rsa"), | ||
| ssh_dir.join("id_ecdsa"), | ||
| ] | ||
| default_key_paths.to_vec() | ||
| }; |
There was a problem hiding this comment.
Support Keychain-backed auth before emptying iOS key paths
try_key_auth only looks at explicit_key_path and default_key_paths. In this extraction, RemotePaths documents that iOS leaves default_key_paths empty because keys live in Keychain, but there is no callback or other hook here to fetch a Keychain private key. For the intended mobile setup, any auth_method == "key" server without an explicit file path will immediately exhaust this list and fail authentication for both shells and tunnels.
Useful? React with 👍 / 👎.
Summary
conch_remotecrate — extracts all SSH/SFTP/tunnel/transfer logic fromconch_tauriinto a platform-agnostic library that both desktop and future mobile apps can shareSshHandlerandTunnelSshHandlerinto a singleConchSshHandlerbacked by aRemoteCallbackstrait~/.ssh/and~/.config/conch/paths with injectableRemotePaths, enabling iOS sandbox/iCloud pathsconch_plugin's JNI dependency is now behind ajavafeature flag so mobile can compile without itDetails
New crate:
conch_remotecallbacks.rs—RemoteCallbackstrait +RemotePathsconfig structhandler.rs— unifiedConchSshHandlerimplementingrussh::client::Handlerssh.rs— connection, auth, channel loop (ProxyCommand gated for iOS)sftp.rs— SFTP operationstransfer.rs— file transfer engine with progresstunnel.rs— tunnel manager (eliminated all duplicated auth/proxy code)config.rs— server config with path-parameterized persistenceknown_hosts.rs— OpenSSH known_hosts with path parameterChanges to
conch_taurimod.rsrewritten as thin wrappers delegating toconch_remoteTauriRemoteCallbacksbridgesRemoteCallbacksto Tauri eventsconch_pluginjnidependency gated behindjavafeature (default enabled)cfg(java_sdk_available)replaced withcfg(feature = "java")build.rscfg emission removedTest plan
cargo test --workspace— 234 tests pass (up from 218 baseline)cargo check -p conch_remote— compiles independentlycargo check -p conch_plugin --no-default-features— compiles without JNIcargo build -p conch_tauri— desktop app buildscargo clippy --workspace— no errors