Skip to content

Release v0.51.302 — Release JR (stage-brick — mobile/iOS brick + large-session perf hotfixes) - #3754

Merged
nesquena-hermes merged 4 commits into
masterfrom
release/stage-brick
Jun 6, 2026
Merged

nesquena-hermes merged 4 commits into
masterfrom
release/stage-brick

Conversation

@nesquena-hermes

Copy link
Copy Markdown
Collaborator

Release v0.51.302 — Release JR (stage-brick)

Three brick / high-severity hotfixes, each rebased onto fresh master (their original PR branches were 8 commits stale — the revert-guard would have rolled back 8 releases on a direct squash-merge). Rebase fidelity verified byte-identical to each PR head.

Fixed

Performance

  • perf(session): skip fuzzy matching for giant merge payloads #3730 (@alvistar) — _matching_visible_duplicate() casefold+regex-tokenized multi-MB tool payloads on every visible key, making /api/session take 10s+ and block /api/sessions ~19s. Loose normalization is now lazy+cached; substring/fuzzy matching skipped for non-exact payloads >200KB (exact visible-key matches still short-circuit).

Gates

  • Full suite: 8118 passed, 0 failed
  • Codex regression gate: SAFE TO SHIP
  • Opus correctness gate: SAFE TO SHIP
  • ESLint runtime + scope-undef + ruff forward gates: CLEAN
  • Revert-guard: origin/master is ancestor (no stale-base rollback)

Closes #3735, closes #3729, closes #3730.

nesquena-hermes and others added 4 commits June 6, 2026 23:49
The .toast container kept pointer-events:auto while hidden (opacity:0), so its
fixed padding sat over mobile profile action buttons and ate their clicks. Set
pointer-events:none when hidden; restore auto on .toast.show.

Co-authored-by: timlawrenz <timlawrenz@users.noreply.github.com>
iOS Safari has no Enter key; the keyboard 'Done' button fires blur, and the old
onblur=cancel discarded the rename. Flip blur to save (Escape still cancels) for
session rename and project create/rename, with a _finishDone guard to prevent a
double-fire between blur and the API callback.

Co-authored-by: reinocheong <reinocheong@users.noreply.github.com>
)

Large tool/log payloads made _matching_visible_duplicate() casefold+regex-tokenize
multi-megabyte contents on every visible key, so /api/session took 10s+ and blocked
/api/sessions for ~19s. Keep loose normalization lazy+cached and skip substring/fuzzy
matching for non-exact payloads >200KB; exact visible-key matches still short-circuit.

Co-authored-by: alvistar <alvistar@users.noreply.github.com>
@nesquena-hermes
nesquena-hermes merged commit bf088cb into master Jun 6, 2026
11 checks passed
@nesquena-hermes
nesquena-hermes deleted the release/stage-brick branch June 6, 2026 23:58
@greptile-apps

greptile-apps Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This release bundles three hotfixes: a CSS pointer-events fix that prevented taps on mobile profile buttons, a blur-saves change that makes conversation/project rename work on iOS Safari, and a lazy-evaluation guard in _matching_visible_duplicate that eliminates multi-second stalls when loading sessions with large tool payloads.

  • Toast fix (style.css, test_issue1796_error_toasts.py): pointer-events:none on the hidden .toast, auto only on .toast.show — invisible padding can no longer eat taps on elements underneath.
  • iOS rename fix (sessions.js): onblur now commits instead of cancelling for session, project-create, and project-rename inputs; _finishDone latch prevents double-fire on blur + callback; error path in _startProjectCreate resets the latch for retry.
  • Large-payload dedup perf (api/models.py, test_merge_key_tool_calls.py): loose_by_key is built lazily per-probe; substring and fuzzy matching are skipped when either payload exceeds 200KB, with exact set-membership dedup preserved unconditionally.

Confidence Score: 3/5

Safe to merge with a one-line follow-up fix to _startProjectCreate; all other changes are correct and well-tested.

The CSS, Python, and test changes are clean. The iOS rename fix is correct — session rename already had its own finishDone latch and the blur direction is right. The one issue is in _startProjectCreate: renderSessionList() sits outside the try-catch, so a network failure during the post-success list refresh leaves _finishDone permanently true with the input stuck in the DOM and no user-accessible recovery path. _startProjectRename handles the identical situation correctly by keeping renderSessionList() inside the try block.

static/sessions.js — specifically the _startProjectCreate finish function around the try-catch boundary.

Important Files Changed

Filename Overview
static/sessions.js Three related changes: session-rename blur now saves (was cancel), _finishDone latch added to _startProjectCreate and _startProjectRename. In _startProjectCreate, renderSessionList() sits outside the try-catch, meaning a post-success refresh failure permanently locks the latch with the input stuck in the DOM.
api/models.py Lazy-initialises loose_by_key in _build_visible_duplicate_lookup and skips substring/fuzzy matching for payloads > 200KB. Exact-key deduplication via the set lookup is preserved. Logic is correct and well-documented.
static/style.css Moves pointer-events:auto from the base .toast rule to .toast.show, adding pointer-events:none to the hidden state. Correct minimal fix with no unintended side-effects on hover/focus interactivity.
tests/test_issue1796_error_toasts.py Test updated to assert pointer-events:auto appears on .toast.show and pointer-events:none on the base rule, faithfully mirroring the CSS change.
tests/test_merge_key_tool_calls.py Two new test cases: one verifies _loose_session_message_content is never called for >200KB payloads (via monkeypatch assert), the other confirms fuzzy matching is still applied for small payloads. Both tests are correct.
CHANGELOG.md New v0.51.302 entry with accurate, user-facing descriptions of all three fixes. No issues.

Sequence Diagram

sequenceDiagram
    participant User
    participant DOM
    participant finish
    participant API
    participant renderSessionList

    Note over User,renderSessionList: _startProjectCreate (happy path)
    User->>DOM: blur / Enter
    DOM->>finish: finish(true)
    finish->>finish: "_finishDone=true"
    finish->>API: POST /api/projects/create
    API-->>finish: 200 OK
    finish->>renderSessionList: await renderSessionList()
    renderSessionList-->>finish: done
    finish->>DOM: showToast("Project created")

    Note over User,renderSessionList: _startProjectCreate (API error — retry allowed)
    User->>DOM: blur / Enter
    DOM->>finish: finish(true)
    finish->>finish: "_finishDone=true"
    finish->>API: POST /api/projects/create
    API-->>finish: error
    finish->>finish: "_finishDone=false (reset for retry)"
    finish->>DOM: showToast("Project create failed")
    finish-->>DOM: return (inp stays in DOM)

    Note over User,renderSessionList: _startProjectCreate (renderSessionList error — UI stuck)
    User->>DOM: blur / Enter
    DOM->>finish: finish(true)
    finish->>finish: "_finishDone=true"
    finish->>API: POST /api/projects/create
    API-->>finish: 200 OK
    finish->>renderSessionList: await renderSessionList()
    renderSessionList-->>finish: throws
    finish-->>DOM: "unhandled rejection, _finishDone=true forever"
Loading

Comments Outside Diff (1)

  1. static/sessions.js, line 5885-5957 (link)

    P2 Multiple unrelated fixes bundled in one PR

    AGENTS.md specifies "Keep one logical change per PR; split unrelated refactors or cleanup." This PR combines three independent hotfixes (toast pointer-events, iOS rename/blur, large-payload dedup performance), each touching different subsystems. The rebase rationale is described in the PR description, but the guideline still applies — it makes the diff harder to bisect if a regression surfaces later from one of the three changes.

    Context Used: AGENTS.md (source)

    Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Reviews (1): Last reviewed commit: "docs(changelog): stamp v0.51.302 — Relea..." | Re-trigger Greptile

Comment thread static/sessions.js
Comment on lines +5895 to 5903
try{
await api('/api/projects/create',{method:'POST',body:JSON.stringify({name:inp.value.trim(),color})});
}catch(e){
_finishDone=false;
showToast('Project create failed: '+(e.message||e));
return;
}
await renderSessionList();
showToast('Project created');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 renderSessionList() sits outside the try-catch in _startProjectCreate, but inside it in _startProjectRename. If a network error occurs during the post-create list refresh, the async finish function rejects with _finishDone still true, leaving inp permanently in the DOM with no way for the user to dismiss it (every subsequent blur/Enter is a no-op) short of a page refresh. Moving renderSessionList() and showToast inside the try block matches _startProjectRename's pattern and restores retry-ability on failure.

Suggested change
try{
await api('/api/projects/create',{method:'POST',body:JSON.stringify({name:inp.value.trim(),color})});
}catch(e){
_finishDone=false;
showToast('Project create failed: '+(e.message||e));
return;
}
await renderSessionList();
showToast('Project created');
try{
await api('/api/projects/create',{method:'POST',body:JSON.stringify({name:inp.value.trim(),color})});
await renderSessionList();
showToast('Project created');
}catch(e){
_finishDone=false;
showToast('Project create failed: '+(e.message||e));
return;
}

SysAdminDoc pushed a commit to SysAdminDoc/hermes-webui that referenced this pull request Jun 26, 2026
…e-session perf hotfixes) (nesquena#3754)

* fix(ui): stop hidden toast from intercepting clicks on mobile (nesquena#3735)

The .toast container kept pointer-events:auto while hidden (opacity:0), so its
fixed padding sat over mobile profile action buttons and ate their clicks. Set
pointer-events:none when hidden; restore auto on .toast.show.

Co-authored-by: timlawrenz <timlawrenz@users.noreply.github.com>

* fix(sessions): rename saves on blur so iOS Safari rename works (nesquena#3729)

iOS Safari has no Enter key; the keyboard 'Done' button fires blur, and the old
onblur=cancel discarded the rename. Flip blur to save (Escape still cancels) for
session rename and project create/rename, with a _finishDone guard to prevent a
double-fire between blur and the API callback.

Co-authored-by: reinocheong <reinocheong@users.noreply.github.com>

* perf(session): skip fuzzy dedup matching for giant merge payloads (nesquena#3730)

Large tool/log payloads made _matching_visible_duplicate() casefold+regex-tokenize
multi-megabyte contents on every visible key, so /api/session took 10s+ and blocked
/api/sessions for ~19s. Keep loose normalization lazy+cached and skip substring/fuzzy
matching for non-exact payloads >200KB; exact visible-key matches still short-circuit.

Co-authored-by: alvistar <alvistar@users.noreply.github.com>

* docs(changelog): stamp v0.51.302 — Release JR (stage-brick brick/perf hotfixes nesquena#3735 nesquena#3729 nesquena#3730)

---------

Co-authored-by: nesquena-hermes <[email protected]>
Co-authored-by: timlawrenz <timlawrenz@users.noreply.github.com>
Co-authored-by: reinocheong <reinocheong@users.noreply.github.com>
Co-authored-by: alvistar <alvistar@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant