@@ -10,10 +10,7 @@ import {
1010 resolveProjectBootstrapVolumeName ,
1111 type TemplateConfig
1212} from "../core/domain.js"
13- import {
14- runDockerVolumeCreate ,
15- runDockerVolumeReplaceFromDirectory
16- } from "../shell/docker-volume.js"
13+ import { runDockerVolumeCreate , runDockerVolumeReplaceFromDirectory } from "../shell/docker-volume.js"
1714import type { DockerCommandError } from "../shell/errors.js"
1815
1916type SharedVolumeSeedEnvironment = CommandExecutor | FileSystem . FileSystem | Path . Path
@@ -74,63 +71,117 @@ const copyFileIfPresent = (
7471 yield * _ ( fs . copyFile ( sourcePath , targetPath ) )
7572 } )
7673
74+ type BootstrapSeedConfig = Pick <
75+ TemplateConfig ,
76+ "authorizedKeysPath" | "envGlobalPath" | "envProjectPath" | "codexAuthPath" | "codexSharedAuthPath"
77+ >
78+
79+ type BootstrapSnapshotSources = {
80+ readonly authorizedKeysSource : string
81+ readonly envGlobalSource : string
82+ readonly envProjectSource : string
83+ readonly codexAuthSource : string
84+ readonly codexSharedAuthSource : string
85+ readonly claudeAuthSource : string
86+ }
87+
88+ type BootstrapSnapshotTargets = {
89+ readonly authorizedKeysTarget : string
90+ readonly envGlobalTarget : string
91+ readonly envProjectTarget : string
92+ readonly projectCodexTarget : string
93+ readonly projectClaudeTarget : string
94+ readonly sharedCodexTarget : string
95+ }
96+
97+ const resolveBootstrapSnapshotSources = (
98+ path : Path . Path ,
99+ projectDir : string ,
100+ config : BootstrapSeedConfig
101+ ) : BootstrapSnapshotSources => {
102+ const codexAuthSource = resolvePathFromBase ( path , projectDir , config . codexAuthPath )
103+ return {
104+ authorizedKeysSource : resolvePathFromBase ( path , projectDir , config . authorizedKeysPath ) ,
105+ envGlobalSource : resolvePathFromBase ( path , projectDir , config . envGlobalPath ) ,
106+ envProjectSource : resolvePathFromBase ( path , projectDir , config . envProjectPath ) ,
107+ codexAuthSource,
108+ codexSharedAuthSource : resolvePathFromBase ( path , projectDir , config . codexSharedAuthPath ) ,
109+ claudeAuthSource : path . join ( path . dirname ( codexAuthSource ) , "claude" )
110+ }
111+ }
112+
113+ const resolveBootstrapSnapshotTargets = (
114+ path : Path . Path ,
115+ stagingDir : string ,
116+ config : BootstrapSeedConfig
117+ ) : BootstrapSnapshotTargets => {
118+ const authorizedKeysBase = config . authorizedKeysPath . replaceAll ( "\\" , "/" ) . split ( "/" ) . at ( - 1 ) ?? "authorized_keys"
119+ const envGlobalBase = config . envGlobalPath . replaceAll ( "\\" , "/" ) . split ( "/" ) . at ( - 1 ) ?? "global.env"
120+ const envProjectBase = config . envProjectPath . replaceAll ( "\\" , "/" ) . split ( "/" ) . at ( - 1 ) ?? "project.env"
121+
122+ return {
123+ authorizedKeysTarget : path . join ( stagingDir , "authorized-keys" , authorizedKeysBase ) ,
124+ envGlobalTarget : path . join ( stagingDir , "env-global" , envGlobalBase ) ,
125+ envProjectTarget : path . join ( stagingDir , "env-project" , envProjectBase ) ,
126+ projectCodexTarget : path . join ( stagingDir , "project-auth" , "codex" ) ,
127+ projectClaudeTarget : path . join ( stagingDir , "project-auth" , "claude" ) ,
128+ sharedCodexTarget : path . join ( stagingDir , "shared-auth" , "codex" )
129+ }
130+ }
131+
132+ const ensureBootstrapSnapshotLayout = (
133+ path : Path . Path ,
134+ fs : FileSystem . FileSystem ,
135+ targets : BootstrapSnapshotTargets
136+ ) : Effect . Effect < void , PlatformError , FileSystem . FileSystem | Path . Path > =>
137+ Effect . gen ( function * ( _ ) {
138+ yield * _ ( fs . makeDirectory ( path . dirname ( targets . authorizedKeysTarget ) , { recursive : true } ) )
139+ yield * _ ( fs . makeDirectory ( path . dirname ( targets . envGlobalTarget ) , { recursive : true } ) )
140+ yield * _ ( fs . makeDirectory ( path . dirname ( targets . envProjectTarget ) , { recursive : true } ) )
141+ yield * _ ( fs . makeDirectory ( targets . projectCodexTarget , { recursive : true } ) )
142+ yield * _ ( fs . makeDirectory ( targets . projectClaudeTarget , { recursive : true } ) )
143+ yield * _ ( fs . makeDirectory ( targets . sharedCodexTarget , { recursive : true } ) )
144+ } )
145+
146+ const copyBootstrapSnapshotFiles = (
147+ fs : FileSystem . FileSystem ,
148+ path : Path . Path ,
149+ sources : BootstrapSnapshotSources ,
150+ targets : BootstrapSnapshotTargets
151+ ) : Effect . Effect < void , PlatformError , FileSystem . FileSystem | Path . Path > =>
152+ Effect . gen ( function * ( _ ) {
153+ yield * _ ( copyFileIfPresent ( fs , path , sources . authorizedKeysSource , targets . authorizedKeysTarget ) )
154+ yield * _ ( copyFileIfPresent ( fs , path , sources . envGlobalSource , targets . envGlobalTarget ) )
155+ yield * _ ( copyFileIfPresent ( fs , path , sources . envProjectSource , targets . envProjectTarget ) )
156+ } )
157+
158+ const copyBootstrapSnapshotAuthDirs = (
159+ fs : FileSystem . FileSystem ,
160+ path : Path . Path ,
161+ sources : BootstrapSnapshotSources ,
162+ targets : BootstrapSnapshotTargets
163+ ) : Effect . Effect < void , PlatformError , FileSystem . FileSystem | Path . Path > =>
164+ Effect . gen ( function * ( _ ) {
165+ yield * _ ( copyDirRecursive ( fs , path , sources . codexAuthSource , targets . projectCodexTarget ) )
166+ yield * _ ( copyDirRecursive ( fs , path , sources . claudeAuthSource , targets . projectClaudeTarget ) )
167+ yield * _ ( copyDirRecursive ( fs , path , sources . codexSharedAuthSource , targets . sharedCodexTarget ) )
168+ } )
169+
77170const stageBootstrapSnapshot = (
78171 stagingDir : string ,
79172 projectDir : string ,
80- config : Pick <
81- TemplateConfig ,
82- "authorizedKeysPath" | "envGlobalPath" | "envProjectPath" | "codexAuthPath" | "codexSharedAuthPath"
83- >
173+ config : BootstrapSeedConfig
84174) : Effect . Effect < void , PlatformError , FileSystem . FileSystem | Path . Path > =>
85175 Effect . gen ( function * ( _ ) {
86176 const fs = yield * _ ( FileSystem . FileSystem )
87177 const path = yield * _ ( Path . Path )
88178
89- const authorizedKeysSource = resolvePathFromBase ( path , projectDir , config . authorizedKeysPath )
90- const envGlobalSource = resolvePathFromBase ( path , projectDir , config . envGlobalPath )
91- const envProjectSource = resolvePathFromBase ( path , projectDir , config . envProjectPath )
92- const codexAuthSource = resolvePathFromBase ( path , projectDir , config . codexAuthPath )
93- const codexSharedAuthSource = resolvePathFromBase ( path , projectDir , config . codexSharedAuthPath )
94- const claudeAuthSource = path . join ( path . dirname ( codexAuthSource ) , "claude" )
95-
96- const authorizedKeysBase = config . authorizedKeysPath . replaceAll ( "\\" , "/" ) . split ( "/" ) . at ( - 1 ) ?? "authorized_keys"
97- const envGlobalBase = config . envGlobalPath . replaceAll ( "\\" , "/" ) . split ( "/" ) . at ( - 1 ) ?? "global.env"
98- const envProjectBase = config . envProjectPath . replaceAll ( "\\" , "/" ) . split ( "/" ) . at ( - 1 ) ?? "project.env"
99-
100- yield * _ ( fs . makeDirectory ( path . join ( stagingDir , "authorized-keys" ) , { recursive : true } ) )
101- yield * _ ( fs . makeDirectory ( path . join ( stagingDir , "env-global" ) , { recursive : true } ) )
102- yield * _ ( fs . makeDirectory ( path . join ( stagingDir , "env-project" ) , { recursive : true } ) )
103- yield * _ ( fs . makeDirectory ( path . join ( stagingDir , "project-auth" , "codex" ) , { recursive : true } ) )
104- yield * _ ( fs . makeDirectory ( path . join ( stagingDir , "project-auth" , "claude" ) , { recursive : true } ) )
105- yield * _ ( fs . makeDirectory ( path . join ( stagingDir , "shared-auth" , "codex" ) , { recursive : true } ) )
106-
107- yield * _ (
108- copyFileIfPresent (
109- fs ,
110- path ,
111- authorizedKeysSource ,
112- path . join ( stagingDir , "authorized-keys" , authorizedKeysBase )
113- )
114- )
115- yield * _ (
116- copyFileIfPresent (
117- fs ,
118- path ,
119- envGlobalSource ,
120- path . join ( stagingDir , "env-global" , envGlobalBase )
121- )
122- )
123- yield * _ (
124- copyFileIfPresent (
125- fs ,
126- path ,
127- envProjectSource ,
128- path . join ( stagingDir , "env-project" , envProjectBase )
129- )
130- )
131- yield * _ ( copyDirRecursive ( fs , path , codexAuthSource , path . join ( stagingDir , "project-auth" , "codex" ) ) )
132- yield * _ ( copyDirRecursive ( fs , path , claudeAuthSource , path . join ( stagingDir , "project-auth" , "claude" ) ) )
133- yield * _ ( copyDirRecursive ( fs , path , codexSharedAuthSource , path . join ( stagingDir , "shared-auth" , "codex" ) ) )
179+ const sources = resolveBootstrapSnapshotSources ( path , projectDir , config )
180+ const targets = resolveBootstrapSnapshotTargets ( path , stagingDir , config )
181+
182+ yield * _ ( ensureBootstrapSnapshotLayout ( path , fs , targets ) )
183+ yield * _ ( copyBootstrapSnapshotFiles ( fs , path , sources , targets ) )
184+ yield * _ ( copyBootstrapSnapshotAuthDirs ( fs , path , sources , targets ) )
134185 } )
135186
136187export const ensureProjectBootstrapVolumeReady = (
0 commit comments