Commit graph

5025 commits

Author SHA1 Message Date
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
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
nesquena-hermes
25ccb0340c release: stamp v0.51.614 (#2814 Kanban consolidated view toggle) 2026-06-23 23:52:12 +00:00
nesquena-hermes
e9283c8182 fix(#2814): default _kanbanLanesByProfile=true to match server default (Opus note)
The JS module default was false (consolidated) while the server defaults
lane_by_profile=True (lanes). If the board painted before _kanbanApplyConfigDefaults
ran, there'd be a one-frame consolidated flicker before snapping to lanes. Matching
the client default to the server default removes the flicker. Co-authored-by: stefan-wisbric
2026-06-23 23:51:22 +00:00
nesquena-hermes
5253724f90 rebase(#2814): resolve i18n onto current master + add kanban_view_* keys to all 13 locales
Took master's i18n.js as base (it has all 13 locale blocks + had reorganized the
kanban keys, so the stale-branch conflict block would have duplicated them in
zh-Hant), then inserted #2814's 5 kanban_view_* keys into every locale block after
kanban_new_task — real translations for it/ja/zh/zh-Hant/fr (from the PR), English
fallback elsewhere. All 13 locales now have exactly 1 of each key; locale-parity +
kanban tests green (291 passed).
2026-06-23 23:40:45 +00:00
nesquena-hermes
2b00bad5ce
Merge pull request #4806 from nesquena/stage/4800-stream-perf
Release v0.51.613 — eliminate O(DOM) streaming render freeze on long answers (#4800)
2026-06-23 16:20:37 -07:00
nesquena-hermes
c184c0c2ad release: stamp v0.51.613 (#4800 streaming render freeze fix) 2026-06-23 23:17:37 +00:00
nesquena-hermes
86c3e67a46 test(#4800): accept _scheduleRender(parsed) in the token-handler anchor-registry assertion
#4800 changed the token SSE handler's call from _scheduleRender() to
_scheduleRender(parsed) (passes the pre-computed parse into the cache — the perf
optimization). The slice6 anchor-registry test asserted the literal no-arg call;
relaxed to _scheduleRender( so it matches the call regardless of args. Behavior
(token handler schedules a render) preserved + improved. Co-authored-by: wlknight
2026-06-23 23:07:15 +00:00
nesquena-hermes
d68afd7862 fix(#4800): key the streaming parse-cache on liveReasoningText too (Codex gate)
The parse-result cache keyed only on assistantText, but _parseStreamState() is a
function of BOTH assistantText AND liveReasoningText. A 'reasoning' SSE event (which
mutates liveReasoningText without calling _scheduleRender) landing between a token's
_scheduleRender(parsed) and the rAF firing made _doRender serve a parsed computed from
the older reasoning -> _renderLiveThinking could show stale thinking text. Keying the
cache on liveReasoningText too forces a fresh _parseStreamState when reasoning changed,
and also makes a canceled-then-rescheduled render miss the stale entry. Co-authored-by: wlknight
2026-06-23 22:52:51 +00:00
Rod Boev
6cf4f7a5d0 test(#4793): decouple recycle reset assertions 2026-06-23 18:49:50 -04:00
nesquena-hermes
643eb2e396 test(#4800): make _scheduleRender guard test signature-agnostic
#4800 changed _scheduleRender() -> _scheduleRender(parsed) (parse-result cache).
test_streaming_race_fix's regex hardcoded the empty-arg signature so it couldn't
find the function ('_scheduleRender not found') even though the _streamFinalized
guard it checks is intact (line 3759). Regex now matches any args. Co-authored-by: wlknight
2026-06-23 22:46:49 +00:00
nesquena-hermes
1dbff4e708 Merge branch 'peek-4800' into gate/4800-stream-perf 2026-06-23 22:46:14 +00:00
nesquena-hermes
f04bd9fd8c
Merge pull request #4802 from nesquena/stage/rodboev-4797-4796
Release v0.51.612 — background-tab notifications + profile default workspace (#4753, #4755)
2026-06-23 15:36:43 -07:00
nesquena-hermes
e8b33066ec Merge remote-tracking branch 'origin/master' into stage/rodboev-4797-4796
# Conflicts:
#	CHANGELOG.md
2026-06-23 22:32:36 +00:00
Rod Boev
a4f33f7687 test(#4793): tighten recycle reset regressions 2026-06-23 18:25:39 -04:00
nesquena-hermes
1083239eb2
Merge pull request #4801 from nesquena/stage/4788-json-view
Release v0.51.611 — configurable JSON/YAML code-block default view (#484)
2026-06-23 15:21:06 -07:00
nesquena-hermes
d818b6a68a release: stamp v0.51.612 (#4753 bg-tab notify + #4755 profile default workspace) 2026-06-23 22:19:40 +00:00
Rod Boev
004c9774d0 fix(#4793): harden recycled assistant turns and messages scrollbar drag 2026-06-23 18:19:23 -04:00
nesquena-hermes
edbe676b0d Merge branch 'peek-4796' into stage/rodboev-4797-4796 2026-06-23 22:19:13 +00:00
nesquena-hermes
e26a6e47c0 Merge branch 'peek-4797' into stage/rodboev-4797-4796 2026-06-23 22:19:12 +00:00
nesquena-hermes
8234cd7a98 release: stamp v0.51.611 (#484 configurable JSON/YAML code-block view) 2026-06-23 22:15:10 +00:00
Rod Boev
bad9fd7e2b fix(#4793): harden recycled assistant turns and messages scrollbar drag 2026-06-23 18:14:05 -04:00
wlknight
20a900be60 fix(perf): eliminate O(DOM) streaming render freeze on long agent answers
Introduce _safeSmdRenderer — a renderer wrapper that hooks smd's set_attr
to validate URL schemes inline as each DOM node is created, eliminating
the per-token _sanitizeSmdLinks(assistantBody) full-DOM scan that caused
progressive freezing on answers of 30,000+ chars (5,000+ DOM nodes).

Also add parse-result caching to _scheduleRender to avoid redundant
_extractInlineThinkingFromContent scans between the token event handler
and the rAF render callback.

Changes:
- New _safeSmdRenderer(el): URL scheme safety inline via set_attr hook
  (identical algorithm to proven _streamFadeRenderer.set_attr, no animation)
- _smdNewParser: non-fade path uses _safeSmdRenderer instead of bare
  default_renderer
- _smdWrite: removed _sanitizeSmdLinks(assistantBody) call — safety now
  handled by renderer's set_attr at node-creation time
- _scheduleRender(parsed): accepts optional cached parse result from
  token handler to avoid duplicate O(n) text scans
- Token handler: passes _parseStreamState() result to _scheduleRender

_sanitizeSmdLinks is preserved at _smdEndParser (stream-end safety net)
and in fallback paths where smd is not available.

All 166 existing tests pass.
2026-06-24 06:09:44 +08:00
Rod Boev
53f18556fb Keep model refresh builds authoritative until cache save completes 2026-06-23 17:53:36 -04:00
Rod Boev
fdedb2078a Keep session-visit model refresh from restamping stale catalogs 2026-06-23 17:40:09 -04:00