@@ -32,12 +32,7 @@ import type {
3232import { WORKSPACE_REPO_MISSING_ERROR } from "./Runtime" ;
3333import { RemoteRuntime , type SpawnResult } from "./RemoteRuntime" ;
3434import { log } from "@/node/services/log" ;
35- import {
36- checkInitHookExists ,
37- getMuxEnv ,
38- runInitHookOnRuntime ,
39- shouldSkipInitHook ,
40- } from "./initHook" ;
35+ import { runInitHookOnRuntime , runWorkspaceInitHook } from "./initHook" ;
4136import { expandTildeForSSH as expandHookPath } from "./tildeExpansion" ;
4237
4338import { expandTildeForSSH , cdCommandForSSH } from "./tildeExpansion" ;
@@ -752,9 +747,9 @@ export class SSHRuntime extends RemoteRuntime {
752747
753748 async createWorkspace ( params : WorkspaceCreationParams ) : Promise < WorkspaceCreationResult > {
754749 try {
755- const { projectPath, branchName , initLogger, abortSignal } = params ;
756- // Compute workspace path using canonical method
757- const workspacePath = this . getWorkspacePath ( projectPath , branchName ) ;
750+ const { projectPath, directoryName , initLogger, abortSignal } = params ;
751+ // Workspace directories follow the persisted workspace name; branch checkout happens later.
752+ const workspacePath = this . getWorkspacePath ( projectPath , directoryName ) ;
758753
759754 // Prepare parent directory for git clone (fast - returns immediately)
760755 // Note: git clone will create the workspace directory itself during initWorkspace,
@@ -805,49 +800,29 @@ export class SSHRuntime extends RemoteRuntime {
805800 }
806801
807802 async initWorkspace ( params : WorkspaceInitParams ) : Promise < WorkspaceInitResult > {
808- const { projectPath, branchName, workspacePath, initLogger, abortSignal, env } = params ;
809-
810803 // Disable git hooks for untrusted projects (prevents post-checkout execution)
811804 const nhp = gitNoHooksPrefix ( params . trusted ) ;
812805
813- try {
814- await this . prepareWorkspaceCheckout ( params , nhp ) ;
815-
816- // 3. Run .mux/init hook if it exists
817- // Note: runInitHookOnRuntime calls logComplete() internally
818- if ( shouldSkipInitHook ( params , initLogger ) ) {
819- initLogger . logComplete ( 0 ) ;
820- } else {
821- const hookExists = await checkInitHookExists ( projectPath ) ;
822- if ( hookExists ) {
823- initLogger . enterHookPhase ?.( ) ;
824- const muxEnv = { ...env , ...getMuxEnv ( projectPath , "ssh" , branchName ) } ;
825- // Expand tilde in hook path (quoted paths don't auto-expand on remote)
826- const hookPath = expandHookPath ( `${ workspacePath } /.mux/init` ) ;
827- await runInitHookOnRuntime (
828- this ,
829- hookPath ,
830- workspacePath ,
831- muxEnv ,
832- initLogger ,
833- abortSignal
834- ) ;
835- } else {
836- // No hook - signal completion immediately
837- initLogger . logComplete ( 0 ) ;
838- }
839- }
840-
841- return { success : true } ;
842- } catch ( error ) {
843- const errorMsg = getErrorMessage ( error ) ;
844- initLogger . logStderr ( `Initialization failed: ${ errorMsg } ` ) ;
845- initLogger . logComplete ( - 1 ) ;
846- return {
847- success : false ,
848- error : errorMsg ,
849- } ;
850- }
806+ return runWorkspaceInitHook ( {
807+ params,
808+ runtimeType : "ssh" ,
809+ hookCheckPath : params . projectPath ,
810+ beforeHook : async ( ) => {
811+ await this . prepareWorkspaceCheckout ( params , nhp ) ;
812+ } ,
813+ runHook : async ( { muxEnv, initLogger, abortSignal } ) => {
814+ // Expand tilde in hook path (quoted paths don't auto-expand on remote).
815+ const hookPath = expandHookPath ( `${ params . workspacePath } /.mux/init` ) ;
816+ await runInitHookOnRuntime (
817+ this ,
818+ hookPath ,
819+ params . workspacePath ,
820+ muxEnv ,
821+ initLogger ,
822+ abortSignal
823+ ) ;
824+ } ,
825+ } ) ;
851826 }
852827
853828 private async prepareWorkspaceCheckout ( params : WorkspaceInitParams , nhp : string ) : Promise < void > {
0 commit comments