Bump to 0.3.1: fix backend hangs, UI layout, and dead-code type error

A day of dogfooding locode on itself surfaced several real bugs, most centered on
the backend request lifecycle silently hanging with no error surfaced to the user:

- bash/hooks: execa's shell:true defaulted to cmd.exe on Windows, which lacks
  Unix tools (cat, sed, grep, ...) and fails a whole pipe with an unhelpful exit
  255 if any stage isn't found. Added src/utils/shell.ts to resolve real Git Bash
  when available.
- agent/loop: the backend client's own `timeout` only bounds time-to-first-byte —
  once a streaming response starts, a backend that goes silent mid-stream (or one
  that sends periodic content-less "heartbeat" chunks to keep the connection alive
  through a proxy) hung the request forever with zero output. Added an idle-abort
  guard that pokes only on chunks carrying real progress (usage/text/tool-calls/
  finish_reason), covering the main stream, the non-streaming malformed-JSON
  retry, and compactSession.
- agent/loop: a single tool-call-heavy turn (e.g. reading dozens of files) had no
  auto-compaction safety net at all — shouldAutoCompact was only ever checked
  between turns, never during one, so a long turn could blow past the context
  window with no mid-turn correction. Now checked every iteration; re-anchors
  mutationCommitLength afterward since compaction replaces session.messages
  wholesale.
- agent/loop: hitting the iteration cap surfaced as an opaque "Request failed"
  even when every prior tool call (including file edits) had actually succeeded.
  Added MaxIterationsError, rendered as a calm "paused, send another message to
  continue" notice instead, and raised the default cap 25 -> 50.
- agent/loop: removed a dead-code branch (fallback-malformed retry handling
  placed inside a native-mode-only code path, so session.mode === "fallback"
  could never be true there) that TypeScript correctly flagged as a type error.
- ui/App: text_done fires with an empty fullText for pure tool-call turns (no
  preceding prose); the assistant-message push had no guard, rendering a blank
  line every time. Now skipped when fullText is empty.
- ui/App+index: alternate-screen-buffer mode and StatusBar-above-ChatInput
  layout, fixing the reported "prompt starts below the dashboard, jumps up on
  space" glitch. Added input history (up/down recall).
- utils/writeFileAtomic: random temp-file suffix instead of a fixed `<file>.tmp`,
  so concurrent writes to the same directory can't collide.

Also fixes two hardcoded version strings (cli.ts --version, mcp/client.ts's
self-reported MCP identity) that were left stale at 0.2.0 through the 0.3.0
bump, and a stale maxIterations default noted in the README.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
kim
2026-07-08 18:06:52 +09:00
co-authored by Claude Sonnet 5
parent 4652ecb87b
commit f01898a9c3
20 changed files with 689 additions and 68 deletions
+1 -1
View File
@@ -24,7 +24,7 @@ function addBackendOptions(cmd: Command): Command {
program
.name("locode")
.description("Agentic coding CLI for local models via Ollama and LM Studio")
.version("0.2.0");
.version("0.3.1");
addBackendOptions(program)
.option("-m, --model <name>", "model name as known to the backend")