Commit graph

3 commits

Author SHA1 Message Date
nesquena-hermes
19080f73b1
Release v0.51.348 — Release LL (Phase 0 hotfix: timeout regression + data-loss + leaks) (#3917)
* stage v0.51.348: Phase 0 hotfix — approval/clarify timeout regression (#3913), queue/draft durability (#3906), settings auto-reopen (#3909), kanban FD leak (#3904)

* stage v0.51.348: re-anchor 4 SSE frontend tests to poll-only design (#3913); apply Opus SHOULD-FIX — immediate first poll tick so pending approval/clarify cards show instantly

---------

Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
2026-06-10 01:12:48 -07:00
nesquena-hermes
9b933e2c83
Release v0.51.266 — Release IH (stage-r16) (#3641)
## Release v0.51.266 — Release IH (stage-r16)

One agent-authored APPROVED fix + two un-held streaming/SSE fixes.

### Fixed
| Issue/PR | Author | Fix |
|----------|--------|-----|
| #3635 (#3637) | @nesquena-hermes (nesquena APPROVED) | Composer profile chip reads `S.activeProfile` again — a #3331 regression keyed it on the loaded session's profile, so opening a cross-profile session made the chip disagree with the dropdown checkmark and misrepresent where the next message routes. #3331's project/session-op scoping is unaffected. |
| #3587 (#3605) | @rodboev | Reasoning persists to the correct intermediate assistant message in multi-turn tool flows. The index only advanced in `on_interim_assistant` (suppressed for contentless tool-call messages) → post-tool reasoning was mis-attributed; it now also advances at the `on_tool` boundary, guarded against over-increment. **(un-held — finding resolved)** |
| #2660 (#3558) | @franksong2702 | Session-event SSE no longer wakes every tab across profiles and never drops a relevant refresh — profile attached when known, root/`default` aliases stay unscoped, and the `maxsize=1` queue falls back to unscoped refresh-all on a profile-mismatch coalesce. **(un-held — both findings resolved)** |

### Gate
- Full pytest suite: **7770 passed, 0 failed**
- ESLint: CLEAN · ruff: CLEAN · browser-smoke: CLEAN
- Codex (regression): **SAFE TO SHIP** — chip matches dropdown/routing (no #3331 scoping regression), reasoning-index advance composes with the agent's tool/interim callback ordering, session-events coalesce safely with no dropped refresh and no profile data leak (`/api/sessions` still server-side filtered).

Co-authored-by: nesquena <nesquena@users.noreply.github.com>
Co-authored-by: rodboev <rodboev@users.noreply.github.com>
Co-authored-by: franksong2702 <franksong2702@users.noreply.github.com>
2026-06-05 00:44:03 -07:00
nesquena-hermes
e7930ad9a5
Release v0.51.241 — Release HI (stage-q13) (#3498)
## Release v0.51.241 — Release HI (stage-q13)

UX-flow bug-fix — approved via Telegram.

### Fixed
| PR | Author | Fix |
|----|--------|-----|
| #3471 (#3333) | @starGazerK | **New Chat keeps your unsent draft after peeking at history.** Start a New Chat draft → open a previous conversation → click New Chat: the draft is no longer lost. Empty New-Chat sessions are hidden from the sidebar, so there was no way back to the session holding the draft — New Chat just created another fresh empty session. The entrypoint now remembers the candidate empty draft session (one `localStorage` pointer) and, before creating a fresh session, re-validates it via `/api/session`, routing back only if it is still a safe empty draft (zero messages, no active stream, no pending message, not worktree-backed, matching profile, non-empty server-side `composer_draft`). |

### Why it's safe for existing installs
- When there is no remembered draft, it's a **pure no-op fall-through** to the existing `newSession()` path — no behavior change.
- Preserves the "zero-message sessions stay hidden from the sidebar" contract.
- Conservative multi-guard validation; the pointer is cleared on draft-clear (after send) so an emptied draft never traps you on New Chat.

### Verified live (end-to-end on a test server)
- **Positive**: typed a draft → visited a 2-message history session → clicked New Chat → landed back on the draft session with the text restored.
- **Negative**: emptied the draft → New Chat created a fresh session (no accidental trap).

### Absorbed on review (Codex CORE MUST-FIX)
The PR added `await _saveComposerDraftNow(...)` before the session-switch, which opened a rapid-switch race: clicking session B then quickly C could let B's stale continuation blank C's freshly-loaded state. Added `if (_loadingSessionId !== sid) return;` immediately after the awaited save and before the destructive state-clear (mirrors the existing #1060 stale-guard) + a regression test pinning the guard's position.

### Gate
- Full pytest suite: **7510 passed, 9 skipped, 3 xpassed, 0 failed**
- ESLint runtime gate: CLEAN · browser-smoke: CLEAN
- Codex (regression): SHIP-ONLY-WITH-FIXES (rapid-switch race) → fixed → re-reviewed **SAFE TO SHIP**
- `tests/test_issue_new_chat_draft_restore.py` (7 assertions incl. the race-guard; live-verified behavior)

UX-flow change, no visual/layout delta — approved via Telegram.

Co-authored-by: starGazerK <starGazerK@users.noreply.github.com>
2026-06-03 15:24:31 -07:00