@@ -14,8 +14,10 @@ import { afterEach, beforeEach, describe, expect, it } from "vitest";
1414import { createWorktree , formatWorktreeSummary } from "./worktree.js" ;
1515
1616let repoDir : string ;
17+ let sessionsToCleanup : string [ ] = [ ] ;
1718
1819beforeEach ( ( ) => {
20+ sessionsToCleanup = [ ] ;
1921 repoDir = mkdtempSync ( path . join ( tmpdir ( ) , "oma-worktree-test-" ) ) ;
2022 execSync ( "git init -b main" , { cwd : repoDir , stdio : "pipe" } ) ;
2123 execSync ( 'git config user.email "test@example.com"' , {
@@ -52,16 +54,32 @@ afterEach(() => {
5254 } catch {
5355 // ignore — repo may already be torn down
5456 }
57+
58+ // Clean up any worktree directories from tmp
59+ for ( const sess of sessionsToCleanup ) {
60+ try {
61+ const wtRoot = path . join ( tmpdir ( ) , "oma-worktrees" , sess ) ;
62+ if ( existsSync ( wtRoot ) ) {
63+ rmSync ( wtRoot , { recursive : true , force : true } ) ;
64+ }
65+ } catch {
66+ // ignore
67+ }
68+ }
69+
5570 if ( existsSync ( repoDir ) ) {
5671 rmSync ( repoDir , { recursive : true , force : true } ) ;
5772 }
5873} ) ;
5974
6075describe ( "createWorktree" , ( ) => {
6176 it ( "creates a worktree + branch from the current HEAD" , ( ) => {
62- const handle = createWorktree ( "sess-001" , "oma-backend" , repoDir ) ;
77+ const sessId = `sess-001-${ Math . random ( ) . toString ( 36 ) . slice ( 2 ) } ` ;
78+ sessionsToCleanup . push ( sessId ) ;
79+
80+ const handle = createWorktree ( sessId , "oma-backend" , repoDir ) ;
6381 expect ( existsSync ( handle . path ) ) . toBe ( true ) ;
64- expect ( handle . branch ) . toBe ( " oma/sess-001 /oma-backend" ) ;
82+ expect ( handle . branch ) . toBe ( ` oma/${ sessId } /oma-backend` ) ;
6583 expect ( handle . base ) . toBe ( "main" ) ;
6684
6785 // The branch should be checked out at the new path
@@ -73,8 +91,12 @@ describe("createWorktree", () => {
7391 } ) ;
7492
7593 it ( "sanitizes unsafe characters in sessionId / agentId for the branch" , ( ) => {
76- const handle = createWorktree ( "sess with space" , "agent$weird" , repoDir ) ;
77- expect ( handle . branch ) . toMatch ( / ^ o m a \/ s e s s - w i t h - s p a c e \/ a g e n t - w e i r d $ / ) ;
94+ const sessId = `sess with space-${ Math . random ( ) . toString ( 36 ) . slice ( 2 ) } ` ;
95+ sessionsToCleanup . push ( sessId ) ;
96+
97+ const handle = createWorktree ( sessId , "agent$weird" , repoDir ) ;
98+ const safeSess = sessId . replace ( / [ ^ A - Z a - z 0 - 9 . _ - ] / g, "-" ) . slice ( 0 , 64 ) ;
99+ expect ( handle . branch ) . toBe ( `oma/${ safeSess } /agent-weird` ) ;
78100 } ) ;
79101
80102 it ( "throws when source is not a git repo" , ( ) => {
@@ -86,8 +108,11 @@ describe("createWorktree", () => {
86108 } ) ;
87109
88110 it ( "throws when the target worktree path already exists" , ( ) => {
89- createWorktree ( "dup-session" , "agent" , repoDir ) ;
90- expect ( ( ) => createWorktree ( "dup-session" , "agent" , repoDir ) ) . toThrow (
111+ const sessId = `dup-session-${ Math . random ( ) . toString ( 36 ) . slice ( 2 ) } ` ;
112+ sessionsToCleanup . push ( sessId ) ;
113+
114+ createWorktree ( sessId , "agent" , repoDir ) ;
115+ expect ( ( ) => createWorktree ( sessId , "agent" , repoDir ) ) . toThrow (
91116 / W o r k t r e e p a t h a l r e a d y e x i s t s / ,
92117 ) ;
93118 } ) ;
0 commit comments