Commit Graph

5912 Commits

Author SHA1 Message Date
nesquena-hermes ba401d3784 Merge #5079 (OpenAI TTS + SSRF hardening) into stage 2026-06-30 20:39:04 +00:00
nesquena-hermes eb2c4b1e7d fix(#5079): no-redirect opener for OpenAI TTS (block redirect-to-private SSRF + bearer leak)
A public TTS host could 301/302/303-redirect POST /audio/speech to an internal
target (e.g. http://169.254.169.254), and urllib's default redirect handler
would follow it carrying the Authorization bearer — both an SSRF bounce past the
base-url guard and a credential leak. Now uses a no-redirect opener
(_NoRedirectTtsHandler raises on any redirect) via the _tts_open seam. +redirect
rejection regression test. Residual DNS-rebinding TOCTOU (re-resolve at connect)
is a narrower low-severity window noted for follow-up.
2026-06-30 20:37:43 +00:00
nesquena-hermes 6bcb728f08 fix(#5079): block private/link-local/reserved IP targets in OpenAI TTS base_url (SSRF hardening)
The base_url validator accepted any https host; an https URL pointing at an
internal/link-local/loopback/reserved IP (e.g. https://169.254.169.254 cloud
metadata, https://10.x internal) passed the scheme-only check. Now resolves the
host and rejects blocked-target addresses (private/loopback/link-local/reserved/
multicast/unspecified), while still allowing public OpenAI-compatible hosts and
the explicit localhost-over-http dev case. DNS-resolution failure is allowed
(unreachable host can't be an SSRF vector + avoids false-rejecting public hosts
that don't resolve in sandboxed envs). +5 regression vectors.
2026-06-30 20:37:43 +00:00
nesquena-hermes df9c643a80 Merge pull request #5288 from nesquena/release/stage-4881
Release v0.51.774 — Kanban modal fields (#4881)
v0.51.774
2026-06-30 13:05:32 -07:00
nesquena-hermes 93d31ebad5 docs(changelog): Kanban modal skills/max_runtime/parents (#4881) 2026-06-30 19:51:22 +00:00
nesquena-hermes 027699b570 Merge #4881 (rodboev Kanban modal fields) into stage 2026-06-30 19:50:46 +00:00
nesquena-hermes 4e8bd002f7 Merge pull request #5286 from nesquena/release/stage-4871
Release v0.51.773 — Mermaid toolbar controls in chat (#4871)
v0.51.773
2026-06-30 12:43:18 -07:00
nesquena-hermes c4b4d874ac docs(changelog): Mermaid toolbar controls in chat (#4871) 2026-06-30 19:27:47 +00:00
nesquena-hermes d954d4c861 Merge #4871 (rodboev Mermaid toolbar) into stage 2026-06-30 19:27:15 +00:00
nesquena-hermes 1ba91d9e6b Merge pull request #5285 from nesquena/release/stage-4574
Release v0.51.772 — mobile titlebar prioritize session title (#4574)
v0.51.772
2026-06-30 12:26:15 -07:00
nesquena-hermes 66714f04e8 docs(changelog): mobile titlebar prioritize session title (#4574) 2026-06-30 19:11:32 +00:00
nesquena-hermes 492fdfb84a Merge #4574 (rodboev mobile titlebar) into stage 2026-06-30 19:10:38 +00:00
nesquena-hermes 750780f056 Merge pull request #5284 from nesquena/release/stage-5019
Release v0.51.771 — mobile approval touch targets (#5019)
v0.51.771
2026-06-30 12:09:00 -07:00
nesquena-hermes ea92608e69 docs(changelog): mobile touch targets + approval layout (#5019) 2026-06-30 18:55:07 +00:00
nesquena-hermes 61cc0d167b Merge #5019 (disco32r mobile touch targets) into stage 2026-06-30 18:54:36 +00:00
nesquena-hermes 0da7d88f48 Merge pull request #5283 from nesquena/release/stage-pq1
Release v0.51.770 — priority-queue batch (#5168 #5211)
v0.51.770
2026-06-30 11:18:27 -07:00
nesquena-hermes 049b98ad01 docs(changelog): priority-queue batch pq1 (#5168 #5211) 2026-06-30 18:06:34 +00:00
nesquena-hermes c7767f9295 Merge #5211 (search-ranking) into stage-pq1 2026-06-30 18:06:11 +00:00
nesquena-hermes 1f00e4de8c Merge #5168 (pet-handoff) into stage-pq1 2026-06-30 18:06:09 +00:00
nesquena-hermes 53a997d52d Merge pull request #5282 from nesquena/release/stage-w5
Release v0.51.769 — Wave 5 (#5161)
v0.51.769
2026-06-30 10:37:13 -07:00
nesquena-hermes f07b1315ca docs(changelog): wave-5 (#5161) 2026-06-30 17:25:36 +00:00
nesquena-hermes 121059b384 Merge #5161 (pr/5144-busy-composer-placeholder-hint) into stage-w5 2026-06-30 17:25:03 +00:00
nesquena-hermes 5f2d82d5c9 Merge pull request #5281 from nesquena/release/stage-w4
Release v0.51.768 — Wave 4 batch (#5248 #5207)
v0.51.768
2026-06-30 10:24:05 -07:00
nesquena-hermes ab5a757ffe docs(changelog): wave-4 batch (#5248 #5207) 2026-06-30 17:14:12 +00:00
sheldon-im 944d57eedc Improve latest assistant response landmark 2026-06-30 17:13:45 +00:00
allenliang2022 4ef9d7c5cb fix(webui): render a server-initiated turn that finished during an SSE gap on a visible tab
A visible tab can permanently miss a server-initiated turn (self-wake /
cron / restart hook) when its per-session SSE is momentarily down at the
emit instant. server_turn_started is a fire-and-forget broadcast with no
replay buffer; if the turn also finishes before the tab reconnects, the
on-subscribe self-heal finds no live run in ACTIVE_RUNS and replays
nothing, so the transcript stays stale until a hard refresh.

Extend the self-heal: the (re)subscribing tab reports its last-known
message_count (?known_count); when there is no live run to replay, the
handler compares the persisted count and, if the server is ahead, emits a
lightweight session-updated frame. The frontend syncs incrementally via
the #5189 keepStaleUntilLoaded swap-in-place loadSession path (no
clear+refetch, so the #5177/#5189 blank-gap jump is not reintroduced).
Idle-only and pane-scoped; emits only when the server is strictly ahead.
2026-06-30 17:13:45 +00:00
nesquena-hermes a09eb83f52 Merge pull request #5280 from nesquena/release/stage-w3
Release v0.51.767 — Wave 3 batch (#5260 #4957)
v0.51.767
2026-06-30 10:12:51 -07:00
nesquena-hermes 67a789d9af docs(changelog): wave-3 batch (#5260 #4957) 2026-06-30 17:06:31 +00:00
Maude Bot 5263b9acf7 feat: add Webhooks sidebar filter parity
Co-authored-by: Kilian Tyler <kilian@kil.dev>
2026-06-30 17:06:31 +00:00
allenliang2022 0a1cf564c7 fix(chat): make keep-settled-worklog-open genuinely transient (#5260 gate-cert)
The RED gate-cert (Codex-verified) found the keep-open was NOT the one-frame
transient the PR claimed: _disarmKeepSettledWorklogOpen() only cleared the token
with no follow-up render, so the just-settled worklog stayed force-open and could
be cached into _sessionHtmlCache and persist across session restores.

Two coordinated fixes:

1. Don't cache the forced-open DOM. Add _isKeepSettledWorklogOpenArmed() and gate
   the _sessionHtmlCache.set() population on a typeof-safe !_keepOpenArmed local, so
   the armed settle render is never cached. The typeof guard also keeps standalone
   renderMessages() node harnesses (which don't define the helper) working.

2. Collapse pass after disarm for BOTH pin states. The STREAM_DONE handler disarms,
   then runs _renderMessagesWithScrollSnapshot() UNCONDITIONALLY (a scroll-preserving
   re-render that collapses the worklog back to its copied live/user disclosure
   state), and only THEN scrollToBottom() for followers to re-settle at the tail.
   The second RED gate-cert caught that gating the collapse pass to the non-following
   path left a pinned follower forced-open, because scrollToBottom() only settles
   scroll position and does NOT re-render. Running the collapse render before the
   follower re-settle fixes both pin states. The same-frame JS restore absorbs the
   collapse height change instead of leaving it to native scroll-anchoring (which
   mobile suppresses mid-render), so there is no jump, and this unarmed render is
   the one that populates the cache.

Net: keep-open is genuinely one settle render for pinned AND unpinned readers —
neither persists nor caches — and a user-collapsed worklog is preserved. Verified
e2e on an isolated debug instance for both pin states (worklog open-while-armed ->
collapsed-after-pass; pinned follower stays pinned at tail). Regression tests lock
the cache-skip and the collapse-before-scrollToBottom ordering; the scrollToBottom
adjacency keeps the #1360 done-follow test green.
2026-06-30 17:06:31 +00:00
allenliang2022 b041789056 docs(chat): note one-frame flash-open for unpinned user-collapsed worklog
Maintainer review on #5260 flagged that dropping the pin gate means an unpinned
reader who manually collapsed the live worklog now gets a one-frame flash-open at
the settle render before it re-collapses. Document the mechanism in-tree at the
call site (disclosure state preserved + keep-open disarms after the render, so
the next re-render honors the collapsed state) so a future reader doesn't mistake
the single-frame override for a lost preference. Doc-only; no behavior change.
2026-06-30 17:06:31 +00:00
allenliang2022 d9622bf9b0 fix(chat): keep just-settled worklog open for unpinned readers too (mobile 往回大跳)
The STREAM_DONE keep-open exception (#4970 round 6/7) was scoped to PINNED
followers only, on the assumption that unpinned readers 'preserve their viewport
normally'. That holds on desktop (overflow-anchor:none + JS snapshot restore) but
NOT on mobile.

Repro (isolated debug instance + CDP touch emulation, faithful to a real phone):
a reader who scrolls UP to read inside the just-settled turn is UNPINNED. At
STREAM_DONE the live worklog/thinking cards collapse into a compact summary,
shrinking the transcript by hundreds of px ABOVE their viewport. On mobile the
CSS resting value is overflow-anchor:auto, but _fixMobileScrollJank() flips an
inline overflow-anchor:none over the settle render — so native scroll-anchoring
is suppressed during exactly the frame the unpinned reader needs it to absorb the
above-viewport shrink. The content then leaps to the top of the latest turn (the
'往回大跳' report). Single-variable measurement: collapse-with-auto shifts the
reader 0px; collapse-with-none shifts -248px.

Fix: keep the just-settled worklog open for BOTH pin states (still one-shot
scoped to the turn that just settled, so historical worklogs still collapse
compact). This removes the shrink entirely, fixing the jump for every
device/anchor-mode instead of fighting the anchor engine. The #4856 guard and the
mobile overflow-anchor:auto CSS are untouched, so Boev's Android DOM-wipe fix and
akrhin's #MOBILESCROLL fix both stay intact.

- Rename _shouldKeepSettledWorklogOpenForPinnedFollow ->
  _shouldKeepSettledWorklogOpenForStreamSettle (drops the _scrollPinned /
  _messageUserUnpinned gate; keeps the one-shot stream-id token).
- Update the #4970 behavioral regression test to assert keep-open is TRUE for the
  armed turn under BOTH pin states, FALSE for historical turns and after disarm.
2026-06-30 17:06:31 +00:00
nesquena-hermes 1a523926d5 Merge pull request #5278 from nesquena/release/stage-w2
Release v0.51.766 — Wave 2 batch (#5266 #5264 #5253 #5244)
v0.51.766
2026-06-30 09:53:11 -07:00
nesquena-hermes 5370623743 docs(changelog): wave-2 batch (#5266 #5264 #5253 #5244) 2026-06-30 16:36:43 +00:00
nesquena-hermes 62310be565 Merge #5244 (fix/subagent-sidebar-stacking) into stage-w2 2026-06-30 16:35:58 +00:00
nesquena-hermes 4a7159a2ee Merge #5253 (franksong2702/fix-live-worklog-manual-scroll) into stage-w2 2026-06-30 16:35:56 +00:00
nesquena-hermes 3a12ac6bb8 Merge #5264 (fix/large-text-paste-toggle-upstream) into stage-w2 2026-06-30 16:35:55 +00:00
nesquena-hermes 6c5e488579 Merge #5266 (fix/hidden-tab-multipane-attach-bool) into stage-w2 2026-06-30 16:35:53 +00:00
nesquena-hermes 8d5ff4c11e Merge pull request #5277 from nesquena/release/stage-w1
Release v0.51.765 — Wave 1 batch (#5276 #5274 #5272 #5256 #5254 #5257)
v0.51.765
2026-06-30 09:34:21 -07:00
nesquena-hermes 3a2f5cdedb docs(changelog): wave-1 batch (#5276 #5274 #5272 #5256 #5254 #5257) 2026-06-30 16:21:26 +00:00
nesquena-hermes 21233f2df8 Merge #5257 (franksong2702/fix-transparent-live-snapshot) into stage-w1 2026-06-30 16:19:52 +00:00
nesquena-hermes 9dc56a7284 Merge #5254 (pr/5250-settings-search-menu-clip) into stage-w1 2026-06-30 16:19:50 +00:00
nesquena-hermes 90180bd56c Merge #5256 (franksong2702/fix-session-menu-delete-delay) into stage-w1 2026-06-30 16:19:49 +00:00
nesquena-hermes b76264c310 Merge #5272 (fix/5141-terminal-failure-transcript-evaluator) into stage-w1 2026-06-30 16:19:47 +00:00
nesquena-hermes a09bc4e1dc Merge #5274 (pr/5270-cli-webui-continuity) into stage-w1 2026-06-30 16:19:46 +00:00
nesquena-hermes 2ac8162820 Merge #5276 (pr/5273-active-done-viewed-sync) into stage-w1 2026-06-30 16:19:44 +00:00
Rod Boev a13b8b996c Keep done-settle unread metadata aligned with compacted counts 2026-06-30 08:50:25 -04:00
Rod Boev 0c67db9513 fix(#5270): keep cron reply tests compatible with route refresh 2026-06-30 08:41:14 -04:00
Rod Boev 22275c895e fix(#5270): keep chat-start auth tests compatible with route refresh 2026-06-30 08:37:36 -04:00
Rod Boev 5f07e12387 fix(#5270): route the continuity refresh through chat start 2026-06-30 08:33:20 -04:00