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#

CommandAction
/sessionsBrowse this project's sessions; Enter resume, n new, r rename, x delete, / filter
/resumeResume the most recent session
/newStart a fresh session in the same project
/renameRename the current session
/clearClear 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/a in 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 /diff shows 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 to ask.
  • 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:

CommandWhat it does
/forkPick 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.
/replayRe-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.
/sdiffStructured 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.