Skip to content

v0.8.21

Choose a tag to compare

@github-actions github-actions released this 28 Jul 07:35

Patch Changes

  • 3036b31: Fix a custom engine launch command in Settings → Engines mis-splitting an attached quoted flag: claude --append-system-prompt="be terse" (the common --flag="value with spaces" idiom) was parsed as two broken argv elements (--append-system-prompt="be and terse") instead of one (--append-system-prompt=be terse), because the tokenizer only honored a quote that started a word. The command splitter now treats a quote opening anywhere in a token as a quoted span that concatenates with the surrounding text — matching a shell — so both the attached (--flag="…") and separated (--flag "…") forms launch the engine with the argv you configured; an unterminated quote runs to the end of the command rather than being kept literally.

  • 7a14dc1: Fix auto-derived branch names showing a double hyphen (kobe/<slug>--<id>) when a long task title's 32-character slug cap lands on a word boundary: the trailing-hyphen trim ran before the cap, so the slice could re-introduce a trailing - that the -<id> suffix then doubled. The slug is now re-trimmed after the cap, so branches read kobe/<slug>-<id> cleanly regardless of where the title is truncated.

  • f469f3d: Fix the returning "claude input box gone" on hidden tabs: the park sweep no longer parks a tab whose session is still streaming (an active stream overruns the 512KB host ring, degrading the lossless wake to a mid-stream replay), and the degraded wake's repaint wiggle now keeps a real gap between its shrink/restore resizes so an actively-streaming child can't race them into one coalesced same-size SIGWINCH that claude ignores.

  • 5d35d66: Fix garbled non-ASCII PR titles in the sidebar check-state chip: the daemon's PR-status poller decoded each gh pr list --json stdout chunk on its own, so a multi-byte UTF-8 character in a PR title (Chinese, emoji, accented text) that straddled a ~64 KB pipe-chunk boundary turned into replacement glyphs () before the JSON was parsed and the title persisted to the task — the same defect already fixed for the background git helpers now closed on the gh capture path by joining the raw bytes before decoding.

  • b414b85: Rate-limit auto-resume: when Claude Code hits its subscription quota, the daemon probes the account's usage API for the exhausted window's reset time, parks a durable quotaResume schedule on the task, and once the window resets automatically delivers a continue prompt into the task's still-live engine session. Vendor knowledge stays engine-owned (quotaResetAtMs on the engine registry entry); a probe that can't produce a reset time changes nothing — the sticky rate-limit badge keeps waiting for the user as before.

  • 70113ed: Quota usage cache + Settings dashboard. The engine quota probe now returns full usage windows, and a daemon-owned cache becomes the only caller of the (itself rate-limited) vendor usage API: slow 15-minute refresh while a snapshot exists, exponential backoff (1m→2m→…, capped) while none can be fetched, a hard 60s per-vendor floor between attempts, shared in-flight dedupe, and strictly bounded memory (one snapshot per vendor). Snapshots fan out on the new usage.snapshot push channel, and Settings → General grows a top-right usage dashboard (per-window meters with utilization tone and reset time). The rate-limit auto-resume scheduler reads the same cache, so a hook event storm can no longer hammer the usage API.

  • e363604: Sidebar visual pass (herdr-inspired): borderless 24-col rail with the KOBE brand text as its focus signal, herdr status circles (◉ needs input, ● turn done unseen, ✓ done and viewed, ○ idle) with a seen bit that digests ● → ✓ once you select the finished task, active tabs render as filled accent chips (opaque contrast fg so transparent mode stays readable), branch subtitles get the full rail width on quiet rows (live per-row cluster subtraction), and hover tooltips drop the worktree path and become an opt-in setting (Settings → General → Task hover tooltips, default off).

  • 2a0e6d9: Tab auto-naming no longer adopts junk first prompts: a conversation opened with a menu answer like "1" or bare punctuation falls back to the vendor default ("claude 2") instead of naming the tab "1". Display-side guard, so already-persisted junk titles heal without a migration.

  • 777e7c5: Fix embedded-terminal copy losing a line when a selection starts in the blank space past a short line: dragging from the empty padding to the right of a short row down into the next line highlighted both rows but copied only the lower one, silently dropping the leading blank line (and its newline) so two visibly-selected lines collapsed into one. The copy now keeps every highlighted row — an empty first line contributes an empty line, matching what the on-screen selection shows.

  • a6db214: Engine sessions and embedded terminals now actually run on Windows. kobe's only PTY path was Bun.spawn(..., { terminal }), which Bun rejects outright on Windows — every pty.open failed with "terminal option is not supported on this platform" and retried in a loop, so the TUI came up with panes that could never hold a session. The PTY host now spawns children through a small driver seam: Bun's terminal API everywhere it works, and node-pty (ConPTY) on Windows. node-pty cannot fill the gap from inside Bun either — Bun can read its output but writing to the ConPTY input pipe returns ERR_SOCKET_CLOSED, i.e. a terminal you cannot type into — so on Windows that one process runs under node instead, with the identical session, scrollback, replay, and wire-protocol code above the seam.

    Its socket becomes a named pipe on Windows (\\.\pipe\kobe-<home>-pty), because node cannot bind a filesystem unix socket there. Clients are unchanged: they speak the same frame grammar, and only the pathname differs. Nothing changes on macOS or Linux — same process, same Bun spawn, same unix socket.

  • a6db214: kobe now starts and holds a session on Windows. Every engine tab and embedded terminal is launched through a composed POSIX shell script (trap, export -p, $$, kill -TERM, [ -f ]), and the shell was hardcoded to /bin/zsh / /bin/bash, so on Windows the PTY spawn of a nonexistent argv0 took the whole process down with a native heap corruption (0xC0000374) about a minute after boot. The shell now resolves through one place, which picks Git for Windows' bash — already present on any machine that can run kobe, since kobe is git-worktree native — and paths interpolated into that script are converted to the form bash reads (C:\a\b/c/a/b), which also fixes .kobe/init.sh being emitted as .kobe\init.sh. macOS and Linux are unchanged: each call site keeps the exact fallback it always had.

    The daemon and PTY host also no longer open a stray terminal window on Windows. They are spawned with detached: true, which on Windows means DETACHED_PROCESS — the background service got its own console, which the OS drew as a second terminal window next to the TUI that retitled itself after whatever the hosted engine was running. POSIX still detaches exactly as before.

    Repo checkouts are now pinned to LF via .gitattributes. Without it a Windows clone lands as CRLF and the first bun run lint reports every line of every file as changed.