@@ -359,7 +359,7 @@ describe("keypress atoms", () => {
359359 expect ( text ) . toBe ( "/mode" )
360360 } )
361361
362- it ( "should complete argument by appending only missing part " , ( ) => {
362+ it ( "should complete argument by replacing partial text " , ( ) => {
363363 // Type '/mode tes' - this will automatically trigger autocomplete
364364 const input = "/mode tes"
365365 for ( const char of input ) {
@@ -398,11 +398,96 @@ describe("keypress atoms", () => {
398398 }
399399 store . set ( keyboardHandlerAtom , tabKey )
400400
401- // Should append only 't ' to complete '/mode test'
401+ // Should replace 'tes' with 'test ' to complete '/mode test'
402402 const text = store . get ( textBufferStringAtom )
403403 expect ( text ) . toBe ( "/mode test" )
404404 } )
405405
406+ it ( "should replace partial argument with full suggestion" , ( ) => {
407+ // Bug fix: Type '/model info gpt' with suggestion 'openai/gpt-5'
408+ // This test verifies the fix where Tab was incorrectly appending instead of replacing
409+ const input = "/model info gpt"
410+ for ( const char of input ) {
411+ const key : Key = {
412+ name : char ,
413+ sequence : char ,
414+ ctrl : false ,
415+ meta : false ,
416+ shift : false ,
417+ paste : false ,
418+ }
419+ store . set ( keyboardHandlerAtom , key )
420+ }
421+
422+ // Set up argument suggestions
423+ const mockArgumentSuggestion : ArgumentSuggestion = {
424+ value : "openai/gpt-5" ,
425+ description : "OpenAI GPT-5 model" ,
426+ matchScore : 90 ,
427+ highlightedValue : "openai/gpt-5" ,
428+ }
429+ store . set ( argumentSuggestionsAtom , [ mockArgumentSuggestion ] )
430+ store . set ( suggestionsAtom , [ ] ) // No command suggestions
431+ store . set ( selectedIndexAtom , 0 )
432+
433+ // Press Tab
434+ const tabKey : Key = {
435+ name : "tab" ,
436+ sequence : "\t" ,
437+ ctrl : false ,
438+ meta : false ,
439+ shift : false ,
440+ paste : false ,
441+ }
442+ store . set ( keyboardHandlerAtom , tabKey )
443+
444+ // Should replace 'gpt' with 'openai/gpt-5' (not append to get 'gptopenai/gpt-5')
445+ const text = store . get ( textBufferStringAtom )
446+ expect ( text ) . toBe ( "/model info openai/gpt-5" )
447+ } )
448+
449+ it ( "should complete argument from empty with trailing space" , ( ) => {
450+ // Type '/model info ' (with trailing space)
451+ const input = "/model info "
452+ for ( const char of input ) {
453+ const key : Key = {
454+ name : char ,
455+ sequence : char ,
456+ ctrl : false ,
457+ meta : false ,
458+ shift : false ,
459+ paste : false ,
460+ }
461+ store . set ( keyboardHandlerAtom , key )
462+ }
463+
464+ // Set up argument suggestions
465+ const mockArgumentSuggestion : ArgumentSuggestion = {
466+ value : "openai/gpt-4" ,
467+ description : "OpenAI GPT-4 model" ,
468+ matchScore : 100 ,
469+ highlightedValue : "openai/gpt-4" ,
470+ }
471+ store . set ( argumentSuggestionsAtom , [ mockArgumentSuggestion ] )
472+ store . set ( suggestionsAtom , [ ] )
473+ store . set ( selectedIndexAtom , 0 )
474+
475+ // Press Tab
476+ const tabKey : Key = {
477+ name : "tab" ,
478+ sequence : "\t" ,
479+ ctrl : false ,
480+ meta : false ,
481+ shift : false ,
482+ paste : false ,
483+ }
484+ store . set ( keyboardHandlerAtom , tabKey )
485+
486+ // Should add the full suggestion value
487+ const text = store . get ( textBufferStringAtom )
488+ expect ( text ) . toBe ( "/model info openai/gpt-4" )
489+ } )
490+
406491 it ( "should handle exact match completion" , ( ) => {
407492 // Type '/help' - this will automatically trigger autocomplete
408493 const input = "/help"
0 commit comments