Commit graph

5048 commits

Author SHA1 Message Date
nesquena-hermes
b9e4e24cbc release: stamp v0.51.624 (#4832 bound kanban column card-list height) 2026-06-24 10:49:28 +00:00
nesquena-hermes
631f1a35da Merge branch 'peek-4832' into gate/4832-kanban-height 2026-06-24 10:38:49 +00:00
nesquena-hermes
a287980799
Merge pull request #4838 from nesquena/fix/4702-portrait-scroll-bottom
Release v0.51.623 — iOS portrait: opening a conversation lands at the bottom (#4702)
2026-06-24 03:28:54 -07:00
nesquena-hermes
718cefc264 release: stamp v0.51.623 (#4702 iOS portrait open-scroll-to-bottom) 2026-06-24 10:25:20 +00:00
nesquena-hermes
7fe6861a54 test(#4702): thread _lastMessageClientHeight through the scroll-pin-reentry JS harness
The #4295 harness runs the extracted scroll-handler body in a Node new Function();
the body now references _lastMessageClientHeight, so it must be a param + threaded
through state (seeded null, samples keep clientHeight stable so grew stays false and
the pin-reentry assertions are unchanged).
2026-06-24 10:15:04 +00:00
nesquena-hermes
671f4504ae fix(#4702): co-seed _lastMessageClientHeight with every programmatic _lastScrollTop write (Codex gate)
Codex found the guard had a first-event gap: programmatic seeds of _lastScrollTop
(_setMessageScrollToBottom, scrollToBottom, snapshot restore paths) didn't seed
_lastMessageClientHeight, so the FIRST native toolbar-collapse scroll saw a null
prior height -> grew=false -> the false-unpin still fired. Now every programmatic
_lastScrollTop=el.scrollTop is paired with _lastMessageClientHeight=el.clientHeight.
2026-06-24 10:02:52 +00:00
nesquena-hermes
fe40912eb9 fix(#4702): don't false-unpin a freshly-opened session on iOS portrait toolbar settle
iOS Safari portrait resolves its dynamic toolbar height after first paint; when the
toolbar collapses the #messages scroller grows (clientHeight up), firing a scroll
event with decreased scrollTop that was misread as an upward user scroll -> falsely
set _messageUserUnpinned, and the ResizeObserver settle then self-cancelled, leaving
the reader stranded at the TOP of a freshly-opened conversation (landscape unaffected
since it doesn't resize late). Sibling of #4701.

Fix (touch-safe, no-op on desktop/landscape where clientHeight is stable):
- Track _lastMessageClientHeight; gate movedUp on !grew so a container-height
  INCREASE can't be read as an upward scroll. Reset on session switch.
- For explicit (open) settles, also observe the scroller itself so a late portrait
  toolbar collapse re-anchors the bottom.

Independent of #4818 (overflow-anchor paint-gap) — different mechanism, coexists.
Diagnosis credit: investigation. Co-authored-by: reinocheong <reporter>
2026-06-24 09:56:06 +00:00
nesquena-hermes
dabbf06575
Merge pull request #4837 from nesquena/fix/4768-cron-graceful-degrade
Release v0.51.622 — Tasks tab no longer 500s when the cron package is absent (#4768)
2026-06-24 02:41:04 -07:00
nesquena-hermes
77b59f7c85 test(#4768): drop unused 're' import (ruff F401) 2026-06-24 09:29:15 +00:00
nesquena-hermes
054e39151b release: stamp v0.51.622 (#4768 cron-absent Tasks tab graceful degrade) 2026-06-24 09:24:54 +00:00
nesquena-hermes
f4e150e105 Merge remote-tracking branch 'origin/master' into fix/4768-cron-graceful-degrade 2026-06-24 09:23:37 +00:00
nesquena-hermes
853c367241
Merge pull request #4835 from nesquena/stage/4241-vietnamese
Release v0.51.621 — Vietnamese UI language (#4241)
2026-06-24 02:15:14 -07:00
nesquena-hermes
1e3132376b fix(#4768): only treat absent cron package as unavailable, re-raise real import bugs (Codex gate)
ModuleNotFoundError fires both when cron.jobs is absent AND when an existing
cron/jobs.py fails to import its own dependency. Catch as exc and only return the
graceful {jobs:[],cron_unavailable:true} when exc.name is 'cron'/'cron.jobs';
re-raise otherwise so a real cron bug isn't silently swallowed.
2026-06-24 09:12:46 +00:00
nesquena-hermes
61f3c766df release: stamp v0.51.621 (#4241 Vietnamese UI language) 2026-06-24 09:11:06 +00:00
jkobject
93afd60425 fix(kanban): bound column card list height 2026-06-24 10:57:03 +02:00
nesquena-hermes
1be24e0660 test(#4241): bump remaining hardcoded locale-count assertions for vi (14th locale)
Full-suite caught 7 more per-locale count tests: open_in_vscode (->13, a
pre-existing one-locale gap unrelated to vi), usage_cache_hit_detail/usage_cached_percent
(->14), and the i18n_tooltips LOCALE_COUNT (13->14). vi carries these keys.
2026-06-24 08:50:52 +00:00
nesquena-hermes
34694a1f02 fix(#4768): degrade GET /api/crons gracefully when the cron module is absent
In split-container / minimal Docker deployments the WebUI image may not ship the
agent's cron package on its import path, so the Tasks tab's GET /api/crons did
'from cron.jobs import list_jobs' and 500'd with ModuleNotFoundError — breaking the
whole tab. Now the import is guarded and returns {jobs: [], cron_unavailable: true}
instead, so the Tasks tab loads (empty) instead of erroring. Happy path unchanged.
Co-authored-by: reporter
2026-06-24 08:42:50 +00:00
nesquena-hermes
1fc24ddf68 feat(#4241): add Vietnamese (vi) as 14th UI locale + wire parity
Maintainer-completed @thanhtantran's #4241 (Nathan approved bringing it in):
- vi locale block in static/i18n.js (contributor's 1615-line translation) rebased onto master.
- Added vi to _LOGIN_LOCALE in api/routes.py (login-page localization, issue #1442 parity).
- Bumped the per-locale hardcoded-count assertions 13->14 across the locale-parity
  tests (rtl, quota_chip, hide_suggestions, virtualize_transcript, no_git, help_tab,
  verdigris/zeus skins, auxiliary_models) and added 'vi' to the composer-voice-buttons
  LOCALES tuples. vi already carries all current English keys (verified 14x per key).
All 497 locale/parity tests pass. Co-authored-by: thanhtantran
2026-06-24 08:39:14 +00:00
nesquena-hermes
3de15e53a5 Merge branch 'peek-4241' into gate/4241-vietnamese 2026-06-24 08:26:00 +00:00
nesquena-hermes
d2a64d7fb9
Merge pull request #4831 from nesquena/fix/4808-streaming-sessions-cache-ttl
Release v0.51.620 — fix /api/sessions CPU spike + slowness during streaming (#4808)
2026-06-24 01:23:07 -07:00
nesquena-hermes
c3d2fe4a20 release: stamp v0.51.620 (#4808 streaming /api/sessions cache TTL hotfix) 2026-06-24 08:19:43 +00:00
nesquena-hermes
1fc86a47c7 Merge remote-tracking branch 'origin/master' into fix/4808-streaming-sessions-cache-ttl 2026-06-24 08:18:44 +00:00
Orange Pi Vietnam
d341f2084c
Merge branch 'nesquena:master' into master 2026-06-24 15:12:44 +07:00
nesquena-hermes
916395108b
Merge pull request #4830 from nesquena/stage/4828-reasoning-echo
Release v0.51.619 — stop final-answer text leaking into the Worklog as reasoning (#4827)
2026-06-24 01:12:23 -07:00
nesquena-hermes
a0c295d4d8 release: stamp v0.51.619 (#4827 reasoning-echo suppression) 2026-06-24 08:09:17 +00:00
nesquena-hermes
8eed95a25e fix(#4808): widen /api/sessions cache TTL while streaming to stop per-poll rebuilds
The frontend polls /api/sessions every 5s while a turn streams
(static/sessions.js _streamingPollMs=5000), but the cache TTL was 2.5s
(_SESSIONS_CACHE_TTL_SECONDS) — so every streaming poll landed in a fresh window
and forced a full all_sessions() rebuild on the hot path under the global store
LOCK, pinning CPU to 100% and starving token rendering on large stores
(recurrence of #4672). The #4680 freeze-marker only de-dupes rebuilds WITHIN one
TTL window; with polls spaced wider than the TTL it never helped.

Fix: while _session_list_cache_streaming_freeze_marker() indicates an active
stream, use _SESSIONS_CACHE_STREAMING_TTL_SECONDS=10.0 (> the 5s poll) so the
sidebar holds steady across streaming polls. Live runtime state (active stream,
sort order, pending flags) is overlaid on every response regardless of cache, and
structural/settings changes still evict immediately via the source stamp — only a
streaming session's own persisted title/message_count can lag up to 10s, which the
#4672 design already deems acceptable. Idle path byte-for-byte unchanged.

Diagnosis credit: investigation reproduced 6 streaming polls -> 6 rebuilds before,
1 after. Co-authored-by: batkuip <reporter>
2026-06-24 08:06:45 +00:00
nesquena-hermes
22b98e3922 Merge branch 'peek-4828' into gate/4828-reasoning-echo
# Conflicts:
#	CHANGELOG.md
2026-06-24 07:57:31 +00:00
nesquena-hermes
27b6cd436e
Merge pull request #4829 from nesquena/stage/4809-worklog-dur
Release v0.51.618 — preserve processed Worklog duration after session merge (#4809)
2026-06-24 00:54:02 -07:00
nesquena-hermes
a51b06910f release: stamp v0.51.618 (#4809 worklog duration preserve) 2026-06-24 07:50:06 +00:00
nesquena-hermes
dcce509e7b Merge remote-tracking branch 'origin/master' into gate/4809-worklog-dur
# Conflicts:
#	CHANGELOG.md
2026-06-24 07:49:32 +00:00
Frank Song
2aaad7a282 Fix final answer reasoning echo 2026-06-24 15:29:25 +08:00
Tony Tran
730c6940c9 fix: add missing Vietnamese locale keys 2026-06-24 14:28:22 +07:00
nesquena-hermes
6b52b06954
Merge pull request #4824 from nesquena/stage/4818-mobile-scroll
Release v0.51.617 — fix mobile scroll-jank to top during streaming (#4818)
2026-06-24 00:27:50 -07:00
nesquena-hermes
f3086f4974 Merge branch 'peek-4809' into gate/4809-worklog-dur
# Conflicts:
#	CHANGELOG.md
2026-06-24 07:25:32 +00:00
nesquena-hermes
19af32f1fa release: stamp v0.51.617 (#4818 mobile scroll-jank fix) 2026-06-24 07:23:29 +00:00
nesquena-hermes
92b3ca7046 Merge branch 'peek-4818' into gate/4818-mobile-scroll 2026-06-24 06:59:17 +00:00
nesquena-hermes
0dba861f74
Merge pull request #4819 from nesquena/stage/4803-recycle-harden
Release v0.51.616 — harden recycled assistant turns + scrollbar-drag detection (#4793)
2026-06-23 23:54:28 -07:00
nesquena-hermes
9883cf80a0 release: stamp v0.51.616 (#4793 recycle hardening) 2026-06-24 06:50:31 +00:00
nesquena-hermes
988acdb441 Merge remote-tracking branch 'origin/master' into gate/4803-recycle-harden 2026-06-24 06:49:41 +00:00
Orange Pi Vietnam
e42d308245
Merge branch 'master' into master 2026-06-24 13:42:54 +07:00
akrhin
d89cfea45e
Merge branch 'master' into fix/mobile-scroll-jank-clean 2026-06-24 09:41:54 +03:00
nesquena-hermes
517fa5ed4d
Merge pull request #4816 from nesquena/stage/4798-model-refresh
Release v0.51.615 — refresh stale model catalogs on session visit (#4756)
2026-06-23 23:41:43 -07:00
Orange Pi Vietnam
b12f541394
Merge branch 'nesquena:master' into master 2026-06-24 13:41:38 +07:00
akrhin
c4e82c6155 chore: cleanup per Greptile review
- Remove dead _scrollAnchorRestore variable (returns undefined)
- Remove redundant _fixMobileScrollJank() call from _doRender()
  (CSS already gives overflow-anchor:auto on mobile via media query;
   desktop exits guard early — call was a no-op on every tick)
- Update JSDoc on _fixMobileScrollJank to reflect actual usage
2026-06-24 09:38:01 +03:00
akrhin
98688491c1 fix(#MOBILESCROLL): prevent scrollTop jank to top on mobile during streaming DOM rebuild
Root cause: .messages had overflow-anchor:none unconditionally. On mobile
touch devices (iOS Safari, Android Chrome), the compositor can paint a frame
with scrollTop=0 between innerHTML='' and snapshot restore, scroll-janking
the user to the top of the transcript.

Three-layer fix:

1. CSS (style.css): Use overflow-anchor:auto on touch devices (mobile),
   keep overflow-anchor:none on desktop (mouse-driven) via
   @media (hover:hover) and (pointer:fine) — preserves the existing
   behavior where tool/card inserts don't yank a reading user.

2. JS guard (ui.js): Add window._fixMobileScrollJank() that temporarily
   sets overflowAnchor='auto' on #messages before innerHTML='' and
   clears it one rAF later — prevents the compositor frame with scrollTop=0.

3. Streaming protection (messages.js): Call _fixMobileScrollJank() at the
   top of each _doRender() tick so streaming DOM growth doesn't jank the
   viewport position.

Tests:
- Updated test_issue1360_streaming_scroll_hardening.py: split the
  overflow-anchor test into desktop (none) and mobile (auto) variants.
- Added test_mobile_scroll_jank.html: interactive visual test that
  simulates the scroll jank on a mobile-sized viewport.
2026-06-24 09:37:55 +03:00
nesquena-hermes
05cf44ffca Merge branch 'peek-4803' into gate/4803-recycle-harden 2026-06-24 06:37:38 +00:00
nesquena-hermes
4855f26098 release: stamp v0.51.615 (#4756 model-catalog session-visit refresh) 2026-06-24 06:37:22 +00:00
nesquena-hermes
b9f1491de7 Merge branch 'peek-4798-v2' into gate/4798-v2 2026-06-24 06:25:59 +00:00
Frank Song
cafeda63ca Preserve processed Worklog duration during message merges 2026-06-24 11:32:27 +08:00
nesquena-hermes
e182a0ec54
Merge pull request #4807 from nesquena/stage/2814-kanban-view
Release v0.51.614 — Kanban consolidated view toggle (#2814)
2026-06-23 17:08:09 -07:00