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

Your First Turn

This chapter walks one change from prompt to applied file. Everything in it is what you saw on the screen when you tried it; the chapters after explain each piece.

Pick a project with a test suite. From its root:

heph

The screen has three parts: the conversation on top, an input line in the middle, a status bar at the bottom.

 message ─────────────────────────────────────────────────────────────────────
>
──────────────────────────────────────────────────────────────────────────────
main | code | 0 tok | $0.00 | opus-5

The conversation starts as <unnamed> and gets a prompt-derived name as soon as you submit your first prompt. A background title may improve it, but failure keeps the local name. Each plain heph creates a fresh UUID; heph --continue resumes the latest branch conversation. The current mode (code, plan, or design) always appears in muted gray after the conversation and branch. opus-5 is the model that will answer, from the coding tier.

Ask for something small

Type a prompt and press Enter:

> add a pow(base: i64, exp: u32) -> i64 function to src/lib.rs with one test

Your prompt appears in the conversation under You:, and the status bar changes to working. The model reads what it needs, silently: the tools that only read (view, grep, ls, and the rest) run without a word. When it edits, you see the edit happen:

Adding `pow` after `mul` with the exact signature you gave, plus one test.

ok edit src/lib.rs

The sentence above the edit is the model's rationale. Heph asks the model to state what it is changing and why before every write, and keeps that sentence with the change. You will see it again in review.

A prompt to approve

If the model wants to run a command, it has to ask, because a command reaches outside the private copy heph gave it:

┌ permission ─────────────────────────────────────────────────────────────────┐
│exec   in worktree of ref main   (mirrors /home/you/project)                  │
│                                                                              │
│cargo test --lib auth                                                         │
│                                                                              │
│y  this call only                                                             │
│a  this session:    exec(cargo) args(*)                                       │
│   = any exec of cargo, any arguments; only cargo is run, and each argument   │
│     is passed to it literally, never through a shell                         │
│A  remember:        the same, written to project config [permissions]      │
│e  edit the pattern before a or A                                             │
│n  deny                                                                       │
│N  deny with reason                                                           │
└──────────────────────────────────────────────────────────────────────────────┘

Read it top to bottom: which tool, where it runs, the exact command, then your choices. y allows this one call. a allows this call and every future cargo test ... for the rest of the session. A does that and writes the pattern to the project's config, so it holds tomorrow too. The line beginning = is the plain-English meaning of the pattern, generated from it, so you know what you are agreeing to. Press a.

Gates

If the project has acceptance gates configured, they run now, on what the model changed, before you are asked to look:

-- running acceptance gates

A gate that fails goes back to the model with its output, and the model fixes it. You only see the change once the gates pass. (A fresh project has no gates; the Gates chapter shows how to add cargo test as one.)

Review

When the model is done and the gates are green, the review opens:

┌ review ─────────────────────────────────────────────────────────────────────┐
│Review: 01a0c63 on main, round 1 -- 1 file, 2 hunks                           │
│                                                                              │
│src/lib.rs                                                                    │
│hunk 1 (18-31)   edit #8fqrN6                                                 │
│Adding `pow` after `mul` with the exact signature you gave, plus one test.    │
│hunk 2 (56-64)   edit #8fqrN6                                                 │
│Adding `pow` after `mul` with the exact signature you gave, plus one test.    │
│                                                                              │
│Enter: review each hunk    q: reject all                                      │
└──────────────────────────────────────────────────────────────────────────────┘

This is the brief: every hunk, the tool call that made it, and the reason the model gave. Press Enter to go through the hunks one at a time:

[1/2] src/lib.rs  (+11 -1)
hunk 1 (lines 18-31)
why: Adding `pow` after `mul` with the exact signature you gave, plus one test.

@@ -18,9 +18,14 @@ pub fn mul(a: i32, b: i32) -> Option<i32> {
     a.checked_mul(b)
 }

+/// Return `base` raised to the power `exp`.
+pub fn pow(base: i64, exp: u32) -> i64 {
+    base.pow(exp)
+}
+
 #[cfg(test)]
 mod tests {

(a)ccept  (r)eject  (c)omment  (e)dit  (s)kip  (q)uit

Press a to accept the first hunk. For the second, press c and type a comment:

comment for the model (Enter sends, Esc cancels):
> make the test check pow(2, 10) == 1024 only

A comment rejects the hunk and tells the model why. When the last hunk is decided, heph keeps what you accepted, sends your comment to the model, and the model takes another round. A second review opens with only the new change in it. Accept it, and the turn ends:

-- turn done, 1 file applied, $0.67

The private worktree now has pow and its test. Nothing you rejected is in it. Heph prepares the publication candidate, passes its final gates, and offers to commit the shown message to the conversation's branch in a dedicated dialog. Choose Yes (y) to publish immediately, Yes, but edit the message (e) to open your editor first, or No (n) or Esc to keep it private. The publication lock stays held while you answer and through the editor and commit. Both publication actions need no further gate pass unless upstream changed. Your checkout stays untouched unless it has that branch checked out.

What just happened

  1. Heph copied your project into a worktree of its own and pointed the model at that.

  2. The model read files silently and edited the copy; each edit was committed to heph's private history with the rationale as its message.

  3. A shell command stopped to ask you, and your a became a session-wide approval.

  4. Gates ran on the model's changes.

  5. You reviewed hunk by hunk; a comment sent the model another round inside the same turn.

  6. What you accepted became private conversation state. The commit offer lets you publish it now or later with /commit; your uncommitted checkout changes were never imported.

Press Ctrl-D to open the exit confirmation, then press it again to leave. The conversation is saved; the next heph in this directory opens it again with everything on screen.