Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Running Commands Yourself

A prompt that begins with ! is not sent to the model. Heph runs it as a shell command, shows its output in the conversation, and attaches that output to your next message, so you can say "look at what this prints" without asking the model to guess the command.

> !cargo test 2>&1 | tail -5
$ cargo test 2>&1 | tail -5
  test result: ok. 6 passed; 0 failed; 0 ignored; 0 measured
  ...
> the last test above is flaky on my machine; find out why

The model receives, ahead of your prompt, the command framed as $ cmd, its output, and its exit code, with ANSI formatting removed. Standard error is shown in yellow unless the command supplies its own colors, and goes to the model too. A non-zero exit shows as [exit N]; a command killed by a signal as [killed].

Waiting and cancellation

Both ! and !! select execution resources as shell(<command>), in the original project's scope. Authorization is still yours; there is no agent permission prompt. Contention shows immediately without blocking input or scrolling. Esc or Ctrl-C asks before aborting a waiting or running command. Cancellation completes after supervised cleanup.

Only one bang command runs at a time in the session. A second stays in the input until the first finishes or is cancelled.

Color and terminal behavior

Heph renders ANSI colors (including 256-color and RGB) and text attributes in command output. Unless NO_COLOR is present in heph's environment, it requests color with FORCE_COLOR=1, CLICOLOR_FORCE=1, CARGO_TERM_COLOR=always, and a Git color.ui=always environment config entry. Existing Git environment config entries are preserved. Explicit command options such as git --color=never (for commands that accept it) can still disable color; programs that only check for a terminal may need their own --color=always option.

Commands still run with stdout and stderr captured through pipes and no stdin, not in an interactive terminal. Git normally skips its pager in this mode; use heph's conversation scrollback for long output. An explicitly invoked pager or another interactive program is not supported yet. Cursor movement, screen clearing, titles, hyperlinks, and other terminal controls are discarded, not executed. This is styled line output, not a terminal emulator.

It is you, not the model

A ! command is yours. It goes through no permission prompt, records no tool call, and runs outside any sandbox heph would put a model's command in. The output is your content, in your message, exactly as if you had pasted it.

Because nothing is recorded but the output, ! is also the way to do things the model is not allowed to: commit, push, or run something the permission patterns deny.

Where it runs

!cmd runs in heph's worktree for the conversation, the copy the model edits, because the conversation is about what the model built there and you usually want to show the model something about it. !!cmd runs in your own tree instead.

[input] bang_runs_in = "tree" swaps the two: ! in your tree, !! in the worktree.

You can run !ls immediately after opening a new session, before sending a prompt. If the selected worktree does not exist yet, heph prepares it in the background before running the command. Existing worktrees are left untouched. This starts neither a model turn nor a naming request, and never falls back to running the command in your checkout.

For a repository, a fresh worktree contains committed files from the conversation's branch or base. If no base has been selected yet, heph previews [git] base_branch, or the first offered branch (current branch first, otherwise the most recently committed local branch before remote-tracking branches). This does not settle the base; the first model turn still uses normal base selection. Uncommitted checkout files are not imported. Projects without a repository or without commits use the usual project observation instead. A resumed conversation's missing worktree is restored from its recorded snapshot, or its base if the turn never ended.

Setup errors appear in command output with exit code 125, without spawning the shell. Cancellation during setup waits for preparation to finish and prevents the command from starting. Commands targeting your own tree need no private worktree setup. Edits you make in the private tree before the first model turn are carried into that turn for review.

What it is good for

  • Running the tests yourself before asking the model to look at a failure: !cargo test -p heph-shadow 2>&1 | tail -30

  • Showing the model the actual state of something it would otherwise have to ask permission to inspect: !git log --oneline -5, !ls -la target/

  • Checking the model's work in the worktree before review opens, since the worktree is where it runs by default.

Output accumulates: several ! commands before one prompt all ride along with it, in order. Sending the prompt clears them.