Repository navigation
Conversation
cli.tsx lifts bracketed-paste payloads off stdin before Ink sees them and republishes them on pasteEvents, but only UserInput subscribed. Every other TextInput (MCP and provider wizards, settings panels, ask_user, the architect revise box) got neither the event nor the raw keystrokes, so a paste into any of them was silently dropped. TextInput now subscribes while focused, the same condition that gates its keystrokes, and inserts the payload at the caret with CR line breaks turned into newlines. UserInput passes its existing handler as onPaste, so the composer keeps its placeholder collapsing and there is still a single subscriber per focused field. Closes Nano-Collective#1456
nc-review: comments — 2 important, 2 nits@addyCooks — a few things worth a look, none blocking. Moves the bracketed-paste subscription from UserInput into the shared TextInput so every text field in the app receives pastes. The design correctly preserves the composer's placeholder-collapsing behaviour via a new optional 🟠 important · The pre-change 🟠 important ·
⚪ nit · The new suite asserts the happy path (insert at caret, CR→\n, onPaste override, focus gate) and the wizard integration, but there is no test that exercises the cleanup path: e.g. rendering a focused ⚪ nit · The change is fully justified — the issue describes a concrete, reproducible bug (paste silently dropped in every non-composer field) with a clear suggested fix at exactly the location this PR modifies, and the diff implements that fix with regression tests in 🔴 blocking · 🟠 a reviewer would ask for a change · ⚪ optional Automated code review — correctness, security, design, tests, plus duplicates and scope. A human still decides; this is not a substitute for review and is not exhaustive. The required status checks separately cover lint, formatting, types, unused dependencies, the test suite and the build. This bot never merges. Maintainers can rerun with |
- Fold `disabled` into the composer's TextInput focus, so the paste gate is explicit at the receiving component instead of relying on the disabled branch never mounting it. - Explain why handlePasteRef is reassigned on every render rather than in an effect. - Test that the paste listener is removed on blur and on unmount.
…fields-1456 # Conflicts: # source/components/text-input-keys.spec.tsx # source/components/user-input.tsx
|
Hey @akramcodez, |
Closes #1456 (part of #907)
Description
cli.tsxenables bracketed paste and lifts each payload off stdin before Ink's keypress parser sees it, then republishes it on thepasteEventsbus. OnlyUserInputsubscribed to that bus, so every other text field (the MCP and provider wizards, the settings panels, theask_userprompt, the architect review's revise box) got neither the paste event nor the raw keystrokes, and a paste into any of them was silently dropped.The subscription now lives in the shared
TextInput, as the issue suggests:focusis true, the same condition that gates itsuseInput. A paste goes to exactly the field that typing would reach, and never to more than one.\n, and leaves the caret after the pasted text.onPasteprop replaces that default.UserInputpasses its existing handler through it, so the composer keeps its placeholder collapsing for long pastes and caret-aware splicing, and it no longer subscribes itself.source/components/text-input.tsxpasteEventswhile focused; insert at the caret or hand off toonPastesource/components/user-input.tsxonPastesource/utils/terminal-paste.tsTextInputas the subscribersource/components/text-input-keys.spec.tsxonPasteoverridesource/wizards/steps/field-input-view.spec.tsxRecording
Type of Change
Changeset
.changeset/paste-all-text-fields.md, patch)Testing
main(paste at the caret, CR line breaks, theonPasteoverride, and the wizard field). The fifth, "unfocused field ignores a paste", guards the new subscription and passes onmainbecause nothing received pastes there.text-input-keys20/20 andfield-input-view15/15. All five existing composer paste tests inuser-input.spec.tsxpass through the new path (placeholder collapse, literal short paste, ignored while disabled, caret parked after the splice).tsc, Biome format and lint, and knip cleanNote
Pasted line breaks are kept in every field, as in the composer, so a trailing newline copied along with an API key ends up in the value. Trimming it in single-line fields would mean deciding per field, which felt out of scope here. Happy to follow up if you want it.
Checklist