Abhed — CLI & Product Surface

Status: Draft · 2026-09-02 · Evidence status: [E]

The architecture makes Abhed work; this document is what makes it feel like a tool an engineer wants to use. These decisions are not cosmetic — approval friction, output density, and interrupt latency determine whether people actually adopt the agent.

1. Interaction model

$ abhed
╭─ abhed ─────────────────────────────── qwen3-32b · ~/proj · main ─╮
│                                                                    │
│  > fix the failing auth tests                                      │
│                                                                    │
│  ● Searching for test files                                        │
│    grep "auth.*test" → 3 files                                     │
│  ● Reading auth_test.go                                            │
│  ● Running tests                                                   │
│    bash go test ./pkg/auth  →  FAIL (2 failures)                   │
│                                                                    │
│    TestLogin_ExpiredToken: expected 401, got 500                   │
│    TestLogin_Refresh:      nil pointer at auth.go:88               │
│                                                                    │
│  ● Reading auth.go                                                 │
│  ● Edit auth.go                                                    │
│    ╭────────────────────────────────────────────────╮              │
│    │ 86    if tok == nil {                          │              │
│    │ 87  -     return nil, err                      │              │
│    │ 87  +     return nil, ErrTokenMissing          │              │
│    │ 88    }                                        │              │
│    ╰────────────────────────────────────────────────╯              │
│    [a]ccept  [r]eject  [e]dit  [A]lways for this file              │
╰────────────────────────────────────────────────────────────────────╯

Design rules

  1. Show work as it happens. Streaming, not a spinner then a wall of text. The user must be able to interrupt early when the agent goes wrong — which it will.
  2. One line per tool call, expanded only on failure or when it carries information the user needs. Verbosity is the default failure mode of agent CLIs.
  3. Diffs before writes, always. The approval prompt shows exactly what changes with surrounding context. Never "Claude wants to edit auth.go — allow?"
  4. Esc interrupts immediately. The running tool is cancelled, partial work is preserved, and the session stays alive. A tool that can't be interrupted will be killed with Ctrl-C, losing the session.
  5. Errors are shown, not swallowed. A failing test is information, displayed plainly.

2. Permission prompts

Per P7, the ordered evaluation decides whether to ask; this is how to ask.

  ● bash  npm install --save-dev vitest
    Adds vitest as a dev dependency
    [a]ccept  [r]eject  [A]lways allow `npm install *`  [?] explain

Batch related approvals. Five edits to one file in one plan = one prompt with five diffs. Prompt fatigue causes blanket-approve, which defeats the permission model entirely.

3. Modes

ModeBehaviorUse
defaultAsk before mutationsEveryday work
accept-editsAuto-approve file edits; ask for bashTrusted refactors
planRead-only; produce a plan, no mutationsExploring an approach
autoApprove by classifier + rules; hard blocks standBatch/CI
restrictedManaged policy, bypass disabledRegulated tenants

Deny rules and destructive-command blocks apply in every mode including auto (P7). bypass exists but is refusable by org policy and blocked when running as root.

4. Slash commands

CommandEffect
/mode <name>Switch mode — implemented
/compact [hint]Compact now, optionally guided — implemented
/costTokens, cache hit rate, prefill saving, compactions — implemented
/sessionsList recent sessions (durable store) — implemented
/resume <id>Replay a prior session's transcript — implemented
/cwdShow the workspace root — implemented
/undoRevert the last turn's file changes — implemented
/diffFiles changed this session, with line counts — implemented
/clearClear context, keep the workspace — implemented
/memoryShow the ABHED.md files in effect — implemented
/model [name]Show or switch the configured provider — implemented
/export [path]Write the transcript to JSON — implemented

/resume replays a session recorded by any process, including one from before a restart, because state is event-sourced and the store is durable.

/undo reverts a whole turn, not one file: a model that edits four files to make one change should undo as one change. Within a turn only the earliest checkpoint per file is applied, so repeated edits still revert to the pre-turn state. Undoing a file the agent created deletes it rather than emptying it.

Checkpointing hangs off tools.Session.Checkpoint rather than living in each tool, so a future mutating tool gets undo by construction and cannot forget to call it.

/model deliberately does not hot-swap mid-session: a different model means a different prompt prefix, which would invalidate the cache the whole context design depends on (P8).

5. Web console

Same event stream (P6), different affordances. Not a second implementation of the loop.

6. Headless and CI

abhed -p "fix failing tests" --output-format json --max-turns 30
abhed -p "review this diff" --mode plan --allow "bash(git *)"

7. Latency budget

What the user actually feels:

InteractionTargetWhy
Keystroke → echo< 16 msLocal; never blocked on the model
Submit → first token< 1.5 sPrefix cache hit makes this achievable (P8)
Tool call → result shown< 100 ms overheadBeyond the tool's own runtime
Esc → cancelled< 200 msTrust depends on this
Session resume< 500 msEvent replay from store

A prefix-cache miss shows up directly as time-to-first-token. The eval report's cache-hit metric (§08) is a user-experience metric, not just a capacity one.