Clear stamped code-block height when Hide Info collapses a tool call - #5924
Clear stamped code-block height when Hide Info collapses a tool call#5924FadhlanR wants to merge 1 commit into
Conversation
The scrollBottomIntoView modifier on a tool call's code block stamped an inline pixel height sized to the Monaco editor's content, but nothing ever cleared it. When a tool-call message mounted while its code area was already expanded (reopening the AI assistant panel, re-entering the room, a submode switch), the modifier stamped the height at install; a later "Hide Info" removed the editor but left the container at its expanded size, leaving an empty gap below the header. Make the modifier consume isDisplayingCode so it re-runs on toggle, and reset the inline height on the collapse / no-measurable-editor paths so the block returns to its header-only height. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
backspace
left a comment
There was a problem hiding this comment.
[Claude Code 🤖]
I went after what changes on the paths this modifier previously never ran on — expand, remount, rebuild — and checked the height math against the code block's own CSS; I did not exercise it in a browser.
The collapse fix is correct and the remount reproduction in the test is real. But consuming isDisplayingCode also activates the height stamp on the expand path, where getContentHeight() over-measures anything past the editor's 250px cap — so for long tool calls this moves the empty block from "Hide Info" to "View Info". That is the one blocking item.
- Drop the outer height stamp, or measure the editor's rendered box instead of its content height — see the
scrollBottomIntoViewthread. Blocking. - Confirm you want "View Info" to scroll the panel; that behavior falls out of the same change — same thread. Needs an answer, not a change.
- Add expanded-state coverage with a payload past the cap — see the tools-test thread. Non-blocking.
Percy is the only non-green check, with 2 unreviewed visual changes. Worth opening rather than bulk-approving, since this change can alter the code block's box height.
| let editor = this.args.monacoSDK.editor | ||
| .getEditors() | ||
| .find((editor) => element.contains(editor.getContainerDomNode())); | ||
| let editorHeight = editor?.getContentHeight() ?? 0; |
There was a problem hiding this comment.
[Claude Code 🤖]
Consuming isDisplayingCode also makes the expand path stamp a height for the first time, and this math over-measures — so as written the PR trades an empty block after "Hide Info" for one after "View Info".
getContentHeight() is Monaco's full content height, but .code-block-editor is capped at --code-block-max-height (250px) in ai-assistant/code-block/index.gts, and the outer .code-block section has no max-height of its own, only overflow: hidden. The stamp is therefore header + contentHeight while the box renders header + min(contentHeight, 250). Monaco's line height here is 1.5 × 12px on macOS (1.35 × elsewhere) plus 16px of padding, so past ~13 lines of tool-call JSON — routine for a patchCardInstance patch or a search filter — expanding leaves a contentHeight − 250 gap. The // max-height is constrained by CSS note on the stamp is what makes it read as safe; that cap is on the child, not on element.
It only bites now because expand previously never re-ran the modifier. And the editor really is measurable on that re-run: Glimmer runs scheduled modifier installs before scheduled updates within one commit, so the freshly created Monaco editor already reports a content height when this update lands.
The stamp is also redundant — the Monaco modifier sizes the editor div and CSS clamps it, so header + renderedEditorHeight is the section's natural height. Dropping it removes both the over-stamp and the need to clear anything:
private scrollBottomIntoView = modifier((element: HTMLElement) => {
// Consume the toggle flag so this re-runs when the code area opens.
if (!this.isDisplayingCode) {
return;
}
this.scrollIntoView(element.parentElement as HTMLElement);
});To keep the stamp instead, measure the rendered box: editor?.getContainerDomNode().offsetHeight in place of getContentHeight().
Either shape carries one decision: expand now reaches scrollIntoView, which it never did on a normal mount, so clicking "View Info" on a message up in the scrollback will scroll the panel. Likely the modifier's original intent, but it is new user-visible behavior — worth confirming you want it.
Regression introduced here, on top of a calculation that was previously only reachable through the remount path. Blocking.
| let codeBlock = find( | ||
| '[data-test-tool-call-id="hide-info-height"] .tool-code-block', | ||
| ) as HTMLElement; | ||
| assert.ok(codeBlock, 'tool code block element exists'); | ||
| assert.strictEqual( | ||
| codeBlock.style.height, | ||
| '', | ||
| 'inline height is cleared so the block collapses to its header-only height', | ||
| ); |
There was a problem hiding this comment.
[Claude Code 🤖]
This pins the collapsed state but not the expanded one, which is where the height math is now newly exercised. The payload here renders 13 lines, just under the 250px editor cap, so it cannot distinguish a correct stamp from an over-stamp.
Add a case whose tool-call payload exceeds --code-block-max-height and assert, while expanded, that the section's height is no greater than the header plus the editor's rendered height. Against the current diff that fails — see the scrollBottomIntoView thread.
Smaller, on these lines: find(...) as HTMLElement is dereferenced immediately after a soft assert.ok, so a null match both fails an assertion and throws; and .tool-code-block carries no CSS rule anywhere in the repo, making it an invisible test-only hook nothing protects. An assert.dom(...).exists() before the read covers the first, and a data-test- attribute alongside the class would make the hook explicit.
Non-blocking; the coverage half is what would have caught the expand-path issue.
Problem
In an AI assistant room, expanding a completed tool call's code (ⓘ → "View Info") and then clicking "Hide Info" intermittently left a large empty area below the tool-call header. The Monaco editor was removed from the DOM but the container kept its expanded height.
Root cause
The
scrollBottomIntoViewmodifier on the tool call's<CodeBlock>stamps an inline pixel height on the container sized to the editor's content:Nothing ever cleared it. The functional modifier consumed no tracked state that changes on toggle, so it only ran at install:
getContentHeight()→ 0, early return) — no height is stamped and collapse works.The inner editor div already self-sizes (the
monaco-editormodifier sets and updates its height and CSS caps it), so the outer-container stamp is only for snug fit + scroll-into-view.Fix
Make the modifier consume
isDisplayingCodeso it re-runs on toggle, and reset the inline height on the collapse / no-measurable-editor paths so the container returns to its header-only height.Test
Adds an integration test that reproduces the remount-while-open condition (close + reopen the AI assistant panel with the code area expanded) and asserts that after "Hide Info" the editor is gone and the container has no leftover inline height.
Verification
findtest helper import).