Skip to content

Clear stamped code-block height when Hide Info collapses a tool call - #5924

Open
FadhlanR wants to merge 1 commit into
mainfrom
cs-12097-plan
Open

Clear stamped code-block height when Hide Info collapses a tool call#5924
FadhlanR wants to merge 1 commit into
mainfrom
cs-12097-plan

Conversation

@FadhlanR

Copy link
Copy Markdown
Contributor

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 scrollBottomIntoView modifier on the tool call's <CodeBlock> stamps an inline pixel height on the container sized to the editor's content:

element.style.height = `${editorHeight + heightOfOtherChildren}px`;

Nothing ever cleared it. The functional modifier consumed no tracked state that changes on toggle, so it only ran at install:

  • Normal mounts start collapsed, so at install there is no editor (getContentHeight() → 0, early return) — no height is stamped and collapse works.
  • The expanded/collapsed flag lives in the room resource (keyed by tool-request id) and survives component remounts. When a message re-mounts while its code area is open — reopening the AI assistant panel, re-entering the room, a submode switch, any list re-render — the modifier installs with the editor present and stamps the height. From then on "Hide Info" removes the editor but leaves the stamped height, so the empty block remains. This is why it was intermittent.

The inner editor div already self-sizes (the monaco-editor modifier 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 isDisplayingCode so 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

  • Change is minimal and type-trivial (boolean guard + height reset + standard find test helper import).
  • This fresh worktree does not have host deps installed, so the browser test harness was not run locally — relying on CI to exercise the new test. Marking as draft accordingly.

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>
@github-actions

github-actions Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Preview deployments

Host Test Results

    1 files      1 suites   2h 1m 22s ⏱️
4 592 tests 4 578 ✅ 14 💤 0 ❌
4 611 runs  4 597 ✅ 14 💤 0 ❌

Results for commit 176c4ea.

Realm Server Test Results

    1 files      1 suites   18m 53s ⏱️
2 351 tests 2 351 ✅ 0 💤 0 ❌
2 434 runs  2 434 ✅ 0 💤 0 ❌

Results for commit 176c4ea.

@FadhlanR
FadhlanR marked this pull request as ready for review August 28, 2026 12:22
@FadhlanR
FadhlanR requested review from a team and lukemelia August 28, 2026 12:22

@backspace backspace left a comment

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.

[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.

  1. Drop the outer height stamp, or measure the editor's rendered box instead of its content height — see the scrollBottomIntoView thread. Blocking.
  2. 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.
  3. 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;

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.

[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.

Comment on lines +1304 to +1312
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',
);

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.

[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.

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