openclaw-droid 2.0.2 → 2.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of openclaw-droid might be problematic. Click here for more details.

package/lib/installer.js CHANGED
@@ -20,71 +20,80 @@ export function checkDependencies() {
20
20
  proot: false
21
21
  };
22
22
 
23
- try {
24
- safeExecSync('node --version', { stdio: 'pipe' });
25
- deps.node = true;
26
- } catch (err) {
27
- logger.debug('Node.js check failed:', err.message);
28
- }
29
- try {
30
- safeExecSync('npm --version', { stdio: 'pipe' });
31
- deps.npm = true;
32
- } catch (err) {
33
- logger.debug('npm check failed:', err.message);
34
- }
35
- try {
36
- safeExecSync('git --version', { stdio: 'pipe' });
37
- deps.git = true;
38
- } catch (err) {
39
- logger.debug('git check failed:', err.message);
40
- }
41
- try {
42
- safeExecSync('which proot-distro', { stdio: 'pipe' });
43
- deps.proot = true;
44
- } catch (err) {
45
- logger.debug('proot-distro check failed:', err.message);
23
+ try {
24
+ safeExecSync('node --version', { stdio: 'pipe' });
25
+ deps.node = true;
26
+ } catch (err) {
27
+ logger.debug('Node.js check failed:', err.message);
28
+ }
29
+ try {
30
+ safeExecSync('npm --version', { stdio: 'pipe' });
31
+ deps.npm = true;
32
+ } catch (err) {
33
+ logger.debug('npm check failed:', err.message);
34
+ }
35
+ try {
36
+ safeExecSync('git --version', { stdio: 'pipe' });
37
+ deps.git = true;
38
+ } catch (err) {
39
+ logger.debug('git check failed:', err.message);
40
+ }
41
+ try {
42
+ safeExecSync('which proot-distro', { stdio: 'pipe' });
43
+ deps.proot = true;
44
+ } catch (err) {
45
+ logger.debug('proot-distro check failed:', err.message);
46
46
  }
47
47
 
48
48
  return deps;
49
49
  }
50
50
 
51
- export function installTermuxDeps() {
52
- console.log('Installing Termux dependencies...');
53
- const packages = ['nodejs-lts', 'git', 'openssh', 'python', 'termux-gui', 'termux-api'];
54
- try {
55
- safeExecSync('pkg update -y', { stdio: 'inherit', timeout: 180000 });
56
- safeExecSync('pkg upgrade -y', { stdio: 'inherit', timeout: 300000 });
57
-
58
- console.log('Enabling X11 repository...');
59
- safeExecSync('pkg install -y x11-repo', { stdio: 'inherit', timeout: 60000 });
60
-
61
- safeExecSync(`pkg install -y ${packages.join(' ')}`, { stdio: 'inherit', timeout: 300000 });
62
- safeExecSync('npm install -g npm@latest', { stdio: 'inherit', timeout: 120000 });
63
-
64
- const checks = [
65
- ['node --version', 'Node.js'],
66
- ['npm --version', 'npm'],
67
- ['git --version', 'git'],
68
- ['command -v proot-distro', 'proot-distro'],
69
- ['command -v python', 'python'],
70
- ['command -v termux-wake-lock', 'termux-api'],
71
- ['python -c "import termuxgui"', 'termux-gui']
72
- ];
73
-
74
- for (const [cmd, label] of checks) {
75
- try {
76
- safeExecSync(cmd, { stdio: 'pipe', timeout: 3000 });
77
- } catch (err) {
78
- logger.warn(`Optional dependency missing: ${label} - install may still work`);
79
- }
80
- }
81
-
82
- return true;
83
- } catch (err) {
84
- console.error('Failed to install Termux packages:', err.message);
85
- return false;
86
- }
87
- }
51
+ export function installTermuxDeps() {
52
+ console.log('Installing Termux dependencies...');
53
+ const packages = ['nodejs-lts', 'git', 'openssh', 'python', 'termux-api'];
54
+ try {
55
+ safeExecSync('pkg update -y', { stdio: 'inherit', timeout: 180000 });
56
+ safeExecSync('pkg upgrade -y', { stdio: 'inherit', timeout: 300000 });
57
+
58
+ console.log('Enabling X11 repository...');
59
+ try {
60
+ safeExecSync('pkg install -y x11-repo', { stdio: 'inherit', timeout: 60000 });
61
+ } catch (err) {
62
+ logger.warn('x11-repo not available. termux-gui may not install.');
63
+ }
64
+
65
+ safeExecSync(`pkg install -y ${packages.join(' ')}`, { stdio: 'inherit', timeout: 300000 });
66
+ try {
67
+ safeExecSync('pkg install -y termux-gui', { stdio: 'inherit', timeout: 120000 });
68
+ } catch (err) {
69
+ logger.warn('termux-gui not available. Overlay features will be disabled.');
70
+ }
71
+ safeExecSync('npm install -g npm@latest', { stdio: 'inherit', timeout: 120000 });
72
+
73
+ const checks = [
74
+ ['node --version', 'Node.js'],
75
+ ['npm --version', 'npm'],
76
+ ['git --version', 'git'],
77
+ ['command -v proot-distro', 'proot-distro'],
78
+ ['command -v python', 'python'],
79
+ ['command -v termux-wake-lock', 'termux-api'],
80
+ ['python -c "import termuxgui"', 'termux-gui']
81
+ ];
82
+
83
+ for (const [cmd, label] of checks) {
84
+ try {
85
+ safeExecSync(cmd, { stdio: 'pipe', timeout: 3000 });
86
+ } catch (err) {
87
+ logger.warn(`Optional dependency missing: ${label} - install may still work`);
88
+ }
89
+ }
90
+
91
+ return true;
92
+ } catch (err) {
93
+ console.error('Failed to install Termux packages:', err.message);
94
+ return false;
95
+ }
96
+ }
88
97
 
89
98
  export function setupBionicBypass() {
90
99
  console.log('Setting up Bionic Bypass...');
@@ -127,189 +136,189 @@ if [ ! -d "$TMPDIR" ]; then mkdir -p "$TMPDIR"; fi
127
136
  return scriptPath;
128
137
  }
129
138
 
130
- export function installOpenClaw() {
131
- console.log('Installing OpenClaw...');
132
- try {
133
- execSync('npm install -g openclaw@latest', { stdio: 'inherit' });
134
- return true;
135
- } catch (err) {
136
- console.error('Failed to install OpenClaw:', err.message);
137
- return false;
138
- }
139
+ export function installOpenClaw() {
140
+ console.log('Installing OpenClaw...');
141
+ try {
142
+ execSync('npm install -g openclaw@latest', { stdio: 'inherit' });
143
+ return true;
144
+ } catch (err) {
145
+ console.error('Failed to install OpenClaw:', err.message);
146
+ return false;
147
+ }
139
148
  }
140
149
 
141
- export function configureTermux() {
142
- console.log('Configuring Termux for background operation...');
143
- const configDir = path.join(HOME, '.openclaw');
144
- if (!fs.existsSync(configDir)) {
145
- ensureDirectoryExists(configDir);
146
- }
147
-
148
- const prefix = process.env.PREFIX || '/data/data/com.termux/files/usr';
149
- const tmpOpenClawDir = path.join(prefix, 'tmp', 'openclaw');
150
- if (!fs.existsSync(tmpOpenClawDir)) {
151
- ensureDirectoryExists(tmpOpenClawDir);
152
- }
153
-
154
- const openclawConfigPath = path.join(configDir, 'openclaw.json');
155
- let config = {};
156
-
157
- if (fs.existsSync(openclawConfigPath)) {
158
- try {
159
- config = JSON.parse(fs.readFileSync(openclawConfigPath, 'utf8'));
160
- } catch (e) {
161
- logger.warn('Warning: Failed to parse existing openclaw.json, starting fresh.');
162
- }
163
- }
164
-
165
- let modified = false;
166
-
167
- // Ensure gateway.bind = lan
168
- if (!config.gateway) config.gateway = {};
169
- if (config.gateway.bind !== 'lan') {
170
- config.gateway.bind = 'lan';
171
- modified = true;
172
- }
173
-
174
- // Ensure logging.file is correct
175
- const expectedLogFile = path.join(tmpOpenClawDir, 'openclaw-YYYY-MM-DD.log');
176
- if (!config.logging) config.logging = {};
177
- if (!config.logging.level) {
178
- config.logging.level = 'info';
179
- modified = true;
180
- }
181
- if (config.logging.file !== expectedLogFile) {
182
- config.logging.file = expectedLogFile;
183
- modified = true;
184
- }
185
-
186
- if (modified || !fs.existsSync(openclawConfigPath)) {
187
- safeWriteFileSync(openclawConfigPath, JSON.stringify(config, null, 2), 'utf8');
188
- console.log(' ✓ Updated openclaw.json config');
189
- } else {
190
- console.log(' ✓ openclaw.json config is up to date');
191
- }
192
-
193
- const wakeLockScript = path.join(configDir, 'wakelock.sh');
194
- const wakeLockContent = `#!/bin/bash
195
- termux-wake-lock
196
- trap "termux-wake-unlock" EXIT
197
- exec "$@"
198
- `;
199
-
200
- safeWriteFileSync(wakeLockScript, wakeLockContent, 'utf8');
201
- setSecurePermissions(wakeLockScript, '750');
202
-
203
- // Copy overlay_daemon.py to HOME for easy access
204
- try {
205
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
206
- const pkgRoot = path.join(__dirname, '..');
207
- const sourceOverlay = path.join(pkgRoot, 'overlay_daemon.py');
208
- const destOverlay = path.join(HOME, 'overlay_daemon.py');
209
-
210
- if (fs.existsSync(sourceOverlay)) {
211
- fs.copyFileSync(sourceOverlay, destOverlay);
212
- setSecurePermissions(destOverlay, '750');
213
- console.log(` ✓ Copied overlay_daemon.py to ${destOverlay}`);
214
- }
215
- } catch (err) {
216
- logger.warn('Failed to copy overlay_daemon.py:', err);
217
- }
218
-
219
- return true;
150
+ export function configureTermux() {
151
+ console.log('Configuring Termux for background operation...');
152
+ const configDir = path.join(HOME, '.openclaw');
153
+ if (!fs.existsSync(configDir)) {
154
+ ensureDirectoryExists(configDir);
155
+ }
156
+
157
+ const prefix = process.env.PREFIX || '/data/data/com.termux/files/usr';
158
+ const tmpOpenClawDir = path.join(prefix, 'tmp', 'openclaw');
159
+ if (!fs.existsSync(tmpOpenClawDir)) {
160
+ ensureDirectoryExists(tmpOpenClawDir);
161
+ }
162
+
163
+ const openclawConfigPath = path.join(configDir, 'openclaw.json');
164
+ let config = {};
165
+
166
+ if (fs.existsSync(openclawConfigPath)) {
167
+ try {
168
+ config = JSON.parse(fs.readFileSync(openclawConfigPath, 'utf8'));
169
+ } catch (e) {
170
+ logger.warn('Warning: Failed to parse existing openclaw.json, starting fresh.');
171
+ }
172
+ }
173
+
174
+ let modified = false;
175
+
176
+ // Ensure gateway.bind = lan
177
+ if (!config.gateway) config.gateway = {};
178
+ if (config.gateway.bind !== 'lan') {
179
+ config.gateway.bind = 'lan';
180
+ modified = true;
181
+ }
182
+
183
+ // Ensure logging.file is correct
184
+ const expectedLogFile = path.join(tmpOpenClawDir, 'openclaw-YYYY-MM-DD.log');
185
+ if (!config.logging) config.logging = {};
186
+ if (!config.logging.level) {
187
+ config.logging.level = 'info';
188
+ modified = true;
189
+ }
190
+ if (config.logging.file !== expectedLogFile) {
191
+ config.logging.file = expectedLogFile;
192
+ modified = true;
193
+ }
194
+
195
+ if (modified || !fs.existsSync(openclawConfigPath)) {
196
+ safeWriteFileSync(openclawConfigPath, JSON.stringify(config, null, 2), 'utf8');
197
+ console.log(' ✓ Updated openclaw.json config');
198
+ } else {
199
+ console.log(' ✓ openclaw.json config is up to date');
200
+ }
201
+
202
+ const wakeLockScript = path.join(configDir, 'wakelock.sh');
203
+ const wakeLockContent = `#!/bin/bash
204
+ termux-wake-lock
205
+ trap "termux-wake-unlock" EXIT
206
+ exec "$@"
207
+ `;
208
+
209
+ safeWriteFileSync(wakeLockScript, wakeLockContent, 'utf8');
210
+ setSecurePermissions(wakeLockScript, '750');
211
+
212
+ // Copy overlay_daemon.py to HOME for easy access
213
+ try {
214
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
215
+ const pkgRoot = path.join(__dirname, '..');
216
+ const sourceOverlay = path.join(pkgRoot, 'overlay_daemon.py');
217
+ const destOverlay = path.join(HOME, 'overlay_daemon.py');
218
+
219
+ if (fs.existsSync(sourceOverlay)) {
220
+ fs.copyFileSync(sourceOverlay, destOverlay);
221
+ setSecurePermissions(destOverlay, '750');
222
+ console.log(` ✓ Copied overlay_daemon.py to ${destOverlay}`);
223
+ }
224
+ } catch (err) {
225
+ logger.warn('Failed to copy overlay_daemon.py:', err);
226
+ }
227
+
228
+ return true;
220
229
  }
221
230
 
222
- export function getInstallStatus() {
223
- let hasProot = false;
224
- try {
225
- safeExecSync('command -v proot-distro', { stdio: 'pipe', timeout: 5000 });
226
- hasProot = true;
227
- } catch (err) {
228
- logger.debug('Proot-distro check failed:', err.message);
229
- }
230
-
231
- let hasUbuntu = false;
232
- try {
233
- hasUbuntu = fs.existsSync(path.join(PROOT_ROOTFS, 'ubuntu'));
234
- } catch (err) {
235
- logger.debug('Ubuntu check failed:', err.message);
236
- }
237
-
238
- let hasOpenClawInProot = false;
239
- if (hasUbuntu) {
240
- // Optimization: Check for binary file existence directly to avoid expensive proot-distro login
241
- const ubuntuFsRoot = path.join(PROOT_ROOTFS, 'ubuntu');
242
- const possiblePaths = [
243
- path.join(ubuntuFsRoot, 'usr', 'local', 'bin', 'openclaw'),
244
- path.join(ubuntuFsRoot, 'usr', 'bin', 'openclaw')
245
- ];
246
-
247
- if (possiblePaths.some(p => fs.existsSync(p))) {
248
- hasOpenClawInProot = true;
249
- } else {
250
- // Fallback: Slow check using proot-distro (for custom installations)
251
- try {
252
- const checkCmd = 'test -f /usr/local/bin/openclaw || test -f /usr/bin/openclaw || command -v openclaw';
253
- safeExecSync(`proot-distro login ubuntu -- bash -c "${checkCmd}"`, { stdio: 'pipe', timeout: 15000 });
254
- hasOpenClawInProot = true;
255
- } catch (err) {
256
- logger.debug('OpenClaw in proot check failed:', err.message);
257
- }
258
- }
259
- }
260
-
261
- let hasBionicBypassInProot = false;
262
- try {
263
- const prootBypassPath = path.join(PROOT_ROOTFS, 'ubuntu', 'root', '.openclaw', 'bionic-bypass.js');
264
- hasBionicBypassInProot = fs.existsSync(prootBypassPath);
265
- } catch (err) {
266
- logger.debug('Bionic bypass in proot check failed:', err.message);
267
- }
268
-
269
- return {
270
- proot: hasProot,
271
- ubuntu: hasUbuntu,
272
- openClawInProot: hasOpenClawInProot,
273
- bionicBypassInProot: hasBionicBypassInProot,
274
- bionicBypass: fs.existsSync(getBypassScriptPath()),
275
- nodeOptions: process.env.NODE_OPTIONS?.includes('bionic-bypass') || false,
276
- openClaw: (() => {
277
- try {
278
- safeExecSync('command -v openclaw', { stdio: 'pipe', timeout: 5000 });
279
- return true;
280
- } catch (err) {
281
- logger.debug('OpenClaw check failed:', err.message);
282
- return false;
283
- }
284
- })(),
285
- python: (() => {
286
- try {
287
- safeExecSync('command -v python', { stdio: 'pipe', timeout: 5000 });
288
- return true;
289
- } catch (err) {
290
- logger.debug('Python check failed:', err.message);
291
- return false;
292
- }
293
- })(),
294
- termuxGui: (() => {
295
- try {
296
- safeExecSync('python -c "import termuxgui"', { stdio: 'pipe', timeout: 5000 });
297
- return true;
298
- } catch (err) {
299
- logger.debug('Termux GUI check failed:', err.message);
300
- return false;
301
- }
302
- })(),
303
- termuxApi: (() => {
304
- try {
305
- safeExecSync('command -v termux-wake-lock', { stdio: 'pipe', timeout: 5000 });
306
- return true;
307
- } catch (err) {
308
- logger.debug('Termux API check failed:', err.message);
309
- return false;
310
- }
311
- })()
312
- };
231
+ export function getInstallStatus() {
232
+ let hasProot = false;
233
+ try {
234
+ safeExecSync('command -v proot-distro', { stdio: 'pipe', timeout: 5000 });
235
+ hasProot = true;
236
+ } catch (err) {
237
+ logger.debug('Proot-distro check failed:', err.message);
238
+ }
239
+
240
+ let hasUbuntu = false;
241
+ try {
242
+ hasUbuntu = fs.existsSync(path.join(PROOT_ROOTFS, 'ubuntu'));
243
+ } catch (err) {
244
+ logger.debug('Ubuntu check failed:', err.message);
245
+ }
246
+
247
+ let hasOpenClawInProot = false;
248
+ if (hasUbuntu) {
249
+ // Optimization: Check for binary file existence directly to avoid expensive proot-distro login
250
+ const ubuntuFsRoot = path.join(PROOT_ROOTFS, 'ubuntu');
251
+ const possiblePaths = [
252
+ path.join(ubuntuFsRoot, 'usr', 'local', 'bin', 'openclaw'),
253
+ path.join(ubuntuFsRoot, 'usr', 'bin', 'openclaw')
254
+ ];
255
+
256
+ if (possiblePaths.some(p => fs.existsSync(p))) {
257
+ hasOpenClawInProot = true;
258
+ } else {
259
+ // Fallback: Slow check using proot-distro (for custom installations)
260
+ try {
261
+ const checkCmd = 'test -f /usr/local/bin/openclaw || test -f /usr/bin/openclaw || command -v openclaw';
262
+ safeExecSync(`proot-distro login ubuntu -- bash -c "${checkCmd}"`, { stdio: 'pipe', timeout: 15000 });
263
+ hasOpenClawInProot = true;
264
+ } catch (err) {
265
+ logger.debug('OpenClaw in proot check failed:', err.message);
266
+ }
267
+ }
268
+ }
269
+
270
+ let hasBionicBypassInProot = false;
271
+ try {
272
+ const prootBypassPath = path.join(PROOT_ROOTFS, 'ubuntu', 'root', '.openclaw', 'bionic-bypass.js');
273
+ hasBionicBypassInProot = fs.existsSync(prootBypassPath);
274
+ } catch (err) {
275
+ logger.debug('Bionic bypass in proot check failed:', err.message);
276
+ }
277
+
278
+ return {
279
+ proot: hasProot,
280
+ ubuntu: hasUbuntu,
281
+ openClawInProot: hasOpenClawInProot,
282
+ bionicBypassInProot: hasBionicBypassInProot,
283
+ bionicBypass: fs.existsSync(getBypassScriptPath()),
284
+ nodeOptions: process.env.NODE_OPTIONS?.includes('bionic-bypass') || false,
285
+ openClaw: (() => {
286
+ try {
287
+ safeExecSync('command -v openclaw', { stdio: 'pipe', timeout: 5000 });
288
+ return true;
289
+ } catch (err) {
290
+ logger.debug('OpenClaw check failed:', err.message);
291
+ return false;
292
+ }
293
+ })(),
294
+ python: (() => {
295
+ try {
296
+ safeExecSync('command -v python', { stdio: 'pipe', timeout: 5000 });
297
+ return true;
298
+ } catch (err) {
299
+ logger.debug('Python check failed:', err.message);
300
+ return false;
301
+ }
302
+ })(),
303
+ termuxGui: (() => {
304
+ try {
305
+ safeExecSync('python -c "import termuxgui"', { stdio: 'pipe', timeout: 5000 });
306
+ return true;
307
+ } catch (err) {
308
+ logger.debug('Termux GUI check failed:', err.message);
309
+ return false;
310
+ }
311
+ })(),
312
+ termuxApi: (() => {
313
+ try {
314
+ safeExecSync('command -v termux-wake-lock', { stdio: 'pipe', timeout: 5000 });
315
+ return true;
316
+ } catch (err) {
317
+ logger.debug('Termux API check failed:', err.message);
318
+ return false;
319
+ }
320
+ })()
321
+ };
313
322
  }
314
323
 
315
324
  export function installProot() {
@@ -334,58 +343,58 @@ export function installUbuntu() {
334
343
  }
335
344
  }
336
345
 
337
- export function setupProotUbuntu() {
338
- console.log('Setting up Node.js and OpenClaw in Ubuntu...');
339
-
340
- console.log('\n⚠️ IMPORTANT: COMPILATION WARNING ⚠️');
341
- console.log('OpenClaw depends on llama.cpp, which must be compiled from source.');
342
- console.log('This process can take 15-30 MINUTES on a mobile device.');
343
- console.log('Please be patient and DO NOT exit the installation.');
344
- console.log('It may look stuck at "make" or "g++" - this is normal.\n');
345
-
346
- // Wait a moment for the user to read
347
- safeExecSync('sleep 5', { stdio: 'inherit', timeout: 10000 });
348
-
349
- const setupScript = `
350
- set -e
351
- apt update
352
- sleep 2
353
- apt upgrade -y
354
- sleep 2
355
- apt install -y curl wget git build-essential python3
356
- sleep 2
357
- curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
358
- apt install -y nodejs
359
- sleep 2
360
- npm install -g npm@latest
361
- sleep 2
362
- npm uninstall -g openclaw
363
- sleep 2
364
- npm install -g openclaw@latest
365
- sleep 2
366
-
367
- # Pre-configure openclaw.json
368
- mkdir -p /root/.openclaw
369
- cat > /root/.openclaw/openclaw.json << 'EOF'
370
- {
371
- "gateway": {
372
- "bind": "lan"
373
- },
374
- "logging": {
375
- "level": "info",
376
- "file": "/root/.openclaw/openclaw-YYYY-MM-DD.log"
377
- }
378
- }
379
- EOF
380
- `;
381
-
382
- try {
383
- safeExecSync(`proot-distro login ubuntu -- bash -c '${setupScript}'`, { stdio: 'inherit', timeout: 3600000 });
384
- return true;
385
- } catch (err) {
386
- logger.error('Failed to setup Ubuntu:', err);
387
- return false;
388
- }
346
+ export function setupProotUbuntu() {
347
+ console.log('Setting up Node.js and OpenClaw in Ubuntu...');
348
+
349
+ console.log('\n⚠️ IMPORTANT: COMPILATION WARNING ⚠️');
350
+ console.log('OpenClaw depends on llama.cpp, which must be compiled from source.');
351
+ console.log('This process can take 15-30 MINUTES on a mobile device.');
352
+ console.log('Please be patient and DO NOT exit the installation.');
353
+ console.log('It may look stuck at "make" or "g++" - this is normal.\n');
354
+
355
+ // Wait a moment for the user to read
356
+ safeExecSync('sleep 5', { stdio: 'inherit', timeout: 10000 });
357
+
358
+ const setupScript = `
359
+ set -e
360
+ apt update
361
+ sleep 2
362
+ apt upgrade -y
363
+ sleep 2
364
+ apt install -y curl wget git build-essential python3
365
+ sleep 2
366
+ curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
367
+ apt install -y nodejs
368
+ sleep 2
369
+ npm install -g npm@latest
370
+ sleep 2
371
+ npm uninstall -g openclaw
372
+ sleep 2
373
+ npm install -g openclaw@latest
374
+ sleep 2
375
+
376
+ # Pre-configure openclaw.json
377
+ mkdir -p /root/.openclaw
378
+ cat > /root/.openclaw/openclaw.json << 'EOF'
379
+ {
380
+ "gateway": {
381
+ "bind": "lan"
382
+ },
383
+ "logging": {
384
+ "level": "info",
385
+ "file": "/root/.openclaw/openclaw-YYYY-MM-DD.log"
386
+ }
387
+ }
388
+ EOF
389
+ `;
390
+
391
+ try {
392
+ safeExecSync(`proot-distro login ubuntu -- bash -c '${setupScript}'`, { stdio: 'inherit', timeout: 3600000 });
393
+ return true;
394
+ } catch (err) {
395
+ logger.error('Failed to setup Ubuntu:', err);
396
+ return false;
397
+ }
389
398
  }
390
399
 
391
400
  export function setupBionicBypassInProot() {