## eneskirca/nodeterm — v0.3.15…v0.3.16

_84 commits._

### Features
- **feat(chat): claude.ai thread look — user bubble, unbubbled assistant, turn action row** (719e33a)
- **feat(chat): claude.ai-style composer — attach, dictation, model/effort labels** (37be863)
- **feat(chat): answer controls on the ⌘M Plan / Question cards** (695947e)
- **feat(hooks): structured hook-reply answers for plans and questions** (7a7e0d2)
- **feat(chat): working indicator + live tail refresh in the ⌘M panel** (650e771)
- **feat(chat): progressive transcript loading in the ⌘M panel** (fce46e0)
- **feat(terminal): quiet ⌘M hint at the end of the node's label row** (51ae911)
- **feat(chat): paged transcript reads in core + every transport** (dcc4237)
- **feat(kanban): the card modal gets the ⌘M view (board parity)** (f0e1178)

### Fixes
- **fix(chat): no mic types into the hidden pane while the chat view is up** (f7e0d00)
- **fix(chat): keep the answer fields visible — scope the composer's borderless input** (a1b8474)
- **fix(chat): gate composer dictation on the composer box, refuse in answer controls** (3090bf0)
- **fix(chat): composer review round 1 — focus on flip, picker in-flight guard, shortcut dictation** (f466d56)
- **fix(hooks): read the pending request through one fd (CodeQL js/file-system-race)** (92a3130)
- **fix(node-header): a refused ✓ Approve / ✕ Deny now says so** (fe4e2e6)
- **fix(hooks): refuse a partial AskUserQuestion answer set** (84876ef)
- **fix(chat): cap the JOINED multi-select answer; keep focus on sent controls** (8e35027)
- **fix(kanban): Esc in the chat view's answer box or composer no longer closes the card modal** (f0af597)
- **fix(hooks): gate structured answers on the hook script revision** (2488391)
- **Merge pull request #953 from eneskirca/fix/chat-live-progress** (bc43574)
- **fix(chat): keep unconfirmed sends across live reads; quieter live loads** (ad31986)
- **Merge pull request #951 from eneskirca/fix/chat-plan-body** (3d35265)
- **Merge origin/main into fix/chat-plan-body** (34064ea)
- **fix(chat): harden plan/question bodies against model-authored markdown** (c412476)
- **fix(chat): show ExitPlanMode plans and AskUserQuestion questions in the ⌘M view** (18adca9)
- **fix(workspace): catch a same-size index rewrite on coarse-mtime filesystems by inode** (b44dcc8)
- **fix(pty): a failed scrollback write re-marks the session dirty** (48e86eb)
- **fix(terminal): resync repaint re-enters tmux's alt screen and mouse modes** (978c719)
- **fix(terminal): recycle banner lands after the joiner's alt-screen switch** (cd83267)
- **perf(workspace): skip re-parsing and unchanged index writes on autosave** (0806446)
- **perf(pty): keep scrollback snapshots correct on failed writes and quit** (3570a28)
- **perf(pty): pace scrollback snapshots and skip unchanged ones** (8df485d)
- **perf(agents): skip session-title reads of unchanged transcripts** (6ae9ebb)
- **perf(ssh): reset the codex remote tail backoff on every hook** (a3bbda1)
- **perf(ssh): back off the remote context tail while the transcript is idle** (a2bc433)
- **perf(terminal): one rect read per frame in the zoom mouse fix** (e43fe37)
- **perf(canvas): working glow settles after four pulses** (267acd8)
- **perf(minimap): transform-only projection on pan/zoom frames** (798b278)
- **perf(canvas): freeze viewport raster scale during camera moves** (00c9c5f)
- **perf(terminal): co-attach joiner re-enters the alternate screen** (8379470)
- **Merge pull request #949 from eneskirca/fix/chat-view-perf** (7034716)
- **fix(ssh): a paged transcript reply must be the window that was asked for** (409907a)
- **fix(chat): one loading row and one spinner for the ⌘M panel** (38d3ba6)
- **fix(chat): an empty tail with history behind it is loading, not empty** (450e35a)
- **fix(chat): grow a paged window instead of skipping a line bigger than it** (500a80f)
- **Merge branch 'fix/chat-view-paging' into HEAD** (338f1aa)
- **Merge branch 'fix/chat-view-ui' into HEAD** (1efe359)
- **fix(chat): never page a hidden panel; keep paging alive across failed reloads** (5466ae7)
- **fix(terminal): the ⌘M hint can never add a line to the label row** (9efade9)
- **fix(chat-view): closed-transcript dialog suspends into the panel shell too** (d749a1a)
- **fix(chat-view): keep tool names on one line; show loading state for ⌘M** (ade06cd)
- **Merge pull request #946 from eneskirca/fix/md-view-output** (5d1dbc8)
- **Merge pull request #945 from eneskirca/fix/md-view-toggle** (731223f)
- **Merge pull request #944 from eneskirca/fix/md-view-chat** (ac6ac35)
- **Merge pull request #943 from eneskirca/fix/md-view-links** (8bc2945)
- **fix(md-view): file paste/drop respects the ⌘M cover; SLEEPING in the card modal; editor chord gate** (cf69354)
- **fix(markdown): a rejecting openExternal bridge never leaks an unhandled rejection** (e514b59)
- **fix(kanban): keep the modal's resize handles above the ⌘M view** (2678421)
- **fix(md-view): tell a render failure from a capture failure** (41966f7)
- **fix(md-view): review round 1 — desktop repeat parity, dispatch-owner doc, focus test** (363d6f9)
- **fix(md-view): keep the hidden xterm unfocused; honest late-answer tests** (61f1adc)
- **fix(chat): refuse sending after the agent CLI exited; derive the gate from agentProcessInPane** (0d464fb)
- **fix(chat): ⌘M chat panel UX — Shift+Enter, scroll-follow, thinking, stale guard, reload, agent label** (037120e)
- **fix(md-view): output view lifecycle — focus, freshness, size** (77a9d04)
- **fix(md-view): ⌘/Ctrl+M in the Server Edition + one verdict for a multi-select toggle** (790da9e)
- **fix(markdown): guard middle-click links, pin the class on each HTML sink** (da1a207)
- **fix(chat): never type into a TUI dialog from the ⌘M chat composer** (7f5e839)
- **fix(markdown): links in rendered markdown never navigate the app window** (46a1321)
- **fix(md-view): render terminal output as readable output, not mangled markdown** (bae38f6)

### Backend
- **Merge pull request #957 from eneskirca/feat/chat-composer** (b950d9b)
- **Merge pull request #955 from eneskirca/feat/chat-answers** (67df147)
- **Merge origin/main into feat/chat-answers** (1c1a99c)
- **Merge pull request #950 from eneskirca/perf/cpu-gpu-optimizations** (a26b5e4)
- **Merge pull request #941 from eneskirca/release/v0.3.15** (5c52fad)

### Tests
- **test(chat-view): use the real path escaper in composer fakes (CodeQL)** (3337b60)

### Docs
- **docs(claude-md): held carries the optional question texts the answer card matches on** (adecbc7)
- **docs(hooks): the PermissionRequest hold is bounded by our explicit timeout: 600** (3d809d8)
- **docs: qualify alt-screen gate, glow replay and title-lag notes; restore test comment order** (e0877c6)
- **docs: the ⌘M loading surfaces, the one spinner, and the label-row hint** (c8c7dba)
- **docs(chat): re-wrap the chatComposerPlaceholder docstring to the file's width** (2924aa9)

### Chore
- **chore(release): v0.3.16** (44eaa4c)
- **refactor(chat): picker labels wait out the unconfirmed send; one upload-scope rule** (f793c83)
- **chore: ignore the local videos/ directory** (42174e3)
- **chore(md-view): Task 2 review fold-ins** (2d65a7f)

_Recap by [Repo Wrapped](https://repowrapped.com/gh/eneskirca/nodeterm?utm_source=github-action)._