Skip to content

fix(ui): revert app-driven iframe width and send containerDimensions per ext-apps spec#7300

Merged
aharvard merged 3 commits intomainfrom
aharvard/revert-iframe-width-add-container-dimensions
Feb 18, 2026
Merged

fix(ui): revert app-driven iframe width and send containerDimensions per ext-apps spec#7300
aharvard merged 3 commits intomainfrom
aharvard/revert-iframe-width-add-container-dimensions

Conversation

@aharvard
Copy link
Collaborator

@aharvard aharvard commented Feb 18, 2026

Summary

Fixes #6818 — Reverts #6376 and implements containerDimensions in the host context per the ext-apps spec.

Commit 1: Revert app-driven iframe width from #6376

PR #6376 let apps drive the container width via size-changed notifications. Per the spec and owtaylor's analysis, the host owns width in inline mode — apps should not resize it. This commit removes:

  • iframeWidth state and setIframeWidth
  • Width handling from handleSizeChanged (height-only now)
  • Conditional width styling — container is always width: 100%

Commit 2: Send containerDimensions in hostContext

Adds a getContainerDimensions() function that maps display modes to the spec's dimension modes. Each axis is independently fixed, flexible, or unbounded:

Mode Spec Field Meaning
Fixed width / height Host controls size, view fills it
Flexible maxWidth / maxHeight View controls size, up to the max
Unbounded Field omitted View controls size, no limit

Display mode → layout mapping:

Display Mode Width Height
inline fixed unbounded
fullscreen fixed fixed
standalone fixed fixed
pip fixed fixed

Container dimensions are measured from the actual container element via ResizeObserver and update reactively on resize.

Types (DimensionMode, DimensionLayout) are exported from McpApps/types.ts.

Test plan

  • npx tsc --noEmit passes
  • npx eslint clean
  • npx vitest run — 340/340 tests pass
  • Open an MCP app inline — should fill chat width, grow vertically
  • Resize the Goose window — app width should follow
  • Open an MCP app in standalone window — should fill the window
  • Resize standalone window — app should fill new size

The host owns container width in inline mode — apps should not resize
the iframe width via onSizeChanged. This reverts the width-related
changes from PR #6376:

- Remove iframeWidth state and setIframeWidth
- Remove width handling from handleSizeChanged (height-only now)
- Always apply width: 100% and [&_iframe]:!w-full unconditionally
- Remove maxWidth: 100% guard (no longer needed)

Refs: #6818, #7256
Copilot AI review requested due to automatic review settings February 18, 2026 13:13
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Reverts app-driven iframe width sizing for MCP apps and adds containerDimensions to hostContext to align with the ext-apps container sizing spec.

Changes:

  • Remove width handling from size-changed and force inline iframe/container width to 100%.
  • Measure host container size with ResizeObserver and send containerDimensions based on display mode.
  • Export new dimension layout/types (DimensionMode, DimensionLayout) for mapping display modes to spec dimension semantics.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
ui/desktop/src/components/McpApps/types.ts Adds exported dimension mode/layout types used to map display modes to spec sizing semantics.
ui/desktop/src/components/McpApps/McpAppRenderer.tsx Removes app-driven width resizing, adds container measurement via ResizeObserver, and sends containerDimensions in hostContext.

Add a getContainerDimensions() function that maps Goose display modes
to the correct ext-apps spec containerDimensions shape:

  Inline mode:
    width (fixed)        — host controls, app fills it
    maxHeight (flexible) — app controls height via size-changed, up to max

  Fullscreen / Standalone mode:
    width (fixed)  — host controls, app fills it
    height (fixed) — host controls, app fills it

Per the spec, each axis is independently fixed, flexible, or unbounded:
  - Fixed (height/width): Host controls size, view fills available space
  - Flexible (maxHeight/maxWidth): View controls size, up to the max
  - Unbounded (omitted): View controls size with no limit

When a dimension is flexible, the host MUST listen for size-changed
notifications and resize the iframe — which we already do for height
in inline mode via onSizeChanged.

Container dimensions are measured from the actual container element
via ResizeObserver and update reactively on resize.

Refs: #6818
@aharvard aharvard force-pushed the aharvard/revert-iframe-width-add-container-dimensions branch from 21cf7dd to afc8480 Compare February 18, 2026 13:19
@aharvard aharvard requested a review from Copilot February 18, 2026 13:25
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure what this comment is for, maybe dorp?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The spec's rules for when to use width/height vs maxWidth/maxHeight vs omitting fields are a bit hard to follow, so I abstracted it into a layout map using more intuitive terms: fixed, flexible, unbounded. We don't have a flexible case yet, but I wanted to capture it now so we don't have to re-derive it later.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could collapse these into one if

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 done

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

eh, isn't that just width/height

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep, simplified to just contentRect.width/height — we don't need logical properties for vertical writing modes.

width: DimensionMode;
height: DimensionMode;
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't we get these from the server spec?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The spec exports the containerDimensions shape on McpUiHostContext but not a DimensionMode/DimensionLayout type — those are our internal mapping for deciding which fields to populate per display mode. If the spec ever exports them we'll switch.

@aharvard aharvard added this pull request to the merge queue Feb 18, 2026
Merged via the queue into main with commit 79af1cf Feb 18, 2026
20 checks passed
@aharvard aharvard deleted the aharvard/revert-iframe-width-add-container-dimensions branch February 18, 2026 14:50
aharvard added a commit that referenced this pull request Feb 18, 2026
* origin/main:
  feat: add GOOSE_SUBAGENT_MODEL and GOOSE_SUBAGENT_PROVIDER config options (#7277)
  fix(openai): support "reasoning" field alias in streaming deltas (#7294)
  fix(ui): revert app-driven iframe width and send containerDimensions per ext-apps spec (#7300)
  New OpenAI event (#7301)
  ci: add fork guards to scheduled workflows (#7292)
  fix: allow ollama input limit override (#7281)
  chore: show important keys for provider configuration (#7265)
  fix: subrecipe relative path with summon (#7295)
  fix extension selector not displaying the correct enabled extensions (#7290)
  Use the working dir from the session (#7285)
  Fix: Minor logging uplift for debugging of prompt injection mitigation (#7195)
  feat(otel): make otel logging level configurable (#7271)
  docs: add documentation for Top Of Mind extension (#7283)
  Document gemini 3 thinking levels (#7282)
  docs: stream subagent tool calls (#7280)
  Docs: delete custom provider in desktop (#7279)

# Conflicts:
#	ui/desktop/src/components/McpApps/McpAppRenderer.tsx
jh-block added a commit that referenced this pull request Feb 18, 2026
* origin/main:
  docs: remove ALPHA_FEATURES flag from documentation (#7315)
  docs: escape variable syntax in recipes (#7314)
  docs: update OTel environment variable and config guides (#7221)
  docs: system proxy settings (#7311)
  docs: add Summon extension tutorial and update Skills references (#7310)
  docs: agent session id (#7289)
  fix(gemini-cli): restore streaming lost in #7247 (#7291)
  Update more instructions (#7305)
  feat: add Moonshot and Kimi Code declarative providers (#7304)
  fix(cli): handle Reasoning content and fix streaming thinking display (#7296)
  feat: add GOOSE_SUBAGENT_MODEL and GOOSE_SUBAGENT_PROVIDER config options (#7277)
  fix(openai): support "reasoning" field alias in streaming deltas (#7294)
  fix(ui): revert app-driven iframe width and send containerDimensions per ext-apps spec (#7300)
  New OpenAI event (#7301)
  ci: add fork guards to scheduled workflows (#7292)
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.

Resize goose desktop shrink the mcp app and it never grows back.

2 participants

Comments