Mod ui.render (AbovePrompt/Pane) not drawn in desktop/iOS views of a Remote Control session
Summary
A mod's ui.render output (e.g. an AbovePrompt band with a Button) is drawn in the terminal but never appears in the Claude desktop app or the Claude iOS app when they view the same session through Remote Control. Only mod-initiated AskUserQuestion prompts reach those views.
Repro
- Run a session in tmux on machine A (terminal surface) with a mod loaded via
CLAUDE_CODE_PLUGIN_DIRS. The mod renders anAbovePromptband:Textplus aButton. - Open the same session from the desktop app and from the iOS app via Remote Control.
- The band is absent in both. An SSH terminal attached to the tmux session shows it.
Expected
The docs list AbovePrompt and Pane as rendered on "Terminal, Desktop" (mods reference, render sites) and say both "work in" the terminal and the Desktop app. The API also lists desktop and mobile surfaces. I expected Remote Control views to draw the band, or the docs to say they don't.
Docs gap
Neither the mods reference/interface pages nor the Remote Control page says whether ui.render reaches Remote Control viewers, or whether mods draw only on the host surface. It is also unclear if the desktop surface draws mods only when the desktop app hosts the session.
Related/feedback also does not work from the desktop app or iOS app in a Remote Control session. Many people drive terminal-hosted sessions from those apps, so terminal-only features are hard to use.
Claude Code 2.1.287, macOS. Feedback was also sent via /feedback (receipt 6c856a17-abfc-4e24-9560-1280829306a1).
Showing cached comments. Read the full discussion on GitHub ↗
3 Comments
Same on 2.1.289 (macOS), with two more data points.
A session started from the desktop app's Code tab draws mods fine there. Our open-asks band (an
AbovePromptwithText,ButtonandInput) renders in that Code tab, so the desktop surface works when the desktop hosts the session.The same mod in a terminal session started with
--remote-controldraws only in the terminal. Open that session in the Code tab and nothing shows above the prompt. Its hooks still run there: theStophook keeps writing to$.store. Only the drawing never reaches the viewer.I host most sessions in the terminal and read them in the desktop app all day, so for me mods are mostly invisible right now.
Separate thing, desktop-hosted session: a mod whose
AbovePromptmounts aClientmodule (a fork of mindful-claude) showsClient hooks/breathe.tsx: did not load within 10s (a content security policy may have refused its runtime...). Same mod, terminal host, draws fine. Want that in its own issue?— printed by Claude Code, signed by me.
Same behaviour here on Linux, one version later.
Setup
claude remote-controlAbovePromptband (Box+Text) and registers a slash commandWhat happens
classic.UserPromptSubmithook fires.AbovePromptband never appears in the desktop app or the mobile app.$.session.surfaces()called from inside that session returns an empty list while both apps are viewing it. So no client attaches as a render surface at all (session.attachnever fires), rather than attaching and failing to draw.Expected
The desktop app attaches as surface
desktopand draws the band, as the render sites table says forAbovePrompt.Updating the desktop app from a July build to 2.9939.4 made no difference.
Same here on newer builds — Claude Code CLI 2.1.291, Claude Desktop 2.19675.1 (bundled Claude Code 2.1.288), macOS. Our mod draws a button toolbar in the
AbovePromptband (logo + buttons that run a skill, send a prompt or fill the input), loaded viaCLAUDE_CODE_PLUGIN_DIRS.One data point that narrows it down: the same mod IS drawn in the Desktop app when the session is a local one created in the Desktop Code tab (bordered band, buttons as chips with hotkey badges). It is only missing when Desktop, claude.ai or mobile view a terminal-hosted session over Remote Control. So the Desktop renderer supports it; what is missing is forwarding
ui.renderto remote viewers and routingonPress/ui.pressback to the host session.The public mods types already seem to anticipate this:
RenderSurface = 'terminal' | 'desktop' | 'mobile' | 'vscode',session.attach/session.detachfor remote clients, and a viewport note about "a remote surface".