Skip to content

Release v0.51.288 — Release JD (stage-r24 — collapsible approval card #3515) - #3697

Merged
nesquena-hermes merged 3 commits into
masterfrom
release/stage-r24
Jun 6, 2026
Merged

nesquena-hermes merged 3 commits into
masterfrom
release/stage-r24

Conversation

@nesquena-hermes

Copy link
Copy Markdown
Collaborator

Release stage-r24 (v0.51.288) — collapsible approval card (#3515)

Phase-3 (next tier up), Nathan-approved via screenshots (expanded + collapsed, desktop 1920 +
mobile 390, all live-driven). Closes #3007.

What it does

Adds a chevron collapse toggle to the tool-call approval card header. Collapsed → the card
shrinks to a ~46px "Approval required" strip (desc/command/counter/buttons hidden) so the
transcript + tool-call rationale scrolled above stays readable. Re-expand to act. State resets
to expanded on each new approval (showApprovalCard re-syncs), so a fresh/pending approval is
never silently hidden.

Footprint (low blast radius)

static/index.html (collapse button + ids), static/messages.js (toggle + sync + transcript
reflow), static/style.css (.approval-card.collapsed rules). NO render-pipeline (renderMd/
renderMessages), NO send-path, NO new API routes.

Verified

  • Rebased onto fresh master, rebase fidelity 153/153 lines identical to PR head.
  • PR's own test passes (tests/test_3007_approval_card_collapse.py, 14/14).
  • Live-driven: real showApprovalCard() + toggleApprovalCardCollapsed() — collapsed card height
    46px, approvalBtns display:none, messages gains .approval-collapsed reflow class, near-bottom
    scroll preserved. Expanded/collapsed verified at 1920 + 390.
  • Pre-gate: markers clean, node -c clean, ruff CLEAN, ESLint CLEAN, browser smoke CLEAN.

What to check

  • Codex (regression): collapsing a PENDING approval hides the action buttons — confirm the user
    can always re-expand to act, the collapse state can't get stuck/persist across a NEW approval
    (so a fresh pending approval is never hidden), and hideApprovalCard clears both visible +
    collapsed + transcript-space classes. No keyboard/Enter-to-approve regression while collapsed.
    SAFE TO SHIP or MUST-FIX.
  • Opus (correctness): the collapse/expand toggle + ARIA state stays consistent; transcript
    padding vars are set/removed correctly on show/hide/collapse; no orphaned --approval-card-height
    after hide. Focused code read + one small targeted check only; do NOT write extensive
    reproduction harnesses.

Files: static/index.html, static/messages.js, static/style.css, tests/test_3007_approval_card_collapse.py.

rodboev and others added 3 commits June 6, 2026 02:27
Adds a collapse toggle to the approval card header so users can shrink it
to a thin header strip and keep the tool-call rationale/transcript above
readable. Full ARIA (aria-expanded/controls/label), chevron swap, and
transcript reflow that preserves near-bottom scroll. Closes #3007.

Co-authored-by: Rod Boev <rod.boev@gmail.com>
…3515)

Codex regression-gate finding: showApprovalCard's sameApproval check didn't
include approval_id and didn't clear .collapsed in the !sameApproval branch, so
a NEW/parallel approval arriving while the card was already collapsed could
render collapsed with its command + action buttons hidden. Add approval_id to
the signature; clear .collapsed for a distinct approval before syncing. +2 regression tests.
@nesquena-hermes
nesquena-hermes merged commit d4f26f5 into master Jun 6, 2026
11 checks passed
@nesquena-hermes
nesquena-hermes deleted the release/stage-r24 branch June 6, 2026 02:52
@greptile-apps

greptile-apps Bot commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a collapsible header strip to the tool-call approval card. A chevron button in the card header allows users to shrink the card to a ~46-56px "Approval required" banner so the transcript above stays readable; clicking again re-expands it. State is always reset to expanded for any distinct new approval.

  • HTML gains the approvalCollapse button with full ARIA (aria-expanded, aria-controls, aria-label) and id="approvalBtns" on the buttons container; CSS adds .approval-card.collapsed rules hiding desc/cmd/counter/btns and a matching transcript-reflow pair (.messages.approval-open / .messages.approval-collapsed); JS adds toggleApprovalCardCollapsed, _syncApprovalCollapseButton, and _syncApprovalTranscriptSpace, plus wires them into both showApprovalCard and hideApprovalCard.
  • approval_id is added to the approval signature so distinct queued approvals with identical desc/cmd always trigger the !sameApproval expanded-reset path; a dedicated test suite (14 assertions) covers all new invariants.

Confidence Score: 4/5

The change is well-scoped: it touches only the approval card's presentation layer (no send path, no render pipeline, no API routes) and the key safety invariants — distinct approvals always expand, hide clears both collapsed state and transcript padding — are correctly implemented and covered by tests.

The collapse/expand logic is sound and mirrors the established clarify-card pattern. One minor point: onceBtn.focus() fires even when the card is collapsed for a same-approval re-render, where the button has display:none and the call silently fails. This is harmless but slightly incorrect. Everything else — ARIA sync, transcript reflow, approval_id-keyed signature, and cleanup in hideApprovalCard — is correct.

No files require special attention; static/messages.js carries the most logic but all critical paths are tested.

Important Files Changed

Filename Overview
static/messages.js Core logic for collapse/expand toggle, ARIA sync, and transcript reflow. Key invariants (expand on new approval, clear on hide, scroll preservation) are correctly handled; minor point: onceBtn.focus() fires unconditionally even when the card is collapsed for a same-approval re-render.
static/index.html Adds collapse button with correct ARIA attributes and id="approvalBtns" on the actions container; clean diff with no regressions to existing markup.
static/style.css Collapse styles follow existing patterns (clarify card); cascade ordering correctly lets .messages.approval-collapsed override .messages.approval-open for padding-bottom.
tests/test_3007_approval_card_collapse.py 14 text-based assertions cover all new functions, CSS classes, HTML attributes, the !sameApproval expanded-reset branch, and call-count invariants for _syncApprovalTranscriptSpace.
CHANGELOG.md Version entry added correctly; format and attribution match existing entries.

Sequence Diagram

sequenceDiagram
    participant Server
    participant showApprovalCard
    participant hideApprovalCard
    participant toggleApprovalCardCollapsed
    participant DOM

    Server->>showApprovalCard: new approval (distinct sig)
    showApprovalCard->>DOM: card.classList.remove("collapsed")
    showApprovalCard->>DOM: card.classList.add("visible")
    showApprovalCard->>DOM: "_syncApprovalCollapseButton() → aria-expanded=true, chevron-down"
    showApprovalCard->>DOM: _syncApprovalTranscriptSpace(card) → approval-open, --approval-card-height

    Note over DOM: User reads transcript, clicks chevron
    DOM->>toggleApprovalCardCollapsed: onclick
    toggleApprovalCardCollapsed->>DOM: card.classList.toggle("collapsed", true)
    toggleApprovalCardCollapsed->>DOM: "_syncApprovalCollapseButton() → aria-expanded=false, chevron-up"
    toggleApprovalCardCollapsed->>DOM: _syncApprovalTranscriptSpace(card) → approval-collapsed, --approval-dock-height

    Note over DOM: User re-expands to act
    DOM->>toggleApprovalCardCollapsed: onclick
    toggleApprovalCardCollapsed->>DOM: card.classList.toggle("collapsed", false)
    toggleApprovalCardCollapsed->>DOM: "_syncApprovalCollapseButton() → aria-expanded=true, chevron-down"
    toggleApprovalCardCollapsed->>DOM: _syncApprovalTranscriptSpace(card) → remove approval-collapsed, --approval-card-height

    DOM->>hideApprovalCard: respondApproval() or session end
    hideApprovalCard->>DOM: card.classList.remove("visible", "collapsed")
    hideApprovalCard->>DOM: _syncApprovalTranscriptSpace(null) → remove approval-open/collapsed, remove CSS vars
Loading

Reviews (1): Last reviewed commit: "fix(approval): clear collapsed state for..." | Re-trigger Greptile

Comment thread static/messages.js
Comment on lines 3020 to 3023
const onceBtn = $("approvalBtnOnce");
if (onceBtn && document.activeElement !== $('msg')) {
setTimeout(() => onceBtn.focus({preventScroll: true}), 50);
}

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.

P2 When showApprovalCard is called for an already-visible, already-collapsed card (sameApproval === true), card.classList.remove("collapsed") is intentionally skipped — so the card stays collapsed. The onceBtn.focus() call that follows will try to focus a button that has display:none via .approval-card.collapsed .approval-btns, which silently fails. The focus hint to the user is lost and the call is wasted. Adding a collapsed guard makes the intent explicit.

Suggested change
const onceBtn = $("approvalBtnOnce");
if (onceBtn && document.activeElement !== $('msg')) {
setTimeout(() => onceBtn.focus({preventScroll: true}), 50);
}
const onceBtn = $("approvalBtnOnce");
if (onceBtn && !card.classList.contains("collapsed") && document.activeElement !== $('msg')) {
setTimeout(() => onceBtn.focus({preventScroll: true}), 50);
}

SysAdminDoc pushed a commit to SysAdminDoc/hermes-webui that referenced this pull request Jun 26, 2026
…esquena#3515) (nesquena#3697)

* feat(approval): make the approval card collapsible (nesquena#3515)

Adds a collapse toggle to the approval card header so users can shrink it
to a thin header strip and keep the tool-call rationale/transcript above
readable. Full ARIA (aria-expanded/controls/label), chevron swap, and
transcript reflow that preserves near-bottom scroll. Closes nesquena#3007.

Co-authored-by: Rod Boev <rod.boev@gmail.com>

* docs(changelog): v0.51.288 — Release JD (stage-r24)

* fix(approval): clear collapsed state for a distinct queued approval (nesquena#3515)

Codex regression-gate finding: showApprovalCard's sameApproval check didn't
include approval_id and didn't clear .collapsed in the !sameApproval branch, so
a NEW/parallel approval arriving while the card was already collapsed could
render collapsed with its command + action buttons hidden. Add approval_id to
the signature; clear .collapsed for a distinct approval before syncing. +2 regression tests.

---------

Co-authored-by: Rod Boev <rod.boev@gmail.com>
Co-authored-by: nesquena-hermes <[email protected]>
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.

approval popup needs to be collapsible too

2 participants