Skip to content

fix: avoid duplicate header copy buttons#1324

Closed
dso2ng wants to merge 1 commit intonesquena:masterfrom
dso2ng:fix/header-copy-button-idempotent
Closed

fix: avoid duplicate header copy buttons#1324
dso2ng wants to merge 1 commit intonesquena:masterfrom
dso2ng:fix/header-copy-button-idempotent

Conversation

@dso2ng
Copy link
Copy Markdown
Contributor

@dso2ng dso2ng commented Apr 30, 2026

Thinking Path

  • Hermes WebUI renders fenced code blocks through repeated post-render passes during normal chat updates.
  • For code blocks with a language header, the copy button is appended to the sibling .pre-header, not inside the <pre> element.
  • The existing duplicate guard only checked inside <pre>, so repeated addCopyButtons() calls could append duplicate header copy buttons.
  • This PR makes the guard check the header before creating a new button.

What Changed

  • Detect an existing .code-copy-btn in the .pre-header sibling before creating a new copy button.
  • Keep the existing no-header behavior unchanged.
  • Added a regression test that verifies the header guard runs before document.createElement('button').

Why It Matters

  • Prevents duplicate copy buttons on language-header code blocks after repeated render/cache/streaming update passes.
  • Keeps the fix small and localized to the existing vanilla JS helper.

Verification

  • python -m pytest tests/test_issue1096_copy_buttons.py -q
  • Result: 10 passed

Risks / Follow-ups

  • Low risk; the change only broadens the idempotency guard before creating a copy button.
  • No layout changes beyond preventing duplicate buttons.

Model Used

  • AI-assisted with OpenAI GPT-5.5 via Hermes Agent, using local git/pytest/GitHub CLI tooling.

@nesquena-hermes
Copy link
Copy Markdown
Collaborator

Thanks for the targeted fix. The duplicate-button bug from #1096 came back specifically on language-header blocks because the existing guard only looked inside <pre>, but for headered blocks the copy button lives on the sibling .pre-header. Repeated addCopyButtons() passes during streaming/cache rerender then appended a fresh button each tick.

The fix in static/ui.js — checking .pre-header for an existing .code-copy-btn before document.createElement('button') — keeps the no-header path untouched and matches the existing idempotency pattern. The regression test asserting the guard runs before createElement is the right shape to prevent this from regressing again.

Small, low-risk, +19/-3. Looks good to merge after CI.

@nesquena-hermes
Copy link
Copy Markdown
Collaborator

Shipped in v0.50.245 via batch release PR #1334 (merge commit 52e1567). Thanks @dso2ng! 🙏

Live now at https://github.com/nesquena/hermes-webui/releases/tag/v0.50.245.

Released alongside 9 other contributor fixes — see the v0.50.245 entry in CHANGELOG.md.

bsgdigital pushed a commit to bsgdigital/hermes-webui that referenced this pull request Apr 30, 2026
GeoffBao pushed a commit to GeoffBao/hermes-webui that referenced this pull request May 1, 2026
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.

2 participants