Commit graph

6404 commits

Author SHA1 Message Date
nesquena-hermes
2fd2d0951f docs(changelog): Batch C — #5464 read-only session-listing projection + #5465 pause hidden-tab polling (#5455) 2026-07-03 20:32:58 +00:00
nesquena-hermes
5ea8b09b83 fix: prefer IPv4 for extension gallery downloads to prevent timeout on broken IPv6
Clean rebase of rumotoshino's #5458 (rebase-first).

Co-authored-by: rumotoshino <rumotoshino@users.noreply.github.com>
2026-07-03 20:26:18 +00:00
nesquena-hermes
97821f5b3f
Merge pull request #5475 from nesquena/release/stage-5442
Release v0.51.837 — persist TTS and voice preferences server-side (#5442)
2026-07-03 13:18:16 -07:00
nesquena-hermes
6edcf14bbc Merge PR #5465 from ai-ag2026: pause background session polling while tab hidden (#5455) 2026-07-03 20:16:35 +00:00
nesquena-hermes
797eb4a1b9 Merge PR #5464 from ai-ag2026: open session-listing projection read-only (#5455) 2026-07-03 20:16:35 +00:00
nesquena-hermes
eb59ac8fb3 docs(changelog): #5442 persist TTS/voice preferences server-side (#5435) 2026-07-03 20:14:49 +00:00
nesquena-hermes
8120e69e1d Merge PR #5442 from rodboev: persist TTS and voice preferences server-side (#5435) 2026-07-03 20:04:55 +00:00
nesquena-hermes
8399241bab
Merge pull request #5474 from nesquena/release/stage-p1a
Release v0.51.836 — profile overflow-model validation (#5453) + read-only fork guard (#5449)
2026-07-03 13:02:10 -07:00
nesquena-hermes
fb6606152a docs(changelog): Batch A — #5453 profile overflow-model validation + #5449 read-only fork guard 2026-07-03 19:56:48 +00:00
nesquena-hermes
a1f75a40c9 fix(test): assert branch-guard on the extracted helper, not stale inline text
test_branch_endpoint_consults_foreign_session_guard_on_missing_sidecar
grepped the inline handler block for _claim_or_synthesize_cli_session +
not_claimable + 403 — but #5449 extracted that logic into the
_load_branch_source_or_refuse helper, leaving only a dead comment carrying
the old text to satisfy the grep. Point the test at the helper so it asserts
real post-refactor structure instead of a comment.
2026-07-03 19:46:56 +00:00
nesquena-hermes
f2ab07757f ship-pass: #5453 overflow-path regression test + drop #5449 dead comment
- Add test_profile_model_selection_accepts_model_in_overflow_extra_models
  (the extra_models overflow-bucket regression test the warm dossier flagged
  as the #5453 ship-pass note).
- Drop the stray dead pseudo-code comment left in handle_post branch route
  (#5449 cosmetic nit).
2026-07-03 19:45:37 +00:00
nesquena-hermes
00e7203ec8 Merge PR #5449 from rodboev: hide read-only cron fork affordances (#5439) 2026-07-03 19:44:33 +00:00
nesquena-hermes
fa4b404542 Merge PR #5453 from WallaceWebster: include extra_models in profile model validation (#5453) 2026-07-03 19:44:33 +00:00
nesquena-hermes
15fbcb4ce0 fix(chat): recover viewport anchor via sessionIdx when content-derived key goes stale
Clean rebase of allenliang2022's #5469 (rebase-first).

Co-authored-by: allenliang2022 <allenliang2022@users.noreply.github.com>
2026-07-03 19:44:32 +00:00
nesquena-hermes
d5e1274258
Merge pull request #5470 from nesquena/release/stage-5454
Release v0.51.835 — remove transparent-stream live-row entrance animation (#5454)
2026-07-03 11:35:03 -07:00
nesquena-hermes
0a80aa2296 docs(changelog): #5454 remove transparent-stream live-row entrance animation (residual #5367) 2026-07-03 18:31:13 +00:00
nesquena-hermes
a085f919f2 Merge PR #5454 from rodboev: suppress transparent stream live row entrance animation (residual #5367)
Removes the #liveAssistantTurn .transparent-event-row entrance animation
rule and its now-unused @keyframes transparent-event-enter, eliminating the
entrance-animation replay on streaming rebuilds that remained after the
#5400 identity-reconcile fix. Depth-fade [data-transparent-fade] rules
preserved (avoids the #5406 opacity-clobber). Follow-up to already-closed #5367.

Co-authored-by: Rod Boev <rodboev@users.noreply.github.com>
2026-07-03 18:28:52 +00:00
TARS
3f4ebf18a8 fix(sidebar): refresh timestamp labels on tab return
Add a dedicated visibilitychange hook for the 60s relative-time refresh poll so skipped hidden-tab ticks repaint immediately when the tab becomes visible, even when no streaming poll is active.
2026-07-03 20:13:24 +02:00
TARS
5973d2b0e0 fix: narrow sidebar render-skip signature 2026-07-03 20:10:44 +02:00
TARS
eedbf8b05f fix: clear stream perf cleanup state 2026-07-03 20:10:40 +02:00
TARS
10ecfbb376 fix: encode read-only session DB URI 2026-07-03 20:04:41 +02:00
TARS
6a0f5937cf test: stub sidebar render-skip globals 2026-07-03 19:55:37 +02:00
TARS
2f8e2ba547 test: match optimized live token render path 2026-07-03 19:55:33 +02:00
TARS
47855eed88 test: account for session index heal connection 2026-07-03 19:55:29 +02:00
Rod Boev
af3eb88225 Drop redundant live-row suppression after removing the animation source 2026-07-03 13:48:20 -04:00
TARS
fcf3e23643 perf(sidebar): pause background session polling while the tab is hidden (#5455)
The 30s streaming poll (renderSessionList -> GET /api/sessions + full sidebar
rebuild) and the 60s relative-time refresh (renderSessionListFromCache -> full
DOM rebuild) ran unconditionally, including in hidden background tabs, so a
backgrounded window kept fetching and rebuilding the sidebar it could not show.

Guard both interval callbacks with document.hidden and refresh the list on
visibilitychange when the tab is shown again, mirroring the existing gateway
poll. Visually neutral while the tab is visible; a hidden tab simply stops
burning network and DOM churn and re-syncs the moment it is shown.

Verified: node --check + ESLint runtime guard clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 18:41:49 +02:00
TARS
a53f3bdaba perf(sidebar): skip full session-list rebuild when the payload is unchanged (#5455)
The 30s streaming poll and the gateway poll re-applied /api/sessions and ran a
full sidebar DOM rebuild (list.innerHTML='' + one node tree per row) on every
tick, even when the payload was byte-identical to what was already on screen —
the common case on an idle sidebar.

Add a signature over the applied rows + projects + coarse display state in
_applySessionListPayload and skip renderSessionListFromCache() when it matches
the last rendered signature and no entrance animation is pending. A streaming
row's fields advance each poll so its signature changes and it still repaints;
client-only display toggles (search, active, density, select, lineage
expansion) render through their own paths. The per-refresh INFLIGHT cleanup is
still run on the skip path. The 60s relative-time refresh and all other render
triggers call renderSessionListFromCache directly and are unaffected.

Output-neutral: a skip only happens when the render would produce the same DOM.
node --check + ESLint runtime guard clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 18:41:49 +02:00
TARS
ed922f4f18 perf(stream): throttle live-turn snapshot and skip redundant per-token parse (#5455)
Two O(n^2) costs on the per-token/per-frame streaming path, both over the
growing answer:

WS2.2 — snapshotLiveTurn() serialized the whole live turn via turn.outerHTML on
every render frame. That snapshot only backs mid-stream session-switch restore,
and the switch path (sessions.js) plus tool/done event boundaries already
capture synchronously, so the per-frame call is throttled to a coarse trailing
snapshot instead of serializing the entire growing DOM each frame.

WS2.3 — the token handler ran _parseStreamState() (strip tool-call XML + extract
inline thinking over the FULL accumulated text) on every token, but _doRender
re-parses once per throttled frame anyway and the only per-token use is the
assistant-row creation gate. Skip the parse once the row exists (the common
case); keep it only until the row is created. Also drop the full-string
toLowerCase() allocation in _stripXmlToolCalls for a non-allocating regex test.

Output-neutral: same rendered DOM; the row-creation gate and snapshot semantics
are preserved (row appears within one 66ms frame; switch/settle snapshots stay
synchronous). node --check + ESLint runtime guard clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 18:41:49 +02:00
TARS
855b7f1ea4 perf(sessions): open the session-listing projection read-only (#5455)
read_importable_agent_session_rows() is a pure read, but it opened a
read-write sqlite connection on the live multi-GB WAL state.db and re-ran a
defensive CREATE INDEX self-heal on every sidebar build. Holding a
write-capable handle while the agent streams into the same DB adds needless
checkpoint/lock surface.

Open the DB read-only (file:...?mode=ro) for the projection, and self-heal a
missing idx_messages_session through a separate short-lived writable
connection only. With the index present (the normal case) the read path
performs zero writes; when it is missing the self-heal still runs and rows
still come back.

Behavior-neutral: identical rows when the index exists; self-heal preserved
when missing; read-only-fs degradation to the pre-aggregated path unchanged.

Tests: tests/test_issue5455_listing_readonly_connection.py (read-only open,
no writable connection when index present, self-heal when missing).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 18:41:49 +02:00
TARS
304a82d9b4 perf(stream): render anchor-scene live prose incrementally via smd (#5455)
In compact-worklog mode the anchor activity scene re-renders every frame, and
its live prose row was rebuilt with renderMd(fullText) each time — re-parsing
the entire growing answer per frame, which is O(n^2) over a long streamed
response (the incremental smd parser that the main body already uses was
bypassed and its segment hidden).

Keep a persistent per-segment smd parser + DOM node (keyed by the prose row's
local_id, using the same safe renderer as the live body) and feed it only the
delta each frame; hand that persistent node back to the scene builder instead
of re-parsing. Turns the per-frame prose cost from O(n) into O(delta), i.e. the
whole answer from O(n^2) to O(n).

Safe by construction: settled rows and any failure (no smd, no stable key,
parser error, text divergence) fall through to the existing renderMd path, so
worst case is identical to today. Cache is bounded (<=32 segments) and self-heals
on non-append text changes, mirroring _smdWrite.

Verified: node --check + ESLint runtime guard clean. Streaming render profiled
in-browser via a per-frame timing probe.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 18:41:49 +02:00
Rod Boev
a9eb90a0d0 test(#5435): preserve raw speech settings between API cases 2026-07-03 09:22:50 -04:00
Rod Boev
8c82ed8f11 fix(#5435): read voice silence timeout at use time 2026-07-03 08:57:44 -04:00
Stacey2911
badb93d472 fix: reduce transparent stream live row churn 2026-07-03 18:16:56 +10:00
Rod Boev
7a21825722 fix(#5435): keep speech settings payload sparse 2026-07-03 00:22:39 -04:00
Rod Boev
904d741ed2 fix(#5367): suppress transparent stream live row animation 2026-07-02 23:31:57 -04:00
nesquena-hermes
654daf8f2a fix(profiles): include extra_models in profile model validation
Clean rebase of WallaceWebster's #5453 (rebase-first).

Co-authored-by: WallaceWebster <WallaceWebster@users.noreply.github.com>
2026-07-03 03:26:25 +00:00
Rod Boev
1127be609c fix(#5413): smooth Mermaid lightbox resize behavior 2026-07-02 22:19:13 -04:00
Rod Boev
7bc33eb054 test(#5413): scope resize snapshot to dropdown handler 2026-07-02 22:10:05 -04:00
Rod Boev
32a127846e test(#5413): prove fullscreen Mermaid resize cleanup 2026-07-02 21:47:57 -04:00
Rod Boev
fdacb4b922 fix(#5435): stop startup workspace repair from persisting speech defaults 2026-07-02 21:28:46 -04:00
Rod Boev
2034d6b51c fix(#5413): fit fullscreen Mermaid diagrams to the lightbox 2026-07-02 21:28:40 -04:00
nesquena-hermes
0735a1b853 fix(#5439): hide read-only cron fork affordances
Clean rebase of rodboev's #5449 (rebase-first).

Co-authored-by: rodboev <rodboev@users.noreply.github.com>
2026-07-03 00:58:30 +00:00
Rod Boev
8f7b9c1d0d fix(#5435): drop dead persisted-key state from config load 2026-07-02 19:38:35 -04:00
Rod Boev
3b344b1d9a fix(#5435): preserve local speech prefs until settings.json owns them 2026-07-02 19:33:13 -04:00
nesquena-hermes
312d3faba4
Merge pull request #5448 from nesquena/release/stage-5434
Release — restore readable inline Mermaid sizing (#5434, fixes #5413)
2026-07-02 15:49:01 -07:00
nesquena-hermes
a6504a8c58 fix(#5434): scope new Mermaid sizing to inline only — restore master lightbox behavior + inline Fit button (Codex gate findings)
Codex re-gate found 2 SILENT regressions the certifier missed:
- inline lost the 'Fit to screen' toolbar button (PR gated Fit to lightbox-only)
- the new readable-scale/envelope path leaked into lightbox mode (changed zoom-out floor + fit init for wide diagrams)
Fix: toolbar restored to master shape (Fit for all modes, Fullscreen inline-only);
_minScale() returns the flat _MERMAID_VIEWER_MIN_SCALE for lightbox; lightbox init
restored to master's _fitScale()/box*initialFit; the new readable-height sizing is
now scoped strictly to inline mode. Tests updated to the master-consistent contract.
2026-07-02 22:37:12 +00:00
nesquena-hermes
9f7d7e986b docs(changelog): #5434 inline Mermaid sizing 2026-07-02 22:23:23 +00:00
nesquena-hermes
cb8ab640b5 Merge #5434: restore readable inline Mermaid sizing (#5413) [rodboev] 2026-07-02 22:22:27 +00:00
nesquena-hermes
a4ad03bd68 fix(#5413): restore readable Mermaid sizing (rebased onto current master w/ #5437)
Clean rebase of rodboev's #5434 (rebase-first, re-based post-#5437).

Co-authored-by: rodboev <rodboev@users.noreply.github.com>
2026-07-02 21:56:29 +00:00
nesquena-hermes
2829b2adf7
Merge pull request #5447 from nesquena/release/stage-5437
Release — harden ElevenLabs TTS transport guards (#5437, fixes #5430)
2026-07-02 14:48:04 -07:00