@@ -13,6 +13,7 @@ const cargoTomlPath = path.join(rootDir, 'src-tauri', 'Cargo.toml');
1313const stageRelativePath = path . join ( 'dist' , 'desktop' , 'codexmate' ) ;
1414const stageDir = path . join ( rootDir , stageRelativePath ) ;
1515const stageNodeModulesDir = path . join ( stageDir , 'node_modules' ) ;
16+ const stageNodeRuntimeDir = path . join ( stageDir , 'node-runtime' ) ;
1617const TAURI_CSP = "default-src 'self' http://127.0.0.1:3737; connect-src 'self' http://127.0.0.1:3737; img-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self'" ;
1718
1819const runtimeEntries = [
@@ -110,12 +111,32 @@ function copyRuntimeNodeModules(pkg, lockFile) {
110111 return copied ;
111112}
112113
113- function writeStageManifest ( pkg , copiedModules ) {
114+ function nodeExecutableName ( ) {
115+ return process . platform === 'win32' ? 'node.exe' : 'node' ;
116+ }
117+
118+ function copyNodeRuntime ( ) {
119+ const source = process . execPath ;
120+ if ( ! source || ! fs . existsSync ( source ) ) {
121+ throw new Error ( 'unable to locate current Node.js executable for desktop packaging' ) ;
122+ }
123+
124+ fs . mkdirSync ( stageNodeRuntimeDir , { recursive : true } ) ;
125+ const executableName = nodeExecutableName ( ) ;
126+ const destination = path . join ( stageNodeRuntimeDir , executableName ) ;
127+ fs . copyFileSync ( source , destination ) ;
128+ const sourceMode = fs . statSync ( source ) . mode ;
129+ fs . chmodSync ( destination , sourceMode | 0o755 ) ;
130+ return path . join ( 'node-runtime' , executableName ) . replace ( / \\ / g, '/' ) ;
131+ }
132+
133+ function writeStageManifest ( pkg , copiedModules , nodeRuntime ) {
114134 writeJson ( path . join ( stageDir , 'codexmate-desktop.json' ) , {
115135 layoutVersion : LAYOUT_VERSION ,
116136 productName : 'Codex Mate' ,
117137 version : pkg . version ,
118138 entrypoint : 'cli.js' ,
139+ nodeRuntime,
119140 nodeModules : 'node_modules' ,
120141 webUi : 'web-ui' ,
121142 copiedRuntimeModules : copiedModules . length
@@ -133,6 +154,7 @@ function validateStagedResources(pkg) {
133154 'web-ui' ,
134155 'web-ui.html' ,
135156 'node_modules' ,
157+ 'node-runtime' ,
136158 'codexmate-desktop.json'
137159 ] ;
138160
@@ -152,14 +174,18 @@ function validateStagedResources(pkg) {
152174 if ( manifest . layoutVersion !== LAYOUT_VERSION || manifest . entrypoint !== 'cli.js' ) {
153175 throw new Error ( 'staged desktop manifest is invalid' ) ;
154176 }
177+ if ( ! manifest . nodeRuntime || ! fs . existsSync ( path . join ( stageDir , manifest . nodeRuntime ) ) ) {
178+ throw new Error ( 'staged desktop Node.js runtime is missing' ) ;
179+ }
155180}
156181
157182function stageDesktopResources ( pkg , lockFile ) {
158183 fs . rmSync ( stageDir , { recursive : true , force : true } ) ;
159184 fs . mkdirSync ( stageDir , { recursive : true } ) ;
160185 copyRuntimeEntries ( ) ;
161186 const copiedModules = copyRuntimeNodeModules ( pkg , lockFile ) ;
162- writeStageManifest ( pkg , copiedModules ) ;
187+ const nodeRuntime = copyNodeRuntime ( ) ;
188+ writeStageManifest ( pkg , copiedModules , nodeRuntime ) ;
163189 validateStagedResources ( pkg ) ;
164190 return copiedModules . length ;
165191}
0 commit comments