From e5ae65f5100bdefc1142201008f4ad02875d8f4e Mon Sep 17 00:00:00 2001 From: happy5318 Date: Thu, 13 Aug 2026 16:13:03 +0800 Subject: [PATCH] fix: preserve transparent-part source window; clean lint in snapshot tests - Keep `const partBodyHtml=_getCachedRender(partDisplayText,false);` line intact (test_issue3397 asserts the exact source string), apply snapshot stamping on the following line via partBodyHtmlStamped. - Drop unused roots_before variable and unused import in test_media_message_snapshots.py (ruff F841/F401 on new lines). - Update the source-invariant assertion to the two-line stamp shape. --- static/ui.js | 12 ++++++++---- tests/test_media_message_snapshots.py | 25 ++++++++----------------- 2 files changed, 16 insertions(+), 21 deletions(-) diff --git a/static/ui.js b/static/ui.js index 7a1e65ca..37ece067 100644 --- a/static/ui.js +++ b/static/ui.js @@ -16842,13 +16842,17 @@ function renderMessages(options){ if(_ERR_MSG_RE.test(String(partDisplayText||'').trim())) orderedSeg.dataset.error='1'; if(!firstSeg&&thinkingText&&window._showThinking!==false&&!((isCompactWorklogMode()||isTransparentStream())&&_assistantThinkingBelongsInWorklog(m, rawIdx, toolCallAssistantIdxs))) orderedSeg.insertAdjacentHTML('beforeend', _thinkingCardHtml(thinkingText)); const isLastTextPart=partIdx===lastTextPartIdx; - const partBodyHtml=(m && m._media_snapshots && typeof m._media_snapshots==='object') - ? _stampMediaSnapshots(_getCachedRender(partDisplayText,false), m._media_snapshots) - : _getCachedRender(partDisplayText,false); + const partBodyHtml=_getCachedRender(partDisplayText,false); + // Message-level media snapshots: transparent ordered segments carry the + // same per-message path→digest map as the main transcript; stamp it so + // historical previews freeze (&snap=) instead of following overwrites. + const partBodyHtmlStamped=(m && m._media_snapshots && typeof m._media_snapshots==='object') + ? _stampMediaSnapshots(partBodyHtml, m._media_snapshots) + : partBodyHtml; if(isLastTextPart&&statusHtml){ orderedSeg.insertAdjacentHTML('beforeend', statusHtml); } - orderedSeg.insertAdjacentHTML('beforeend', `${isLastTextPart?filesHtml:''}
${partBodyHtml}
${isLastTextPart?footHtml:''}`); + orderedSeg.insertAdjacentHTML('beforeend', `${isLastTextPart?filesHtml:''}
${partBodyHtmlStamped}
${isLastTextPart?footHtml:''}`); blocks.appendChild(orderedSeg); if(!firstSeg) firstSeg=orderedSeg; }); diff --git a/tests/test_media_message_snapshots.py b/tests/test_media_message_snapshots.py index dc64a30c..5dbe609f 100644 --- a/tests/test_media_message_snapshots.py +++ b/tests/test_media_message_snapshots.py @@ -143,25 +143,14 @@ def test_media_capture_allowed_denies_hermes_state(tmp_path, monkeypatch): allowed.write_text("x") assert media_capture_allowed(allowed) is True - # ...but Hermes-internal state filenames are never snapshotted. + # ...but a deny-listed filename under a Hermes root is never snapshotted. + # Point HOME at the fake tree so /.hermes counts as a root. hermes_home = tmp_path / ".hermes" hermes_home.mkdir() secret = hermes_home / "settings.json" secret.write_text("{}") monkeypatch.setenv("HOME", str(tmp_path)) - from api.media_snapshots import _allowed_roots_for_capture - - # Force the root list to include our fake home so the deny path runs. - roots_before = _allowed_roots_for_capture() - try: - # Re-import with env pointing at fake home is not possible in-process; - # instead assert the deny predicate directly on the filename. - assert media_capture_allowed(secret) is False or True # root-dependent - finally: - pass - # The deny FILENAME check is independent of roots: settings.json under a - # hermes root is denied whenever that root is allowed. - assert not media_capture_allowed(secret) or True + assert media_capture_allowed(secret) is False # ── annotate_media_snapshots ─────────────────────────────────────────────── @@ -299,8 +288,6 @@ def test_handle_media_denies_direct_store_path(routes, monkeypatch, tmp_path): # Simulate the production layout: the store lives under a Hermes root, with # HOME pointing at tmp_path so that directory counts as a Hermes root. The # #3234 deny list denies /media_snapshots. - import api.media_snapshots as ms - hermes_home = tmp_path / ".hermes" store = hermes_home / "media_snapshots" monkeypatch.setenv("HOME", str(tmp_path)) @@ -468,7 +455,11 @@ def test_frontend_stamp_source_invariants(): src = open(ROOT / "static" / "ui.js", encoding="utf-8").read() # Main transcript path and transparent ordered segments must stamp. assert "_stampMediaSnapshots(bodyHtml, m._media_snapshots)" in src - assert "_stampMediaSnapshots(_getCachedRender(partDisplayText,false), m._media_snapshots)" in src + # Transparent segments: original _getCachedRender line is preserved (source + # window contract), stamping applied on the next line via *_Stamped. + assert "_getCachedRender(partDisplayText,false);" in src + assert "partBodyHtmlStamped" in src + assert "_stampMediaSnapshots(partBodyHtml, m._media_snapshots)" in src # Worklog scene prose path must stamp via the owner message's map. assert "_anchorSceneOwnerMediaSnapshots" in src # Lazy loaders must read the stamped digest.