Description
cli.tsx enables bracketed paste (DECSET 2004) for the whole interactive session and strips each pasted payload out of the raw stdin stream before Ink ever sees it, re-emitting it on a singleton pasteEvents bus instead. Exactly one component in the entire codebase subscribes to that bus: the main composer (UserInput). Every other text field the MCP setup wizard, settings panels, the ask_user prompt, the architect review's revise-instructions box receives neither the paste event (nothing subscribes) nor the raw keystrokes (they were already stripped out at the source), so a paste into any of them is silently discarded.
Parent: #907
Steps to Reproduce
- Run
/settings mcp → "Configure MCP Servers" → "+ Add an MCP server…" → accept the default config location → "Add MCP servers" → scroll down and select "Custom MCP Server".
- Accept the default transport (Field 1/6) to reach "Server name" (Field 2/6).
- Paste any text into the field.
Expected Behavior
The pasted text appears in the field, the same way it would in the main composer.
Actual Behavior
Nothing appears. The field stays completely empty no text, no error, no indication the paste was even received.
Recording
Root Cause
source/utils/terminal-paste.ts:45: /** Singleton bus: cli.tsx publishes payloads, UserInput subscribes. */ and indeed, a repo-wide search for pasteEvents turns up exactly one subscriber, source/components/user-input.tsx:304-306 (pasteEvents.on('paste', handleTerminalPaste) / the matching .off on cleanup). Every other TextInput-based field in the codebase wizards/steps/mcp-step.tsx, wizards/steps/field-input-view.tsx, components/question-prompt.tsx, components/architect-review-prompt.tsx, the app/components/settings-*.tsx panels, components/json-viewer/json-viewer.tsx has no path to receive a paste at all, because cli.tsx already removed the payload from the stream before any of them could see it as ordinary keystrokes.
Suggested Fix
Move the paste subscription into the shared TextInput component (or a small hook it uses) so every text field receives payloads by default, instead of wiring it into one specific composer component.
Additional Context
Description
cli.tsxenables bracketed paste (DECSET 2004) for the whole interactive session and strips each pasted payload out of the raw stdin stream before Ink ever sees it, re-emitting it on a singletonpasteEventsbus instead. Exactly one component in the entire codebase subscribes to that bus: the main composer (UserInput). Every other text field the MCP setup wizard, settings panels, theask_userprompt, the architect review's revise-instructions box receives neither the paste event (nothing subscribes) nor the raw keystrokes (they were already stripped out at the source), so a paste into any of them is silently discarded.Parent: #907
Steps to Reproduce
/settings mcp→ "Configure MCP Servers" → "+ Add an MCP server…" → accept the default config location → "Add MCP servers" → scroll down and select "Custom MCP Server".Expected Behavior
The pasted text appears in the field, the same way it would in the main composer.
Actual Behavior
Nothing appears. The field stays completely empty no text, no error, no indication the paste was even received.
Recording
Root Cause
source/utils/terminal-paste.ts:45:/** Singleton bus: cli.tsx publishes payloads, UserInput subscribes. */and indeed, a repo-wide search forpasteEventsturns up exactly one subscriber,source/components/user-input.tsx:304-306(pasteEvents.on('paste', handleTerminalPaste)/ the matching.offon cleanup). Every otherTextInput-based field in the codebasewizards/steps/mcp-step.tsx,wizards/steps/field-input-view.tsx,components/question-prompt.tsx,components/architect-review-prompt.tsx, theapp/components/settings-*.tsxpanels,components/json-viewer/json-viewer.tsxhas no path to receive a paste at all, becausecli.tsxalready removed the payload from the stream before any of them could see it as ordinary keystrokes.Suggested Fix
Move the paste subscription into the shared
TextInputcomponent (or a small hook it uses) so every text field receives payloads by default, instead of wiring it into one specific composer component.Additional Context
main