Shell

Run a command, read its output in the panel, run it again

palupdated 2026-09-29DeveloperComes with pal

Open in pal

Comes with pal, so a new install already has it; the button finds it in pal again if you removed it. This page can't see what your pal has installed.

Shell: A command typed: one Run row, nothing has run yet
A command typed: one Run row, nothing has run yet
Shell: The output view: exit 0 and the duration as badges, stdout in mono on the sunken surface
The output view: exit 0 and the duration as badges, stdout in mono on the sunken surface
Shell: A failing command: stderr in red, exit 1
A failing command: stderr in red, exit 1
Shell: rm -rf on the way: the confirm card before anything runs
rm -rf on the way: the confirm card before anything runs
Shell: Shell History: past commands with their exit codes, Enter runs one again
Shell History: past commands with their exit codes, Enter runs one again
1 of 5

What it does

Run a command in your login shell and read its output in the panel, with the exit code and how long it took. Nothing runs until you press Enter, and destructive-looking commands ask first.

  • Nothing runs as you type; rm, sudo, git reset --hard and the like ask first
  • Runs in your login shell, so your PATH, aliases and functions work
  • Output in the panel: stdout in monospace, stderr in red, the exit code and duration on top
  • Long commands show the elapsed time and the result lands when they finish
  • enter copies the output, cmd+enter opens the command in your terminal, cmd+r runs it again
  • A history of every command with its exit code; type $ ls at the root to run it right there

Palettes 2

  • Shellshellinputinline

    Type a command; the one row runs it on Enter and shows the output as a view. At the root `$ ls` or `> ls` lists the same row inline.

    • ↵Run the command (in the view: copy the output)
    • ⌘↵Run it in a terminal window instead (in the view: open one)
    • ⌘CCopy the command
    • ⌘RIn the view: run it again
    • ⌘⇧EIn the view: copy stderr
  • Shell Historyhistoryinput

    Every command run here, newest first, with its exit code and duration; Enter runs it again.

    • ↵Run the command again
    • ⌘↵Run it in a terminal window
    • ⌘CCopy the command
    • ⌘DRemove the entry

Actions

  • RunThe command in the login shell; the output as a view. Asks first when it looks destructive.↵
  • Run in terminalOpens a terminal window on the command in the working directory.⌘↵
  • Copy command⌘C
  • Copy outputIn the output view: stdout (stderr when there is no stdout) onto the clipboard.↵
  • Open in terminalIn the output view: the same command in a terminal window.⌘↵
  • Run againIn the output view: the command once more, the view replaced.⌘R
  • Copy stderrIn the output view.⌘⇧E
  • Remove from history⌘D

Settings

Extension, [extensions.shell]

shell
$SHELL -lic text

The shell and its flags; `$SHELL` is your login shell. `-l` loads the login profile (PATH), `-i` the interactive one (aliases); `-c` takes the command. A `zsh -lc` skips the aliases and the interactive noise.

cwd
~ path

Where commands run; `~` is expanded.

timeout
10seconds number

A command still running after this is killed (SIGTERM, then SIGKILL) and the view says so; what it printed until then is kept.

env
none list

`KEY=VALUE` lines set for every command, on top of the host's environment.

confirm
On boolean
terminal
empty text

What cmd+Enter opens: `Terminal` (default), `iTerm`, `kitty`, `Alacritty`, `WezTerm`, `Ghostty`, or any app name (`open -na <name> --args -e ...`); on Linux a command name (`kitty`, `foot`, `alacritty`, `wezterm`, `ghostty`, ...), else `$TERMINAL`, else the first of those installed.

Defaults shown. Change them in pal's settings window or in the config file.

The README

Everything Shell does, key by key, from the extension's own README.md

Shell

Run one command in your login shell and read what it printed without leaving the panel. An input palette: what you type is one Run: <cmd> row and nothing runs until you press enter; the answer is a view with the output. $ ls or > git status at the root lists the same row inline.

What the query does

query rows
nothing three hints: the shell, folder and timeout in use; the root prefixes; where the history is
ls -la one row, Run: ls -la; enter runs it, cmd+enter opens it in a terminal, cmd+c copies it
rm -rf build the same row, with asks first in the subtitle: enter shows a confirm card before anything runs (while confirm is on)
$ ls, > ls the marker is stripped; at the root these are what wakes the palette inline

The output view

The command runs through the shell setting ($SHELL -lic by default: your login shell with the profile and the interactive rc loaded, so PATH, aliases and functions apply), in cwd, with the env lines set, for at most timeout seconds. The view:

  • the command as the title and the first line, the folder under it;
  • badges on the right: exit 0 (green) or exit N (red), the duration; killed after N s (red) when the timeout struck; output cut (amber) when a stream passed 256 KB (the tail is kept);
  • stdout in monospace on a sunken surface, stderr under it in red, the whole thing scrolling past the panel; (no output) when both were empty.

A command still running 2.5 s after enter gets the view at once with a blue running badge and the elapsed time ticking; when it ends the result lands in the same view (view.update), so a command may take longer than the panel would wait for a pick. cmd+r runs it again in place.

keys action
enter Copy the output (stdout; stderr when there was no stdout)
cmd+enter Open the command in a terminal window, in the working directory
cmd+r Run again
cmd+c Copy the command
cmd+shift+e Copy stderr
escape Back to the palette

cmd+r is the panel's Refresh on a list; in a view level the view's own actions take the keys, so here it re-runs.

Terminal

cmd+enter on the row or in the view opens a terminal on cd <cwd> && <command>; exec <shell>, so the window stays open with the output. The terminal setting names the app: Terminal (default) and iTerm are driven over AppleScript; kitty, Alacritty, WezTerm and Ghostty by their own flags through open -na; any other name is open -na <name> --args -e <shell> -c .... On Linux the setting is a command name, else $TERMINAL, else the first installed of x-terminal-emulator, kitty, foot, Alacritty, WezTerm, Ghostty, GNOME Terminal, Konsole, xfce4-terminal and xterm, each handed the command the way it takes one (kitty and foot as trailing arguments, WezTerm after start --, the rest after -e).

Shell History

Every command that ran lands in the Shell History palette (shell-history), newest first, once each, the last hundred (storage), with its exit code (exit 0 green, exit N red, killed for a timeout), the duration and the folder. enter runs it again (the same confirm for a destructive-looking one), cmd+enter opens it in a terminal, cmd+c copies it, cmd+d removes the entry; the last row clears the history (asks first). The palette is input, not live: it lists on every keystroke so a command just run is there, and its rows never reach the root, where an enter would run one.

Marked history rows copy as one command per line, a script's worth, and are removed in one write.

What looks destructive

With confirm on (the default) the Run action asks first when any simple command of the line (split on ;, &&, ||, |, subshells; VAR=x prefixes and wrappers like xargs, time, nohup, exec skipped) is rm, mv, dd, mkfs, shred, truncate, wipefs, shutdown, reboot, halt, poweroff, dropdb, sudo or doas; or, by its arguments, chmod/chown/chgrp -R, git push --force / -f, git reset --hard, git clean -f, git branch -D, git checkout --, kill -9, docker rm/rmi/system prune, a package manager's uninstall/remove/purge, diskutil erase, launchctl bootout, a DROP TABLE; or a redirect onto a disk device. An argument named rm (grep rm *.txt) is not a command, and rmdir, mvn, format never match. A heuristic, not a sandbox: the shell runs whatever you confirm.

Setup

Nothing to install. Settings, [extensions.shell]:

key type default what
shell text $SHELL -lic The shell and its flags; the command is appended as the last argument. zsh -lc skips aliases and the interactive rc's noise (a zle warning from an rc file that assumes a terminal shows up in red).
cwd folder ~ Where commands run.
timeout 1 to 600 s 10 SIGTERM after this, SIGKILL 1.5 s later; the process group, so a pipeline dies whole.
env list of KEY=VALUE empty Set for every command, on top of the host's environment.
confirm boolean true Ask before a destructive-looking command.
terminal text empty (Terminal) What cmd+enter opens.

What it does not do

  • Interactive commands: stdin is closed. A command that prompts gets EOF.
  • Colour: ANSI escapes are shown as printed, not rendered. NO_COLOR=1 or TERM=dumb in env keeps most tools plain.
  • Streaming: the view fills when the command ends (or is killed), not line by line.
  • A shell session: every command is a fresh shell; cd does not stick. Set cwd instead.

Platforms

macOS and Linux.