@@ -720,7 +720,8 @@ function rebindSidebarEvents(projects) {
720720 wtDeleteBtn . onclick = async ( e ) => {
721721 e . stopPropagation ( ) ;
722722 const name = wtProject . projectPath . split ( '/' ) . pop ( ) ;
723- if ( ! confirm ( `Delete worktree "${ name } " from disk?\n\nThis runs "git worktree remove -f" and permanently removes the working tree. This cannot be undone.` ) ) return ;
723+ const confirmed = await showDeleteWorktreeDialog ( name , wtProject . projectPath ) ;
724+ if ( ! confirmed ) return ;
724725 const result = await window . api . deleteWorktree ( wtProject . projectPath ) ;
725726 if ( result && result . ok ) {
726727 loadProjects ( ) ;
@@ -1025,3 +1026,75 @@ function startRename(summaryEl, session) {
10251026 }
10261027 } ) ;
10271028}
1029+
1030+ // --- Delete worktree confirmation dialog ---
1031+ // Returns a Promise<boolean> — true if the user confirmed deletion.
1032+ async function showDeleteWorktreeDialog ( name , worktreePath ) {
1033+ // Fetch worktree status (dirty files) while the dialog is shown
1034+ const statusPromise = window . api . worktreeStatus ( worktreePath ) ;
1035+
1036+ return new Promise ( ( resolve ) => {
1037+ const overlay = document . createElement ( 'div' ) ;
1038+ overlay . className = 'new-session-overlay' ;
1039+
1040+ const dialog = document . createElement ( 'div' ) ;
1041+ dialog . className = 'new-session-dialog delete-worktree-dialog' ;
1042+
1043+ dialog . innerHTML = `
1044+ <h3>Delete worktree "${ escapeHtml ( name ) } "?</h3>
1045+ <div class="delete-worktree-warning">
1046+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="flex-shrink:0;margin-top:1px"><path d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
1047+ <span>Any uncommitted changes in this worktree will be permanently lost.</span>
1048+ </div>
1049+ <div class="delete-worktree-status" id="dwt-status">
1050+ <span class="dwt-loading">Checking worktree status…</span>
1051+ </div>
1052+ <div class="new-session-actions">
1053+ <button class="new-session-cancel-btn" id="dwt-cancel">Cancel</button>
1054+ <button class="delete-worktree-confirm-btn" id="dwt-confirm">Delete anyway</button>
1055+ </div>
1056+ ` ;
1057+
1058+ overlay . appendChild ( dialog ) ;
1059+ document . body . appendChild ( overlay ) ;
1060+
1061+ const statusEl = dialog . querySelector ( '#dwt-status' ) ;
1062+
1063+ // Populate status once the IPC resolves
1064+ statusPromise . then ( ( status ) => {
1065+ if ( ! overlay . isConnected ) return ; // dialog already closed
1066+ if ( ! status || ! status . ok ) {
1067+ const errMsg = ( status && status . error ) ? escapeHtml ( status . error ) : 'Unknown error' ;
1068+ statusEl . innerHTML = `<span class="dwt-error">Unable to read worktree status: ${ errMsg } </span>` ;
1069+ return ;
1070+ }
1071+ if ( status . total === 0 ) {
1072+ statusEl . innerHTML = `<span class="dwt-clean">Worktree is clean — no uncommitted changes.</span>` ;
1073+ return ;
1074+ }
1075+ const shown = status . dirty . slice ( 0 , 10 ) ;
1076+ const overflow = status . total - shown . length ;
1077+ const lines = shown . map ( l => escapeHtml ( l ) ) . join ( '\n' ) ;
1078+ const extra = overflow > 0 ? `\n+ ${ overflow } more…` : '' ;
1079+ statusEl . innerHTML = `<div class="dwt-dirty-label">${ status . total } uncommitted file${ status . total !== 1 ? 's' : '' } :</div><pre class="dwt-dirty-list">${ lines } ${ extra } </pre>` ;
1080+ } ) . catch ( ( err ) => {
1081+ if ( ! overlay . isConnected ) return ;
1082+ statusEl . innerHTML = `<span class="dwt-error">Unable to read worktree status: ${ escapeHtml ( String ( err ) ) } </span>` ;
1083+ } ) ;
1084+
1085+ function close ( confirmed ) {
1086+ overlay . remove ( ) ;
1087+ document . removeEventListener ( 'keydown' , onKey ) ;
1088+ resolve ( confirmed ) ;
1089+ }
1090+
1091+ dialog . querySelector ( '#dwt-cancel' ) . onclick = ( ) => close ( false ) ;
1092+ dialog . querySelector ( '#dwt-confirm' ) . onclick = ( ) => close ( true ) ;
1093+ overlay . addEventListener ( 'click' , ( e ) => { if ( e . target === overlay ) close ( false ) ; } ) ;
1094+
1095+ function onKey ( e ) {
1096+ if ( e . key === 'Escape' ) close ( false ) ;
1097+ }
1098+ document . addEventListener ( 'keydown' , onKey ) ;
1099+ } ) ;
1100+ }
0 commit comments