# aicodeman ## 1.16.5 ### Patch Changes - Mobile keyboard dismissal, and a tidier Save/Close pair in the phone settings sheet. **The on-screen keyboard can finally be closed from inside the app.** The terminal keeps focus on a hidden textarea and nothing ever released it, so once the keyboard was up it covered roughly half the screen with no way out but the OS back gesture. Two gestures now dismiss it: - **A tap outside the terminal** (header, tab strip, empty page chrome). Deliberately narrow: it only fires while the terminal input actually holds focus, never inside the terminal (tap classification owns that decision), and never on a control, since anything focusable is about to take focus itself and the keyboard accessory bar exists to be used _while_ the keyboard is open. A scroll ends in `touchend` too, so finger travel is tracked from `touchstart` and only a near-stationary gesture counts as a tap, sharing the terminal's own 8px threshold so both agree on tap-vs-scroll. Scrolling to read something mid-compose no longer drops the composer. - **A second tap on inert transcript content.** Every terminal tap used to re-focus, which left the accessory bar's chevron as the only way out. Scoped to inert rows on purpose: the prompt row keeps focus-then-position, so a second tap there still places the caret, and actionable rows (readbacks, `esc to interrupt` status rows, menu selections) still blur as before. **Settings sheet header on phones.** Below 860px Save moves into the header, which left the two ways out of the sheet as a fat accent pill beside a bare glyph. Save and Close now share a recessed tray with matching 36px pill geometry, reading as one 44px cluster the height of the phone header. Tray colors come from skin tokens, so the light skins keep their look, and the tray stays off the sheets that carry a lone close button. Also fixes a test that could never have caught a regression: the case asserting that tapping a control does _not_ dismiss the keyboard was picking a button from the hidden welcome overlay, whose rect still measures while the hit-test lands on the terminal underneath, so it passed for the wrong reason and stayed green even with the exemption deleted. All four guards in the dismiss handler are now individually pinned. ## 1.16.4 ### Patch Changes - **Voice dictation through your Claude Code login (no API key).** The mic button can now transcribe using this machine's existing Claude Code subscription, via the same speech-to-text service the CLI's own `/voice` mode uses. Off by default (`claudeVoiceEnabled`, synced): turning it on spends the server owner's Claude subscription on transcription for anyone who can reach the UI. The OAuth token never leaves the server process, credentials are read-only (Codeman never refreshes them, which would rotate the refresh token out from under the CLI), streams are capped at 5 minutes and 4 concurrent, and the WebSocket carries the same allowed-Host + same-site Origin guard as the terminal socket. A new Speech engine picker (Auto / Claude / Deepgram / Browser) sits alongside the existing Deepgram and Web Speech paths, which are untouched. **One settings surface.** Session Options and Add Case now use the same `set-*` chrome as App Settings instead of the old modal-tab chrome, with a left rail, grouped rows, per-group device/synced scope badges and a search box. App Settings leads with version + update; the Session Options rail stays a real switcher (one section at a time) because Summary and Respawn are each long enough to bury the other. Collapsed Add Case blocks gained a disclosure chevron. **Read My Mind: rethink steer note (phase 3 part 2).** Rethink now carries an optional free-text note ("no, I meant the mobile bug") sent as `steer`, the highest-authority signal the predictor gets. It stays in the field across re-runs, clears on each open, and the empty-result copy points at it. The modal footer moved to the styled `btn-toolbar` convention; the bare `btn btn-*` classes it shipped with match no CSS in this codebase and rendered as unstyled browser buttons. **Mobile terminal taps no longer fight the keyboard.** Taps on TUI-owned rows (expandable readbacks, tool results, decision menus, the working/status row) now act on the CLI without popping the keyboard, while a tap on inert transcript text keeps the keyboard reachable. Rows are told apart by the affordance the CLI prints (`ctrl+r to expand`, `tap to collapse`, `esc to interrupt`) rather than by row titles, which vary per CLI and per version. A tap with the viewport scrolled up sends no mouse report at all but still restores focus, so the keyboard is reachable after every tab switch. Thanks to @Lint111. **Path labels abbreviate `$HOME` on both platforms.** The "show `~/project`" rule had three implementations and two were platform-specific in opposite directions: the Run menu's matched `/home//` only, so on macOS every Recent Sessions row spent its first ~19 characters on an identical `/Users//` prefix and ellipsized away the tail that identifies it (#273); the case-manage list's matched `/Users/` only, so no Linux case path was ever abbreviated. Both now route through one helper, with a static guard against a fourth copy appearing. **Run menu Recent Sessions rows are legible.** Rows now read as folder, worktree pill, dimmed parent path, timestamp, with only the parent path allowed to shrink, so truncation can never hide which project (or which worktree) a row refers to. `/.claude/worktrees` is dropped from the parent path as noise. Thanks to @jordan8037310. Follow-up fix: the widened menu was not actually usable by its rows, since `.run-mode-history` is a block scroller and its `