@@ -8,9 +8,9 @@ import * as path from "path";
88import { simpleGit } from "simple-git" ;
99import { promisify } from "util" ;
1010import { v4 as uuidv4 } from "uuid" ;
11- import { PersistedSession , SessionConfig } from "./types" ;
12- import { isTerminalReady } from "./terminal-utils" ;
1311import { getBranches } from "./git-utils" ;
12+ import { isTerminalReady } from "./terminal-utils" ;
13+ import { PersistedSession , SessionConfig , SessionType } from "./types" ;
1414
1515const execAsync = promisify ( exec ) ;
1616
@@ -22,7 +22,16 @@ const store = new Store();
2222
2323// Helper functions for session management
2424function getPersistedSessions ( ) : PersistedSession [ ] {
25- return ( store as any ) . get ( "sessions" , [ ] ) ;
25+ const sessions = ( store as any ) . get ( "sessions" , [ ] ) as PersistedSession [ ] ;
26+
27+ // Migrate old sessions that don't have sessionType field
28+ return sessions . map ( session => {
29+ if ( ! session . config . sessionType ) {
30+ // If session has a worktreePath, it's a worktree session; otherwise local
31+ session . config . sessionType = session . worktreePath ? SessionType . WORKTREE : SessionType . LOCAL ;
32+ }
33+ return session ;
34+ } ) ;
2635}
2736
2837function getWorktreeBaseDir ( ) : string {
@@ -232,7 +241,7 @@ function parseMcpOutput(output: string): any[] {
232241// Helper function to spawn PTY and setup coding agent
233242function spawnSessionPty (
234243 sessionId : string ,
235- worktreePath : string ,
244+ workingDirectory : string ,
236245 config : SessionConfig ,
237246 sessionUuid : string ,
238247 isNewSession : boolean ,
@@ -244,7 +253,7 @@ function spawnSessionPty(
244253 name : "xterm-color" ,
245254 cols : 80 ,
246255 rows : 30 ,
247- cwd : worktreePath ,
256+ cwd : workingDirectory ,
248257 env : process . env ,
249258 } ) ;
250259
@@ -397,6 +406,7 @@ ipcMain.handle("get-branches", async (_event, dirPath: string) => {
397406ipcMain . handle ( "get-last-settings" , ( ) => {
398407 return ( store as any ) . get ( "lastSessionConfig" , {
399408 projectDir : "" ,
409+ sessionType : SessionType . WORKTREE ,
400410 parentBranch : "" ,
401411 codingAgent : "claude" ,
402412 skipPermissions : true ,
@@ -417,15 +427,36 @@ ipcMain.on("create-session", async (event, config: SessionConfig) => {
417427 // Use custom branch name as session name if provided, otherwise default
418428 const sessionName = config . branchName || `Session ${ sessionNumber } ` ;
419429
420- // Generate UUID for this session (before creating worktree)
430+ // Generate UUID for this session
421431 const sessionUuid = uuidv4 ( ) ;
422432
423- // Create git worktree with custom or default branch name
424- const { worktreePath, branchName } = await createWorktree ( config . projectDir , config . parentBranch , sessionNumber , sessionUuid , config . branchName ) ;
433+ let worktreePath : string | undefined ;
434+ let workingDirectory : string ;
435+ let branchName : string | undefined ;
436+ let mcpConfigPath : string | undefined ;
425437
426- // Extract and write MCP config
427- const mcpServers = extractProjectMcpConfig ( config . projectDir ) ;
428- const mcpConfigPath = writeMcpConfigFile ( config . projectDir , mcpServers ) ;
438+ if ( config . sessionType === SessionType . WORKTREE ) {
439+ // Validate that parentBranch is provided for worktree sessions
440+ if ( ! config . parentBranch ) {
441+ throw new Error ( "Parent branch is required for worktree sessions" ) ;
442+ }
443+
444+ // Create git worktree with custom or default branch name
445+ const worktreeResult = await createWorktree ( config . projectDir , config . parentBranch , sessionNumber , sessionUuid , config . branchName ) ;
446+ worktreePath = worktreeResult . worktreePath ;
447+ workingDirectory = worktreeResult . worktreePath ;
448+ branchName = worktreeResult . branchName ;
449+
450+ // Extract and write MCP config
451+ const mcpServers = extractProjectMcpConfig ( config . projectDir ) ;
452+ mcpConfigPath = writeMcpConfigFile ( config . projectDir , mcpServers ) || undefined ;
453+ } else {
454+ // For local sessions, use the project directory directly (no worktree)
455+ worktreePath = undefined ;
456+ workingDirectory = config . projectDir ;
457+ branchName = undefined ;
458+ mcpConfigPath = undefined ;
459+ }
429460
430461 // Create persisted session metadata
431462 const persistedSession : PersistedSession = {
@@ -436,7 +467,7 @@ ipcMain.on("create-session", async (event, config: SessionConfig) => {
436467 worktreePath,
437468 createdAt : Date . now ( ) ,
438469 sessionUuid,
439- mcpConfigPath : mcpConfigPath || undefined ,
470+ mcpConfigPath,
440471 gitBranch : branchName ,
441472 } ;
442473
@@ -445,8 +476,8 @@ ipcMain.on("create-session", async (event, config: SessionConfig) => {
445476 sessions . push ( persistedSession ) ;
446477 savePersistedSessions ( sessions ) ;
447478
448- // Spawn PTY in worktree directory
449- spawnSessionPty ( sessionId , worktreePath , config , sessionUuid , true , mcpConfigPath || undefined , config . projectDir ) ;
479+ // Spawn PTY in the appropriate directory
480+ spawnSessionPty ( sessionId , workingDirectory , config , sessionUuid , true , mcpConfigPath , config . projectDir ) ;
450481
451482 event . reply ( "session-created" , sessionId , persistedSession ) ;
452483 } catch ( error ) {
@@ -490,8 +521,11 @@ ipcMain.on("reopen-session", (event, sessionId: string) => {
490521 return ;
491522 }
492523
493- // Spawn new PTY in worktree directory
494- spawnSessionPty ( sessionId , session . worktreePath , session . config , session . sessionUuid , false , session . mcpConfigPath , session . config . projectDir ) ;
524+ // For non-worktree sessions, use project directory; otherwise use worktree path
525+ const workingDir = session . worktreePath || session . config . projectDir ;
526+
527+ // Spawn new PTY in the appropriate directory
528+ spawnSessionPty ( sessionId , workingDir , session . config , session . sessionUuid , false , session . mcpConfigPath , session . config . projectDir ) ;
495529
496530 event . reply ( "session-reopened" , sessionId ) ;
497531} ) ;
@@ -540,12 +574,15 @@ ipcMain.on("delete-session", async (_event, sessionId: string) => {
540574
541575 const session = sessions [ sessionIndex ] ;
542576
543- // Remove git worktree
544- await removeWorktree ( session . config . projectDir , session . worktreePath ) ;
577+ // Only clean up git worktree and branch for worktree sessions
578+ if ( session . config . sessionType === SessionType . WORKTREE && session . worktreePath ) {
579+ // Remove git worktree
580+ await removeWorktree ( session . config . projectDir , session . worktreePath ) ;
545581
546- // Remove git branch if it exists
547- if ( session . gitBranch ) {
548- await removeGitBranch ( session . config . projectDir , session . gitBranch ) ;
582+ // Remove git branch if it exists
583+ if ( session . gitBranch ) {
584+ await removeGitBranch ( session . config . projectDir , session . gitBranch ) ;
585+ }
549586 }
550587
551588 // Remove from store
0 commit comments