@@ -383,6 +383,18 @@ export class StackgazerApp {
383383 }
384384 } ) ;
385385
386+ // Global paste support for clipboard
387+ window . addEventListener ( 'paste' , e => {
388+ // Don't handle paste if user is typing in an input/textarea
389+ const target = e . target as HTMLElement ;
390+ if ( target . matches ( 'input, textarea, [contenteditable="true"]' ) ) {
391+ return ;
392+ }
393+
394+ e . preventDefault ( ) ;
395+ this . handleClipboardPaste ( e ) ;
396+ } ) ;
397+
386398 // Back button
387399 const backBtn = document . getElementById ( 'backBtn' ) ;
388400 if ( backBtn ) {
@@ -779,10 +791,31 @@ export class StackgazerApp {
779791 }
780792 }
781793
794+ private async handleClipboardPaste ( e : ClipboardEvent ) : Promise < void > {
795+ const clipboardData = e . clipboardData ;
796+ if ( ! clipboardData ) return ;
797+
798+ // Check for files first (e.g., screenshots or files copied from file explorer)
799+ const files = clipboardData . files ;
800+ if ( files && files . length > 0 ) {
801+ await this . handleFiles ( Array . from ( files ) ) ;
802+ return ;
803+ }
804+
805+ // Check for text content (stack dump as string)
806+ const text = clipboardData . getData ( 'text/plain' ) ;
807+ if ( text && text . trim ( ) ) {
808+ // Create a File object from the text content
809+ const blob = new Blob ( [ text ] , { type : 'text/plain' } ) ;
810+ const file = new File ( [ blob ] , 'clipboard-paste.txt' , { type : 'text/plain' } ) ;
811+ await this . handleFiles ( [ file ] ) ;
812+ }
813+ }
814+
782815 private async handleFiles ( files : File [ ] ) : Promise < void > {
783816 const fileCount = files . length ;
784817 const fileNames = files . map ( f => f . name ) . join ( ', ' ) ;
785-
818+
786819 // Show loading overlay
787820 this . showLoadingOverlay (
788821 fileCount === 1 ? 'Processing file...' : `Processing ${ fileCount } files...` ,
0 commit comments