SPB Git

spb/khaelor Public

KHAELOR — a terminal-native autonomous engineering agent powered by Anthropic.

TypeScript 82.9% HTML 14.9% CSS 1.1% JavaScript 0.7%
15.3 KB · 252 lines html
Raw Blame History
1<!doctype html>2<!--3KHAELOR4File: website/public/docs/usage.html5Description: The TUI in depth — composer, file mentions, shell mode, interruption, steering, tool presentation.6Author: Simon-Pierre Boucher7Contact: contact@spboucher.ai8-->9<html lang="en">10<head>11<meta charset="utf-8">12<meta name="viewport" content="width=device-width, initial-scale=1">13<title>The TUI — KHAELOR</title>14<meta name="description" content="KHAELOR's terminal interface in depth: composer, multiline editing, @ file mentions, ! shell mode, Esc interruption, steering while the agent works.">15<link rel="stylesheet" href="/styles.css">16<script>17(function(){try{var t=localStorage.getItem("khaelor-theme");if(!t&&window.matchMedia&&window.matchMedia("(prefers-color-scheme: light)").matches)t="light";if(t==="light")document.documentElement.setAttribute("data-theme","light");}catch(e){}})();18</script>19<script defer src="/site.js"></script>20</head>21<body>2223<header class="site-header"><div class="inner">24  <a class="wordmark" href="/"><span class="glyph">&#10095;</span><span class="g-ember">KHAELOR</span></a>25  <nav>26    <a href="/docs/getting-started.html">Docs</a>27    <a href="/#install">Install</a>28    <button id="theme-toggle" type="button" aria-label="Toggle color theme">light</button>29  </nav>30</div></header>3132<main class="page"><div class="docs-layout">3334<aside class="sidebar">35  <div class="group"><div class="group-title">Start</div>36    <a href="/docs/getting-started.html">Getting started</a>37    <a href="/docs/cookbook.html">Cookbook</a>38  </div>39  <div class="group"><div class="group-title">Using KHAELOR</div>40    <a href="/docs/usage.html">The TUI</a>41    <a href="/docs/commands.html">Commands &amp; keyboard</a>42    <a href="/docs/tools.html">Tools</a>43    <a href="/docs/sessions.html">Sessions</a>44  </div>45  <div class="group"><div class="group-title">Autonomy</div>46    <a href="/docs/phases.html">Phase gates</a>47    <a href="/docs/verification.html">Verification</a>48    <a href="/docs/worktrees.html">Parallel worktrees</a>49    <a href="/docs/daemon.html">The daemon</a>50  </div>51  <div class="group"><div class="group-title">Intelligence</div>52    <a href="/docs/repograph.html">Semantic index</a>53    <a href="/docs/memory.html">Project memory</a>54    <a href="/docs/context.html">Context engine</a>55    <a href="/docs/fork-replay.html">Fork · replay · sdiff</a>56  </div>57  <div class="group"><div class="group-title">Control</div>58    <a href="/docs/permissions.html">Permissions</a>59    <a href="/docs/configuration.html">Configuration</a>60    <a href="/docs/cli.html">CLI reference</a>61  </div>62  <div class="group"><div class="group-title">Internals</div>63    <a href="/docs/architecture.html">Architecture</a>64    <a href="/docs/events.html">The event model</a>65    <a href="/docs/theming.html">Theming &amp; terminal</a>66  </div>67  <div class="group"><div class="group-title">Help</div>68    <a href="/docs/faq.html">FAQ &amp; troubleshooting</a>69  </div>70</aside>7172<article class="content">7374<h1>The TUI</h1>75<p class="lead">KHAELOR is not a <code>&gt; prompt / AI: response</code> REPL. It is a modern76interactive computing environment built for the terminal — and this page is how to drive it.</p>7778<h2 id="layout">How the screen works<a class="anchor" href="#layout">#</a></h2>79<p>KHAELOR renders into your terminal's <strong>normal scrollback</strong>, like a well-behaved80CLI — not a full-screen alternate-screen app. Two zones:</p>81<ul>82  <li><strong>Settled content</strong> — finished messages, completed tool rows, your submitted83  prompts. Printed exactly once, never touched again. Native selection, copy, and terminal84  search work on all of it, and the transcript survives even if KHAELOR crashes.</li>85  <li><strong>Live region</strong> — a small strip pinned to the bottom (at most ~24 rows): the86  streaming tail of the current response, one agent status line, the composer, and the status87  bar. It is the only thing that ever repaints, in flicker-free synchronized frames.</li>88</ul>89<p>Consequences you will feel: no scroll jumps, no flicker, no layout destruction from long90output, and typing latency that stays under 16&nbsp;ms even while the model streams at full91rate. If you scroll up to read something, nothing yanks you back down — new content92accumulates below, exactly like <code>tail -f</code>.</p>93<p>The one full-screen exception is the <a href="/docs/commands.html#diff-viewer"><code>/diff</code>94viewer</a>, which behaves like <code>less</code>: enter, navigate, <kbd>q</kbd>, and your95conversation is untouched.</p>9697<h2 id="composer">The composer<a class="anchor" href="#composer">#</a></h2>98<p>The input line is a real editor, not a bare readline:</p>99<pre class="term" data-no-copy><code> <span class="t-accent">&#10095;</span> refactor <span class="t-accent">@src/session/store.ts</span> to journal events atomically,100   then run the tests</code></pre>101102<h3 id="multiline">Multiline editing</h3>103<ul>104  <li><kbd>Enter</kbd> submits. <kbd>Shift+Enter</kbd> or <kbd>Ctrl+J</kbd> inserts a newline105  (<kbd>Shift+Enter</kbd> works in terminals with the kitty keyboard protocol or106  modifyOtherKeys; <kbd>Ctrl+J</kbd> works everywhere; a trailing <code>\</code> before107  <kbd>Enter</kbd> also continues the line).</li>108  <li>The composer grows from one row up to a third of the screen, then scrolls internally.</li>109  <li>Full cursor movement: characters (<kbd>&larr;</kbd>/<kbd>&rarr;</kbd>,110  <kbd>Ctrl+B</kbd>/<kbd>Ctrl+F</kbd>), words (<kbd>Alt+&larr;/&rarr;</kbd>,111  <kbd>Alt+B</kbd>/<kbd>Alt+F</kbd>), line start/end (<kbd>Ctrl+A</kbd>/<kbd>Ctrl+E</kbd>),112  lines (<kbd>&uarr;</kbd>/<kbd>&darr;</kbd> inside a multiline buffer).</li>113  <li>Deletion: word back <kbd>Ctrl+W</kbd>/<kbd>Alt+Backspace</kbd>, word forward114  <kbd>Alt+D</kbd>, to line start <kbd>Ctrl+U</kbd>. Undo with <kbd>Ctrl+_</kbd>.</li>115  <li><kbd>Ctrl+G</kbd> round-trips the whole buffer through <code>$EDITOR</code> for heavy116  editing, then returns it to the composer.</li>117</ul>118119<h3 id="history">History</h3>120<p>Prompt history is per-project (50 entries, deduplicated, stored in121<code>~/.khaelor/prompt-history.jsonl</code>). <kbd>&uarr;</kbd> at the start of the buffer and122<kbd>&darr;</kbd> at the end navigate it — cursor-position-aware, so history never hijacks123multiline editing. <kbd>Ctrl+R</kbd> opens incremental history search.</p>124125<h3 id="paste">Paste intelligence</h3>126<p>Bracketed paste is handled structurally. A paste of three or more lines (or &gt;150127characters) collapses into a compact span — <code>&#9707; pasted 47 lines</code> — that expands128only at submit, so a big stack trace never wrecks your editing view. A paste that looks like a129file path becomes a file mention automatically.</p>130131<h2 id="mentions">@ file mentions<a class="anchor" href="#mentions">#</a></h2>132<p>Type <code>@</code> anywhere to fuzzy-search the repository (respecting133<code>.gitignore</code> and <code>.khaelorignore</code>), ranked by match quality and134frecency — files you touch often float to the top:</p>135<pre class="term" data-no-copy><code> <span class="t-accent">&#10095;</span> refactor @agent136            &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;137             src/kernel/agent.ts                 <span class="t-warn">&#9733;</span>138             src/agents/agent-runtime.ts139             tests/agent.test.ts140            &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;</code></pre>141<p>Selecting inserts a <strong>structured file reference</strong> — the agent's context engine142receives a reference to resolve intelligently, not a blind dump of the file's contents. Line143ranges are supported in the syntax: <code>@src/kernel/agent.ts:40-90</code>.</p>144145<h2 id="shell-mode">! shell mode<a class="anchor" href="#shell-mode">#</a></h2>146<p>Type <code>!</code> as the first character to run a shell command yourself, without147involving the model:</p>148<pre class="term" data-no-copy><code> <span class="t-warn">!</span> git status --short149150 <span class="t-dim">$ git status --short</span>151  M src/session/store.ts152 ?? notes.md153 <span class="t-dim">a — add output to context</span></code></pre>154<p>The prompt glyph switches to <code>!</code> (warning tint). Output prints into the155conversation as a settled block; press <kbd>a</kbd> immediately after to hand that output to156the agent as context — it never enters the model's context without your say-so. Shell mode157runs under the same <a href="/docs/permissions.html">permission rules</a> as the agent's own158<code>bash</code> tool.</p>159160<h2 id="status">Knowing what the agent is doing<a class="anchor" href="#status">#</a></h2>161<p>One compact status line above the composer tracks the agent's real state —162<em>thinking &middot; reading &middot; searching &middot; editing &middot; running &middot;163waiting &middot; verifying &middot; idle</em>:</p>164<pre class="term" data-no-copy><code> <span class="t-accent">&#9679;</span> Searching repository <span class="t-dim">&middot; 2.3s</span>165 <span class="t-accent">&#9679;</span> Editing src/kernel/agent.ts166 <span class="t-accent">&#9679;</span> Running npm test <span class="t-dim">&middot; 41/148</span>167 <span class="t-accent">&#9679;</span> Waiting for permission</code></pre>168<p>Every element is real data: elapsed time is a real timer; counts like <code>41/148</code>169appear only when a tool's output actually contained them. There are no fake spinners and no170invented percentages, ever. When idle, the line disappears entirely.</p>171172<h3 id="tool-rows">Tool call presentation</h3>173<p>Each tool call settles into one collapsed line — enough to audit, quiet enough to ignore:</p>174<pre class="term" data-no-copy><code> <span class="t-dim">&#9656;</span> Read <span class="t-b">src/kernel/agent.ts</span> <span class="t-dim">&middot; 212 lines</span>175 <span class="t-dim">&#9656;</span> Search <span class="t-b">"ContextEngine"</span> <span class="t-dim">&middot; 14 matches</span>176 <span class="t-dim">&#9656;</span> Edit <span class="t-b">src/context/engine.ts</span> <span class="t-dim">&middot; +31 −12</span>177 <span class="t-dim">&#9656;</span> Run <span class="t-b">npm test</span> <span class="t-dim">&middot;</span> <span class="t-ok">passed</span> <span class="t-dim">&middot; 4.2s</span></code></pre>178<ul>179  <li><kbd>Ctrl+T</kbd> cycles detail on the currently-running tool (collapsed &harr; a rolling180  12-line tail of its output).</li>181  <li><kbd>d</kbd> (with an empty composer) prints the diff of the most recent edit.</li>182  <li>Very long output is truncated head/tail with an explicit marker; the full output is saved183  to a file whose path is shown — nothing is silently lost.</li>184</ul>185186<h2 id="interruption">Interruption — <kbd>Esc</kbd><a class="anchor" href="#interruption">#</a></h2>187<p>Press <kbd>Esc</kbd> at any moment. Acknowledgment is immediate — the status line flips to188<code>&#9678; Stopping&hellip;</code> in the same frame — then cancellation propagates cleanly189through the model stream, any in-flight tools, and the agent loop:</p>190<pre class="term" data-no-copy><code> <span class="t-dim">&#9656;</span> Run <span class="t-b">npm test</span> <span class="t-dim">&middot; cancelled &middot; 3.2s</span>191 <span class="t-dim">&#9678; Interrupted — partial response kept</span></code></pre>192<p>The session is never corrupted by an interrupt: partial output is kept and marked, and193background processes you started (dev servers, watchers) are deliberately left running.194<kbd>Esc</kbd> with an overlay open closes the overlay instead; with text in an idle composer195it clears the current completion/selection first.</p>196197<h2 id="steering">Steering while the agent works<a class="anchor" href="#steering">#</a></h2>198<p>The composer never locks. Type while the agent is mid-task and press <kbd>Enter</kbd> —199your message is queued and injected at the next safe boundary between tool calls:</p>200<pre class="term" data-no-copy><code> <span class="t-dim">&#9656;</span> Run <span class="t-b">npm test</span> <span class="t-dim">&middot; running 8s</span>201202 <span class="t-warn">&#8943;</span> Queued — use the smaller fixture instead203   <span class="t-dim">Esc cancel run &middot; Ctrl+U discard queued</span></code></pre>204<p>Queued messages show with the <code>&#8943;</code> marker until injected, then settle into the205transcript as normal user messages. Multiple queued messages stack in order. <kbd>Ctrl+U</kbd>206with an empty composer discards the most recent queued message. This is how you course-correct207without killing a run: <em>"skip the lint step"</em>, <em>"target Node 22"</em>,208<em>"that file is generated, edit the template instead"</em>.</p>209210<h2 id="statusbar">The status bar<a class="anchor" href="#statusbar">#</a></h2>211<p>One dim row at the very bottom — persistent, never animated:</p>212<pre class="term" data-no-copy><code> <span class="t-dim">main +4 −1  │  claude-sonnet-4-5  │  context 31%  │  $0.42  │  &#9679; 2</span></code></pre>213<table>214  <tr><th>Segment</th><th>Meaning</th></tr>215  <tr><td><code>main +4 −1</code></td><td class="wrap">Git branch and dirty-file counts, live.</td></tr>216  <tr><td><code>claude-sonnet-4-5</code></td><td class="wrap">The session's model (shortens to an alias on narrow terminals).</td></tr>217  <tr><td><code>context 31%</code></td><td class="wrap">Real context-window utilization. At &ge;80% it tints and suggests <code>/compact</code>.</td></tr>218  <tr><td><code>$0.42</code></td><td class="wrap">Session cost from actual API usage metadata.</td></tr>219  <tr><td><code>&#9679; 2</code></td><td class="wrap">Running background processes.</td></tr>220  <tr><td><code>&#8943; 1 queued</code></td><td class="wrap">Queued steering messages, when any.</td></tr>221</table>222<p>Segments with no real data are absent, not zeroed. On narrow terminals, lower-priority223segments drop whole rather than truncating.</p>224225<h2 id="accessibility">Color, monochrome, accessibility<a class="anchor" href="#accessibility">#</a></h2>226<ul>227  <li>One calm default theme (dark), with an automatic light variant when your terminal228  background is detected as light.</li>229  <li><code>NO_COLOR</code> and <code>TERM=dumb</code> are honored absolutely. State is never230  conveyed by color alone — every state pairs a symbol or a word: <code>&#10003;</code> done,231  <code>&#9656;</code> tool, <code>&#9679;</code>/<code>&#9675;</code> running/stopped,232  <code>&#8943;</code> queued, <code>&#9678;</code> interrupted, <code>failed</code>/<code>passed</code>233  spelled out.</li>234  <li>Keyboard-only use is complete — there is nothing that requires a mouse.</li>235</ul>236237<div class="pager">238  <div><span class="label">Previous</span><a href="/docs/getting-started.html">&larr; Getting started</a></div>239  <div class="next"><span class="label">Next</span><a href="/docs/commands.html">Commands &amp; keyboard &rarr;</a></div>240</div>241242</article>243</div></main>244245<footer class="site-footer"><div class="inner">246  <span>KHAELOR — Simon-Pierre Boucher &middot; <a href="mailto:contact@spboucher.ai">contact@spboucher.ai</a></span>247  <span>Anthropic-powered &middot; terminal-native by design</span>248</div></footer>249250</body>251</html>252