77 select ,
88 confirm ,
99 isCancel ,
10+ text ,
1011} from '@clack/prompts' ;
1112import {
1213 assertGitRepo ,
@@ -344,10 +345,36 @@ export default async (
344345 commitSpinner . start ( `Creating commit ${ i + 1 } /${ groups . length } : ${ group . message } ` ) ;
345346
346347 try {
348+ // Optionally edit this group's commit message before committing
349+ let finalMessage = group . message ! ;
350+ const wantsEdit = await confirm ( { message : `Edit commit ${ i + 1 } message before committing?` } ) ;
351+ if ( wantsEdit && ! isCancel ( wantsEdit ) ) {
352+ const edited = await text ( {
353+ message : 'Edit commit message:' ,
354+ initialValue : finalMessage ,
355+ validate : ( value ) => ( value && value . trim ( ) . length > 0 ? undefined : 'Message cannot be empty' ) ,
356+ } ) ;
357+ if ( isCancel ( edited ) ) {
358+ outro ( 'Commits cancelled' ) ;
359+ return ;
360+ }
361+ finalMessage = String ( edited ) . trim ( ) ;
362+ group . message = finalMessage ;
363+ }
364+
365+ // Confirm proceed with the (possibly edited) message for this commit
366+ const proceedGroup = await confirm ( {
367+ message : `Proceed with commit ${ i + 1 } /${ groups . length } message?\n\n ${ finalMessage } \n` ,
368+ } ) ;
369+ if ( ! proceedGroup || isCancel ( proceedGroup ) ) {
370+ outro ( 'Commits cancelled' ) ;
371+ return ;
372+ }
373+
347374 // Reset and stage only files for this group
348375 await execa ( 'git' , [ 'reset' , 'HEAD' , '--' ] ) ;
349376 await execa ( 'git' , [ 'add' , ...group . files ] ) ;
350- await execa ( 'git' , [ 'commit' , '-m' , group . message ! , ...rawArgv ] ) ;
377+ await execa ( 'git' , [ 'commit' , '-m' , finalMessage , ...rawArgv ] ) ;
351378 } finally {
352379 commitSpinner . stop ( `Commit ${ i + 1 } created` ) ;
353380 }
@@ -401,16 +428,36 @@ export default async (
401428 }
402429
403430 let message : string ;
431+ let editedAlready = false ;
404432 if ( messages . length === 1 ) {
405433 [ message ] = messages ;
406- const confirmed = await confirm ( {
407- message : `Use this commit message?\n\n ${ message } \n` ,
434+ const choice = await select ( {
435+ message : `Review generated commit message:\n\n ${ message } \n` ,
436+ options : [
437+ { label : 'Use as-is' , value : 'use' } ,
438+ { label : 'Edit' , value : 'edit' } ,
439+ { label : 'Cancel' , value : 'cancel' } ,
440+ ] ,
408441 } ) ;
409442
410- if ( ! confirmed || isCancel ( confirmed ) ) {
443+ if ( isCancel ( choice ) || choice === 'cancel' ) {
411444 outro ( 'Commit cancelled' ) ;
412445 return ;
413446 }
447+
448+ if ( choice === 'edit' ) {
449+ const edited = await text ( {
450+ message : 'Edit commit message:' ,
451+ initialValue : message ,
452+ validate : ( value ) => ( value && value . trim ( ) . length > 0 ? undefined : 'Message cannot be empty' ) ,
453+ } ) ;
454+ if ( isCancel ( edited ) ) {
455+ outro ( 'Commit cancelled' ) ;
456+ return ;
457+ }
458+ message = String ( edited ) . trim ( ) ;
459+ editedAlready = true ;
460+ }
414461 } else {
415462 const selected = await select ( {
416463 message : `Pick a commit message to use: ${ dim ( '(Ctrl+c to exit)' ) } ` ,
@@ -425,6 +472,32 @@ export default async (
425472 message = selected as string ;
426473 }
427474
475+ // Offer editing of the final commit message (skip if already edited)
476+ if ( ! editedAlready ) {
477+ const wantsEdit = await confirm ( { message : 'Edit the commit message before committing?' } ) ;
478+ if ( wantsEdit && ! isCancel ( wantsEdit ) ) {
479+ const edited = await text ( {
480+ message : 'Edit commit message:' ,
481+ initialValue : message ,
482+ validate : ( value ) => ( value && value . trim ( ) . length > 0 ? undefined : 'Message cannot be empty' ) ,
483+ } ) ;
484+ if ( isCancel ( edited ) ) {
485+ outro ( 'Commit cancelled' ) ;
486+ return ;
487+ }
488+ message = String ( edited ) . trim ( ) ;
489+ }
490+ }
491+
492+ // Final proceed confirmation displaying the message
493+ const proceed = await confirm ( {
494+ message : `Proceed with this commit message?\n\n ${ message } \n` ,
495+ } ) ;
496+ if ( ! proceed || isCancel ( proceed ) ) {
497+ outro ( 'Commit cancelled' ) ;
498+ return ;
499+ }
500+
428501 await execa ( 'git' , [ 'commit' , '-m' , message , ...rawArgv ] ) ;
429502
430503 outro ( `${ green ( '✔' ) } Successfully committed!` ) ;
0 commit comments