@@ -270,6 +270,138 @@ describeIntegration("WORKSPACE_CREATE with both runtimes", () => {
270270 } ,
271271 TEST_TIMEOUT_MS
272272 ) ;
273+
274+ test . concurrent (
275+ "creates new branch from specified trunk branch, not from default branch" ,
276+ async ( ) => {
277+ const env = await createTestEnvironment ( ) ;
278+ const tempGitRepo = await createTempGitRepo ( ) ;
279+
280+ try {
281+ // Create a custom trunk branch with a unique commit
282+ const customTrunkBranch = "custom-trunk" ;
283+ await execAsync (
284+ `git checkout -b ${ customTrunkBranch } && echo "custom-trunk-content" > trunk-file.txt && git add . && git commit -m "Custom trunk commit"` ,
285+ { cwd : tempGitRepo }
286+ ) ;
287+
288+ // Create a different branch (which will become the default if we checkout to it)
289+ const otherBranch = "other-branch" ;
290+ await execAsync (
291+ `git checkout -b ${ otherBranch } && echo "other-content" > other-file.txt && git add . && git commit -m "Other branch commit"` ,
292+ { cwd : tempGitRepo }
293+ ) ;
294+
295+ // Switch back to the original default branch
296+ const defaultBranch = await detectDefaultTrunkBranch ( tempGitRepo ) ;
297+ await execAsync ( `git checkout ${ defaultBranch } ` , { cwd : tempGitRepo } ) ;
298+
299+ // Now create a workspace specifying custom-trunk as the trunk branch
300+ const newBranchName = generateBranchName ( "from-custom-trunk" ) ;
301+ const runtimeConfig = getRuntimeConfig ( newBranchName ) ;
302+
303+ const { result, cleanup } = await createWorkspaceWithCleanup (
304+ env ,
305+ tempGitRepo ,
306+ newBranchName ,
307+ customTrunkBranch , // Specify custom trunk branch
308+ runtimeConfig
309+ ) ;
310+
311+ expect ( result . success ) . toBe ( true ) ;
312+ if ( ! result . success ) {
313+ throw new Error (
314+ `Failed to create workspace from custom trunk '${ customTrunkBranch } ': ${ result . error } `
315+ ) ;
316+ }
317+
318+ // Wait for workspace initialization to complete
319+ await new Promise ( ( resolve ) => setTimeout ( resolve , getInitWaitTime ( ) ) ) ;
320+
321+ // Verify the new branch was created from custom-trunk, not from default branch
322+ const workspacePath = result . metadata . namedWorkspacePath ;
323+
324+ // For LocalRuntime, check the worktree directly
325+ // For SSHRuntime, we need to check the remote workspace
326+ if ( type === "local" ) {
327+ // Check that trunk-file.txt exists (from custom-trunk)
328+ const trunkFileExists = await fs
329+ . access ( path . join ( workspacePath , "trunk-file.txt" ) )
330+ . then ( ( ) => true )
331+ . catch ( ( ) => false ) ;
332+ expect ( trunkFileExists ) . toBe ( true ) ;
333+
334+ // Check that other-file.txt does NOT exist (from other-branch)
335+ const otherFileExists = await fs
336+ . access ( path . join ( workspacePath , "other-file.txt" ) )
337+ . then ( ( ) => true )
338+ . catch ( ( ) => false ) ;
339+ expect ( otherFileExists ) . toBe ( false ) ;
340+
341+ // Verify git log shows the custom trunk commit
342+ const { stdout : logOutput } = await execAsync (
343+ `git log --oneline --all` ,
344+ { cwd : workspacePath }
345+ ) ;
346+ expect ( logOutput ) . toContain ( "Custom trunk commit" ) ;
347+ } else if ( type === "ssh" && sshConfig ) {
348+ // For SSH runtime, check files on the remote host
349+ const checkFileCmd = `test -f ${ workspacePath } /trunk-file.txt && echo "exists" || echo "missing"` ;
350+ const checkFileStream = await env . mockIpcRenderer . invoke (
351+ IPC_CHANNELS . RUNTIME_EXEC ,
352+ result . metadata . id ,
353+ checkFileCmd ,
354+ { cwd : workspacePath , timeout : 10 }
355+ ) ;
356+
357+ // Read stdout to check if file exists
358+ let checkOutput = "" ;
359+ const reader = checkFileStream . stdout . getReader ( ) ;
360+ const decoder = new TextDecoder ( ) ;
361+ try {
362+ while ( true ) {
363+ const { done, value } = await reader . read ( ) ;
364+ if ( done ) break ;
365+ checkOutput += decoder . decode ( value , { stream : true } ) ;
366+ }
367+ } finally {
368+ reader . releaseLock ( ) ;
369+ }
370+
371+ expect ( checkOutput . trim ( ) ) . toBe ( "exists" ) ;
372+
373+ // Check that other-file.txt does NOT exist
374+ const checkOtherFileCmd = `test -f ${ workspacePath } /other-file.txt && echo "exists" || echo "missing"` ;
375+ const checkOtherStream = await env . mockIpcRenderer . invoke (
376+ IPC_CHANNELS . RUNTIME_EXEC ,
377+ result . metadata . id ,
378+ checkOtherFileCmd ,
379+ { cwd : workspacePath , timeout : 10 }
380+ ) ;
381+
382+ let checkOtherOutput = "" ;
383+ const otherReader = checkOtherStream . stdout . getReader ( ) ;
384+ try {
385+ while ( true ) {
386+ const { done, value } = await otherReader . read ( ) ;
387+ if ( done ) break ;
388+ checkOtherOutput += decoder . decode ( value , { stream : true } ) ;
389+ }
390+ } finally {
391+ otherReader . releaseLock ( ) ;
392+ }
393+
394+ expect ( checkOtherOutput . trim ( ) ) . toBe ( "missing" ) ;
395+ }
396+
397+ await cleanup ( ) ;
398+ } finally {
399+ await cleanupTestEnvironment ( env ) ;
400+ await cleanupTempGitRepo ( tempGitRepo ) ;
401+ }
402+ } ,
403+ TEST_TIMEOUT_MS
404+ ) ;
273405 } ) ;
274406
275407 describe ( "Init hook execution" , ( ) => {
0 commit comments