VibeShell is a desktop SSH/SFTP terminal application. Think of it as a modern alternative to PuTTY/Tabby/Xshell, built with Tauri 2 (Rust) + React 18 (TypeScript).
npx tauri dev # Dev mode (hot reload)
npm run build && cargo check # Verify both sides compile
unset CI CXX CC && npx tauri build --no-bundle # Release exe| What | Where |
|---|---|
| App entry + layout | src/App.tsx |
| All Tauri commands registered | src-tauri/src/lib.rs (invoke_handler) |
| Backend command implementations | src-tauri/src/commands/*.rs |
| SSH client (russh) | src-tauri/src/ssh/client.rs |
| Session manager | src-tauri/src/session/manager.rs |
| Database schema + CRUD | src-tauri/src/storage/database.rs |
| Data models | src-tauri/src/storage/models.rs |
| Frontend Tauri wrapper | src/lib/tauri.ts (safeInvoke) |
| Zustand stores | src/stores/*.ts |
| Tailwind theme config | tailwind.config.js |
| Tauri config | src-tauri/tauri.conf.json |
Frontend (React + Zustand) → safeInvoke('command', args) → Tauri IPC → Rust command handler → business logic (SSH/SFTP/DB/tunnel)
Session I/O: mpsc::channel for input, broadcast::channel for output. Terminal uses xterm.js with WebGL renderer.
Database: SQLite via rusqlite. Tables: servers, groups, credentials, tunnel_configs, command_snippets, recordings, settings.
client::HandleandChannelare NOT Clone- For shared handle access:
Arc<tokio::sync::Mutex<Option<Handle>>> - For channel I/O:
channel.into_stream()thentokio::io::split() - Never try
.clone()on Handle or Channel — it won't compile
- All colors use CSS custom properties via Tailwind:
bg-tokyo-bg,text-tokyo-fg,border-tokyo-bg-hl - Available theme colors:
tokyo-bg,tokyo-bg-dark,tokyo-bg-hl,tokyo-fg,tokyo-comment,tokyo-selection,tokyo-blue,tokyo-green,tokyo-red,tokyo-yellow,tokyo-magenta,tokyo-cyan - Do not use hardcoded hex colors like
#1a1b26— they break theme switching
const result = await safeInvoke<MyType>('command_name', { arg1: 'value' });
if (result.success) {
// result.data is MyType
} else {
// result.error is TauriError (has .message, .isTauriUnavailable)
}unset CI CXX CC before npx tauri build to avoid cc-rs detecting wrong MinGW toolchain.
- Add model struct to
src-tauri/src/storage/models.rs - Add DB table/migration to
database.rs::init_schema()(useALTER TABLE ADD COLUMNfor existing tables,CREATE TABLE IF NOT EXISTSfor new) - Add CRUD methods to
database.rs - Create command file in
src-tauri/src/commands/your_feature.rs - Export in
src-tauri/src/commands/mod.rs - Register commands in
src-tauri/src/lib.rsinvoke_handler
- Add TypeScript types to
src/types/or inline - Create Zustand store in
src/stores/yourStore.tsusingsafeInvoke - Create component in
src/components/YourComponent/ - Use
tokyo-*Tailwind classes,cursor-pointeron interactive elements,transition-colorson hover states - Wire into
App.tsxif needed
npm run build # TS + Vite
cargo check # Rust
cargo test # Unit tests- Rust:
cargo test(unit tests in modules, integration test intests/) - Frontend: No test framework yet
- Manual:
npx tauri devthen interact with UI
Session: session_list, session_create, session_connect, session_kill, session_kill_all, session_send_input, session_send_bytes, session_resize, session_attach, session_detach, get_server_status
Server: get_servers, add_server, update_server, delete_server, get_groups, add_group, delete_group
SFTP: sftp_init, sftp_list_dir, sftp_download_file, sftp_upload_file, sftp_mkdir, sftp_delete, sftp_rename, sftp_pwd, sftp_stat, sftp_read_file, sftp_write_file, sftp_compress, sftp_extract
Tunnel: tunnel_config_list, tunnel_config_add, tunnel_config_update, tunnel_config_delete, tunnel_start, tunnel_stop, tunnel_list_active, tunnel_stop_all_for_session
Snippet: snippet_list, snippet_add, snippet_update, snippet_delete, snippet_search
Recording: start_recording, stop_recording, list_recordings, is_session_recording, get_session_recording_id, delete_recording, get_recording_content
Local Shell: local_shell_list_shells, local_shell_get_default, local_shell_list_sessions, local_shell_create, local_shell_send_input, local_shell_send_bytes, local_shell_resize, local_shell_attach, local_shell_detach, local_shell_kill, local_shell_kill_all
Fingerprint: get_fingerprint, save_fingerprint, delete_fingerprint, delete_fingerprint_by_id, list_fingerprints, verify_fingerprint, touch_fingerprint, clear_fingerprints
Credential: save_credential, get_credential, delete_credential
Install: detect_ai_tools, install_to_tool, uninstall_from_tool
Dialog: pick_ssh_key_file, pick_file_for_upload, pick_download_directory, read_ssh_key_file