# v0.35.0

These are the release notes for gptme version v0.35.0.

## Contributors

Thanks to everyone who contributed to this release:

@erikbjare, @harimaruthachalam, @jaideeppyne, @Thibaultjaigu, @TimeToBuildBob, @vanshtaneja23

## Changelog

Changes since v0.34.0:


## 📦 gptme

### ✨ Features (61)

 - feat(shell): memory guard kills the agent's largest command when system memory runs low ([#4348](https://github.com/gptme/gptme/issues/4348)) ([`6aa340f35`](https://github.com/gptme/gptme/commit/6aa340f3570fd17e8f75b49d10d7df652f8673c4))
 - feat(tui): queued prompts steer the running turn at its next step ([#4346](https://github.com/gptme/gptme/issues/4346)) ([`e4fb3d976`](https://github.com/gptme/gptme/commit/e4fb3d9760e712e6284c7d2049bf9df21e29aa76))
 - feat(tui,ipython): Ctrl+C stops a running tool in the TUI; ipython cells time out ([#4354](https://github.com/gptme/gptme/issues/4354)) ([`d8a54a974`](https://github.com/gptme/gptme/commit/d8a54a97437f75db6b0740ae32112290cbbd41ca))
 - feat(tui): show the running tool call, its elapsed time and timeout ([#4344](https://github.com/gptme/gptme/issues/4344)) ([`804273354`](https://github.com/gptme/gptme/commit/804273354d4e9a04be1e1c96ca8a4ce61a959373))
 - feat(lessons): capture private final-item evidence for precision readouts ([#4340](https://github.com/gptme/gptme/issues/4340)) ([`ffd45727c`](https://github.com/gptme/gptme/commit/ffd45727c14461afcb63c047a4a84cb584239c4a))
 - feat(tui): command-driven status line ([tui] statusline) ([#4339](https://github.com/gptme/gptme/issues/4339)) ([`3160b45f1`](https://github.com/gptme/gptme/commit/3160b45f14f9cd42cd5c94c3dc6510a8bbc0b156))
 - feat(context): add max_tokens to ContextSelectorConfig; use it in LLMSelector ([#4336](https://github.com/gptme/gptme/issues/4336)) ([`c4f1e463d`](https://github.com/gptme/gptme/commit/c4f1e463df7509cc872388c8dcda3eab7a86aa56))
 - feat(lessons): record final native context emissions ([#4328](https://github.com/gptme/gptme/issues/4328)) ([`47673511b`](https://github.com/gptme/gptme/commit/47673511b006041b585d39a5e2c78e8606dbad23))
 - feat(compaction): record 'chunked' and 'native' methods in compaction.jsonl ([#4318](https://github.com/gptme/gptme/issues/4318)) ([`7413443fc`](https://github.com/gptme/gptme/commit/7413443fc5894b7c090cbb9611a40fd54bbe49aa))
 - feat(compaction): summarize overflowed history in fresh-context chunks ([#4309](https://github.com/gptme/gptme/issues/4309)) ([`fe24c6c0c`](https://github.com/gptme/gptme/commit/fe24c6c0cfe9e6b60a8af4002551ede7660683a9))
 - feat(lessons): add optional GPTME_LESSONS_MAX_PER_TURN limit ([#4294](https://github.com/gptme/gptme/issues/4294)) ([`7835c616f`](https://github.com/gptme/gptme/commit/7835c616f83332a0ef925919fbf6b0d1f18cdcd9))
 - feat(server): apply model default_tool_format when webui omits tool_format ([#4245](https://github.com/gptme/gptme/issues/4245)) ([`3e9169958`](https://github.com/gptme/gptme/commit/3e916995854c58ab045751c9d3dbc6adfecbd5c7))
 - feat(compaction): capability-gated Anthropic native compaction with signed-block replay (Phase 2) ([#4244](https://github.com/gptme/gptme/issues/4244)) ([`6fe8ad4e1`](https://github.com/gptme/gptme/commit/6fe8ad4e1b93c581db498951f06c891ed8bbed0f))
 - feat(lessons): add opt-in shared selector command adapter ([#4283](https://github.com/gptme/gptme/issues/4283)) ([`6b4338cfc`](https://github.com/gptme/gptme/commit/6b4338cfca571019932a1934c20136a1d97aeb20))
 - feat(site): add gptme.org/stats/ page from gptme/stats ([#4279](https://github.com/gptme/gptme/issues/4279)) ([`381c29320`](https://github.com/gptme/gptme/commit/381c29320ad66b16c16d7220063707ef0b5ab326))
 - feat(config): persist --agent-profile and re-apply it on resume ([#4040](https://github.com/gptme/gptme/issues/4040)) ([`9511db3b7`](https://github.com/gptme/gptme/commit/9511db3b73cc604aad363595e0321af4a3841908))
 - feat(eval): add constraint-satisfaction eval suite ([#4082](https://github.com/gptme/gptme/issues/4082)) ([`4a9eb56ad`](https://github.com/gptme/gptme/commit/4a9eb56ad497b10f5a2e451dc70d8c76a6df9fd8))
 - feat(server): share auto-generated token with local clients via token file ([#4061](https://github.com/gptme/gptme/issues/4061)) ([`6fdbc7bac`](https://github.com/gptme/gptme/commit/6fdbc7bac0abbd29504f75283e094ac4e4a06c6e))
 - feat(compaction): run checkpoint through normal tool loop ([#4223](https://github.com/gptme/gptme/issues/4223)) ([`56ae66070`](https://github.com/gptme/gptme/commit/56ae66070ea708eb63a2b320f2d8e8b348e6ad4d))
 - feat(models): register Mistral Large 4 ([#4229](https://github.com/gptme/gptme/issues/4229)) ([`83401e8bf`](https://github.com/gptme/gptme/commit/83401e8bf894117408b3cadf64a36ae51ecb0789))
 - feat(compaction): remind normal tool loop before context budget ([#4174](https://github.com/gptme/gptme/issues/4174)) ([`021e57777`](https://github.com/gptme/gptme/commit/021e57777ed7077e217f1a224704d0436486aa38))
 - feat(webui): expose server-owned global MCP settings ([#4218](https://github.com/gptme/gptme/issues/4218)) ([`945cc4da9`](https://github.com/gptme/gptme/commit/945cc4da9dd404f3b1af3a5ac236ba6a4a1a5af3))
 - feat(server): structured GET/PUT /api/v2/user/config/mcp for global MCP config ([#4095](https://github.com/gptme/gptme/issues/4095)) ([`b8c8527c9`](https://github.com/gptme/gptme/commit/b8c8527c96ea4ffef3fdcbc85d2ac7bf4f291041))
 - feat(util): add `gptme-util sound` to play notification sounds from other harnesses ([#4205](https://github.com/gptme/gptme/issues/4205)) ([`70dab56ff`](https://github.com/gptme/gptme/commit/70dab56ffecb0434185c509aff81c561a62d0740))
 - feat(hooks): behavioral anomaly watchdog — scope_escape, write_storm, novel_host ([#3953](https://github.com/gptme/gptme/issues/3953)) ([`3c8408463`](https://github.com/gptme/gptme/commit/3c8408463f710af69b45cfd36d68b59cb299a332))
 - feat(subagent): context_mode=fork, per-call reasoning_effort, usage reporting ([#4096](https://github.com/gptme/gptme/issues/4096)) ([`101b8a7e4`](https://github.com/gptme/gptme/commit/101b8a7e4cd9389609ed386bddb87ca1b64cea3e))
 - feat(compaction): Phase 2 — compact_instructions, keep_recent, structured checkpoint ([#3812](https://github.com/gptme/gptme/issues/3812)) ([#3966](https://github.com/gptme/gptme/issues/3966)) ([`e632523b5`](https://github.com/gptme/gptme/commit/e632523b5c498117f22dfdccfda7d83a539ac19d))
 - feat(watch): refuse sleep-N polling chains in the shell while watch is loaded ([#4094](https://github.com/gptme/gptme/issues/4094)) ([`b3eacfcab`](https://github.com/gptme/gptme/commit/b3eacfcab7962c5e1b85fe25d9e668a80683e0fe))
 - feat(llm): client-side degeneration guard for OpenRouter streams ([#4034](https://github.com/gptme/gptme/issues/4034)) ([`9f1697c21`](https://github.com/gptme/gptme/commit/9f1697c217dc58374e005a4f98f49f91139864d4))
 - feat(webui): thread sseToken through to ApiClient EventSource ?token= ([#4035](https://github.com/gptme/gptme/issues/4035)) ([`7f172f7fe`](https://github.com/gptme/gptme/commit/7f172f7fe2d1fa4e1015529fa087a4dbac4d43c3))
 - feat(eval): add OpenShellExecutionEnv with kernel-enforced policy isolation ([#4027](https://github.com/gptme/gptme/issues/4027)) ([`e549e7cf6`](https://github.com/gptme/gptme/commit/e549e7cf68713222c00b6636da899a83be9342d7))
 - feat(llm): attribute OpenRouter serving provider from response body ([#4031](https://github.com/gptme/gptme/issues/4031)) ([`43b17c69d`](https://github.com/gptme/gptme/commit/43b17c69de65d9dea3c51f86e9b191339761b4ba))
 - feat(llm): record provider-served model in message metadata ([#4026](https://github.com/gptme/gptme/issues/4026)) ([`852ddc4f8`](https://github.com/gptme/gptme/commit/852ddc4f890c7cfcc6ceb1863c65380133be8edc))
 - feat(eval): Phase 0 pruning evaluation script ([#3997](https://github.com/gptme/gptme/issues/3997)) ([#4021](https://github.com/gptme/gptme/issues/4021)) ([`86f3ff7c6`](https://github.com/gptme/gptme/commit/86f3ff7c689ec743498228bd3863bdae24373d69))
 - feat(autocompact): shadow/dry-run ledger for Phase-0 evaluation ([#4015](https://github.com/gptme/gptme/issues/4015)) ([`39a4b894f`](https://github.com/gptme/gptme/commit/39a4b894f8957fe39a050f607e9698ccc16fa1d2))
 - feat(site): port the landing prompt scroller to gptme.org ([#4018](https://github.com/gptme/gptme/issues/4018)) ([`5fca02f3f`](https://github.com/gptme/gptme/commit/5fca02f3f316a2a917a0f3c2a7eda0fe8d5cc5fa))
 - feat(plugins): isolate failures and validate plugin contracts ([#4010](https://github.com/gptme/gptme/issues/4010)) ([`1f093d2cf`](https://github.com/gptme/gptme/commit/1f093d2cf6ca57d7545d9ee4dae6e92279336667))
 - feat(watch): arm event sources and get woken when they fire ([#3987](https://github.com/gptme/gptme/issues/3987)) ([`08347b887`](https://github.com/gptme/gptme/commit/08347b887b18b4c6a89ecf1f3b6a3730c6587bd7))
 - feat(autocompact): relevance-scored pruning of stale tool outputs (Phase 0) ([#4013](https://github.com/gptme/gptme/issues/4013)) ([`842a2b1ff`](https://github.com/gptme/gptme/commit/842a2b1ff63e321891e850aeb9e84b18523b05c6))
 - feat(compaction): cap long-window context budgets ([#3973](https://github.com/gptme/gptme/issues/3973)) ([`c41a3802a`](https://github.com/gptme/gptme/commit/c41a3802a03a1ae9d419cc3199761e826bf0c35b))
 - feat(doctor): validate plugin tool init() contracts in isolation ([#3881](https://github.com/gptme/gptme/issues/3881)) ([`3471bf259`](https://github.com/gptme/gptme/commit/3471bf2595e271187e633402e9a06408a59912f7))
 - feat(identity): read neutral AGENT_SESSION_ID before BOB_SESSION_ID ([#3963](https://github.com/gptme/gptme/issues/3963)) ([`80ea18e0b`](https://github.com/gptme/gptme/commit/80ea18e0b3318d751911b624d2b20b8e17caa231))
 - feat(webui): apply configured role colors ([#4004](https://github.com/gptme/gptme/issues/4004)) ([`a171781af`](https://github.com/gptme/gptme/commit/a171781af343c73a4b3c6a68743e1b98a4e2dacf))
 - feat(tauri): LAN access settings panel with QR code — Phase 2 ([#3958](https://github.com/gptme/gptme/issues/3958)) ([`353898ec3`](https://github.com/gptme/gptme/commit/353898ec3a73eee296035c25d56c7127a15a548f))
 - feat: [agent].color and [user].color for names in the CLI and TUI ([#3977](https://github.com/gptme/gptme/issues/3977)) ([`7a2cb0e93`](https://github.com/gptme/gptme/commit/7a2cb0e937f87c1261d10815bc20dfa4d78e34c8))
 - feat(restart): switch interface with /restart cli|tui|web ([#3990](https://github.com/gptme/gptme/issues/3990)) ([`58e81a299`](https://github.com/gptme/gptme/commit/58e81a29937361ca85fa733ef9a4238bf02021b7))
 - feat(tui): accept prompts on the command line, like the CLI ([#3980](https://github.com/gptme/gptme/issues/3980)) ([`4e2816b81`](https://github.com/gptme/gptme/commit/4e2816b81b236be423788d372e12c170a2930103))
 - feat(tui): --resume [NAME]: pick from a list, or open NAME directly ([#3971](https://github.com/gptme/gptme/issues/3971)) ([`5a8447560`](https://github.com/gptme/gptme/commit/5a84475601597a217c14b27dc42d86e81860789d))
 - feat(tui): collapse long pastes into atomic placeholder tokens ([#3972](https://github.com/gptme/gptme/issues/3972)) ([`77e2a5daf`](https://github.com/gptme/gptme/commit/77e2a5daf44bac66b27411e8dfac1d8b5b51654b))
 - feat(tools): URL host allowlist for autonomous web access ([#3954](https://github.com/gptme/gptme/issues/3954)) ([`e14e96743`](https://github.com/gptme/gptme/commit/e14e9674391e8c49c6bc65cdfe24e035587fb1fb))
 - feat(compaction): Phase 1 — one budget, always-on trigger, no per-call mutation ([#3812](https://github.com/gptme/gptme/issues/3812)) ([#3895](https://github.com/gptme/gptme/issues/3895)) ([`c0a08f821`](https://github.com/gptme/gptme/commit/c0a08f821452b47f0460a3120896028fcb592290))
 - feat(providers): make api_key_env optional in ProviderPlugin ([#3957](https://github.com/gptme/gptme/issues/3957)) ([`b41335250`](https://github.com/gptme/gptme/commit/b413352502cc6c401d7bfda552faaf23c554fa46))
 - feat(tauri): LAN QR access backend — Phase 1 ([#3947](https://github.com/gptme/gptme/issues/3947)) ([`9da3f45f4`](https://github.com/gptme/gptme/commit/9da3f45f44f7b7843e3b8ef552407c405ced6dad))
 - feat(server): forward temperature and top_p request overrides to provider ([#3942](https://github.com/gptme/gptme/issues/3942)) ([`00df83152`](https://github.com/gptme/gptme/commit/00df8315232125e1c2b46617111a8a84b22a40e4))
 - feat(webui): add provider health dot badge to model picker label ([#3917](https://github.com/gptme/gptme/issues/3917)) ([`c377ecf71`](https://github.com/gptme/gptme/commit/c377ecf71a8446cf33af8cdc25d3d1db0dff1e65))
 - feat(webui): subscription provider setup (ChatGPT/Grok/OpenRouter PKCE) ([#3912](https://github.com/gptme/gptme/issues/3912)) ([`fc2951579`](https://github.com/gptme/gptme/commit/fc295157951338e7780c1b09afc370b0458b0c9c))
 - feat(models): add GPT-6 Sol and GPT-6 Luna to OpenAI model registry ([#3914](https://github.com/gptme/gptme/issues/3914)) ([`d22c3f271`](https://github.com/gptme/gptme/commit/d22c3f271698c175a768cb872469adeb05b331df))
 - feat(subagent): deliver completions to idle server sessions ([#3897](https://github.com/gptme/gptme/issues/3897)) ([`1a0e76109`](https://github.com/gptme/gptme/commit/1a0e761098dfa520886157e8e26191c217a36a5a))
 - feat(shell): promote slow foreground commands ([#3898](https://github.com/gptme/gptme/issues/3898)) ([`4b15dfc11`](https://github.com/gptme/gptme/commit/4b15dfc11ce8a275803bb8f4555b7718b050abf4))
 - feat(compaction): recover once from provider context overflow ([#3816](https://github.com/gptme/gptme/issues/3816)) ([`0e4ef82bd`](https://github.com/gptme/gptme/commit/0e4ef82bd6a6090bf9cefd357acc8f1dbebf2662))
 - feat(doctor): add interactive provider repair ([#3891](https://github.com/gptme/gptme/issues/3891)) ([`7e382b139`](https://github.com/gptme/gptme/commit/7e382b139a344efe5fa2d129bd4fa3237c6b1ef3))

### 🐛 Fixes (217)
<details><summary>Click to expand</summary>
<p>

 - fix(compact): keep the last message, default to summarize, no-op trim says so ([#4371](https://github.com/gptme/gptme/issues/4371)) ([`f1cf26c76`](https://github.com/gptme/gptme/commit/f1cf26c76a8f744044c569f228b0a91d5d3b1e7a))
 - fix(tools): declare undeclared kwargs params; add conformance test ([#4366](https://github.com/gptme/gptme/issues/4366)) ([`f34595c08`](https://github.com/gptme/gptme/commit/f34595c0858d11add5d67ee6fe11c53b946c1ec4))
 - fix(tui): use Markdown widget for prose segments to stop layout jump at finalize ([#4364](https://github.com/gptme/gptme/issues/4364)) ([`ba1266910`](https://github.com/gptme/gptme/commit/ba126691065a7c7ce01d010269a44a2826d40d29))
 - fix(e2e): fix flaky sidebar tests broken by virtualization scroll-to-bottom ([#4362](https://github.com/gptme/gptme/issues/4362)) ([`b9465faae`](https://github.com/gptme/gptme/commit/b9465faaeea73b2869a1aac410276b4ed6207cec))
 - fix(tui): show message and tool indicator before tool execution begins ([#4347](https://github.com/gptme/gptme/issues/4347)) ([`3c06e73c6`](https://github.com/gptme/gptme/commit/3c06e73c6820d32ecd861253adf53e0379be6332))
 - fix(tui): compact, readable markdown headers in messages ([#4358](https://github.com/gptme/gptme/issues/4358)) ([`a539998e1`](https://github.com/gptme/gptme/commit/a539998e12a2b74332ecba5f21fbddd902e822c0))
 - fix(tui): drop duplicate _generation_thread declaration ([#4344](https://github.com/gptme/gptme/issues/4344) + [#4354](https://github.com/gptme/gptme/issues/4354)) ([#4361](https://github.com/gptme/gptme/issues/4361)) ([`cfab89ad1`](https://github.com/gptme/gptme/commit/cfab89ad138a87ea1021cfb9676620fdb0408eb5))
 - fix(tui): handle `<think redacted>` tags from Anthropic extended thinking ([#4345](https://github.com/gptme/gptme/issues/4345)) ([`274053684`](https://github.com/gptme/gptme/commit/274053684c4c1b36b04f44a5137cdeba432bbced))
 - fix(tui): body mode in _update_hidden_segments when show_thinking=True ([#4356](https://github.com/gptme/gptme/issues/4356)) ([`bd96a8016`](https://github.com/gptme/gptme/commit/bd96a8016a1a85380c3d7f9aed75ee7c6cee55d6))
 - fix(shell): only block pipes that feed an interpreter its program ([#4350](https://github.com/gptme/gptme/issues/4350)) ([`f0c586178`](https://github.com/gptme/gptme/commit/f0c5861786f720f6ce07945ce3b2edb18fa07d30))
 - fix(tui): ignore a statusline result that arrives after the screen is gone ([#4357](https://github.com/gptme/gptme/issues/4357)) ([`64bf8c817`](https://github.com/gptme/gptme/commit/64bf8c817c8557a8f53b1d4b50a759af7ba2d714))
 - fix(webui): don't show model selector skeleton pill on home page ([#4349](https://github.com/gptme/gptme/issues/4349)) ([`f70bafa8b`](https://github.com/gptme/gptme/commit/f70bafa8be48bb8d3ed7802e56589135c1f5fd29))
 - fix(webui): move embedded keyboard shortcuts into account menu ([#4343](https://github.com/gptme/gptme/issues/4343)) ([`d51ee35d3`](https://github.com/gptme/gptme/commit/d51ee35d3cb90ab12d0f0d1493b7fef8c016c2ff))
 - fix(tui): statusline payload says '`<no model set>`' instead of None ([#4352](https://github.com/gptme/gptme/issues/4352)) ([`ddf4d42cd`](https://github.com/gptme/gptme/commit/ddf4d42cd5954ca9bbcdb18b17ce205abdf9c9e7))
 - fix(llm): bound selector input and actual provider requests ([#4341](https://github.com/gptme/gptme/issues/4341)) ([`b4d3f35e5`](https://github.com/gptme/gptme/commit/b4d3f35e523cd1d5113b3806d53a5d1322bee815))
 - fix(tui): stream tool-call blocks as collapsed stubs to prevent layout jumps ([#4342](https://github.com/gptme/gptme/issues/4342)) ([`785864972`](https://github.com/gptme/gptme/commit/785864972d05dc1a71b2ff4e2045bbb47e6b5ebf))
 - fix(config): accept CSS color names like 'pink' for [agent]/[user] color ([#4337](https://github.com/gptme/gptme/issues/4337)) ([`463aa34f6`](https://github.com/gptme/gptme/commit/463aa34f650afc6ccfff013ed36d0e93e587c897))
 - fix(tui): render assistant message in place, no preview→final swap ([#4334](https://github.com/gptme/gptme/issues/4334)) ([`49472c7f2`](https://github.com/gptme/gptme/commit/49472c7f21fdd6bea3ed0f459876e21082709f0c))
 - fix(webui): patch 7 transitive dependabot alerts in package-lock.json ([#4333](https://github.com/gptme/gptme/issues/4333)) ([`955bb55d1`](https://github.com/gptme/gptme/commit/955bb55d125eb691e68c168c5cb44df26d8e6023))
 - fix(context): stop attaching bare words that match cwd entries; add TUI path completion ([#4329](https://github.com/gptme/gptme/issues/4329)) ([`35fff805d`](https://github.com/gptme/gptme/commit/35fff805d0432a8951feb467c94407eca21ba014))
 - fix(tui): run slash-commands in a worker so slow ones don't freeze the UI ([#4330](https://github.com/gptme/gptme/issues/4330)) ([`2ac769218`](https://github.com/gptme/gptme/commit/2ac76921830e1cdda7d8d2bb28c000a278bab44d))
 - fix(context): don't crash on '~word' prose; include_paths never crashes a prompt ([#4326](https://github.com/gptme/gptme/issues/4326)) ([`1dbdfad6b`](https://github.com/gptme/gptme/commit/1dbdfad6b6082e340801f57ee8c3680306810354))
 - fix(context): don't crash on '~word' prose; include_paths never crashes a prompt ([#4326](https://github.com/gptme/gptme/issues/4326)) ([`b1de5fe9a`](https://github.com/gptme/gptme/commit/b1de5fe9a70602457c80b3a8bd342a43d6b9536d))
 - fix(tui): don't crash on a click that hits a just-removed widget ([#4323](https://github.com/gptme/gptme/issues/4323)) ([`fb2b9deed`](https://github.com/gptme/gptme/commit/fb2b9deed1268d3dea643deebcdddd3c898c57ba))
 - fix(tui): don't crash when a prompt contains a URL ([#4320](https://github.com/gptme/gptme/issues/4320)) ([`cb36d2081`](https://github.com/gptme/gptme/commit/cb36d20813acbfc46fa9621a4d50df15aa3d015a))
 - fix(docs): fix garbled provider integration table and lint grid table alignment ([#4312](https://github.com/gptme/gptme/issues/4312)) ([`9162d6ef9`](https://github.com/gptme/gptme/commit/9162d6ef9ffa65432d25e0a4e510b0266bb56688))
 - fix(tauri): bump rustls to 0.23.45 and serde_with to 3.21.0 in Cargo.lock ([#4308](https://github.com/gptme/gptme/issues/4308)) ([`fff2c75a1`](https://github.com/gptme/gptme/commit/fff2c75a1e3dee897b9f8d96dd696a7af0d66b45))
 - fix(release): fail closed on partial API errors in default shell ([#4310](https://github.com/gptme/gptme/issues/4310)) ([`8bd8a4be1`](https://github.com/gptme/gptme/commit/8bd8a4be1d17bc84350121b59ae95ffad2e2cdeb))
 - fix(release): only count push-triggered checks in release preflight ([#4305](https://github.com/gptme/gptme/issues/4305)) ([`6348d7895`](https://github.com/gptme/gptme/commit/6348d78955e95c18c9bbda2c5341f9a771330232))
 - fix(deps): switch Dependabot pip → uv ecosystem for root Python deps ([#4295](https://github.com/gptme/gptme/issues/4295)) ([`198742898`](https://github.com/gptme/gptme/commit/198742898f8aec6f29afc9f62badf845814dfd51))
 - fix(models): apply OpenRouter pricing.overrides long-context tiers to cost accounting ([#4272](https://github.com/gptme/gptme/issues/4272)) ([`d694cbc61`](https://github.com/gptme/gptme/commit/d694cbc617c8790edf80ae386a053394c33eef50))
 - fix(mcp): alias qualified tool names for native providers ([#4265](https://github.com/gptme/gptme/issues/4265)) ([`a8a9feeac`](https://github.com/gptme/gptme/commit/a8a9feeacac21ac0637b1de7e12d7b318d47120f))
 - fix(tauri): use platform-correct URL in IPC test helper for tauri 2.12 ([#4288](https://github.com/gptme/gptme/issues/4288)) ([`b6e4e7278`](https://github.com/gptme/gptme/commit/b6e4e72787f249d3289be9f2a6a2a1ede8f75316))
 - fix(server): return empty list for /api/v2/external-sessions when provider unconfigured ([#4281](https://github.com/gptme/gptme/issues/4281)) ([`2062db709`](https://github.com/gptme/gptme/commit/2062db7092e22c14e3b243ce68efedafbca34cf7))
 - fix(context): fall back to rule-based pre-filter when LLM refinement reply is malformed ([#4291](https://github.com/gptme/gptme/issues/4291)) ([`ca5da494d`](https://github.com/gptme/gptme/commit/ca5da494d699ca42bd3ed4128798ed479e2250fb))
 - fix(mcp): drop the closed client from the registry before reconnecting in _restart_mcp_client ([#4292](https://github.com/gptme/gptme/issues/4292)) ([`411276ae6`](https://github.com/gptme/gptme/commit/411276ae6fb74bb40b59aee3eaf2713a6caeeacb))
 - fix(context): fall back when selector replies are malformed ([#4282](https://github.com/gptme/gptme/issues/4282)) ([`375c863af`](https://github.com/gptme/gptme/commit/375c863af7c8aaffb856d5a07ab94e9150148295))
 - fix(slop): print suppression notice to stderr when --no-fail overrides a FAIL verdict ([#4280](https://github.com/gptme/gptme/issues/4280)) ([`810112bfa`](https://github.com/gptme/gptme/commit/810112bfa4fd0813310ed415213f13b7b121907e))
 - fix(llm): replay Gemini thought signatures on native tool calls ([#4276](https://github.com/gptme/gptme/issues/4276)) ([`5dbbacc68`](https://github.com/gptme/gptme/commit/5dbbacc680fe6400d1d12599affbac332edf81fa))
 - fix(docs): exclude gptme-contrib from linkcheck to prevent recurring 429s ([#4275](https://github.com/gptme/gptme/issues/4275)) ([`28b9518c5`](https://github.com/gptme/gptme/commit/28b9518c56c84d67797f7414008fe9395492388f))
 - fix(shell): use incremental UTF-8 decoder in BackgroundJob ([#4269](https://github.com/gptme/gptme/issues/4269)) ([`3c18c09a8`](https://github.com/gptme/gptme/commit/3c18c09a8175c3f39f6bd97a6646029544fcaac6))
 - fix(models): remove retired Qwen3 Max OpenRouter entry ([#4268](https://github.com/gptme/gptme/issues/4268)) ([`5b0e5fb9d`](https://github.com/gptme/gptme/commit/5b0e5fb9deb397bd2408d2eecc3ffcabdece95bd))
 - fix(gh): preserve explicit repository in native run log retrieval ([#4271](https://github.com/gptme/gptme/issues/4271)) ([`b648113b8`](https://github.com/gptme/gptme/commit/b648113b8a121c95f4c773b8dac815f970142670))
 - fix(eventlog): recover correctly after a damaged compacted tail ([#4249](https://github.com/gptme/gptme/issues/4249)) ([`0ddbb90f5`](https://github.com/gptme/gptme/commit/0ddbb90f50aab961feed8188041febf2345cee8d))
 - fix(docs): skip crawler-throttled GitHub topic links ([#4248](https://github.com/gptme/gptme/issues/4248)) ([`b1af28ed8`](https://github.com/gptme/gptme/commit/b1af28ed8015025f8b0ccc04ea3816a386cb52f0))
 - fix(server): honor TOOL_FORMAT and parse native tool calls in steps ([#4243](https://github.com/gptme/gptme/issues/4243)) ([`1464b2586`](https://github.com/gptme/gptme/commit/1464b2586362679bb720556e3ef8c527d30a8247))
 - fix(server): reject an exhausted stream with no output instead of persisting an empty assistant turn ([#4239](https://github.com/gptme/gptme/issues/4239)) ([`15210e96b`](https://github.com/gptme/gptme/commit/15210e96b3abbae28b29f16dcbfe6026f908a9e4))
 - fix(compaction): reland [#4224](https://github.com/gptme/gptme/issues/4224)-[#4226](https://github.com/gptme/gptme/issues/4226) that merged into a stacked branch ([#4236](https://github.com/gptme/gptme/issues/4236)) ([`b5dfecf85`](https://github.com/gptme/gptme/commit/b5dfecf8590f027183141d43aba1478a1e88f96d))
 - fix(test): use column check instead of substring check in test_shell_session_records_its_pgid ([#4241](https://github.com/gptme/gptme/issues/4241)) ([`f7d38b582`](https://github.com/gptme/gptme/commit/f7d38b5829e8609c78a939aba804e2fc3aff2b89))
 - fix(logmanager): handle same-process Windows conversation locks ([#3848](https://github.com/gptme/gptme/issues/3848)) ([`2714e3345`](https://github.com/gptme/gptme/commit/2714e33452589ef33233bbf8ba3b9d45fd6f3c64))
 - fix(llm): retry plain APIError from in-stream error events ([#4074](https://github.com/gptme/gptme/issues/4074)) ([`bd4a8b4d4`](https://github.com/gptme/gptme/commit/bd4a8b4d408c47d57e14a1c92334e11add38d78e))
 - fix(subagent): cap thread-mode subagent LLM request timeout by remaining deadline ([#4208](https://github.com/gptme/gptme/issues/4208)) ([`080097767`](https://github.com/gptme/gptme/commit/0800977673df1e940de59bfa88afa98d1f7eb61f))
 - fix(openai-responses): drop orphaned tool results with no preceding call ([#4207](https://github.com/gptme/gptme/issues/4207)) ([`05e4508dc`](https://github.com/gptme/gptme/commit/05e4508dc7f46a8058ee9204227699fcb789b29d))
 - fix(anthropic): pass an explicit timeout so non-streaming chat() accepts 64k+ max_tokens ([#4221](https://github.com/gptme/gptme/issues/4221)) ([`6f4e95081`](https://github.com/gptme/gptme/commit/6f4e95081555efd5f15375ef7e5569d4e49f7670))
 - fix(mcp): preserve complete search queries ([#4235](https://github.com/gptme/gptme/issues/4235)) ([`cad7a5245`](https://github.com/gptme/gptme/commit/cad7a5245a54743ccdf083897654c9440e1042fd))
 - fix(llm): reject an exhausted stream with no output instead of persisting an empty assistant turn ([#4222](https://github.com/gptme/gptme/issues/4222)) ([`d538cbf49`](https://github.com/gptme/gptme/commit/d538cbf4983d315d5b4b1dafb0a2d683f85dc3e8))
 - fix(ci): retry apt-get update up to 3 times with timeout ([#4231](https://github.com/gptme/gptme/issues/4231)) ([`1dffc3aa9`](https://github.com/gptme/gptme/commit/1dffc3aa9b438c00b397312c2147cf2a14a620c8))
 - fix(cli): clean errors for non-UTF-8 input files (tokens count, attest verify, capabilities) ([#4176](https://github.com/gptme/gptme/issues/4176)) ([`35663e34f`](https://github.com/gptme/gptme/commit/35663e34f2945215b1360918d354a387bd15e771))
 - fix(compaction): re-compaction carries the previous checkpoint and drops stale intros ([#4183](https://github.com/gptme/gptme/issues/4183)) ([`3502854c5`](https://github.com/gptme/gptme/commit/3502854c55625d46733f752db9d40a7d1435bebe))
 - fix(cli): keep plugin subcommand args opaque to gptme's own options ([#4220](https://github.com/gptme/gptme/issues/4220)) ([`3f5aa436e`](https://github.com/gptme/gptme/commit/3f5aa436e4297a4945d715ba6bc8ae7ead79e687))
 - fix(mcp): load_mcp_server now registers ToolSpecs and updates cache ([#4215](https://github.com/gptme/gptme/issues/4215)) ([`f0927eb65`](https://github.com/gptme/gptme/commit/f0927eb65abfb7caf94033348675abe6c1d99aa1))
 - fix(context): skip unreadable files in prompt path inclusion instead of crashing ([#4185](https://github.com/gptme/gptme/issues/4185)) ([`d2ec08d12`](https://github.com/gptme/gptme/commit/d2ec08d120d50542c139680c4e1b493a41c0e17a))
 - fix(init): report invalid gptme-init targets as clean errors ([#4173](https://github.com/gptme/gptme/issues/4173)) ([`c4ecb8183`](https://github.com/gptme/gptme/commit/c4ecb818306670144b78649591d783125bd4e9e7))
 - fix(tokens): warn when model has no native tiktoken encoding ([#4196](https://github.com/gptme/gptme/issues/4196)) ([`a7509a5a0`](https://github.com/gptme/gptme/commit/a7509a5a0c05d2a4810b5991e6dc20d72f3f23df))
 - fix(webui): navigate before clearing store on conversation delete ([#4209](https://github.com/gptme/gptme/issues/4209)) ([`a0705c188`](https://github.com/gptme/gptme/commit/a0705c18830231980cbcf0681e0acf655b28b08f))
 - fix(chats): skip malformed external sessions instead of aborting the search ([#4192](https://github.com/gptme/gptme/issues/4192)) ([`e790ad183`](https://github.com/gptme/gptme/commit/e790ad18363511039494b89539595f9061c11da4))
 - fix(read): stream line ranges of large files instead of loading them whole ([#4191](https://github.com/gptme/gptme/issues/4191)) ([`f4f3205dc`](https://github.com/gptme/gptme/commit/f4f3205dcaf5207129cd3210c6612a12e5f12a0a))
 - fix(context): read only the capped prefix of large files named in a prompt ([#4187](https://github.com/gptme/gptme/issues/4187)) ([`ada33c3b8`](https://github.com/gptme/gptme/commit/ada33c3b880ed6684e663ad15864477ae82968e5))
 - fix(models-info): exit 1 when model resolves to unknown provider ([#4210](https://github.com/gptme/gptme/issues/4210)) ([`16ada496c`](https://github.com/gptme/gptme/commit/16ada496c76348d2ff17d68cf4ec2e67e6b5e6a8))
 - fix(computer): audit-log sees keyword/positional computer() calls via AST ([#4203](https://github.com/gptme/gptme/issues/4203)) ([`01f7e6b3f`](https://github.com/gptme/gptme/commit/01f7e6b3f535221b1e7cea78656dc77d8b46cb19))
 - fix(anti-slop): use fractional em-dash excess so short texts aren't over-penalised ([#4195](https://github.com/gptme/gptme/issues/4195)) ([`63e651b2a`](https://github.com/gptme/gptme/commit/63e651b2a0b088c9766ed4e9f1208b7f80639fe0))
 - fix(lessons): coerce non-string frontmatter name to str ([#4181](https://github.com/gptme/gptme/issues/4181)) ([`16cfbdd82`](https://github.com/gptme/gptme/commit/16cfbdd82e1c0f817cd36f75ee0f1257e42c9447))
 - fix(slop): lower STACCATO_MAX_WORDS 8→7 to fix false positive on technical doc sentences ([#4211](https://github.com/gptme/gptme/issues/4211)) ([`65c778b6c`](https://github.com/gptme/gptme/commit/65c778b6cd7a4f65979b13372259ae080c8b4790))
 - fix(init): escape project name when writing gptme.toml ([#4175](https://github.com/gptme/gptme/issues/4175)) ([`461a603d4`](https://github.com/gptme/gptme/commit/461a603d4670a4e529e0cecb0cbbb6c5b5277e90))
 - fix(cli): tolerate non-UTF-8 .gitignore and journal files in context commands ([#4177](https://github.com/gptme/gptme/issues/4177)) ([`6e1600fb3`](https://github.com/gptme/gptme/commit/6e1600fb39923aa3db7c501439c7b4d38a82616d))
 - fix(config): reject non-list prompt.files and other string-list project settings ([#4179](https://github.com/gptme/gptme/issues/4179)) ([`da489220b`](https://github.com/gptme/gptme/commit/da489220b95ffc5e4ca058af6efad2da1037b7dd))
 - fix(agents): don't attribute the newest log dir to unnamed gptme processes ([#4189](https://github.com/gptme/gptme/issues/4189)) ([`59db3b19e`](https://github.com/gptme/gptme/commit/59db3b19e982dd5e714738c9990e2a13e25c50a9))
 - fix(chats): reject blank and normalize multi-line names in chats rename ([#4198](https://github.com/gptme/gptme/issues/4198)) ([`3858b248e`](https://github.com/gptme/gptme/commit/3858b248eaf4d97c174f0d12540d4db5e7fe1a83))
 - fix(save): refuse non-regular-file targets instead of hanging on a FIFO ([#4190](https://github.com/gptme/gptme/issues/4190)) ([`472e98a4d`](https://github.com/gptme/gptme/commit/472e98a4dde6d1fd40630a9563a5ab523d8e533d))
 - fix(llm): use NOT_GIVEN timeout in Anthropic non-streaming chat() ([#4064](https://github.com/gptme/gptme/issues/4064)) ([`4885cb0be`](https://github.com/gptme/gptme/commit/4885cb0be80dec4deda5f214f73222cd7579c120))
 - fix(logmanager): skip corrupt conversation lines instead of failing the whole read ([#4182](https://github.com/gptme/gptme/issues/4182)) ([`14b9387b5`](https://github.com/gptme/gptme/commit/14b9387b5c95739278c21852a1c55ecd52aa8e80))
 - fix(message): don't append ellipsis to short oneline messages ([#4197](https://github.com/gptme/gptme/issues/4197)) ([`7454b0f29`](https://github.com/gptme/gptme/commit/7454b0f296042441be56d7c1a6b4defe1328e21c))
 - fix(hooks): reject malformed Claude Code settings.json instead of crashing ([#4178](https://github.com/gptme/gptme/issues/4178)) ([`fa1842a4f`](https://github.com/gptme/gptme/commit/fa1842a4f5aeee085985245a61b78047dacfb16c))
 - fix(ci): disable provenance attestation on Docker push to fix GHCR unknown blob ([#4202](https://github.com/gptme/gptme/issues/4202)) ([`a6ce80cdb`](https://github.com/gptme/gptme/commit/a6ce80cdbf183021827627922be3dccf27535c68))
 - fix(openai-responses): clamp instructions to 1MB char cap for Responses API ([#4206](https://github.com/gptme/gptme/issues/4206)) ([`4f2303ce8`](https://github.com/gptme/gptme/commit/4f2303ce8e8a79b9713e84e49cdde5a009f6ecd4))
 - fix(openai-subscription): clamp Codex instructions to 1MB char cap ([#4166](https://github.com/gptme/gptme/issues/4166)) ([`db903ba37`](https://github.com/gptme/gptme/commit/db903ba37d512888cb5c7df1b2a7ad09b4d890de))
 - fix(cli): reject unknown --provider in models list instead of listing nothing ([#4184](https://github.com/gptme/gptme/issues/4184)) ([`d56550f12`](https://github.com/gptme/gptme/commit/d56550f127917bfe891cc3398979bc1f0b4da509))
 - fix(preview): send Cache-Control private, no-store on preview responses ([#4180](https://github.com/gptme/gptme/issues/4180)) ([`c5c520913`](https://github.com/gptme/gptme/commit/c5c520913ddde67c299d4ab38ec4a62f601ac8ab))
 - fix(llm): accept mixed-case image attachment extensions ([#4171](https://github.com/gptme/gptme/issues/4171)) ([`536e6c379`](https://github.com/gptme/gptme/commit/536e6c379fbcd8c5493da818f7df8f4e0974b632))
 - fix(telemetry): use Fable 5.1 cached-input pricing ([#4126](https://github.com/gptme/gptme/issues/4126)) ([`7bf274124`](https://github.com/gptme/gptme/commit/7bf2741249e597a484b607abaef93aa6cd89bf7c))
 - fix(compaction): reject empty summarize checkpoints instead of replacing history ([#4172](https://github.com/gptme/gptme/issues/4172)) ([`ce5ed9f22`](https://github.com/gptme/gptme/commit/ce5ed9f224f0018a6ddadbb97a429c8a693ecb8e))
 - fix(responses): surface explicit SSE generation failures ([#4170](https://github.com/gptme/gptme/issues/4170)) ([`a990d028e`](https://github.com/gptme/gptme/commit/a990d028ed5c0fff814699ebd220c24fafdc1be4))
 - fix(anthropic): register Claude 5 models and use supported thinking modes ([#4125](https://github.com/gptme/gptme/issues/4125)) ([`0939c341d`](https://github.com/gptme/gptme/commit/0939c341d76a92607e692c5931b54ee2e8b1c500))
 - fix(compaction): share bounded overflow recovery across CLI and server ([#4123](https://github.com/gptme/gptme/issues/4123)) ([`4dab17fb8`](https://github.com/gptme/gptme/commit/4dab17fb8c5c551c0bcae15f1ff51d340095210d))
 - fix(cli): warn on stderr when prompts expand path not found ([#3943](https://github.com/gptme/gptme/issues/3943)) ([`127dc5c91`](https://github.com/gptme/gptme/commit/127dc5c91c4bee3a52c50621c5cfe48cad11c304))
 - fix(webui): keep welcome view reachable on short/mobile viewports ([#4056](https://github.com/gptme/gptme/issues/4056)) ([`36ada30f8`](https://github.com/gptme/gptme/commit/36ada30f8514ee81f184a092e7980b5ef7fda105))
 - fix(llm): raise on Responses API error/response.failed events, warn on incomplete ([#4084](https://github.com/gptme/gptme/issues/4084)) ([`c507599ae`](https://github.com/gptme/gptme/commit/c507599ae96899cc593afaa7775b29b872dd807d))
 - fix(server): evict idle client-less sessions unconditionally ([#4067](https://github.com/gptme/gptme/issues/4067)) ([`968f8b381`](https://github.com/gptme/gptme/commit/968f8b38187e632b70adb442f2759af46b17628c))
 - fix(models): concise provider errors and parallel fetch in models list ([#4062](https://github.com/gptme/gptme/issues/4062)) ([`b7eb9f51c`](https://github.com/gptme/gptme/commit/b7eb9f51c272e5c31f6b9d05a60cbe5936f614b4))
 - fix(browser): configure executable independently of engine ([#4168](https://github.com/gptme/gptme/issues/4168)) ([`546e88ab0`](https://github.com/gptme/gptme/commit/546e88ab02a6eb86ba79ad43a0a7ad7853e254f0))
 - fix(subagent): kill the child's persistent shells when escalating to SIGKILL ([#4097](https://github.com/gptme/gptme/issues/4097)) ([`801f20062`](https://github.com/gptme/gptme/commit/801f20062da680fd074773488afeb81aa39a2152))
 - fix(webui): gate sidebar external-sessions query on server capability ([#4148](https://github.com/gptme/gptme/issues/4148)) ([`fec0bec44`](https://github.com/gptme/gptme/commit/fec0bec4438f7e55569ac99510f2d037376da2a7))
 - fix(webui): anchor toasts at the top so they never cover the composer ([#4149](https://github.com/gptme/gptme/issues/4149)) ([`4ea9068d0`](https://github.com/gptme/gptme/commit/4ea9068d01a30b2c8780fd08bf09a696ed0f2915))
 - fix(telemetry): account for explicit OpenRouter cache-read prices ([#4151](https://github.com/gptme/gptme/issues/4151)) ([`2992c9a6f`](https://github.com/gptme/gptme/commit/2992c9a6f237e69fce3b7a0f91fd6b2105b7b1d3))
 - fix(hooks): make deprecated knowledge injection opt in ([#4160](https://github.com/gptme/gptme/issues/4160)) ([`f25cb5bf6`](https://github.com/gptme/gptme/commit/f25cb5bf603a98b2bd11ddfb21240b91ffb52455))
 - fix(vent): preserve launcher session and runtime provenance ([#4156](https://github.com/gptme/gptme/issues/4156)) ([`944554e39`](https://github.com/gptme/gptme/commit/944554e392fcda62d8760766116e1247734ba5c7))
 - fix(memory): report the written entry in scoped save JSON ([#4155](https://github.com/gptme/gptme/issues/4155)) ([`ce208c9f6`](https://github.com/gptme/gptme/commit/ce208c9f6263c6d998c56e8d8216378198eee0cc))
 - fix(subagent): select native child tool format from model metadata ([#4154](https://github.com/gptme/gptme/issues/4154)) ([`be054fc58`](https://github.com/gptme/gptme/commit/be054fc585a86b43cd89094a45422874a921130c))
 - fix(webui): don't skip cloud sign-in when a local server is already connected ([#4153](https://github.com/gptme/gptme/issues/4153)) ([`a7702f96f`](https://github.com/gptme/gptme/commit/a7702f96f736372c8f7faf818cc2f7189eb57bc1))
 - fix(mcp): load workspace config in diagnostic CLI commands ([#4050](https://github.com/gptme/gptme/issues/4050)) ([`3615e94d9`](https://github.com/gptme/gptme/commit/3615e94d9ad78a040ca81941a1a4df6a20c6e66d))
 - fix(startup): defer prompt UI imports until interactive input ([#4131](https://github.com/gptme/gptme/issues/4131)) ([`f26d7dbe5`](https://github.com/gptme/gptme/commit/f26d7dbe57d855dd6de68d8b0bfb44e09227087e))
 - fix(webui): show the sent model in the pill while chatConfig loads ([#4150](https://github.com/gptme/gptme/issues/4150)) ([`ee32da7ec`](https://github.com/gptme/gptme/commit/ee32da7ecdf3bd8f7ffeade6f812119998e0ea75))
 - fix(tools): preserve CRLF line endings in patch and morph ([#4081](https://github.com/gptme/gptme/issues/4081)) ([`a015ee4c4`](https://github.com/gptme/gptme/commit/a015ee4c43763ada07ce3d7f50e353d48dda1563))
 - fix(webui): redirect after deleting active conversation ([#4140](https://github.com/gptme/gptme/issues/4140)) ([`649170b0a`](https://github.com/gptme/gptme/commit/649170b0aa5694d225d0283d5f586e673c28666e))
 - fix(eval): stop leaking multiprocessing_logging wrappers onto the root logger ([#4132](https://github.com/gptme/gptme/issues/4132)) ([`16b93eaf7`](https://github.com/gptme/gptme/commit/16b93eaf75bc33fb96b919055951ee967a2fbc57))
 - fix(context): handle deleted CWD in file_to_display_path ([#4142](https://github.com/gptme/gptme/issues/4142)) ([`75cc006b6`](https://github.com/gptme/gptme/commit/75cc006b6824da31b796fbeaf686b391b2b75e2e))
 - fix(cli): make skills show prefer exact matches and reject ambiguous ones ([#4058](https://github.com/gptme/gptme/issues/4058)) ([`4bad9ea0c`](https://github.com/gptme/gptme/commit/4bad9ea0c0d082426628bf083dbf08d913a7f485))
 - fix(changelog): link commits by full SHA; fix 404 links in release notes ([#4113](https://github.com/gptme/gptme/issues/4113)) ([`eeebc82e2`](https://github.com/gptme/gptme/commit/eeebc82e238df14d90c673c9f4e1fcb0f3bb2b6e))
 - fix(python): cap unbounded stdout and result output ([#4078](https://github.com/gptme/gptme/issues/4078)) ([`b89b0f84e`](https://github.com/gptme/gptme/commit/b89b0f84ec9d83c2dd4bb2419ad165d36add5a54))
 - fix(responses): pair orphaned function calls with missing-result errors ([#4139](https://github.com/gptme/gptme/issues/4139)) ([`02f025ec6`](https://github.com/gptme/gptme/commit/02f025ec6c73eebc7d176a54aaf75d00825ff9db))
 - fix(webui): sync rotated Tauri sidecar token on non-default ports ([#4065](https://github.com/gptme/gptme/issues/4065)) ([`c81db98a1`](https://github.com/gptme/gptme/commit/c81db98a15833ece6d26c34928a3f33819eb3956))
 - fix(webui): correct local TTS setup instructions and port ([#4124](https://github.com/gptme/gptme/issues/4124)) ([`a48546e64`](https://github.com/gptme/gptme/commit/a48546e64bbd8c1137c3de34f03fa4186b253e3d))
 - fix(server): honor --tools allowlist for new conversations ([#4049](https://github.com/gptme/gptme/issues/4049)) ([`ab0fe88be`](https://github.com/gptme/gptme/commit/ab0fe88be3354097ec6eae35b117687128918d74))
 - fix(server): tool/confirm 404 names the tool and the conversation correctly ([#4135](https://github.com/gptme/gptme/issues/4135)) ([`da71531d9`](https://github.com/gptme/gptme/commit/da71531d90d970be636570b9f16cfe450a2f9d30))
 - fix(llm): back off and retry 429/5xx on openai-subscription requests ([#4085](https://github.com/gptme/gptme/issues/4085)) ([`f0dbbffe3`](https://github.com/gptme/gptme/commit/f0dbbffe373b21d79648af97b7ec901b63aa4609))
 - fix(server): trim session events with clients connected; lock append/trim/read ([#4087](https://github.com/gptme/gptme/issues/4087)) ([`2420f9e4f`](https://github.com/gptme/gptme/commit/2420f9e4ff9fe7dae9a0e0850621ae06bc26b929))
 - fix(docs): update dead repo links to current locations ([#4043](https://github.com/gptme/gptme/issues/4043)) ([`5746ec73e`](https://github.com/gptme/gptme/commit/5746ec73ec6b9d2b97a311c5dd873514c6e4ffcc))
 - fix(llm): retry Anthropic connection/timeout errors and 408/409 ([#4066](https://github.com/gptme/gptme/issues/4066)) ([`c11f08778`](https://github.com/gptme/gptme/commit/c11f0877898c2aafaff7472431b7f34c871463c1))
 - fix(webui): refresh stale 'How do I use the web UI?' demo answer ([#4042](https://github.com/gptme/gptme/issues/4042)) ([`39e5ddf33`](https://github.com/gptme/gptme/commit/39e5ddf33ca222d7d1b151cb60d5ed9a68e1c970))
 - fix(context): read scout_model from project/user config ([#4086](https://github.com/gptme/gptme/issues/4086)) ([`3eeadc199`](https://github.com/gptme/gptme/commit/3eeadc19977e2ec47b82ba5d5e35e82049a047dc))
 - fix(cli): print fatal KeyError messages without repr quotes ([#4101](https://github.com/gptme/gptme/issues/4101)) ([`cbefb1d4f`](https://github.com/gptme/gptme/commit/cbefb1d4fc30d22d7e1bdb7458da69beb6403a75))
 - fix(grok-subscription): bump client version header to 1.0.13 ([#4063](https://github.com/gptme/gptme/issues/4063)) ([`f8975b005`](https://github.com/gptme/gptme/commit/f8975b00572fa30933ad6819d7c9e3838e8a228a))
 - fix(server): gate internal error details behind debug setting ([#4076](https://github.com/gptme/gptme/issues/4076)) ([`a5b6f7768`](https://github.com/gptme/gptme/commit/a5b6f776889663d49d7d84868fa1ae15317eed98))
 - fix(docs): render --cors-origin example as literal and seed theme mode ([#4045](https://github.com/gptme/gptme/issues/4045)) ([`4c9ffee55`](https://github.com/gptme/gptme/commit/4c9ffee55434e264a508b6be65ea950737bcd82f))
 - fix(compaction): trigger from anchored provider input usage ([#4036](https://github.com/gptme/gptme/issues/4036)) ([`927cba1df`](https://github.com/gptme/gptme/commit/927cba1dfcf08c9cc851b657993f8a5999b44602))
 - fix(llm): keep tool calls and content in non-stream OpenAI chat() regardless of finish_reason ([#4079](https://github.com/gptme/gptme/issues/4079)) ([`1bcb49ba2`](https://github.com/gptme/gptme/commit/1bcb49ba2be699ddcaafc8375946dff7d2113ccb))
 - fix(llm): record streamed OpenAI-compat usage once per response ([#4044](https://github.com/gptme/gptme/issues/4044)) ([`e03270c45`](https://github.com/gptme/gptme/commit/e03270c45e0df6749a189b7a1b995cd5fa44652d))
 - fix(telemetry): move LLM token counts and cost out of metric labels ([#4053](https://github.com/gptme/gptme/issues/4053)) ([`c8d2a5cfa`](https://github.com/gptme/gptme/commit/c8d2a5cfad29f8bf1b67828e2b5a05f91ee626a6))
 - fix(site): hide .sig files on downloads page and list Android APK ([#4055](https://github.com/gptme/gptme/issues/4055)) ([`5bf572162`](https://github.com/gptme/gptme/commit/5bf572162bf18d34071a6fa701c71bb8e897eae0))
 - fix(cli): gptme-auth login tolerates transient network errors ([#4077](https://github.com/gptme/gptme/issues/4077)) ([`52c322428`](https://github.com/gptme/gptme/commit/52c322428d8e0d732561ced3c5e585afa2a78a8b))
 - fix(cli): drop non-interactive stderr noise ([#4060](https://github.com/gptme/gptme/issues/4060)) ([`ec991e34c`](https://github.com/gptme/gptme/commit/ec991e34c3db029429be9abcd77ac6861a804c48))
 - fix(llm): serialize tools for all OpenAI-compatible providers ([#4047](https://github.com/gptme/gptme/issues/4047)) ([`4920de63d`](https://github.com/gptme/gptme/commit/4920de63d7d11a8821180a461ab4db8b52d49dd8))
 - fix(webui): shared nav items and 5-slot mobile bottom nav with More sheet ([#4059](https://github.com/gptme/gptme/issues/4059)) ([`38786ee30`](https://github.com/gptme/gptme/commit/38786ee307506657c81d7ce7574f6d76040e0a78))
 - fix(webui): show sign-in notice instead of a 401 iframe for remote instance previews ([#4093](https://github.com/gptme/gptme/issues/4093)) ([`4da431fcd`](https://github.com/gptme/gptme/commit/4da431fcd578a287b71dd7abfeb3f4a5cc50b8ea))
 - fix(deps): update vulnerable Poetry dependencies and unblock Dependabot ([#4068](https://github.com/gptme/gptme/issues/4068)) ([`9204dcabe`](https://github.com/gptme/gptme/commit/9204dcabe154fb38488838dab9904cb710fe9f8b))
 - fix(cli): reject unknown options before prompt text ([#4051](https://github.com/gptme/gptme/issues/4051)) ([`1ccd90a71`](https://github.com/gptme/gptme/commit/1ccd90a71bd9a4641dd6e6f59804f9f8e3851afc))
 - fix(shell): preserve UTF-8 sequences across persistent pipe reads ([#4073](https://github.com/gptme/gptme/issues/4073)) ([`8857f22d4`](https://github.com/gptme/gptme/commit/8857f22d49dc736a5c4a5d3035fafb79c834322f))
 - fix(todo): replay only assistant messages, ignore system-prompt examples ([#4054](https://github.com/gptme/gptme/issues/4054)) ([`a64460489`](https://github.com/gptme/gptme/commit/a644604893fec9202b79afbf5c0a0fdc5530bca3))
 - fix(subagent): allow graceful cleanup on subprocess timeout ([#4075](https://github.com/gptme/gptme/issues/4075)) ([`1a5a0cff5`](https://github.com/gptme/gptme/commit/1a5a0cff5d0b776ca699d1618cddd45811eb9579))
 - fix(patch): actionable messages for non-UTF-8 files and multi-hunk failures ([#4083](https://github.com/gptme/gptme/issues/4083)) ([`d586f8587`](https://github.com/gptme/gptme/commit/d586f8587663851f135e66e683418c8b1f531387))
 - fix(hooks): don't swallow TypeError raised inside generator hooks ([#4071](https://github.com/gptme/gptme/issues/4071)) ([`f4f1e4954`](https://github.com/gptme/gptme/commit/f4f1e4954fcd1b90aec04390c04753708ffe3883))
 - fix(mcp): stop per-tool allowlist warning spam and demote tool repr log ([#4057](https://github.com/gptme/gptme/issues/4057)) ([`e2f48222b`](https://github.com/gptme/gptme/commit/e2f48222b0f9d50762fde9fcd1b876e3739edff1))
 - fix(mcp): accept tool-format kwargs in MCP adapter execute ([#4048](https://github.com/gptme/gptme/issues/4048)) ([`a032b0d25`](https://github.com/gptme/gptme/commit/a032b0d25a586e0fcad03ed62437c970ad2f288d))
 - fix(webui): hide e2e stress-test fixture and internal issue ref from users ([#4046](https://github.com/gptme/gptme/issues/4046)) ([`a947fc4aa`](https://github.com/gptme/gptme/commit/a947fc4aa6dc273c4e7246baf7217a8b46bb2078))
 - fix(compaction): bound summarize request ([#3812](https://github.com/gptme/gptme/issues/3812)) ([#4037](https://github.com/gptme/gptme/issues/4037)) ([`8b4fd8c48`](https://github.com/gptme/gptme/commit/8b4fd8c48f7252f755e5e6ada3df7013008481f7))
 - fix(webui): share winning connection probe with superseded callers ([#4041](https://github.com/gptme/gptme/issues/4041)) ([`c9c0b6aa6`](https://github.com/gptme/gptme/commit/c9c0b6aa696f9f1f3e24f03dfbf4abdfb56d74b0))
 - fix(restart): show the token-bearing URL when the browser fails to open ([#4039](https://github.com/gptme/gptme/issues/4039)) ([`92483d672`](https://github.com/gptme/gptme/commit/92483d672deeb5051bfbc306ee93e0f6b11a6057))
 - fix(webui): don't render disconnected UI before the connection has failed ([#4028](https://github.com/gptme/gptme/issues/4028)) ([`fedde8ff6`](https://github.com/gptme/gptme/commit/fedde8ff67a4ee0d94db972ad0adf25a9ad25ed9))
 - fix(commands): run SESSION_END hooks before the CLI /restart re-exec ([#4038](https://github.com/gptme/gptme/issues/4038)) ([`8e394134f`](https://github.com/gptme/gptme/commit/8e394134f63ded433d3abe21490e97bd220b27e0))
 - fix(compaction): Phase 1.5b — hysteresis trim target + post-hoc savings gate ([#3812](https://github.com/gptme/gptme/issues/3812)) ([#4023](https://github.com/gptme/gptme/issues/4023)) ([`1f8d73638`](https://github.com/gptme/gptme/commit/1f8d73638a25253fd0e1824c3d0a72ec93007582))
 - fix(server): strip additional identity headers in preview proxy ([#4033](https://github.com/gptme/gptme/issues/4033)) ([`7ef228ec9`](https://github.com/gptme/gptme/commit/7ef228ec9659cb00a94eef1b8aaedaffe3a242ae))
 - fix(server): leave a conversation's directory before deleting it (cwd vanishes → all PUTs 500) ([#4029](https://github.com/gptme/gptme/issues/4029)) ([`c36a5917c`](https://github.com/gptme/gptme/commit/c36a5917cc34734a1648ab1c669cdfc901b97a54))
 - fix(ci): retry flaky Android NDK download in Tauri workflow ([#4022](https://github.com/gptme/gptme/issues/4022)) ([`2725ba841`](https://github.com/gptme/gptme/commit/2725ba84199b2201cea7f13ab61639048417b214))
 - fix(compaction): Phase 1.5a — failure latch, pending-tool guard, reasoning policy, UI-only status ([#3812](https://github.com/gptme/gptme/issues/3812)) ([#3968](https://github.com/gptme/gptme/issues/3968)) ([`37cff5c08`](https://github.com/gptme/gptme/commit/37cff5c08e8781ed2b041494f79ee44c6a8f359f))
 - fix(models): switch OpenRouter recommended model to deepseek-v4.1-flash ([#4006](https://github.com/gptme/gptme/issues/4006)) ([`886ad8a32`](https://github.com/gptme/gptme/commit/886ad8a32391ce71eaa61fb83dba2b2f7ee63777))
 - fix(doctor): treat placeholder API keys as not-configured, not ERROR ([#4014](https://github.com/gptme/gptme/issues/4014)) ([`39a54936e`](https://github.com/gptme/gptme/commit/39a54936ed9e676a2316dcbecac58860d470c6b4))
 - fix(ci): stop TUI tmux e2e from hanging the test job for 6h ([#4012](https://github.com/gptme/gptme/issues/4012)) ([`574db0929`](https://github.com/gptme/gptme/commit/574db09293dc9c1cbadef5dbce3535e96f0aa2a8))
 - fix(ci): give PR test runs the same timeout/retries as master ([#4008](https://github.com/gptme/gptme/issues/4008)) ([`b7512b33c`](https://github.com/gptme/gptme/commit/b7512b33caa21d387253f91618f452d8aed77c95))
 - fix(webui): notify when Tauri window loses focus ([#4007](https://github.com/gptme/gptme/issues/4007)) ([`a1852c5bf`](https://github.com/gptme/gptme/commit/a1852c5bf09aad79c8ba497de8f0d00878508a26))
 - fix(subagent): stop thread-mode subagents from breaking the parent session's tool calls ([#3989](https://github.com/gptme/gptme/issues/3989)) ([`fea7c6706`](https://github.com/gptme/gptme/commit/fea7c67066ae727b99a986e2d3e168e8f26635d1))
 - fix(tui): no freeze/lost focus on pane switch, /restart after cwd moved, compact + highlighted sections ([#3976](https://github.com/gptme/gptme/issues/3976)) ([`2106abdd1`](https://github.com/gptme/gptme/commit/2106abdd168b2037c89cff5b057c248e109b4be9))
 - fix(shell): gate workspace hint on subagent tool, say denied commands ran nothing ([#3995](https://github.com/gptme/gptme/issues/3995)) ([`9a4a80d8a`](https://github.com/gptme/gptme/commit/9a4a80d8a89ce251ef43117fff4948e1e5b3462f))
 - fix(subagent): load disabled-by-default tools named by a profile allowlist ([#3974](https://github.com/gptme/gptme/issues/3974)) ([`471f0f44b`](https://github.com/gptme/gptme/commit/471f0f44bd636402a8fa848ff70b36bf9d8a77a0))
 - fix(server): bound client-controlled session_id in reconnect log line ([#3969](https://github.com/gptme/gptme/issues/3969)) ([`92dccaeaa`](https://github.com/gptme/gptme/commit/92dccaeaa67e8e54c76bce1a4f9c0e72a6987d93))
 - fix(time-awareness): one timezone-aware clock with full date, real session start and resume gaps ([#3992](https://github.com/gptme/gptme/issues/3992)) ([`deec3974b`](https://github.com/gptme/gptme/commit/deec3974bc5ada407ea56a3591edf359a89ab7a3))
 - fix(hooks): don't inject another agent's identity instructions on cd ([#3993](https://github.com/gptme/gptme/issues/3993)) ([`4d7354bcd`](https://github.com/gptme/gptme/commit/4d7354bcd233a323351f2e500521811d2c329045))
 - fix(confirm): show tool-format call arguments in confirmation previews ([#3979](https://github.com/gptme/gptme/issues/3979)) ([`71f0c4883`](https://github.com/gptme/gptme/commit/71f0c48831c0738925b94b6e32785fe9d807cd02))
 - fix(cli): print the resume command after a fatal error ([#3978](https://github.com/gptme/gptme/issues/3978)) ([`0fc35b21a`](https://github.com/gptme/gptme/commit/0fc35b21a265cb5fed3e656a01efc8d64b8d0d64))
 - fix(llm): convert OpenAI stream chunk-parsing crash into a clean, classifiable error ([#3984](https://github.com/gptme/gptme/issues/3984)) ([`f0890168e`](https://github.com/gptme/gptme/commit/f0890168eaca708fd0fae1f1737b82c04d34b313))
 - fix(shell): make promoted background job output reachable and respect explicit timeouts ([#3996](https://github.com/gptme/gptme/issues/3996)) ([`b86177e6e`](https://github.com/gptme/gptme/commit/b86177e6e0572567a0a4883d36177f9cab476724))
 - fix(tools): cap tool descriptions on all provider paths, not just OpenAI ([#3964](https://github.com/gptme/gptme/issues/3964)) ([`a1675a8ae`](https://github.com/gptme/gptme/commit/a1675a8ae28d928d23903fc0abfa929c9da94788))
 - fix(openrouter): accept every quantization level OpenRouter supports ([#3983](https://github.com/gptme/gptme/issues/3983)) ([`2dfc15255`](https://github.com/gptme/gptme/commit/2dfc152550c18e90adf4822ea6bc68c56bbd0247))
 - fix(openrouter): accept `max` reasoning effort ([#3985](https://github.com/gptme/gptme/issues/3985)) ([`24345a494`](https://github.com/gptme/gptme/commit/24345a4949a97a4f14542df912fc3f1b7846f348))
 - fix(tui): normalize CR/CRLF line breaks in collapsed pastes ([#3982](https://github.com/gptme/gptme/issues/3982)) ([`923cdfe92`](https://github.com/gptme/gptme/commit/923cdfe9200e011b98d93abd30c96e9849155bf2))
 - fix(subagent): preserve result past system postamble ([#3986](https://github.com/gptme/gptme/issues/3986)) ([`d1ae87635`](https://github.com/gptme/gptme/commit/d1ae87635c4df3027946c643184b7017fe10ceee))
 - fix(tui): inline-mode UX — hide thinking by default, keep scrollback on resize, show queued prompts and confirm keys ([#3970](https://github.com/gptme/gptme/issues/3970)) ([`c5c9733c8`](https://github.com/gptme/gptme/commit/c5c9733c87a580827b401e2bf1ced627b854b266))
 - fix(server,webui): recover event stream after server restart; keep native notification grant out of browser path ([#3967](https://github.com/gptme/gptme/issues/3967)) ([`f7bb34871`](https://github.com/gptme/gptme/commit/f7bb34871442bb69d3cbecde49c7ce1f2e22517a))
 - fix(webui): preserve generation settings for initial step ([#3913](https://github.com/gptme/gptme/issues/3913)) ([`fbc5825ef`](https://github.com/gptme/gptme/commit/fbc5825eff4f85a005ca9ebb475b5d53e4aeed3c))
 - fix(autocompact): only record attempt after successful compaction, not before ([#3965](https://github.com/gptme/gptme/issues/3965)) ([`2cbc587e0`](https://github.com/gptme/gptme/commit/2cbc587e0248c22df41a290a585bcdaa39acac6f))
 - fix(service): parse last systemd Environment model assignment ([#3930](https://github.com/gptme/gptme/issues/3930)) ([`50c92b4b0`](https://github.com/gptme/gptme/commit/50c92b4b0e6148e68793b1b793831dce33a1f328))
 - fix(tauri): regenerate icons from SVG for readable small-size rendering ([#3928](https://github.com/gptme/gptme/issues/3928)) ([`686ce71df`](https://github.com/gptme/gptme/commit/686ce71dfa16f6504012c250570055bf5b8ec758))
 - fix(config): don't crash on malformed [[mcp.servers]] entry ([#3927](https://github.com/gptme/gptme/issues/3927)) ([`23f548c24`](https://github.com/gptme/gptme/commit/23f548c24f54509b3c28ff7b92a3bcd7abc312ee))
 - fix(server): honor per-step max token override ([#3905](https://github.com/gptme/gptme/issues/3905)) ([`b51622915`](https://github.com/gptme/gptme/commit/b51622915e2aab37ba22f376349f2009fcef2a6e))
 - fix(tauri): preserve OAuth chars in deep-link auth code injection ([#3926](https://github.com/gptme/gptme/issues/3926)) ([`6a969f9b8`](https://github.com/gptme/gptme/commit/6a969f9b86d2c01ed1032e6fd10fd8e5f1b03e19))
 - fix(tauri): retry connect on managed sidecar startup delay ([#3934](https://github.com/gptme/gptme/issues/3934)) ([`69ac31095`](https://github.com/gptme/gptme/commit/69ac310958ac235eb46f6d6cc8d54563bac359a2))
 - fix(review-pr): don't let a trailing shutdown log mask the real session error ([#3910](https://github.com/gptme/gptme/issues/3910)) ([`274b01c5d`](https://github.com/gptme/gptme/commit/274b01c5db8d5b83c19ed8356a8021332441e725))
 - fix(tests): update browser-lynx test to use stable gptme.org assertion ([#3916](https://github.com/gptme/gptme/issues/3916)) ([`29ab7b79f`](https://github.com/gptme/gptme/commit/29ab7b79fe8c470e06fbc73bc4ac838654edcab1))
 - fix(webui): cancel subscription poll and in-flight request on wizard unmount ([#3922](https://github.com/gptme/gptme/issues/3922)) ([`5b333f06d`](https://github.com/gptme/gptme/commit/5b333f06de380e25be9bdf0adea1cf39e4deabc2))
 - fix(webui): bundle Inter font locally instead of CDN import ([#3908](https://github.com/gptme/gptme/issues/3908)) ([`8ff2dadcc`](https://github.com/gptme/gptme/commit/8ff2dadcc4898e7e19a45e8ccd43ac6d61427235))
 - fix(server): add timeout to subscription OAuth background threads ([#3923](https://github.com/gptme/gptme/issues/3923)) ([`43817c81f`](https://github.com/gptme/gptme/commit/43817c81f415b9efe3c81d3deb3efcbe0ba76347))
 - fix(config): don't crash on malformed [[providers]] entry ([#3915](https://github.com/gptme/gptme/issues/3915)) ([`593da3a33`](https://github.com/gptme/gptme/commit/593da3a33695006a9b336d08a8d8ec77e53cc8e2))
 - fix(tauri): rename user-facing product to gptme ([#3907](https://github.com/gptme/gptme/issues/3907)) ([`be343267b`](https://github.com/gptme/gptme/commit/be343267b3de06c67d60b89428ef13c6ae9a2a92))
 - fix(memory): reject unknown list filters ([#3904](https://github.com/gptme/gptme/issues/3904)) ([`06e7275b8`](https://github.com/gptme/gptme/commit/06e7275b8efaa4bf8eaddb134d1723dd803ac3b7))
 - fix(doctor): resolve effective model source ([#3893](https://github.com/gptme/gptme/issues/3893)) ([`186123300`](https://github.com/gptme/gptme/commit/186123300aa8ccefb69f1c17f66847a33908c947))
 - fix(cli): import extras lazily so gptme-server and gptme-dspy start without them ([#3901](https://github.com/gptme/gptme/issues/3901)) ([`557b9757e`](https://github.com/gptme/gptme/commit/557b9757e5bf3e98fd2442d0863d17375591bb29))
 - fix(cli): honor gitignore anchoring and negation in context tree ([#3899](https://github.com/gptme/gptme/issues/3899)) ([`31e6025a9`](https://github.com/gptme/gptme/commit/31e6025a9fbeee8a2cdc901bb0394d89eb66958e))
 - fix(doctor): surface exhausted OpenRouter quota ([#3892](https://github.com/gptme/gptme/issues/3892)) ([`9547bfed9`](https://github.com/gptme/gptme/commit/9547bfed94f965a9f2ee3bd10a784de05096de7d))
 - fix(llm): render GptmeAuthError as a plain message, not KeyError's repr ([#3889](https://github.com/gptme/gptme/issues/3889)) ([`16c6ca5c7`](https://github.com/gptme/gptme/commit/16c6ca5c77c202eba9e412f843b06a9f923bdcfd))
 - fix(lessons): deduplicate skills by name, not by file path ([#3887](https://github.com/gptme/gptme/issues/3887)) ([`5c049d1e9`](https://github.com/gptme/gptme/commit/5c049d1e91146dc7ae05570be50741ecab638612))
 - fix(lessons): skip hidden subdirectories during skill/lesson discovery ([#3888](https://github.com/gptme/gptme/issues/3888)) ([`062ddecf3`](https://github.com/gptme/gptme/commit/062ddecf34220f4ec00c1c98ccc1ef5627d30930))
 - fix(anti-slop): fail short dense-slop text instead of skipping it ([#3878](https://github.com/gptme/gptme/issues/3878)) ([`759fa30a0`](https://github.com/gptme/gptme/commit/759fa30a09f2b5a7723ea02a23b6bcf23e30a8ef))
 - fix(server): bundle gptme.hooks and gptme.context in the PyInstaller sidecar ([#3883](https://github.com/gptme/gptme/issues/3883)) ([`abd0f3537`](https://github.com/gptme/gptme/commit/abd0f35370f2d82036265b40625b7c6922682362))
 - fix(server): emit step_complete after generating=False to close queue-flush 409 race ([#3874](https://github.com/gptme/gptme/issues/3874)) ([`879e13e0d`](https://github.com/gptme/gptme/commit/879e13e0dfd5c5db5487686da12cb538a6e07387))
 - fix(webui): don't treat the Tauri webview origin as a bundled gptme-server ([#3882](https://github.com/gptme/gptme/issues/3882)) ([`183bfd75d`](https://github.com/gptme/gptme/commit/183bfd75dacdbdcd398006aaa1940f7ca9772d80))
 - fix(patch_many): accumulate repeated paths instead of silently dropping hunks ([#3880](https://github.com/gptme/gptme/issues/3880)) ([`f65cb9050`](https://github.com/gptme/gptme/commit/f65cb905079b7db5e605b55f4c721b6d39ff6780))
 - fix(release): always write release notes with a trailing newline ([#3876](https://github.com/gptme/gptme/issues/3876)) ([`da6832bd8`](https://github.com/gptme/gptme/commit/da6832bd895a7264799d830033f1d7ab9692c1fe))
 - fix: add missing trailing newline to v0.34.0 release notes ([#3875](https://github.com/gptme/gptme/issues/3875)) ([`2e50bdf6b`](https://github.com/gptme/gptme/commit/2e50bdf6b1d4fc554adee57b2b8994b0ae39508d))

</p>
</details>

### 🔨 Misc (65)
<details><summary>Click to expand</summary>
<p>

 - chore: bump version to 0.35.0 ([`v0.35.0`](https://github.com/gptme/gptme/tree/v0.35.0))
 - test(tui): update thinking-toggle stream test for per-segment stream rows ([#4353](https://github.com/gptme/gptme/issues/4353)) ([`87b376108`](https://github.com/gptme/gptme/commit/87b37610846f8c85d191009e2b7bc5d0dc2a07ec))
 - test(tui): cover mid-stream thinking toggles and delayed finalization flush ([#4338](https://github.com/gptme/gptme/issues/4338)) ([`3e9b6a455`](https://github.com/gptme/gptme/commit/3e9b6a455f28c274f263c811fcfe24160fdc3eb1))
 - perf(tui): batch stream renders, anchor the chat scroll, keep one tool status line ([#4332](https://github.com/gptme/gptme/issues/4332)) ([`37c1250ed`](https://github.com/gptme/gptme/commit/37c1250ed03f907b18ab50aa42890cebb6f7da40))
 - docs(voice): install with uv instead of Poetry ([#4327](https://github.com/gptme/gptme/issues/4327)) ([`0880593fb`](https://github.com/gptme/gptme/commit/0880593fbcb4b780a206831adf9d5a91d0672078))
 - docs(building): install with uv instead of Poetry ([#4316](https://github.com/gptme/gptme/issues/4316)) ([`9ee310ec1`](https://github.com/gptme/gptme/commit/9ee310ec17dbd5e535cadb628b7209de1ebba6be))
 - test(webui): make location mocks jsdom-26-safe and move to jest 30 ([#4285](https://github.com/gptme/gptme/issues/4285)) ([`f2ffcb246`](https://github.com/gptme/gptme/commit/f2ffcb24642843ef2c2f997243047eaf0d4e1b42))
 - test(logmanager): cover damaged-tail checkpoint and concurrent appends ([#4247](https://github.com/gptme/gptme/issues/4247)) ([`1ff896c9e`](https://github.com/gptme/gptme/commit/1ff896c9e5b6ba7246ff4e9598bc50b1c73f56af))
 - test(shell): cover invalid UTF-8 and per-stream decoder state in background jobs ([#4267](https://github.com/gptme/gptme/issues/4267)) ([`c1d42b726`](https://github.com/gptme/gptme/commit/c1d42b7266b65ebbd853d8233cd465edc2f0c7c0))
 - chore(webui): delete unused components and deps, gate with knip ([#4290](https://github.com/gptme/gptme/issues/4290)) ([`987ad1cf0`](https://github.com/gptme/gptme/commit/987ad1cf07fcac6088d41fe31cc4b534fc2fea3e))
 - refactor(webui): drop unused calendar wrapper + react-day-picker, bump date-fns to 4 ([#4286](https://github.com/gptme/gptme/issues/4286)) ([`44e1ef05f`](https://github.com/gptme/gptme/commit/44e1ef05f1d7b8fb07c8f4c8157edd27f28f4b00))
 - docs(providers): add DemonRoute as remote cloud gateway example ([#4277](https://github.com/gptme/gptme/issues/4277)) ([`6cd42c802`](https://github.com/gptme/gptme/commit/6cd42c8028ad80be9f6879f243862c6ea142ecc1))
 - test(eventlog): property test for recovery from arbitrary log damage ([#4263](https://github.com/gptme/gptme/issues/4263)) ([`214d4c328`](https://github.com/gptme/gptme/commit/214d4c3283813f4564e3f2e869370b5ef0f65a61))
 - test(llm): stub init_llm in degeneration reply() test so it runs in isolation ([#4242](https://github.com/gptme/gptme/issues/4242)) ([`c4a3a2ca6`](https://github.com/gptme/gptme/commit/c4a3a2ca6787ccd187ec76451b98cdd070f71a09))
 - test(server): isolate v2 API tests from the real logs dir ([#4240](https://github.com/gptme/gptme/issues/4240)) ([`9a6e5e42c`](https://github.com/gptme/gptme/commit/9a6e5e42c0ee13baa9690930f846a09761b8ac51))
 - docs: add philosophy page (mission, principles, non-goals) ([#4232](https://github.com/gptme/gptme/issues/4232)) ([`6ef2dd14d`](https://github.com/gptme/gptme/commit/6ef2dd14d96bb98e248c789e9e5ae51968c4948a))
 - docs(mcp): add ContextVar contract to load/unload_mcp_server + copy_context regression test ([#4230](https://github.com/gptme/gptme/issues/4230)) ([`33e1952ee`](https://github.com/gptme/gptme/commit/33e1952ee1be34c7d0ca0b5ed132f24f94426cb9))
 - test(e2e): wait for clickability before clicking wizard buttons ([#4219](https://github.com/gptme/gptme/issues/4219)) ([`eb420fc79`](https://github.com/gptme/gptme/commit/eb420fc79f6b7d7948bfc2204499d1c9948f7ade))
 - docs(anti-slop): document float types and fix stale rounding comment ([#4216](https://github.com/gptme/gptme/issues/4216)) ([`77d354820`](https://github.com/gptme/gptme/commit/77d354820daee0f984142f9c47f2ac40d2dcd6b2))
 - test(browser): add local blockage conformance suite ([#4200](https://github.com/gptme/gptme/issues/4200)) ([`36a9bc146`](https://github.com/gptme/gptme/commit/36a9bc1461ee34c4e9daa8db7d85cbac3b8abc9f))
 - docs(citation): add Zenodo concept DOI and badge ([#4147](https://github.com/gptme/gptme/issues/4147)) ([`651fec3c3`](https://github.com/gptme/gptme/commit/651fec3c3f92fd5207bc4993ab69bb01ccf4dc46))
 - test(knowledge): protect outside stores across CLI subprocesses ([#4159](https://github.com/gptme/gptme/issues/4159)) ([`67e1c854b`](https://github.com/gptme/gptme/commit/67e1c854bd45e891b16e15a469e4388f83b3cfc1))
 - test(cli): add CLI-level regression for KeyError repr-quote stripping ([#4105](https://github.com/gptme/gptme/issues/4105)) ([`ca1310b03`](https://github.com/gptme/gptme/commit/ca1310b03b4768e6ab1f8be2e95965195cd4ece0))
 - docs(computer-use): note that macOS needs no Full Disk Access ([#4152](https://github.com/gptme/gptme/issues/4152)) ([`41a9986b6`](https://github.com/gptme/gptme/commit/41a9986b60870e944370ec4c675b02dd1ac73631))
 - docs(models): recommend GPT-6.1 Sol over GPT-5.6 Sol, describe Astra; add gpt-6.1-sol to registry ([#4137](https://github.com/gptme/gptme/issues/4137)) ([`192393c87`](https://github.com/gptme/gptme/commit/192393c87ce7d954abc535cce05b394fe2b61db2))
 - docs(server): document 11 missing /api routes in OpenAPI spec ([#4052](https://github.com/gptme/gptme/issues/4052)) ([`ac501883e`](https://github.com/gptme/gptme/commit/ac501883ec28692e1316f22c183feb9ce269f0d4))
 - docs(tts): correct Kokoro first-run download size ([#4133](https://github.com/gptme/gptme/issues/4133)) ([`69f0b9e60`](https://github.com/gptme/gptme/commit/69f0b9e60ed67919b445f6ef32d701213e36df49))
 - docs: make provider host advice policy-first ([#4130](https://github.com/gptme/gptme/issues/4130)) ([`f15f18ed1`](https://github.com/gptme/gptme/commit/f15f18ed1d1a1507f17aff16bed8e1378e104027))
 - docs: refresh model recommendations, data policy, and gptme-tts setup ([#4114](https://github.com/gptme/gptme/issues/4114)) ([`ba1149f0b`](https://github.com/gptme/gptme/commit/ba1149f0bf790509bc7c3f0a863733d1013d4823))
 - chore(deps): apply non-breaking npm audit fixes and configure npm/cargo Dependabot ([#4090](https://github.com/gptme/gptme/issues/4090)) ([`4e5bdfc3a`](https://github.com/gptme/gptme/commit/4e5bdfc3a791249f74e0e7d334f436482a4bf2e9))
 - docs(contributing): fix stale telemetry env vars and metrics path ([#4072](https://github.com/gptme/gptme/issues/4072)) ([`98f0767a7`](https://github.com/gptme/gptme/commit/98f0767a73ddd0c73bd3405d940b45087749b549))
 - perf(startup): keep prompt_toolkit out of gptme.message, requests out of gptme.commands ([#4088](https://github.com/gptme/gptme/issues/4088)) ([`0d64706d4`](https://github.com/gptme/gptme/commit/0d64706d420faa8dfe86d90f12f724a9b13c1360))
 - docs(tools): add reference pages for memory, patch_many, convert (+ opt-in watch, progress, clarify) ([#4091](https://github.com/gptme/gptme/issues/4091)) ([`c413a4fdf`](https://github.com/gptme/gptme/commit/c413a4fdf830163a9e059eb81a8f4f1c874ccd8d))
 - docs: surface gptodo and gptmail from gptme-contrib for agent workflows ([#4098](https://github.com/gptme/gptme/issues/4098)) ([`daa4cf883`](https://github.com/gptme/gptme/commit/daa4cf8835a9a3214e9610baa676a614aff5eb49))
 - docs(config): document missing project config keys ([#4080](https://github.com/gptme/gptme/issues/4080)) ([`9043660ee`](https://github.com/gptme/gptme/commit/9043660eefc0a265ee18c6035e49c2f6ac06ec94))
 - docs(evals): mention OpenShell policy-governed sandboxes ([#4025](https://github.com/gptme/gptme/issues/4025)) ([`5f6cff254`](https://github.com/gptme/gptme/commit/5f6cff254682e0f235e2205fb519bfd22ca6cac9))
 - docs(server): say /preview/{port}/ is the cloud preview backend, not a user URL ([#4030](https://github.com/gptme/gptme/issues/4030)) ([`10133577d`](https://github.com/gptme/gptme/commit/10133577d366c47d9d2a077aa226b8fe37743624))
 - refactor(reduce): delete dead proactive_summarize_log and its cache ([#3812](https://github.com/gptme/gptme/issues/3812)) ([#4024](https://github.com/gptme/gptme/issues/4024)) ([`3efde6e80`](https://github.com/gptme/gptme/commit/3efde6e800b6e1504cf66180c7b460aa5f842b04))
 - test: isolate the web-tool host allowlist across tests (fix flaky browser failures) ([#4019](https://github.com/gptme/gptme/issues/4019)) ([`4be9a7883`](https://github.com/gptme/gptme/commit/4be9a7883b9b505e4a7903638e1a48caff9be802))
 - test: keep the autouse init fixture from scanning the host's lesson dirs ([#4017](https://github.com/gptme/gptme/issues/4017)) ([`c581aa5a1`](https://github.com/gptme/gptme/commit/c581aa5a1a63be7dded2c5cba9ae943c2d45712a))
 - test: keep color-warning tests independent of a leaked root log level ([#4003](https://github.com/gptme/gptme/issues/4003)) ([`94383696b`](https://github.com/gptme/gptme/commit/94383696bdae3f4e4e6b6e5312ef630da78b6959))
 - test(tui): cover initial prompt queue exit path ([#3998](https://github.com/gptme/gptme/issues/3998)) ([`2bd15c53b`](https://github.com/gptme/gptme/commit/2bd15c53b7fe16d15f29f9de1af31aff02c3d7f4))
 - test(browser): serve read_page_text fixture locally instead of example.com ([#3991](https://github.com/gptme/gptme/issues/3991)) ([`f2061c44d`](https://github.com/gptme/gptme/commit/f2061c44d16aac9d8184ebd27bd212f6be6a113c))
 - test: make two order/load-dependent CI tests hermetic ([#3988](https://github.com/gptme/gptme/issues/3988)) ([`01292e009`](https://github.com/gptme/gptme/commit/01292e00942d7838fd431c502258e12dc06f6b17))
 - docs(readme): mention Requesty alongside OpenRouter ([#3994](https://github.com/gptme/gptme/issues/3994)) ([`656b94ac2`](https://github.com/gptme/gptme/commit/656b94ac25aecdfbaa064e76779e780943f4f97b))
 - test(e2e): Playwright tests for InlineToolConfirmation (tool_pending flow) ([#3948](https://github.com/gptme/gptme/issues/3948)) ([`978d4f9aa`](https://github.com/gptme/gptme/commit/978d4f9aa876688d030733c149bf942b6c9a393b))
 - refactor(shell): remove bashlex fallback after tree-sitter soak ([#3944](https://github.com/gptme/gptme/issues/3944)) ([`0c31b18fa`](https://github.com/gptme/gptme/commit/0c31b18fa36f66583ce81d364100a5137f99544a))
 - test(hooks): unregister server_confirm in test_register to stop TOOL_CONFIRM leak ([#3962](https://github.com/gptme/gptme/issues/3962)) ([`9e3ab7cf5`](https://github.com/gptme/gptme/commit/9e3ab7cf5418ae623d4b01ad7710fc9cfcf43a9c))
 - perf(shell): batch 7 separate export calls in _init() into one ([#3952](https://github.com/gptme/gptme/issues/3952)) ([`30e7c8407`](https://github.com/gptme/gptme/commit/30e7c840713257b9bf422ad55ce30fb0eccf1d5a))
 - docs(plugins): add Plugin Registry section — how to get listed via GitHub topics ([#3951](https://github.com/gptme/gptme/issues/3951)) ([`1597a632f`](https://github.com/gptme/gptme/commit/1597a632fa642d8d46723ffe7ce75f5a9449ccc8))
 - chore(meta): add PyPI keywords and classifiers ([#3955](https://github.com/gptme/gptme/issues/3955)) ([`c251d70be`](https://github.com/gptme/gptme/commit/c251d70beb6021aa877a6721a7c7cc63f0b49272))
 - docs(shell): document allowlist, transparent wrappers, and tree-sitter-bash parser ([#3946](https://github.com/gptme/gptme/issues/3946)) ([`3b6a9bb13`](https://github.com/gptme/gptme/commit/3b6a9bb135942950b660194eed8af87164d70fb2))
 - docs(contributing): add setup smoke test ([#3902](https://github.com/gptme/gptme/issues/3902)) ([`992731311`](https://github.com/gptme/gptme/commit/9927313117df2b88b4a2cbbf79550b878543380e))
 - refactor(server): stop falling back to the legacy web UI ([#3938](https://github.com/gptme/gptme/issues/3938)) ([`764b4cc0e`](https://github.com/gptme/gptme/commit/764b4cc0ed3e27cf75dc988f98b65182323d729d))
 - refactor(cli): remove --gear, --multi-tool, --injection-hygiene, --manifest-dir ([#3940](https://github.com/gptme/gptme/issues/3940)) ([`48af60d28`](https://github.com/gptme/gptme/commit/48af60d28865fd0e462b808355260b5b1ef60a64))
 - refactor(tools): remove patch_anchored and view_anchored ([#3941](https://github.com/gptme/gptme/issues/3941)) ([`7784b6d59`](https://github.com/gptme/gptme/commit/7784b6d598d4811a4e924acc053c5b9accf81328))
 - docs: select workspace before gptme-agent install ([#3933](https://github.com/gptme/gptme/issues/3933)) ([`c41b20cd5`](https://github.com/gptme/gptme/commit/c41b20cd5cfb90406d073ff610f41c62ad114ad8))
 - docs: correct inaccurate and stale claims across README and docs ([#3936](https://github.com/gptme/gptme/issues/3936)) ([`886556f74`](https://github.com/gptme/gptme/commit/886556f744cefa7538d2e37541a600f5ddd15ef4))
 - refactor(cli): remove architect/editor split mode ([#3937](https://github.com/gptme/gptme/issues/3937)) ([`ad622602e`](https://github.com/gptme/gptme/commit/ad622602ee6e48d80a473e920c1eaa00e00ac610))
 - test(server): gate cold conversation scan on scaling, not milliseconds ([#3900](https://github.com/gptme/gptme/issues/3900)) ([`2adc55b81`](https://github.com/gptme/gptme/commit/2adc55b816a41614e07084cf8291f60a929a478a))
 - test(models): make warn-once assertion logger-local ([#3896](https://github.com/gptme/gptme/issues/3896)) ([`4bd2560ef`](https://github.com/gptme/gptme/commit/4bd2560efc3e5693d3cf267284e0de38c0cfb156))
 - test(tauri): real first-run E2E with webui + sidecar ([#3886](https://github.com/gptme/gptme/issues/3886)) ([`c8560b2e8`](https://github.com/gptme/gptme/commit/c8560b2e86fb2e7e4a726e97b1874d94c815e2cf))
 - test(eval): isolate process-global side effects of in-process act_process calls ([#3885](https://github.com/gptme/gptme/issues/3885)) ([`f40b6dbf9`](https://github.com/gptme/gptme/commit/f40b6dbf9356d24e59061104fb24f4fbb68fb039))
 - test(ci): smoke-test frozen gptme-server startup for missing modules ([#3884](https://github.com/gptme/gptme/issues/3884)) ([`945517f13`](https://github.com/gptme/gptme/commit/945517f134f28294a250eb7c9438aa9eeb6e5e68))
 - test(shell): make SIGTERM regression independent of inherited SIG_IGN ([#3877](https://github.com/gptme/gptme/issues/3877)) ([`4246b6814`](https://github.com/gptme/gptme/commit/4246b6814a39eaf276c508bf028f826c8222de4d))

</p>
</details>

*(excluded 49 less relevant [commits](https://github.com/gptme/gptme/compare/v0.34.0...v0.35.0))*

**Full Changelog**: https://github.com/gptme/gptme/compare/v0.34.0...v0.35.0
