All notable changes to Klaat Code are documented here. Format follows Keep a Changelog; versions follow SemVer.
- Code graph, everywhere. Your project is indexed into a local code graph (tree-sitter quality, all plans including free) and the agent navigates with it instead of grepping around:
project_graph_queryanswers "where is X / what calls Y" with exact file:line,file_outlinereads a file's structure for ~10% of the tokens,read_file symbol="Name"serves exactly one definition,impact_checkshows the blast radius before an edit, andplan_explorationreturns the optimal read order for a task. Directory listings append a graph outline (top symbols per file, community labels). Markdown docs are indexed as heading sections, so READMEs and plans are searchable too./graphopens an interactive force-graph of the whole project in your browser — communities colored, god nodes sized, search and legend filters. - Cross-session memory — the agent learns you. Every few turns a background pass distills durable facts into
~/.klaatai/memory/: project memory (commands that worked, conventions, decisions, corrections) and user memory (how you like to work). Both load at session start, so the next session already knows "uses bun not npm" and never repeats a correction you already made./memoryviews,/memory updateforces a pass,/memory clearforgets, and/memory graphrenders your persona as a labeled graph in the browser. Shared with the VS Code extension — teach the terminal, the editor remembers. - Skills — reusable playbooks with progressive disclosure. Drop a
SKILL.mdin.klaatai/skills/<name>/(project) or~/.klaatai/skills/(global) and the agent follows it whenever a task matches: only name + description ride in the prompt; the body loads on demand. Invoke directly with/<name> [args](autocompleted in the/strip), list with/skill, create with/skill new. Interops with the open skills ecosystem: repos installed vianpx skills add <repo>(the cross-agent.agents/skills/convention, YAML folded-block frontmatter, Claude Code.claude/skills/) are discovered from any subfolder of the repo.
- Windows, seriously.
run_commandand every other shell site now usecmd.exeinstead of spawning a nonexistentsh(commands ran nowhere and turns died mid-sentence); grep is in-process JavaScript, so a missing grep binary can no longer masquerade as "No matches found"; the write sandbox no longer misjudges cross-drive paths; protected system paths (C:\Windows, Program Files) are properly refused. - Stuck text and garbled UI. Wide (CJK/emoji) glyphs could leave permanently stuck fragments on screen when overlapped by other UI — the renderer now breaks wide-glyph pairs correctly. Skill invocations show a compact
/nameline instead of dumping the whole playbook into the transcript. - Compaction correctness. The post-compaction tail can no longer start with orphaned tool results (a provider-rejection class of failure), and every compaction summary carries a cumulative list of files touched — after any number of compactions the agent still knows every file it worked on all session.
- Graph queries answer natural language. Multi-word queries ("authentication auth login session token") fall back to per-keyword scoring instead of one exact-phrase match that found nothing.
- Honest reads. One
read_filecall returns up to 1000 lines; descriptions no longer invite the model to page through files in 100-line slices, and duplicate overlapping reads are short-circuited with an honest notice.
multi_editno longer dies on redundant sub-edits — if one edit in a batch has identicalold_stringandnew_string, it is skipped and the rest apply. Previously a single no-op edit (e.g. 1/12) aborted the whole batch and stalled the turn.- Rate-limit drops retry instead of killing the turn — a 429 mid tool-loop now waits for the server's
retry_after(capped at 30s) and auto-retries once, instead of falling through to a fatal error. - Stream errors no longer leave raw
<tool_call>XML on screen — partial output from a dropped stream is masked the same way as live streaming, so a mid-block disconnect can't leave tool XML as the visible answer. - Exploration promises get the same nudge as action promises — "Let me read the rest of the file" with no tool call is now detected and nudged (read/check/inspect/search verbs), not only "I'll fix it" style promises.
- Update on launch —
klaatcodenow checks for a newer release at startup and asksUpdate now? [Y/n]before doing anything else. Answer yes and it upgrades through whichever channel installed it, then relaunches with your original arguments; answer no and it won't ask again for that release. The check is cached 4h and fail-silent, so being offline never delays a launch.- Skipped automatically in CI and any non-interactive shell (one stderr line instead of a prompt), and with
--no-update-checkorKLAATAI_NO_UPDATE=1. - Verified upgrades. A zero exit code is no longer taken as proof: the CLI asks the installed binary for its version, and detects when a second copy on
PATH(Homebrew over npm, or a leftoverklaatcode-ai1.x binary) is still winning. - Repair fallback. If the upgrade fails or the version doesn't move, it runs a clean uninstall + reinstall for that channel — including removing the retired
klaatcode-aipackage — and prints exact manual commands if that still doesn't work. It never leaves you without a working CLI. - Minimum supported version.
klaatai.com/api/latestnow serves aminSupportedfloor; below it the update is required rather than optional, and the server can refuse very old builds with an upgrade instruction. Bypass withKLAATAI_SKIP_VERSION_GATE=1at your own risk.
- Skipped automatically in CI and any non-interactive shell (one stderr line instead of a prompt), and with
- Install identity headers — every request now reports client version, platform (
darwin-arm64), install channel, and a random install id stored in~/.klaatai/install-id, so we can see how many installs are live and which builds are still in the wild. The id is not derived from your machine and carries nothing about your project — no paths, repo names, or prompt content. Opt out withKLAATAI_TELEMETRY=0,DO_NOT_TRACK=1, or"telemetry": "off"in~/.klaatai/config.json; version and platform still travel so the server can refuse unsupported builds. See the README for the full table.
- Version alignment — ensures
klaatcode --versionreports2.4.2on every install channel (npm, curl/PowerShell installer, Homebrew). No functional changes beyond 2.4.1; use this release to verify you are on the current build.
-
Headless exec contract (
klaatai runfor CI/automation) —runis now a real agentic loop (tools, multi-round) with a machine-facing contract, so scripts and CI can drive it reliably:--jsonemits a JSONL event stream (start/tool/turn/cost/result) instead of prose.--output-schema <file>forces the final answer to match a JSON Schema (validated client-side, one corrective retry, exit 2 on mismatch) — reliable structured output that's model-agnostic (no server support needed).--output-last-message <file>writes just the final answer/JSON to a file.--allow-tools <spec>bounds autonomy by category (read,edit,shell,search,web,all,none) or explicit tool name;--no-toolsis pure chat;--max-turns <n>caps rounds.- Deterministic exit codes:
0ok ·1auth/error ·2task failed (or schema mismatch) ·3--max-costreached ·4needed approval. - Ships a composite GitHub Action (
.github/actions/klaatai) that installs the CLI and passes the API key by env only (never a CLI arg, so it can't leak into process listings or tool output). All server-side unchanged — same/v1/chat/completions. Contract logic (schema validation, JSON extraction) unit-tested insrc/agent/headless-contract.test.ts.
-
Proof-of-work verification (
/verify+ auto) — the agent can now prove an edit works instead of just claiming it./verifydetects the project's typecheck + test commands (Bun/Vitest/Jest/pytest/Go/Cargo/npm;tsc --noEmit,cargo check, or atypecheckscript), runs them, and posts a pass/fail receipt:✓ Verified — ✓ typecheck · ✓ Bunor✗ Verification failed …with the actual error. Pairs with the cost receipt — every turn can now show both what it cost and that it works.- Auto mode with an in-CLI picker —
/verify autoopens a selector (Off / Types only / Full) that saves straight to config, no hand-editing. When on, verification runs after any turn that edits files. - No false blame — auto mode correlates failures with the files the turn actually touched. A project that was already failing typecheck reads as "✓ your changes look clean — issues only in files you didn't touch (pre-existing)", and only genuinely introduced failures are fed back to the agent to fix. (Fixes the first-run experience of pointing it at a repo with pre-existing errors.)
- Detection, summary, and failing-file extraction are unit-tested (
src/agent/verify.test.ts).
- Auto mode with an in-CLI picker —
-
Time travel (
/rewind, Esc-Esc) — press Esc twice on an empty prompt (or run/rewind) to fork the conversation at any earlier message: the transcript and API history truncate to that point, every file the rewound turns modified is restored to its pre-turn state (new files are removed; per-turn pre-write snapshots are captured automatically, including subagent writes), the session file is rewritten so resume follows the new branch, and your original message lands back in the input for editing. The picker shows each message with how many files a rewind would restore.
-
Mid-stream stall no longer hangs the turn forever — the client already salvaged a socket error, but a silent stall (socket stays open, zero bytes — a load balancer holding the connection or a hung model) left
reader.read()pending indefinitely with no spinner progress and no way out but Ctrl+C. An idle watchdog now races each read: the first body read gets a generous allowance (buffered reason/heavy/titan tiers send nothing until the whole completion is ready), and once streaming begins a 90s gap between chunks is treated as a stall — routed into the existing salvage path (partial output preserved) and surfaced as a transient error, which the turn auto-retries once. Deterministic (no cancel/reject race). Configurable viaidleTimeoutMs. -
Timeout / dropped-connection UX — a mid-turn stream error no longer dumps a raw red
Error: Timed out waiting for the model to respond. Transient drops (timeout, network, 502/503/504) now auto-retry once silently; if it still fails, any partial answer that already streamed is preserved, the message is friendly and actionable ("Your message is still here — press Enter to resend"), and your text is put back in the composer for a one-key resend. Buffered tiers (reason/heavy/titan, which hold the whole completion server-side until the A2 streaming deploy) now get a 180s first-byte timeout instead of the 45s default, so long turns stop timing out in the first place. -
Raw
<tool_call>XML never reaches the screen — some cheap-tier models emit tool calls as literal<tool_call><function=write_file>…text instead of a real tool call. Previously that XML streamed straight into the transcript as if it were the answer, and if the stream dropped before it finished, the turn ended with the block on screen and nothing executed. The stream renderer now withholds output from the moment a tool-call opener appears (including openers split across tokens) and releases only the safe remainder, so a leak can no longer masquerade as the reply. Server-side parsing still converts the block into a real tool call, so the work actually runs. (Paired with a server fix that stops these models from taking the live-streaming path at all.) -
"I'll fix it now" no longer ends the turn without doing anything — a round that announced work but called zero tools used to be treated as the final answer, so the agent would promise a fix, stop, and repeat the same promise every time you re-asked. Such a round is now detected and nudged to act (up to twice per turn), the narration is kept, and the model is reported to routing health (
promised_action_no_tool_call) so the router learns which models narrate instead of working. Skipped in plan mode, when tools are unavailable, and when the message ends in a question (a genuine hand-off to you). -
Weak-model "I can't run commands" denials — some cheap-tier models occasionally claim they have no filesystem/shell access despite receiving tool schemas. Three-layer fix: the system prompt now explicitly forbids that claim, the response is auto-detected and reported to routing health (
tool_validationfeedback, so the model demotes server-side), and the user gets an immediate hint (retry or/tier code). Side-channel calls (/btw,/advisor) also no longer overwrite the main conversation's tier/model state, which could subtly shift the dialect and window between turns. -
Clipboard image paste now "just works" — the ctrl+v machinery existed but the common flows missed it: cmd+v with an image-only clipboard produces an empty terminal paste on many emulators (now falls through to the OS clipboard image reader automatically), Finder/Explorer copies that paste as
file://URLs are now resolved, and a new/pastecommand covers terminals that swallow ctrl+v entirely (Windows Terminal, some tmux setups). Input placeholder now advertises the shortcut.
- repl.ts split, step 1 — the pure presentation helpers (cost/label formatting, tier-clamp parsing, shell/path syntax highlighting, rotating status verbs and tips) moved to
src/screens/repl-format.ts, which is now independently unit-tested (repl-format.test.ts). No behavior change; first safe slice of the Phase 0.3 decomposition. The deep-closure functions (render/handleSlashCommand/sendMessage) remain in place pending the dedicated ReplContext refactor.
- Requires the Klaatu gateway deployed 2026-08-03 or later for the server half of the tool-call XML fix and the timeout guards. Check with
curl https://api.klaatai.com/health— thebuildfield now reports the serving commit. - Verify an install actually carries this release:
klaatcode --versionreports2.4.1. (2.4.0 shipped as two different builds under one version string; that is what this bump fixes.)
- Cost receipt on every turn — the end-of-turn summary now carries the money:
Read 3 files · 2 edits · ran 2 commands · $0.033 · saved $0.29 vs frontier · 34s(frontier baseline = titan rates on the same tokens)./costgains a "Last turn (receipt)" block: cost, per-tier request mix, tokens in/out (+cached), duration. Pinning a premium tier (/tier reason|heavy|titan) shows an honest pre-flight estimate before the turn runs; auto-routed turns are never estimated (the server picks the tier per request, so a number would be a guess). - Side-channel accounting —
/btwand/advisorresponses now register in session accounting: request count, per-tier tally,/whymetadata (served model/tier), quota snapshot, and cost computed from the tier the server actually served (was hardcoded to the requested tier). Previously they were invisible — sidebar showed zero requests and/whysaid "No request made yet" after a successful consult. /advisorheavy-tier timeout fix — heavy responses are still server-buffered until the A2 deploy, so the consult now uses a 120s response-header timeout (connectTimeoutMsoption onchatStream) instead of the 45s default that made it fail with "Timed out waiting for the model"./advisor(Oracle-style consult) — one command escalates to the heavy tier for a senior-engineer review of the current approach: it reads a condensed transcript, streams sharp guidance into an⚖ advisorblock, and feeds the advice back into the conversation so the main agent applies it next turn./advisor <specific question>to direct it./security-review— security-focused preset over/review(injection, authz, secrets, SSRF, deserialization, traversal, XSS, races, dependency risk)./add-dir <path>— session-scoped extra working directory: extends the write sandbox and informs the agent./btwside channel — ask a quick side question any time, even mid-turn: answered immediately on the fast tier in its own↷ btwtranscript block, streaming live. The main conversation, its context, and the running turn are completely untouched (nothing entersapiMessages).- Type while the agent works (steering + queue) — input stays live during a turn; Enter queues the message, and non-slash messages are injected into the running turn at the next round boundary so the model course-corrects mid-task (Claude Code-style). Slash commands and leftovers run in order after the turn. Queued items show as
↳ queuedchips; Esc interrupt clears the queue. - /review presets —
/review(uncommitted),/review base <branch>(branch vs merge-base),/review commit <sha>,/review <ref|range>, or/review <free text>as a custom focus. Findings ordered by severity. - Terminal notifications — OSC9 + bell when a >15s turn finishes or the agent needs approval, so you can tab away.
notifications: "off"in config disables. - Layered AGENTS.md discovery — global
~/.klaatai/AGENTS.md, then git root → cwd chain (per-dir first match of.klaatai/rules.md→AGENTS.md→CLAUDE.md), concatenated root-first with closer files winning, capped at 32KiB. Matches the emerging industry semantics. - Durable command rules on "always allow" — approving a command with "always" now stores a two-token prefix rule per chained sub-command (
bun test *,git push *) instead of the exact string, so the next variation doesn't re-prompt.
/reviewargument injection closed — ref arguments are validated (no leading-, ref-safe charset) before reaching git argv; flag-like or multi-word input is treated as a review focus and never touches git (blocks e.g./review --output=<file>).- Terminal notification sanitization — OSC9 payloads strip C0/C1 control characters and DEL, so no message content can smuggle further escape sequences.
- Shell-chain permission bypass fixed — allowlist patterns like
cat *previously glob-matched the whole command string, socat x; sudo rm -rf /auto-passed. Commands are now split on&&/||/;/|(quote-aware) and every sub-command must pass the allowlist on its own; commands with redirects/substitution/backgrounding are opaque and only match exact allowlist entries. Deny list checks both the whole string and each sub-command. Covered by newsrc/permissions/index.test.ts.
- TUI froze during long shell commands — foreground
run_command(andgrep) usedspawnSync, which blocks the entire event loop: no spinner, no rendering, no Esc until the command finished (up to its timeout). Both now run async with a 10MB output cap; the UI stays live and animated throughout. - Esc now actually stops running commands — interrupt kills the whole process group (not just
sh, whose orphaned children previously kept the pipe open and the round hung until their natural exit). Kill latency measured ~300ms; the tool result is marked[killed …]so the model knows. - Auth refresh can no longer hang or force needless re-login at boot — the Supabase refresh call now has an 8s timeout, and a network failure (offline/slow) falls back to the stored access token instead of returning null and triggering browser OAuth; only a genuinely rejected refresh token (4xx) demands re-login. The 401 recovery path retries once online.
- Instant startup — boot no longer blocks on a network ping gate (up to ~27s on flaky networks) or artificial splash delays (~1.5s of
sleeps on every launch). The REPL opens immediately after credential load; connectivity is probed in the background and surfaces as a status-bar badge (· connecting…/⚠ offline — retrying, auto-retry every 10s).
- Live tool group — running tool calls now appear in the transcript the moment they start, as one Claude Code-style aggregate line with a pulsating dot ("● Reading 1 file, running 2 shell commands…") and a ⎿ detail line per call. Calls leave the group and become normal ⏺ result rows as each one finishes.
- Claude-style busy status line — the input-area status now shows the real activity ("Reading 1 file, running 2 shell commands… (1m 40s · ↓ 6.2k tokens) · esc to interrupt") instead of a bare whimsy verb; the redundant footer "esc interrupt" line is merged into it.
grepnow skips node_modules/.git/dist/lockfiles/tsbuildinfo by default. - Session counters survive resume — a cumulative usage snapshot (requests, tokens, cost) is appended to the session file each turn; resuming restores the sidebar Session block instead of showing zeros.
- Turn activity summary — after a multi-tool turn, one dim line tallies the work:
Read 3 files · 2 edits · ran 2 commands · 34s. - Background shell badge — the status bar now shows running background shells (
⚙ N bg shells) alongside the existing bg-agent badge, with an animated spinner while any background work is live. - Path-guessing guard — "File not found" errors from read/edit tools now include a listing of the nearest existing directory plus an explicit "do not guess" instruction, and the system prompt forbids reading paths never seen in a listing/search result (kills the observed loop of models inventing conventional paths like
src/app/dashboard/page.tsxand retrying variations). MCP tools that overlap with built-ins are now explicitly deprioritized in the prompt. - Context meter survives resume — after
/resume(orklaatcode -r) the context gauge shows an estimate of the restored transcript instead of 0; the server's real count replaces it on the first request. MCP tool names render asmcp:server toolinstead ofMcp__server__tool. - Session self-awareness — the agent now knows who is logged in (account email, backend URL, CLI version, from the Environment block) and answers "what account am I connected to?"-style questions directly instead of exploring the project's .env/config files. New
/whoamislash command shows account, plan, backend, version, and connectivity.
- Windows
klaatcode upgrade— PowerShell/curl installs no longer try to replaceklaatcode.exewhile it is running (the cause of silentUpgrade command failedon v2.3.2–2.3.4). Upgrade now spawns a detached helper that waits for the current process to exit, then runs the install script. npm global upgrades run throughcmd.exe(barespawnSync("npm")fails on Windows). Also detects.bunglobal installs. - CI unit tests —
acp/agent.test.tsmock no longer breakschatStreamsocket-drop tests inapi/client.test.ts.
- Session resume freeze after first message —
klaatcode -rcould lock up after the first reply (no typing, scroll, or Ctrl+C). The pre-boot session picker left a stdin listener attached; the first Enter in the TUI re-ran cleanup and disabled raw mode. The picker now detaches cleanly on exit. - Resume forked a duplicate session — continuing a resumed chat wrote a new
.jsonlinstead of appending to the original. Resume now keeps the original session id/file and restores server session affinity. - Permission card Esc was a no-op — Esc advertised as “deny” did nothing while the card was up (specific Escape handler blocked the catch-all). Esc now denies / dismisses permission and budget-pause cards.
- Mid-stream socket drops — Bun’s “socket connection was closed unexpectedly” no longer kills the turn with a raw error; partial output is kept when possible, and connect waits have a headers-only timeout.
- Faster
-r//sessions— session previews stop at the first user message instead of parsing entire transcripts (large sessions no longer stall startup).
- Tier picker UX — wider professional layout, aligned descriptions that no longer bleed past the border, current tier marked with ✓ and focused on open, clickable rows (mouse select), and a clickable ← Back footer (Esc still cancels).
- Titan tier (
/tier titan) — Klaatu's new top tier, Kimi K3 (2.5T params), is now selectable from the CLI:/tier titan, the/tierpicker,--model titanonklaatai run, and shell completions. Previously the client rejected it as an invalid tier. - Correct cost and context for titan turns — the cost receipt,
/cost,/stats, the context meter, and compaction now use titan's real price ($7.50 in / $37.50 out per MTok) and 220K window instead of falling back to code-tier numbers. - Session lifecycle hooks —
session_startandsession_endevents in.klaatai/hooks.json, firing exactly once per session. - MCP config import — auto-import MCP servers from
.mcp.json,.claude.json, and.cursor/mcp.json.
- Titan is never auto-routed — the router will not escalate you into it; you ask for it by name. It is a Pro-and-above tier, capped per day, and de-escalates to
heavyonce the cap is spent (Starter gets it only during a promo window). Sub-agents (delegate_task) deliberately cannot select titan, so a delegated turn can't spend your daily allowance.
- Prompt-cache savings in the sidebar — the Context panel now shows
Cached N (X% of input)when the server's prompt cache is hitting, so you can see the cost saving in real time. - Honest context meter — the Context panel shows the active model's real window (not a misleading sum of all tiers), a
Compact at %indicator, and cumulativeProcessedtokens since the last compaction.
- Cleaner tool-call display — reads, edits, and commands now render as a single tidy line (Claude-style), colour-coded by status (green ok / red fail), and expand on demand. No more three-line content dumps cluttering the transcript.
- Window-aware compaction — context compaction now triggers at ~78% of the active model's window instead of a fixed 60K threshold, so it works correctly on every tier — including small ones where it previously never fired.
- Tier context windows aligned with the server — removes a double-trim that could shrink your working context more than intended.
- Context no longer pins at 100% / stalls — compaction reliably frees space as context fills, on every tier (the old threshold was larger than the small-tier window, so it never ran).
- "Continue" no longer loops — after an exploration-budget pause, continuing no longer re-reads the same files and hits the identical wall; the agent gets more room plus a directive to act on what it already has.
- No false "agent may be stuck" pauses on analysis — deep read/analysis tasks (e.g. comparing large datasets) are no longer stopped mid-way. The pause now fires only on a genuine repetition loop, and producing a real answer counts as progress.
- MCP file writes now tracked — files written via MCP filesystem tools appear in Modified Files and support
/undo(previously showed "Modified Files 0" despite successful writes).
- Several routing improvements ship server-side and roll out automatically (no CLI update needed): heavy / multi-file conversations auto-escalate to a larger-window model so builds don't stall; mechanical build steps (writing files, running commands) use the faster code tier instead of the slower reasoning tier; large prompts prefer cache-capable models to cut cost.
- Windows browser auto-open — Now tries 3 methods in sequence:
explorer.exe(most reliable, no shell interpretation),powershell.exe Start-Process, andrundll32 url.dllas final fallback. Covers machines where PowerShell is blocked or not in PATH. - URL not copyable in TUI — When browser fails to open, the auth URL is now auto-copied to clipboard (
clipon Windows,pbcopyon macOS,xclipon Linux). User sees "URL copied to clipboard — paste in browser" instead of trying to select text from the TUI alt-screen.
- Version display — Splash screen now shows "KlaatCode v2.2.8" instead of hardcoded "CLI v0.1.0".
- Fallback URL overflow — When browser fails to auto-open, the auth URL no longer bleeds into other UI components. Long URLs are now wrapped to fit the terminal width.
- Fallback URL visibility — Auth URL displayed in blue underlined text, auto-detected as clickable by modern terminals (Windows Terminal, iTerm2, VS Code terminal).
- Windows login STILL broken —
cmd.exetruncates URL at&even viaspawn. The v2.2.5 fix usedspawn("cmd.exe", ["/c", "start", "", url])but cmd.exe processes&as a command separator regardless of how it's invoked. Switched topowershell.exe Start-Processwhich correctly handles URLs containing&,=, and other special characters without interpretation. Windows users will now see the full auth page with all parameters intact.
- Windows (and all new installs) pointed at localhost instead of production API. The default
baseUrlinDEFAULT_CONFIGwashttp://127.0.0.1:8765(the local dev server). Fresh installs with no~/.klaatai/config.jsonwould open the browser tohttp://localhost:4410/klaatu/cli-auth— which doesn't exist on user machines. Default is nowhttps://api.klaatai.com, so login correctly openshttps://klaatai.com/klaatu/cli-auth. Existing installs with a config file are unaffected.
- Claude Code skills compatibility —
.claude/skillsdirectory is now auto-discovered alongside.klaatai/skills. Thanks @syf2211! (#43) /exportslash command — export the current session to a Markdown file. Thanks @Ayush7614! (#45)- Swift, PHP, Kotlin, Shell post-edit diagnostics — the feedback loop now runs
swiftc,php -l,kotlinc, andshellcheckwhen available. Thanks @Ayush7614! (#44)
- Windows login broken — browser auth now works on Windows. Three issues combined to break the OAuth redirect on Windows: (1)
cmd.exe'sstartcommand misinterpreted&in the login URL as a command separator, truncating query params — fixed by usingspawnwith an explicit arg array that bypasses shell interpretation; (2) the local callback server bound only to127.0.0.1which some Windows firewall configs block — now binds to0.0.0.0on Windows; (3) the redirect URI used127.0.0.1which some browsers resolve to IPv6[::1]— now useslocalhoston Windows for correct resolution. (#47)
- Shell completions (bash / zsh / fish).
klaatcode completions bash|zsh|fishprints a static completion script — works in the compiled binary without reading from disk. Covers bothklaatcodeandklaataibinary names. Thanks @Ayush7614! (#46)
pull-from-public.shnow recommendspatch -p1instead ofgit apply(which silently skips patches in monorepo layouts).- Fallback URL display — if the browser doesn't open on any platform, the full login URL is printed to the terminal after 2 seconds so users can copy-paste manually.
Six features no other CLI coding agent ships built-in — token efficiency and runaway-protection, all on by default, all with an off switch. Plus the first two community contributions.
- Tokyo Night theme (
/theme tokyo-night) — deep navy with cool blue & green accents. Thanks @floze-the-genius! (#40) - Ruby diagnostics — post-edit feedback loop now runs
rubocopon.rbfiles when it's on PATH. Thanks @siddhanttiwari19! (#41)
-
Tool-output noise filter (
outputFilter). 60–75% of command-output tokens are noise you pay for on every later request. Progress bars now collapse to their final frame, long runs of passing tests collapse to a count ([✓ 40 passing tests — collapsed]), repeated lines dedupe, ANSI codes and carriage-return spinner frames are cleaned up. Failures, exit codes, and summary lines are always kept in full, and the filter fails open — any doubt, you get raw output. -
plan_explorationtool — a query optimizer for code. Before reading anything, the agent can ask for the optimal file-read order for a task: files you named (full read), files defining matched symbols (targeted section at the right line), and their callers (outline only). Derived from the local code graph; the system prompt tells the agent to use it first on any multi-file task. No other CLI plans its reads. -
Attention-ordered context (
attentionOrder). Models attend most strongly to the start and end of their context window ("lost in the middle"). Older history is now arranged so the highest-relevance turns sit at the context edges and exploration noise is buried in the middle. Tool-call/result pairs never split; recent turns and the system prompt never move. -
Budget guards. Real-time burn-rate tracking with a warning when spend runs 3× your session average; per-task cost attribution and a phase breakdown in
/cost; an optional hard session cap (maxSessionCost) that pauses agent rounds instead of burning on;klaatcode run --max-cost <usd>for CI and cron (exit code 3). No other CLI monitors spend rate. -
Per-phase token budgets (
phaseBudgets). The classic stuck-agent failure — the whole budget burned exploring before a single line is written — is now caught directly: tokens are attributed to explore/implement/verify phases, and exploration that exhausts its budget without producing an edit pauses and asks instead of continuing. -
Context-collapse detection. Compaction is lossy and normally silent. Klaat Code now snapshots the critical state (your task in your own words + the files being modified) to the session ledger before compacting, mechanically verifies the summary still covers it after, and — when something was lost — injects a recovery note telling the model exactly what it forgot and where to re-read it. First CLI that can tell you it forgot something.
-
/contextcommand. See what's actually in the model's window (message counts, token estimate, degraded tool results) vs. what's been compacted away, plus the ledger path where compacted details stay recoverable. -
Server doom-loop reaction. Klaatu detects when the agent repeats the same tool call with identical arguments and identical results; the CLI now refuses that round, injects recovery guidance ("change approach — don't repeat the call"), and stops entirely after three refusals. Works in the TUI and headless runs. Pairs with the existing no-tool-call-limit design: unlimited productive loops, zero tolerance for stuck ones.
-
Server retry contract honored.
X-KlaatAI-Retry: no(the server's failover cascade already exhausted every fallback) is never blindly retried;after-<s>schedules exactly one retry; waits over 60 s surface as errors instead of hanging your terminal. -
Benchmark refresh — 33-task suite, model-variant lanes (2026-07-20). Suite grown to 33 tasks (5 long-context). New adapters: Claude Code on Sonnet 5, opencode on Nemotron 3 Ultra (promo-free tokens priced at published paid rates), and Cursor via both Composer 2.5 variants (
cursor-agent, plus acursor-ide-bench.tsIDE-chat lane with an objective check-script referee for when the headless CLI is unusable). Results: Klaat Code 33/33 at $0.027/solve and 23s median/task — 5.4× cheaper than Claude Code, 1.7× cheaper than the nearest rival, and no rival is both cheap and fast (Composer 2.5 standard: within 1.7× on cost but ~113s/task). Interactive cost curves + per-task comparison: klaatai.com/benchmarks.
- Installer channels served the retired 1.x line.
klaatai.com/api/latestand the curl installer's npm fallback pointed at the oldklaatcode-aipackage — when the GitHub API was unreachable they reported/installed1.15.xinstead of the current CLI. Both now resolve theklaatcodepackage. The Windows installer also stopped requesting the discontinuedwindows-arm64asset (Windows-on-ARM uses the x64 binary via built-in emulation).
- All new behaviors are on by default. Opt out per feature in
~/.klaatai/config.json:outputFilter,attentionOrder,phaseBudgets("off"),maxSessionCost(unset). - New docs: Configuration, Commands, CLI reference.
Pre-changelog era: smart per-request tier routing, code knowledge graph (impact_check, semantic search), 28-tool agentic loop, tier-aware toolset dialects, fuzzy 9-pass edit engine, apply_patch, real plan mode, background sub-agents, MCP (stdio + HTTP + OAuth), hooks v2, skills v2, plugins, retention-aware compaction + session ledger, sessions/resume, write sandbox, post-edit diagnostics, published 4-way benchmark (equal accuracy at 18% of Claude Code's cost). See the README and git history.