@pedro_klein/pi-ssh-session0.2.0
Approved commands and file transfers over persistent named SSH shells for Pi
Untested on omp
This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.
Reports 0
No reports yet.
Readme
pi-ssh-session
Provides one ssh_session tool for approved work through persistent, non-interactive SSH shells. Connections can be named so multiple remote shells stay alive at once; omitting the name uses a backward-compatible default connection.
Install
pi install npm:@pedro_klein/pi-ssh-session
The local machine must provide OpenSSH. Authentication uses configured SSH keys or an SSH agent; SSH passwords, key-passphrase prompts, and keyboard-interactive login are not supported. The remote host must provide bash. File transfers also require base64, and elevated commands require sudo.
Actions
| Action | Parameters | Behavior |
|---|---|---|
connect |
host; optional connection, options, cacheSudoPassword |
Asks the user to choose prompt or YOLO mode, then starts one ssh -T process and a persistent remote bash -l shell. connection names the shell and defaults to default; reconnecting replaces only that name. cacheSudoPassword applies only when YOLO is chosen. |
execute |
command; optional connection, timeout |
Runs a command in the selected shell and streams its combined stdout/stderr while it is active. Working directory and exported environment changes persist. Commands beginning with sudo are rejected; use sudo instead. |
status |
optional connection |
Reports the selected connection, or lists every active connection when no name is supplied. A lone default connection retains the original status output. |
disconnect |
optional connection |
Terminates the selected SSH process. |
sudo |
command; optional connection, timeout |
Runs the command through non-interactive sudo after checking or acquiring a remote sudo timestamp, streaming its combined stdout/stderr while active. |
upload |
localPath and remotePath, or files; optional connection, timeout |
Transfers one or more local files to the selected host. files is an array of { localPath, remotePath } pairs. Relative local paths resolve against Pi's current working directory. |
download |
remotePath and localPath, or files; optional connection, timeout |
Transfers one or more remote files to the local machine. files is an array of { localPath, remotePath } pairs. Relative local paths resolve against Pi's current working directory. |
timeout is an optional limit in milliseconds. Commands and transfers wait indefinitely when it is omitted or set to 0. An explicit positive timeout closes the SSH connection because the remote shell may still be running the timed-out operation and cannot safely accept another command. Connection setup always has a 30,000 ms timeout.
Approval modes
Every connection presents a human choice between prompt and YOLO mode; the agent cannot choose the mode. Prompt mode asks for confirmation before:
- connecting, showing the host and every supplied SSH option;
- executing or running with
sudo, showing the command; - uploading or downloading, showing every source and destination in the request.
YOLO mode replaces those repeated confirmations with one explicit warning during connect. Approving it authorizes commands, sudo, uploads, and downloads on that connection without further confirmation. Use it only when the agent and task are trusted: any of those operations may change the remote or local system without another human checkpoint.
YOLO authorization belongs only to the active SSH process. It ends on disconnect, connection replacement, timeout, abort, stream loss, or Pi shutdown. It is not persisted or restored after reload or resume. Every later connection presents the choice again.
Required approvals fail closed when Pi has no interactive UI. status and disconnect do not require approval. The extension recommends ssh_session for remote work but does not intercept or rewrite Pi's built-in bash tool.
SSH behavior
Connections use these OpenSSH defaults:
-T
-o BatchMode=yes
-o PreferredAuthentications=publickey
-o StrictHostKeyChecking=accept-new
-o ServerAliveInterval=60
-o ServerAliveCountMax=3
accept-new records previously unseen host keys through the user's normal OpenSSH configuration and rejects changed host keys. connect.options accepts complete tokens for -4, -6, -a, -b, -C, -c, -i, -J, -l, -m, -o, -p, -q, -T, -v, and -x. Positional arguments and options that enable forwarding, local command execution, control sockets, password authentication, a PTY, or a different remote session are rejected. Option parsing ends before host, so a host beginning with - remains a host argument.
Each name owns its SSH process, remote shell state, approval mode, command queue, and optional cached sudo password. Each connection serializes its own remote commands and transfers. Disconnecting, replacing, timing out, aborting, or losing one connection does not close the others. Pi shutdown closes every connection. Connection state is not restored after reload or resume.
Output and files
execute and sudo combine stdout and stderr. Results are limited to 2,000 lines or 50 KiB. When output is truncated, the complete output is written to an owner-only temporary output.txt and its path is returned.
Uploads and downloads encode bytes with base64 inside the existing shell; they do not create another SSH connection. A files batch is processed sequentially and stops at the first failure; earlier files may already have completed. Transfer results contain only the host, paths, and byte counts. Uploads create or overwrite remote files, and downloads create or overwrite local files after successful remote reads. Parent directories must already exist. Relative remote paths resolve against the persistent remote shell's current directory. Download writes use Pi's file mutation queue.
Sudo passwords
The sudo action first runs sudo -n true. In prompt mode, an expired remote sudo timestamp opens a masked prompt in the normal chat-input area. Pi sends the entered password separately over the existing SSH stdin to sudo -S -p '' -v, clears its temporary buffer, and relies on the renewed remote timestamp for later calls.
A connection request can set cacheSudoPassword: true. If the user chooses YOLO, Pi opens the same masked chat-input prompt after SSH connects and validates the password immediately before connect returns. If the user chooses prompt mode, the flag is ignored. Canceling the password prompt or failing validation closes the connection. The password is retained only in a best-effort-zeroed memory buffer for that connection. If the remote sudo timestamp later expires, Pi reauthenticates from that buffer without opening another prompt. Without a cached password, unattended YOLO sudo fails instead of pausing for input.
The retained buffer is cleared on disconnect, connection replacement, timeout, abort, stream loss, or Pi shutdown. The password is not a tool parameter and is not placed in the command, tool result, result details, session entries, temporary files, settings, or SSH/sudo arguments. It is never persisted and is not used for SSH login or key-passphrase authentication.
Limitations
- No PTY and no interactive remote programs or TUI applications.
- No SSH password, key-passphrase, or keyboard-interactive authentication.
- No support for remote sudo policies that require a TTY (
requiretty). - No recursive transfer, directory synchronization, resume, compression, or transfer progress reporting.
- Remote commands require
bash; file transfers require a compatiblebase64command.
Development
pnpm --dir packages/pi-ssh-session test
pnpm --dir packages/pi-ssh-session typecheck
pnpm --dir packages/pi-ssh-session build
License
MIT