Shell
Run a command, read its output in the panel, run it again
palupdated 2026-09-29DeveloperComes with 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.





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 --hardand 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
entercopies the output,cmd+enteropens the command in your terminal,cmd+rruns it again- A history of every command with its exit code; type
$ lsat the root to run it right there
Palettes 2
-
Shell
shellinputinlineType 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 History
historyinputEvery 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]
shellThe 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.
cwdWhere commands run; `~` is expanded.
timeoutA command still running after this is killed (SIGTERM, then SIGKILL) and the view says so; what it printed until then is kept.
env`KEY=VALUE` lines set for every command, on top of the host's environment.
confirmterminalWhat 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) orexit 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=1orTERM=dumbinenvkeeps 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;
cddoes not stick. Setcwdinstead.
Platforms
macOS and Linux.