@aiyiran/myclaw 1.0.124 → 1.0.126
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.
- package/package.json +1 -1
- package/patch-manifest.json +1 -1
- package/wsl2.js +84 -59
package/package.json
CHANGED
package/patch-manifest.json
CHANGED
package/wsl2.js
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
* MyClaw WSL2 一键安装器
|
|
6
6
|
* ============================================================================
|
|
7
7
|
*
|
|
8
|
-
*
|
|
8
|
+
* 采用"固定流程 + 状态标记"机制,避免使用容易出错的环境嗅探(wsl --status)。
|
|
9
9
|
* 标记文件:~/.myclaw_wsl_state
|
|
10
10
|
*
|
|
11
|
-
* Phase 1:
|
|
12
|
-
* Phase 2:
|
|
11
|
+
* Phase 1: 启用底层功能 + 安装 WSL + 下载 Linux 镜像 → 需要重启
|
|
12
|
+
* Phase 2: 导入已下载的 Linux 环境 → 自动启动 Gateway(极快)
|
|
13
13
|
* ============================================================================
|
|
14
14
|
*/
|
|
15
15
|
|
|
@@ -34,6 +34,7 @@ const C = isWindows
|
|
|
34
34
|
: { r: '\x1b[31m', g: '\x1b[32m', y: '\x1b[33m', b: '\x1b[34m', nc: '\x1b[0m' };
|
|
35
35
|
|
|
36
36
|
const STATE_FILE = path.join(os.homedir(), '.myclaw_wsl_state');
|
|
37
|
+
const MARKER_PATH_PS = STATE_FILE.replace(/\\/g, '\\\\');
|
|
37
38
|
|
|
38
39
|
// ============================================================================
|
|
39
40
|
// 工具函数
|
|
@@ -51,7 +52,6 @@ function setState(state) {
|
|
|
51
52
|
}
|
|
52
53
|
|
|
53
54
|
function launchElevatedPS(script) {
|
|
54
|
-
// 把脚本写到临时文件(避免 Windows 命令行长度限制)
|
|
55
55
|
const tmpDir = process.env.LOCALAPPDATA
|
|
56
56
|
? path.join(process.env.LOCALAPPDATA, 'myclaw')
|
|
57
57
|
: path.join(os.tmpdir(), 'myclaw');
|
|
@@ -62,7 +62,6 @@ function launchElevatedPS(script) {
|
|
|
62
62
|
const BOM = '\uFEFF';
|
|
63
63
|
fs.writeFileSync(scriptPath, BOM + script, 'utf8');
|
|
64
64
|
|
|
65
|
-
// 用 -NoExit 确保即使脚本出错窗口也不会关闭
|
|
66
65
|
const escaped = scriptPath.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
67
66
|
const cmd = `powershell -Command "Start-Process powershell -ArgumentList @('-NoProfile','-ExecutionPolicy','Bypass','-NoExit','-File','${escaped}') -Verb RunAs"`;
|
|
68
67
|
|
|
@@ -127,12 +126,18 @@ if ($resolved) {
|
|
|
127
126
|
if ($userInput) {
|
|
128
127
|
Write-Host ' 将改为从网络下载...'
|
|
129
128
|
}
|
|
130
|
-
Write-Host '
|
|
129
|
+
Write-Host ''
|
|
130
|
+
Write-Host ' ============================================================='
|
|
131
|
+
Write-Host ' [防卡住警告] 正在从网络下载,带有进度条,请耐心等待文件较大。'
|
|
132
|
+
Write-Host ' ⚠️ 请切勿使用鼠标点击此窗口内部!'
|
|
133
|
+
Write-Host ' ⚠️ 在 Windows 的机制下,只要用鼠标点一下窗口,下载就会被瞬间暂停冻结!'
|
|
134
|
+
Write-Host ' ⚠️ 如果你觉得进度条卡住不动了,请在键盘上按一下【回车键】即可解冻!'
|
|
135
|
+
Write-Host ' ============================================================='
|
|
131
136
|
try {
|
|
132
|
-
Start-BitsTransfer -Source '${cdnUrl}' -Destination ${destVar} -Description '下载
|
|
137
|
+
Start-BitsTransfer -Source '${cdnUrl}' -Destination ${destVar} -Description '下载 ${desc}' -DisplayName 'OpenClaw'
|
|
133
138
|
Write-Host ' 下载完成!'
|
|
134
139
|
} catch {
|
|
135
|
-
Write-Host ' [失败] 下载失败,请检查网络后重试
|
|
140
|
+
Write-Host ' [失败] 下载失败,请检查网络后重试'
|
|
136
141
|
throw '下载失败'
|
|
137
142
|
}
|
|
138
143
|
}
|
|
@@ -140,16 +145,17 @@ if ($resolved) {
|
|
|
140
145
|
}
|
|
141
146
|
|
|
142
147
|
// ============================================================================
|
|
143
|
-
// Phase 1: 启用功能 + 安装 WSL
|
|
148
|
+
// Phase 1: 启用功能 + 安装 WSL + 下载 Linux 镜像(全部在重启前完成)
|
|
144
149
|
// ============================================================================
|
|
145
150
|
|
|
146
151
|
function runPhase1() {
|
|
147
152
|
console.log('');
|
|
148
|
-
console.log('[当前进度] WSL 功能
|
|
149
|
-
console.log(' WSL 组件
|
|
150
|
-
console.log(' Linux
|
|
153
|
+
console.log('[当前进度] WSL 功能 ' + C.y + '[安装/覆盖]' + C.nc);
|
|
154
|
+
console.log(' WSL 组件 ' + C.y + '[安装/重置]' + C.nc);
|
|
155
|
+
console.log(' Linux 镜像 ' + C.y + '[待下载]' + C.nc);
|
|
156
|
+
console.log(' Linux 环境 ' + C.r + '[未安装]' + C.nc);
|
|
151
157
|
console.log('');
|
|
152
|
-
console.log('阶段 1/2:
|
|
158
|
+
console.log('阶段 1/2: 配置系统组件 + 下载全部安装素材');
|
|
153
159
|
console.log(' 完成后需要 ' + C.y + '重启电脑' + C.nc);
|
|
154
160
|
console.log('');
|
|
155
161
|
console.log('[' + C.y + '注意' + C.nc + '] 请在 UAC 弹窗中点击【是】');
|
|
@@ -163,6 +169,14 @@ function runPhase1() {
|
|
|
163
169
|
'wsl_full.msi'
|
|
164
170
|
);
|
|
165
171
|
|
|
172
|
+
const askTar = makeAskLocalOrCDN(
|
|
173
|
+
'拖拽 tar 包或回车下载',
|
|
174
|
+
'$tarPath',
|
|
175
|
+
WSL_CDN.rootfs,
|
|
176
|
+
'Linux 环境包 (openclaw-rootfs.tar)',
|
|
177
|
+
'openclaw-rootfs.tar'
|
|
178
|
+
);
|
|
179
|
+
|
|
166
180
|
const ps = `
|
|
167
181
|
$ErrorActionPreference = 'Continue'
|
|
168
182
|
$Host.UI.RawUI.WindowTitle = 'MyClaw WSL2 Installer - Phase 1'
|
|
@@ -170,14 +184,16 @@ try {
|
|
|
170
184
|
Write-Host ''
|
|
171
185
|
Write-Host '========================================'
|
|
172
186
|
Write-Host ' MyClaw WSL2 安装 - 阶段 1/2'
|
|
187
|
+
Write-Host ' 配置系统 + 下载全部安装素材'
|
|
173
188
|
Write-Host '========================================'
|
|
174
189
|
Write-Host ''
|
|
175
190
|
|
|
176
|
-
$dir = "$env:LOCALAPPDATA
|
|
191
|
+
$dir = "$env:LOCALAPPDATA\\\\myclaw"
|
|
177
192
|
New-Item -ItemType Directory -Force -Path $dir | Out-Null
|
|
178
|
-
$msi = "$dir
|
|
193
|
+
$msi = "$dir\\\\wsl_full.msi"
|
|
194
|
+
$tarPath = "$dir\\\\openclaw-rootfs.tar"
|
|
179
195
|
|
|
180
|
-
Write-Host '[1/
|
|
196
|
+
Write-Host '[1/5] 启用 Windows Subsystem for Linux...'
|
|
181
197
|
try {
|
|
182
198
|
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart | Out-Null
|
|
183
199
|
Write-Host ' [OK]'
|
|
@@ -186,7 +202,7 @@ try {
|
|
|
186
202
|
}
|
|
187
203
|
Write-Host ''
|
|
188
204
|
|
|
189
|
-
Write-Host '[2/
|
|
205
|
+
Write-Host '[2/5] 启用虚拟机平台...'
|
|
190
206
|
try {
|
|
191
207
|
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart | Out-Null
|
|
192
208
|
Write-Host ' [OK]'
|
|
@@ -195,14 +211,13 @@ try {
|
|
|
195
211
|
}
|
|
196
212
|
Write-Host ''
|
|
197
213
|
|
|
198
|
-
Write-Host '[3/
|
|
199
|
-
# 移除文件以保证不做本地缓存
|
|
214
|
+
Write-Host '[3/5] 获取 WSL 安装包...'
|
|
200
215
|
if (Test-Path $msi) { Remove-Item $msi -Force }
|
|
201
216
|
|
|
202
217
|
${askMsi}
|
|
203
218
|
|
|
204
219
|
Write-Host ''
|
|
205
|
-
Write-Host '[4/
|
|
220
|
+
Write-Host '[4/5] 强制覆盖安装 WSL...'
|
|
206
221
|
try {
|
|
207
222
|
Start-Process msiexec.exe -ArgumentList @('/i', $msi, '/quiet', '/norestart') -Wait -NoNewWindow
|
|
208
223
|
if ($LASTEXITCODE -ne 0 -and $LASTEXITCODE -ne 3010) {
|
|
@@ -215,20 +230,27 @@ try {
|
|
|
215
230
|
throw 'MSI 安装失败'
|
|
216
231
|
}
|
|
217
232
|
|
|
218
|
-
#
|
|
233
|
+
# MSI 装完立即删除
|
|
219
234
|
if (Test-Path $msi) { Remove-Item $msi -Force }
|
|
235
|
+
Write-Host ''
|
|
236
|
+
|
|
237
|
+
Write-Host '[5/5] 下载 Linux 环境镜像...'
|
|
238
|
+
Write-Host ' (此文件较大,下载完成后会保留到重启后使用)'
|
|
239
|
+
if (Test-Path $tarPath) { Remove-Item $tarPath -Force }
|
|
240
|
+
|
|
241
|
+
${askTar}
|
|
220
242
|
|
|
221
|
-
#
|
|
222
|
-
$markerPath = "${
|
|
243
|
+
# 写入状态标记(使用普通用户路径)
|
|
244
|
+
$markerPath = "${MARKER_PATH_PS}"
|
|
223
245
|
Out-File -FilePath "$markerPath" -InputObject "phase1-done" -Encoding utf8 -Force
|
|
224
246
|
|
|
225
247
|
Write-Host ''
|
|
226
248
|
Write-Host '========================================'
|
|
227
|
-
Write-Host ' 阶段 1/2 完成!'
|
|
249
|
+
Write-Host ' 阶段 1/2 完成! 所有文件已准备就绪!'
|
|
228
250
|
Write-Host ''
|
|
229
251
|
Write-Host ' >>> 请立即 [重启电脑] <<<'
|
|
230
252
|
Write-Host ''
|
|
231
|
-
Write-Host '
|
|
253
|
+
Write-Host ' 重启后请点击桌面上的 [龙虾图标] 继续安装'
|
|
232
254
|
Write-Host '========================================'
|
|
233
255
|
|
|
234
256
|
} catch {
|
|
@@ -247,33 +269,26 @@ Write-Host '========================================'
|
|
|
247
269
|
if (launchElevatedPS(ps)) {
|
|
248
270
|
console.log('[' + C.g + '已启动' + C.nc + '] 请查看新弹出的蓝色窗口');
|
|
249
271
|
console.log('');
|
|
250
|
-
console.log('执行完请 ' + C.y + '重启电脑' + C.nc + '
|
|
272
|
+
console.log('执行完请 ' + C.y + '重启电脑' + C.nc + ',然后点击桌面上的 ' + C.y + '龙虾图标' + C.nc + ' 继续安装');
|
|
251
273
|
console.log('');
|
|
252
274
|
}
|
|
253
275
|
}
|
|
254
276
|
|
|
255
277
|
// ============================================================================
|
|
256
|
-
// Phase 2:
|
|
278
|
+
// Phase 2: 导入已下载的 Linux 环境(重启后,纯本地操作,极快)
|
|
257
279
|
// ============================================================================
|
|
258
280
|
|
|
259
281
|
function runPhase2() {
|
|
260
282
|
console.log('');
|
|
261
|
-
console.log('[当前进度] WSL 功能
|
|
262
|
-
console.log(' WSL 组件
|
|
263
|
-
console.log(' Linux
|
|
283
|
+
console.log('[当前进度] WSL 功能 ' + C.g + '[已就绪]' + C.nc);
|
|
284
|
+
console.log(' WSL 组件 ' + C.g + '[已就绪]' + C.nc);
|
|
285
|
+
console.log(' Linux 镜像 ' + C.g + '[已下载]' + C.nc);
|
|
286
|
+
console.log(' Linux 环境 ' + C.y + '[待导入]' + C.nc);
|
|
264
287
|
console.log('');
|
|
265
|
-
console.log('即将导入预制 Linux
|
|
288
|
+
console.log('即将导入预制 Linux 环境(纯本地操作,很快)...');
|
|
266
289
|
console.log('[' + C.y + '注意' + C.nc + '] 请在 UAC 弹窗中点击【是】');
|
|
267
290
|
console.log('');
|
|
268
291
|
|
|
269
|
-
const askTar = makeAskLocalOrCDN(
|
|
270
|
-
'拖拽 tar 包或回车下载',
|
|
271
|
-
'$tarPath',
|
|
272
|
-
WSL_CDN.rootfs,
|
|
273
|
-
'Linux 环境包 (openclaw-rootfs.tar)',
|
|
274
|
-
'openclaw-rootfs.tar'
|
|
275
|
-
);
|
|
276
|
-
|
|
277
292
|
const ps = `
|
|
278
293
|
$ErrorActionPreference = 'Continue'
|
|
279
294
|
$Host.UI.RawUI.WindowTitle = 'MyClaw WSL2 Installer - Phase 2'
|
|
@@ -285,27 +300,37 @@ Write-Host ' 导入预制 Linux 环境'
|
|
|
285
300
|
Write-Host '========================================'
|
|
286
301
|
Write-Host ''
|
|
287
302
|
|
|
288
|
-
$dir = "$env:LOCALAPPDATA
|
|
303
|
+
$dir = "$env:LOCALAPPDATA\\\\myclaw"
|
|
289
304
|
New-Item -ItemType Directory -Force -Path $dir | Out-Null
|
|
290
|
-
$tarPath = "$dir
|
|
305
|
+
$tarPath = "$dir\\\\openclaw-rootfs.tar"
|
|
306
|
+
$distroName = 'OpenClaw'
|
|
307
|
+
$installDir = "$dir\\\\OpenClaw"
|
|
308
|
+
$installed = $false
|
|
291
309
|
|
|
292
|
-
Write-Host '[1/
|
|
310
|
+
Write-Host '[1/4] 设置 WSL2 为默认版本...'
|
|
293
311
|
try { wsl --set-default-version 2 2>$null } catch {}
|
|
294
312
|
Write-Host ' [OK]'
|
|
295
313
|
Write-Host ''
|
|
296
314
|
|
|
297
|
-
Write-Host '[2/
|
|
298
|
-
$
|
|
299
|
-
$
|
|
300
|
-
$
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
${
|
|
306
|
-
|
|
307
|
-
|
|
315
|
+
Write-Host '[2/4] 检查 Linux 镜像文件...'
|
|
316
|
+
if (Test-Path $tarPath) {
|
|
317
|
+
$size = (Get-Item $tarPath).Length / 1MB
|
|
318
|
+
Write-Host " 找到本地镜像 ($([math]::Round($size, 1)) MB)"
|
|
319
|
+
Write-Host ' [OK]'
|
|
320
|
+
} else {
|
|
321
|
+
Write-Host ' [警告] 未找到已下载的镜像文件,需要重新获取...'
|
|
322
|
+
Write-Host ''
|
|
323
|
+
${makeAskLocalOrCDN(
|
|
324
|
+
'拖拽 tar 包或回车下载',
|
|
325
|
+
'$tarPath',
|
|
326
|
+
WSL_CDN.rootfs,
|
|
327
|
+
'Linux 环境包 (openclaw-rootfs.tar)',
|
|
328
|
+
'openclaw-rootfs.tar'
|
|
329
|
+
)}
|
|
330
|
+
}
|
|
331
|
+
Write-Host ''
|
|
308
332
|
|
|
333
|
+
Write-Host '[3/4] 导入 Linux 环境 (可能需要几分钟)...'
|
|
309
334
|
Write-Host ' 清理旧版本...'
|
|
310
335
|
try { wsl --unregister $distroName 2>$null } catch {}
|
|
311
336
|
Write-Host ' [OK]'
|
|
@@ -324,10 +349,10 @@ try {
|
|
|
324
349
|
}
|
|
325
350
|
Write-Host ''
|
|
326
351
|
|
|
327
|
-
# 导入完毕清理
|
|
352
|
+
# 导入完毕清理 tar 文件
|
|
328
353
|
if (Test-Path $tarPath) { Remove-Item $tarPath -Force }
|
|
329
354
|
|
|
330
|
-
Write-Host '[
|
|
355
|
+
Write-Host '[4/4] 验证安装结果...'
|
|
331
356
|
try {
|
|
332
357
|
$result = wsl -l -v 2>&1 | Out-String
|
|
333
358
|
Write-Host $result
|
|
@@ -342,7 +367,7 @@ if ($installed) {
|
|
|
342
367
|
Write-Host '========================================'
|
|
343
368
|
Write-Host ''
|
|
344
369
|
|
|
345
|
-
$markerPath = "${
|
|
370
|
+
$markerPath = "${MARKER_PATH_PS}"
|
|
346
371
|
Out-File -FilePath "$markerPath" -InputObject "phase2-done" -Encoding utf8 -Force
|
|
347
372
|
|
|
348
373
|
Write-Host '[镜像信息]'
|
|
@@ -356,7 +381,7 @@ if ($installed) {
|
|
|
356
381
|
|
|
357
382
|
wsl -d $distroName -- myclaw launch
|
|
358
383
|
} else {
|
|
359
|
-
Write-Host ' [失败]
|
|
384
|
+
Write-Host ' [失败] 请截图此窗口并联系老师'
|
|
360
385
|
Write-Host '========================================'
|
|
361
386
|
}
|
|
362
387
|
|
|
@@ -391,7 +416,7 @@ function run() {
|
|
|
391
416
|
process.exit(0);
|
|
392
417
|
}
|
|
393
418
|
|
|
394
|
-
//
|
|
419
|
+
// 隐藏的高级玩家后门
|
|
395
420
|
if (process.argv.includes('--force-phase1')) {
|
|
396
421
|
setState('needs-features');
|
|
397
422
|
}
|
|
@@ -417,7 +442,7 @@ function run() {
|
|
|
417
442
|
console.log('(运行 wsl -l -v 查看详情)');
|
|
418
443
|
}
|
|
419
444
|
console.log('');
|
|
420
|
-
console.log('
|
|
445
|
+
console.log('点击桌面上的 ' + C.y + '龙虾图标' + C.nc + ' 即可启动。');
|
|
421
446
|
console.log('');
|
|
422
447
|
|
|
423
448
|
const readline = require('readline');
|