portal_shell
Run commands on a remote host in a persistent shell session that preserves working directory and environment across calls. Use for sequences of dependent commands.
Instructions
Run a command (or a sequence) on ONE remote host in a persistent shell session: cwd and environment (cd / export / venv activation) survive across calls. Use it only when you need that continuity — otherwise portal_exec is faster (no session setup) and can target many hosts; for a long task to background and poll, use portal_job.
Pick one:
command="pytest" → {host, session_id, command, exit_code, output, duration_s}.
commands=["cd /app","source .venv/bin/activate","pytest"] → steps run in order in the SAME session, so cwd / exports / venv carry across them (what portal_exec's multi-command path cannot do). Returns {host, session_id, results:[…]}; stop_on_error=True (default) halts at the first failure and adds stopped_at.
Behavior:
bash or zsh; an unknown login shell falls back to bash (if bash is missing the call is refused — use portal_exec).
Output is the COMBINED stdout+stderr stream (use portal_exec when you need them split). Oversize output is capped and flagged truncated=true.
A command that wedges on an interactive prompt (sudo password, ssh first-connect, passphrase, …) is auto-aborted, returning exit_code -1 + error:"interactive_prompt_blocked" + session_preserved:true — cwd/env survive, so the next command runs straight away.
★ No sudo or secret injection here (both are one-shot by nature): to run as root use portal_exec(use_sudo=True); for a command needing a secret use portal_exec(secrets=[…]).
timeout (per command, seconds; default 1h, operator-lowerable via PORTAL_DEFAULT_TIMEOUT): the call is held open until the command exits or timeout elapses. Keepalive pings stop the client aborting a hung call, so timeout is your real cut-off — for an exploratory / re-runnable command pass a SMALL one first (e.g. 10–30) to fail fast, raising it only for genuinely slow commands.
⚠️ By convention, write operations should target /tmp/ on the remote unless the user approved another path (not enforced here).
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| host | Yes | ||
| command | No | ||
| timeout | No | ||
| commands | No | ||
| stop_on_error | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |