1- import { app , BrowserWindow , ipcMain , dialog } from "electron" ;
1+ import { exec } from "child_process" ;
2+ import { app , BrowserWindow , dialog , ipcMain } from "electron" ;
3+ import Store from "electron-store" ;
4+ import * as fs from "fs" ;
25import * as pty from "node-pty" ;
36import * as os from "os" ;
47import * as path from "path" ;
5- import * as fs from "fs" ;
6- import { simpleGit } from "simple-git" ;
7- import Store from "electron-store" ;
8- import { exec } from "child_process" ;
9- import { promisify } from "util" ;
10- import { v4 as uuidv4 } from "uuid" ;
8+ import { simpleGit } from "simple-git" ;
9+ import { promisify } from "util" ;
10+ import { v4 as uuidv4 } from "uuid" ;
11+ import { PersistedSession , SessionConfig } from "./types" ;
1112
1213const execAsync = promisify ( exec ) ;
1314
14- interface SessionConfig {
15- projectDir : string ;
16- parentBranch : string ;
17- branchName ?: string ;
18- codingAgent : string ;
19- skipPermissions : boolean ;
20- setupCommands ?: string [ ] ;
21- }
22-
23- interface PersistedSession {
24- id : string ;
25- number : number ;
26- name : string ;
27- config : SessionConfig ;
28- worktreePath : string ;
29- createdAt : number ;
30- sessionUuid : string ;
31- mcpConfigPath ?: string ;
32- }
33-
3415let mainWindow : BrowserWindow ;
3516const activePtyProcesses = new Map < string , pty . IPty > ( ) ;
3617const mcpPollerPtyProcesses = new Map < string , pty . IPty > ( ) ;
@@ -344,10 +325,10 @@ async function ensureFleetcodeExcluded(projectDir: string) {
344325 }
345326}
346327
347- async function createWorktree ( projectDir : string , parentBranch : string , sessionNumber : number , sessionUuid : string , customBranchName ?: string ) : Promise < string > {
328+ async function createWorktree ( projectDir : string , parentBranch : string , sessionNumber : number , sessionUuid : string , customBranchName ?: string ) : Promise < { worktreePath : string ; branchName : string } > {
348329 const git = simpleGit ( projectDir ) ;
349330 const fleetcodeDir = path . join ( projectDir , ".fleetcode" ) ;
350- const worktreeName = `session${ sessionNumber } ` ;
331+ const worktreeName = customBranchName || `session${ sessionNumber } ` ;
351332 const worktreePath = path . join ( fleetcodeDir , worktreeName ) ;
352333
353334 // Use custom branch name if provided, otherwise generate default
@@ -357,7 +338,7 @@ async function createWorktree(projectDir: string, parentBranch: string, sessionN
357338 } else {
358339 // Include short UUID to ensure branch uniqueness across deletes/recreates
359340 const shortUuid = sessionUuid . split ( '-' ) [ 0 ] ;
360- branchName = `fleetcode/session ${ sessionNumber } -${ shortUuid } ` ;
341+ branchName = `fleetcode/${ worktreeName } -${ shortUuid } ` ;
361342 }
362343
363344 // Create .fleetcode directory if it doesn't exist
@@ -385,7 +366,7 @@ async function createWorktree(projectDir: string, parentBranch: string, sessionN
385366 // This creates a new branch named "fleetcode/session<N>" starting from the parent branch
386367 await git . raw ( [ "worktree" , "add" , "-b" , branchName , worktreePath , parentBranch ] ) ;
387368
388- return worktreePath ;
369+ return { worktreePath, branchName } ;
389370}
390371
391372async function removeWorktree ( projectDir : string , worktreePath : string ) {
@@ -397,6 +378,15 @@ async function removeWorktree(projectDir: string, worktreePath: string) {
397378 }
398379}
399380
381+ async function removeGitBranch ( projectDir : string , branchName : string ) {
382+ const git = simpleGit ( projectDir ) ;
383+ try {
384+ await git . raw ( [ "branch" , "-D" , branchName ] ) ;
385+ } catch ( error ) {
386+ console . error ( "Error removing git branch:" , error ) ;
387+ }
388+ }
389+
400390// Open directory picker
401391ipcMain . handle ( "select-directory" , async ( ) => {
402392 const result = await dialog . showOpenDialog ( mainWindow , {
@@ -453,7 +443,7 @@ ipcMain.on("create-session", async (event, config: SessionConfig) => {
453443 ensureFleetcodeExcluded ( config . projectDir ) ;
454444
455445 // Create git worktree with custom or default branch name
456- const worktreePath = await createWorktree ( config . projectDir , config . parentBranch , sessionNumber , sessionUuid , config . branchName ) ;
446+ const { worktreePath, branchName } = await createWorktree ( config . projectDir , config . parentBranch , sessionNumber , sessionUuid , config . branchName ) ;
457447
458448 // Extract and write MCP config
459449 const mcpServers = extractProjectMcpConfig ( config . projectDir ) ;
@@ -469,6 +459,7 @@ ipcMain.on("create-session", async (event, config: SessionConfig) => {
469459 createdAt : Date . now ( ) ,
470460 sessionUuid,
471461 mcpConfigPath : mcpConfigPath || undefined ,
462+ gitBranch : branchName ,
472463 } ;
473464
474465 // Save to store
@@ -572,6 +563,11 @@ ipcMain.on("delete-session", async (_event, sessionId: string) => {
572563 // Remove git worktree
573564 await removeWorktree ( session . config . projectDir , session . worktreePath ) ;
574565
566+ // Remove git branch if it exists
567+ if ( session . gitBranch ) {
568+ await removeGitBranch ( session . config . projectDir , session . gitBranch ) ;
569+ }
570+
575571 // Remove from store
576572 sessions . splice ( sessionIndex , 1 ) ;
577573 savePersistedSessions ( sessions ) ;
@@ -778,6 +774,7 @@ const createWindow = () => {
778774app . whenReady ( ) . then ( ( ) => {
779775 createWindow ( ) ;
780776
777+ // Handles launch from dock on macos
781778 app . on ( "activate" , ( ) => {
782779 if ( BrowserWindow . getAllWindows ( ) . length === 0 ) {
783780 createWindow ( ) ;
0 commit comments