SSH Studio
English | 简体中文
🔍 Get it from the VS Code Marketplace: open the Extensions view (Cmd+Shift+X / Ctrl+Shift+X) and search for SSH Studio — publisher lupee.
Manage SSH servers from the VS Code sidebar: a nested server tree, remote terminals, dual-pane SFTP with remote file editing, port forwarding, key management, a reusable command library, live monitoring panels, and a 3D fleet inspection view — all multiplexed over one reused SSH connection per server.
No local ssh/scp binaries required: SSH Studio ships a pure-JavaScript SSH implementation (ssh2) and runs entirely on your local machine (extensionKind: ui).
Table of Contents
Highlights
|
|
| 🗂 Server tree |
Arbitrarily deep folders, search, jump hosts, import from ~/.ssh/config |
| 💻 Terminals |
Native VS Code terminals over SSH, several per server, all sharing one connection |
| 📁 File transfer |
Dual-pane SFTP with a transfer queue, resumable transfers, and conflict policies |
| ✏️ Remote editing |
Open a remote file in VS Code; saving writes it straight back over SFTP |
| 🔀 Tunnels |
Local & remote port forwards that open automatically with the connection |
| 📊 Monitoring |
CPU/memory/network charts, processes, ports, Docker, GPU, Nginx, users, routes, LAN scan |
| 🏢 Inspection |
A 3D rack view of a whole folder of servers, each reporting CPU, memory and disk |
| ⚡ Skills |
A personal library of parameterized shell one-liners, two clicks from any server |
| 🔑 Keys |
Import, generate (ed25519 / RSA / ECDSA), and inspect SSH keys |
| 🌍 Localized |
English, 简体中文, Deutsch, Français, 日本語, 한국어 |
Features
Hosts — the server tree
The sidebar holds a single view with three tabs: Hosts, Keys, and Skills.
The Hosts tab is a folder tree with SSH connections at any depth — group by project, datacenter, customer, whatever fits.
- New Folder / New Connection at any level, plus Edit, Delete, and Duplicate.
- Search, Expand All / Collapse All, and manual Refresh.
- Jump hosts: a connection can route through a chain of other connections in the tree; each hop is tunnelled through the previous one.
- Import from
~/.ssh/config — pull in the hosts you already have.
- Export / Import Configuration — move your tree between machines. Exports deliberately leave saved passwords and private keys behind.
- Disconnect / Reconnect per server; the row icon shows the live connection state.
- Per-connection extras: terminal type and text encoding, commands to run on login, a colour for the terminal tab, and keepalive/timeout overrides.
- The connection editor and key dialogs open in a floating window (in compact mode) by default, or as a normal editor tab (
sshStudio.ui.dialogWindow).
Each server gets one authenticated SSH connection, and everything — terminals, the SFTP panel, monitoring panels, tunnels — rides on it as a separate channel. Opening a second tool never re-prompts for a password, and the connection is torn down a few seconds after the last consumer closes, so closing a terminal mid-transfer does not kill the transfer.
Authentication is driven by an explicit plan rather than trial-and-error:
- Private key (from the built-in key store), password (optionally saved), and SSH agent (
SSH_AUTH_SOCK, or Pageant on Windows).
keyboard-interactive / PAM: the password you already entered answers the PAM challenge, so password login works on the many Linux images that expose passwords only through PAM — just like desktop SSH clients. 2FA prompts are passed through to you.
- Methods the server has already refused are skipped, so a failure names the real reason instead of "all methods failed".
Keepalive interval, handshake timeout and prompt timeout are all configurable; while a password or fingerprint dialog is on screen the handshake clock stops, so a prompt you have not answered yet never counts as a stalled connection.
Terminals
- Opens in VS Code's integrated terminal — full colour, mouse, scrollback, find, splits and terminal tabs, because it is the editor's own terminal.
- New Terminal (same server) opens as many terminals as you like over the same connection.
- Non-UTF-8 servers are handled: set the connection's encoding and both input and output are transcoded.
- When a session ends, the terminal offers to reconnect instead of just closing.
- Right-click inside an SSH Studio terminal → Open File Transfer for this Terminal to jump into SFTP for that server, starting in the terminal's current directory.
File transfer (SFTP)
A dual-pane panel: local filesystem on one side, remote on the other.
- List or tree view per pane, sortable columns with draggable widths, a path bar, and quick jumps (home, Downloads,
/opt, /mnt, the terminal's current folder).
- Drag and drop between the panes, or the Upload / Download buttons.
- Transfer queue with configurable parallelism (1–10), per-task pause / resume / cancel / retry, and pause-all / resume-all / cancel-all.
- Resumable: a paused or failed transfer picks up from the byte it stopped at rather than starting over.
- Atomic writes: transfers land in a
.part file that is renamed on completion, so an interrupted transfer never leaves a truncated file (sshStudio.transfer.useTempFile).
- Conflict policy when the target exists: ask (with "apply to all"), overwrite, skip, or keep both.
- Remote file operations: new folder, rename, delete, change permissions (a chmod dialog with the rwx grid and the octal box kept in sync), copy path.
- Toggle for hidden files, a collapsible local pane, and a collapsible queue with an in-flight transfer counter in the title bar.
- Deleting a remote folder runs as a single
rm -rf over the connection's command channel, falling back to a concurrent SFTP walk on servers that only expose SFTP.
Editing remote files in VS Code
Open a remote file from the transfer panel and it is pulled into a scratch copy under ~/.x1/ssh-studio/tmp, opened as a normal editor tab, and written straight back over SFTP every time you save.
- Writes are in place — truncate and write the original path — so the file keeps its mode, owner and symlink-ness.
- While the transfer panel is open both legs show up in its queue; if you closed it, the upload is reported on the status bar instead.
- Scratch copies are keyed by extension-host pid, so two VS Code windows never wipe each other's open files, and they are cleaned up on start and on exit.
Port forwarding
Local and remote tunnels are configured per server in the connection editor:
- All tunnels open automatically when the server connects — no manual start/stop.
- Editing the rules while connected applies the diff live: removed or changed tunnels stop, new ones start.
- A rule that fails to start is reported once and not retried until you change it.
- Tunnels share the server's authenticated connection, so
localhost:3306 can reach a database that only listens on the server's loopback interface.
Monitoring panels
One panel per server with nine tabs, all reading over the shared connection. Every list has its own Auto toggle that only ticks while its tab is showing, so a window left on another tab costs no round trips.
| Tab |
What it shows |
| Monitor |
Host facts (CPU model, kernel, uptime) plus live CPU, load, memory and per-interface traffic charts |
| Processes |
The process table with a filter box, and a detail pane for whichever process you select |
| Ports |
Listening sockets with the process behind each one, including the Docker container serving a published port |
| Containers |
Docker containers, their images, ports and state |
| GPU |
NVIDIA GPU utilization, memory, temperature and the processes using them |
| Nginx |
Whether Nginx is installed and running, its version and build flags, master/worker processes, and the config files it actually loads |
| Users |
Accounts from /etc/passwd, current sessions, each home's authorized_keys, and what sshd_config actually allows |
| Route |
The routing table, plus traceroute with whois lookups per hop |
| Tools |
ARP-based LAN scan that finds used addresses and IP conflicts — multi-round sampling with confidence levels, arp-scan when available and a tcpdump + ping fallback otherwise |
Everything is read with ordinary /proc, ip, ss, docker, nvidia-smi and nginx -T calls — nothing is installed on the server.
Folder inspection — the 3D rack view
Right-click a folder → Inspect Folder opens a WebGL data-centre view of everything in it: each folder becomes a rack, each server a unit in that rack, and every unit lights up with its own progress — pending, inspecting, done, or failed.
- Each server reports CPU busy share, load average, memory, and disk usage per real filesystem.
- Servers that are not connected are dialled on demand and dropped again as soon as they have answered.
- Drag to orbit, scroll to zoom, double-click to reset. The scene is drawn by three.js bundled with the extension — no textures, no network, everything painted at runtime.
Skills — your command library
The Skills tab is a personal library of shell one-liners, organized into folders and runnable on any server:
- Placeholders like
[p#1 port number] turn into a parameter strip at the bottom of the tab and are filled in before the command is sent.
- A skill can append a carriage return (run it immediately) or leave the line for you to edit, and can decode escape sequences (
\C-b, \e, \r) so it can drive tmux, screen or an interactive prompt rather than just typing text.
- Sending a skill targets the active SSH Studio terminal, or opens one for the server you pick.
- First launch seeds a starter library (system status, network, disk & directories, …) to demonstrate the format — it is ordinary data afterwards: edit, replace, or delete everything.
Key management
The Keys tab manages your SSH identities:
- Import existing private keys — paste the text or open a file; the passphrase, if any, is stored with the key.
- Generate new key pairs: ed25519 (recommended), RSA 3072, or ECDSA 256.
- Details view with the fingerprint and the public key line, ready to copy into
authorized_keys, plus rename and delete.
- Keys live in the extension's own store, so a connection references a key by id and nothing depends on where the file sits on disk.
Security
- Host key verification is trust-on-first-use: the first connection shows the fingerprint and asks. A fingerprint that changes afterwards always stops the connection and warns you — that is what a man-in-the-middle looks like — and you have to confirm the new one explicitly.
sshStudio.security.strictHostKeyChecking controls the first contact: with it off, a host you have never seen is trusted silently. Trusted fingerprints can be dropped with Clear Trusted Host Fingerprints.
- Files that hold secrets are created
0600, in a 0700 directory.
- Configuration exports never include saved passwords or private keys.
- Every webview runs under a strict Content-Security-Policy with a per-load nonce, and remote data (file names, process names, container names) is only ever written as text, never as markup.
- A full SSH protocol trace can be enabled for debugging (
sshStudio.diagnostics.verboseLogging) and read via SSH Studio: Show Log.
Languages
The UI ships in English, 简体中文, Deutsch, Français, 日本語, 한국어. It follows VS Code's display language by default, and SSH Studio: Select UI Language… switches it on the fly, independent of VS Code. (Command titles and setting descriptions in VS Code's own menus still follow VS Code's language — that is how the editor loads them.)
Command Reference
All commands are available from the Command Palette under SSH Studio; most also sit on the row or toolbar they belong to.
| Command |
What it does |
SSH Studio: New Folder |
Add a folder at the selected level |
SSH Studio: New Connection |
Add a connection at the selected level |
SSH Studio: Edit |
Open the connection or folder editor |
SSH Studio: Duplicate |
Copy a connection, without its saved password |
SSH Studio: Delete |
Delete a node and everything under it |
SSH Studio: Search |
Focus the search box in the Hosts tab |
SSH Studio: Refresh / Expand All / Collapse All |
Tree housekeeping |
SSH Studio: Open Terminal |
Terminal for this server (reuses an open one) |
SSH Studio: New Terminal (same server) |
Another terminal on the same connection |
SSH Studio: Open File Transfer |
The dual-pane SFTP panel |
SSH Studio: Open File Transfer for this Terminal |
SFTP for the active terminal, at its current folder |
SSH Studio: Open Monitor |
Monitoring panel (charts tab) |
SSH Studio: Open Processes / Ports / Containers / GPU / Nginx / Users / Route |
The same panel, opened on that tab |
SSH Studio: Inspect Folder |
The 3D rack view for a folder of servers |
SSH Studio: Disconnect / Reconnect |
Drop or re-establish the connection |
SSH Studio: Import from ~/.ssh/config |
Import hosts you already have |
SSH Studio: Export Configuration... / Import Configuration... |
Move the tree between machines |
SSH Studio: Import Key / Generate New Key Pair / Show Details |
Key library |
SSH Studio: Clear Trusted Host Fingerprints |
Forget every remembered host key |
SSH Studio: Select UI Language… |
Switch the extension's language |
SSH Studio: Show Log |
Open the output channel |
Installation
Requirements: VS Code 1.90 or newer. The extension runs on the UI side, so it works in a local window; it is not meant to be installed into a Remote-SSH/WSL/Container host.
From the Marketplace (recommended):
- Open the Extensions view (
Cmd+Shift+X / Ctrl+Shift+X).
- Search for
SSH Studio and pick the one published by lupee.
- Click Install.
From a VSIX: grab the .vsix from the release/ folder of this repository, then
code --install-extension ssh-studio-<version>.vsix
or in VS Code: Extensions view → ··· menu → Install from VSIX…
From source:
git clone https://github.com/lupee/ssh-studio
cd ssh-studio
npm install
npm run vsix # produces ssh-studio-<version>.vsix
Getting Started
- Click the SSH Studio icon in the activity bar.
- Click + to add a connection — or run SSH Studio: Import from ~/.ssh/config.
- Fill in host, port, user, and how to authenticate (key, password, or agent). Test checks it without saving.
- Hover a server row for its actions: terminal, file transfer, monitor, and the rest under the row's menu.
Settings
| Setting |
Default |
Description |
sshStudio.transfer.concurrency |
3 |
Number of files transferred in parallel (1–10) |
sshStudio.transfer.conflict |
ask |
When the target file exists: ask / overwrite / skip / rename |
sshStudio.transfer.useTempFile |
true |
Write to a .part temp file and rename on completion |
sshStudio.connection.keepalive |
30000 |
Keepalive heartbeat interval (ms); 0 disables it |
sshStudio.connection.readyTimeout |
20000 |
Handshake timeout (ms) |
sshStudio.connection.promptTimeout |
120000 |
How long a connection waits for you to answer a password or fingerprint prompt (ms); 0 waits forever |
sshStudio.terminal.followCwdToSftp |
true |
Experimental: the remote pane follows the terminal's current directory (OSC 7, bash/zsh) |
sshStudio.monitor.sampleInterval |
5 |
Seconds between traffic samples in the monitor |
sshStudio.monitor.historySeconds |
60 |
Seconds of traffic history kept in memory |
sshStudio.security.strictHostKeyChecking |
true |
Ask before trusting a host you have never connected to |
sshStudio.ui.showHiddenFiles |
false |
Show dotfiles in the transfer panel |
sshStudio.ui.dialogWindow |
float |
Where the connection editor and key dialogs open: floating window or editor tab |
sshStudio.diagnostics.verboseLogging |
false |
Log the full SSH protocol trace to the output channel |
Where Your Data Lives
Everything SSH Studio remembers is kept as plain, human-readable files under ~/.x1/ssh-studio — not in VS Code's internal state database, so you can read, edit, diff and back it up with ordinary tools.
| File |
Contents |
servers.json |
The server tree — including passwords you chose to save (file mode 0600) |
skills.json |
Your skill library |
hosts.yaml |
Trusted host fingerprints, one host:port: SHA256:… line each |
conf.yaml |
UI language, panel preferences, and the key library with its private keys (file mode 0600) |
tmp/ |
Scratch copies of remote files open in the editor; cleared on start and exit |
Back up or sync that directory and your whole setup moves with you. The in-app Export Configuration is the safe way to share a setup: it strips passwords and keys.
Development
npm install
npm run watch # esbuild in watch mode (auto-starts on folder open)
- Press F5 to launch an Extension Development Host with the extension loaded; after edits, reload that window (
Cmd+R).
npm run check-types — TypeScript type check.
npm test — starts a throwaway sshd on port 2222 (test/run-local-sshd.sh, Linux; on macOS start it by hand) and runs the suite against it: a real SSH integration test plus JSDOM tests that drive each webview's front-end through its real message protocol.
npm run vsix — package a VSIX.
npm run dev:link / dev:unlink / dev:status — symlink the repo into ~/.vscode/extensions so your daily VS Code runs the working tree (reload the window after each build; don't reinstall the VSIX while linked).
Layout: src/core (connection, auth, host keys), src/storage (the file-backed store), src/views (sidebar and dialogs), src/sftp, src/monitor, src/terminal, src/tunnel, with each webview's front-end under media/<panel>/.
License
MIT
| |