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

Typing a Prompt

The input line is where you spend the session. It behaves like a small editor with the keys a readline user expects, and a few things of its own.

Editing

A line longer than the window wraps onto the next row between words (a word too long for a row is split where it must be), and the input grows to eight rows as you type and scrolls after that. Up and Down move by line of the prompt, not by row on screen.

KeyDoes
EnterSend
Shift+Enter, Alt+Enter, Ctrl-JNew line
Left, Right, Home, EndMove; Ctrl-B, Ctrl-F, and Ctrl-A do the same as in a shell
Ctrl-Left, Ctrl-Right, Alt-B, Alt-FMove by word
Up, DownMove between lines of a multi-line prompt
Backspace, DeleteDelete a character (Ctrl-H is backspace)
Ctrl-W, Ctrl-BackspaceDelete the word before the cursor
Ctrl-KDelete to the end of the line
Ctrl-UClear the input (or withdraw the newest queued message)
Ctrl-CClear the input, when no turn is running

Whether Shift+Enter is distinguishable from Enter depends on the terminal. Heph asks the terminal to report modified keys (the kitty keyboard protocol); terminals that support it, such as kitty, foot, WezTerm, and Ghostty, send Shift+Enter as itself. In others, use Alt+Enter or Ctrl-J.

A paste arrives whole, newlines included, as one edit. The first newline does not send.

Editing in your editor

Ctrl-E opens what you have typed in $VISUAL, or $EDITOR, or vi. Heph suspends its screen while the editor runs; save and quit, and the file's contents become the input. Quit without saving and the input is unchanged. A variable that is set but empty counts as unset.

Attaching files: @path

Type @ followed by a path anywhere in a prompt and the file goes to the model with your message, saving a tool call and a round:

> the parser in @src/parse.rs rejects @tests/fixtures/odd.toml; why?

Tab completes the path. The first Tab lists files under the worktree that match what you have typed, fuzzily and case-insensitively, like fzf: every character in order, closer matches and matches on the file name first. It fills in the best match; each further Tab cycles to the next. Hidden directories, target, and node_modules are skipped.

What the model receives depends on the file:

AttachedBecomes
A text fileA document block, titled with the path
A PNG, JPEG, GIF, or WebPAn image block the model can see
A directoryA listing of its entries
A file over 64 KBA note with the path and size; the model reads the part it needs with view

The size limit is [input] max_attach. The path may be anywhere, not only in the project: @~/notes/design.md works. Attaching a file gives the model that file and nothing else; it still cannot read a second file outside the worktree.

An @word that names nothing on disk is left as text, since @ is also how people write handles. In the conversation, attachments show as chips under your message: [src/parse.rs (2.1 KB)].

Images from the clipboard

Ctrl-V with an image on the clipboard saves it to a temporary PNG and puts @that-path in the input, so it goes with the next message. Heph reads the clipboard with wl-paste or xclip, whichever is on PATH, or the command in [input] clipboard_image. With text on the clipboard, Ctrl-V does nothing; paste text with your terminal's paste key as usual.

History

Up on an empty input recalls your previous prompt on this conversation, and each further Up goes one further back; Down comes forward again, ending at whatever you had typed before you started. The history is the conversation's own record of your prompts, so it is there across sessions too.

Ctrl-R, prompt search, is not here yet; it arrives with /search.

Drafts

Whatever is in the input is saved as you type, and comes back when you next open the conversation: after Ctrl-D, after a crash, after a reboot. Sending clears it.

Sending while the model works

Enter while a turn is running does not interrupt it. Each message joins a first-in, first-out queue instead of replacing earlier feedback. Messages drain one at a time, each starting its own turn after the previous turn and any review or publication pause finish. You can keep submitting small pieces of feedback while reading a document.

The status bar shows the number waiting, such as 3 queued. A Queued messages preview above the input shows the count and submitted text in queue order, including while you scroll the conversation or view only user prompts. It wraps at the terminal width and uses at most four content rows; overflow shows .... Up recalls the newest queued message into the input to edit; Ctrl-U withdraws only the newest message. Earlier messages stay queued. Resubmitting recalled text appends it at the back. The queue is session-local; draft recovery does not restore the entire queue after quitting or restarting.

The title's color says what the session is waiting for at a glance: green message when it is ready for you, blue while a turn runs and a message would queue, yellow commit pending while publication is busy and new prompts cannot start, and red when a prompt above needs you (approve or deny the call above, answer the question above, review the changes above).

This is deliberate: a message injected into a running turn would land between two of the model's steps with no way to know which. If you want the model to stop and do something else, interrupt first.

Slash commands

A prompt beginning / is a command to heph, not a message. /help, /clear, /quit, /exit, /plan, /design, /code, and /commit exist today; see Slash Commands.