@@ -18,7 +18,7 @@ import { usePromptStash } from "./stash"
1818import { DialogStash } from "../dialog-stash"
1919import { type AutocompleteRef , Autocomplete } from "./autocomplete"
2020import { useCommandDialog } from "../dialog-command"
21- import { useRenderer } from "@opentui/solid"
21+ import { useKeyboard , useRenderer } from "@opentui/solid"
2222import { Editor } from "@tui/util/editor"
2323import { useExit } from "../../context/exit"
2424import { Clipboard } from "../../util/clipboard"
@@ -368,6 +368,20 @@ export function Prompt(props: PromptProps) {
368368 ]
369369 } )
370370
371+ // Windows Terminal 1.25+ handles Ctrl+V on keydown when kitty events are
372+ // enabled, but still reports the kitty key-release event. Probe on release.
373+ if ( process . platform === "win32" ) {
374+ useKeyboard (
375+ ( evt ) => {
376+ if ( ! input . focused ) return
377+ if ( evt . name === "v" && evt . ctrl && evt . eventType === "release" ) {
378+ command . trigger ( "prompt.paste" )
379+ }
380+ } ,
381+ { release : true } ,
382+ )
383+ }
384+
371385 const ref : PromptRef = {
372386 get focused ( ) {
373387 return input . focused
@@ -862,10 +876,9 @@ export function Prompt(props: PromptProps) {
862876 e . preventDefault ( )
863877 return
864878 }
865- // Handle clipboard paste (Ctrl+V) - check for images first on Windows
866- // This is needed because Windows terminal doesn't properly send image data
867- // through bracketed paste, so we need to intercept the keypress and
868- // directly read from clipboard before the terminal handles it
879+ // Check clipboard for images before terminal-handled paste runs.
880+ // This helps terminals that forward Ctrl+V to the app; Windows
881+ // Terminal 1.25+ usually handles Ctrl+V before this path.
869882 if ( keybind . match ( "input_paste" , e ) ) {
870883 const content = await Clipboard . read ( )
871884 if ( content ?. mime . startsWith ( "image/" ) ) {
@@ -948,6 +961,9 @@ export function Prompt(props: PromptProps) {
948961 // Replace CRLF first, then any remaining CR
949962 const normalizedText = decodePasteBytes ( event . bytes ) . replace ( / \r \n / g, "\n" ) . replace ( / \r / g, "\n" )
950963 const pastedContent = normalizedText . trim ( )
964+
965+ // Windows Terminal <1.25 can surface image-only clipboard as an
966+ // empty bracketed paste. Windows Terminal 1.25+ does not.
951967 if ( ! pastedContent ) {
952968 command . trigger ( "prompt.paste" )
953969 return
0 commit comments