Sessions
Every KHAELOR session is an append-only event log. Nothing is "saved" as an afterthought — the log is the session, and resume is simply replay.
The event log#
Everything that happens flows through a typed event bus and is journaled to a JSONL file as it happens: your messages, model responses, every tool request, every permission decision, every file read and modification, process starts and exits, compaction checkpoints. This design buys you:
- Crash safety — there is no unsaved state to lose; the journal is written event by event, atomically.
- Faithful resume — replaying the log reconstructs the transcript, the cost accounting, and the agent's file-state tracking (which files it has read, and whether they changed externally since).
- A real audit trail — for any action KHAELOR ever took, you can reconstruct what was requested, which permission rule matched, and who granted it.
- Durable prompts — a permission request that was pending when you quit reappears when you resume. Silence is never treated as consent, even across restarts.
Session metadata#
Each session carries: id, title (auto-derived from your first request, or set with
/rename), project, created/updated timestamps, model, token usage, cost, git
branch, and working directory. All of it is real recorded data — the costs in the session
picker are the actual API-metered costs.
Managing sessions#
| Command | Action |
|---|---|
/sessions | Browse this project's sessions; Enter resume, n new, r rename, x delete, / filter |
/resume | Resume the most recent session |
/new | Start a fresh session in the same project |
/rename | Rename the current session |
/clear | Clear the conversation and working context |
┌─ sessions · ~/dev/my-project ───────────────────────────┐
❯ retry logic in session store 12m ago $0.42 main
context compaction checkpoint 2h ago $1.13 main
initial TUI scaffolding 1d ago $2.87 tui/shell
└────────────────────────────────────────────────────────┘
↑↓ select · Enter resume · n new · r rename · x delete · / filter · Esc
Starting khaelor in a project with an interrupted session adds exactly one
quiet line under the banner — Interrupted session from 12 min ago · /resume to
continue — never an auto-resume, never a modal.
Context management and compaction#
Long sessions eventually press against the model's context window. KHAELOR watches real
token pressure (the status bar's context 31% segment) and, before the window
becomes dangerous, distills the older conversation into a structured
checkpoint:
objective: ...
completed: [...]
current_state: ...
important_files:
- path: ...
reason: ...
failed_attempts: [...]
decisions: [...]
running_processes: [...]
next_steps: [...]
Raw evidence that would be destroyed by summarization — exact error messages, key diffs —
is preserved alongside. Compaction is designed to be invisible unless you look:
/context shows the checkpoint and the full token budget breakdown;
/compact triggers it on your schedule. At ≥80% utilization the status bar
nudges you toward /compact; at ≥90% it turns urgent.
Cost tracking#
Every model response's usage metadata — input tokens, output tokens, cache writes, cache
reads — is recorded in the event log as it arrives. /cost aggregates it;
the status bar shows the running total. Two honesty rules:
- Numbers come only from actual API usage metadata. KHAELOR never estimates token counts.
- If pricing for your configured model is unknown, you get real token counts and an honest
n/ain the dollar column — never an invented figure.
Cache reads are shown with their hit rate, because prompt-cache health is where most of your money goes: KHAELOR keeps its prompts byte-stable specifically to maximize cache hits.
Git awareness and protecting your work#
- KHAELOR records the git baseline when the session starts, so
/diffshows only what KHAELOR changed — your pre-existing uncommitted work is never mixed in or attributed to the agent. - It never auto-commits. Git mutations (
commit,push,reset, …) go through permissions and default toask. - Files you edit outside KHAELOR while a session runs are protected by external-modification detection — the agent must re-read before touching them.
Fork, replay, sdiff#
Because resume is a replay of the JSONL, three operations come almost for free — and turn sessions into a comparison instrument no other CLI agent offers:
| Command | What it does |
|---|---|
/fork | Pick a checkpoint (any user turn, approved design, or context checkpoint) and branch the session there. The JSONL prefix is copied into a fresh session with a meta.json recording parent and forkPoint; KHAELOR opens the fork immediately. |
/replay | Re-run another session's user turns with the current model, inside a throwaway git worktree so re-executed tool calls have zero side effects on your working copy. |
/sdiff | Structured diff between two runs: agent turns, tool calls, files modified, tokens in/out, cache reads, verify failures, outcome — plus which files each run touched exclusively. |
sdiff
01J8K2… (sonnet) 01J8K9… (haiku)
agent turns 12 17
tool calls 34 61
files modified 2 3
tokens (in/out) 145.0k / 12.0k 210.0k / 19.0k
verify failures 0 2
outcome completed completed
files only in B: src/c.ts
Run it twice, diff the runs — the cheapest honest model comparison you can do.
Where sessions live#
Session logs are stored under ~/.khaelor/sessions/ as plain JSONL — one event
per line, inspectable with standard tools. Associated artifacts (spilled tool output, process
logs) live beside them under ~/.khaelor/tool-output/ and
~/.khaelor/process-logs/, garbage-collected when sessions are deleted and capped
in total size. Deleting a session from /sessions removes its log and artifacts.