@aiyiran/myclaw 1.0.164 → 1.0.165
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/restrict.js +68 -49
package/package.json
CHANGED
package/restrict.js
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* 步骤 3: 在 Windows 桌面创建快捷方式,指向 \\wsl.localhost\OpenClaw\root\.openclaw\workspace
|
|
12
12
|
*
|
|
13
13
|
* 使用方法:
|
|
14
|
-
* myclaw
|
|
14
|
+
* myclaw safe
|
|
15
15
|
*
|
|
16
16
|
* 前提:OpenClaw WSL2 发行版已安装(myclaw wsl2 完成)
|
|
17
17
|
* ============================================================================
|
|
@@ -33,8 +33,8 @@ const C = isWindows
|
|
|
33
33
|
: { r: '\x1b[31m', g: '\x1b[32m', y: '\x1b[33m', b: '\x1b[34m', nc: '\x1b[0m' };
|
|
34
34
|
|
|
35
35
|
const DISTRO_NAME = 'OpenClaw';
|
|
36
|
-
const WORKSPACE_PATH = '/root/.openclaw/workspace/myclaw';
|
|
37
|
-
const SHORTCUT_TARGET = '/root/.openclaw/workspace';
|
|
36
|
+
const WORKSPACE_PATH = '/root/.openclaw/workspace/myclaw';
|
|
37
|
+
const SHORTCUT_TARGET = '/root/.openclaw/workspace';
|
|
38
38
|
|
|
39
39
|
// ============================================================================
|
|
40
40
|
// 工具函数
|
|
@@ -46,10 +46,10 @@ function printSuccess(msg) { console.log(C.g + '[成功]' + C.nc + ' ' + msg); }
|
|
|
46
46
|
function printWarning(msg) { console.log(C.y + '[警告]' + C.nc + ' ' + msg); }
|
|
47
47
|
function printError(msg) { console.error(C.r + '[错误]' + C.nc + ' ' + msg); }
|
|
48
48
|
|
|
49
|
-
// 在 WSL
|
|
49
|
+
// 在 WSL 中执行命令,返回 stdout
|
|
50
50
|
function wslExec(cmd) {
|
|
51
51
|
try {
|
|
52
|
-
return execSync('wsl -d ' + DISTRO_NAME + ' --
|
|
52
|
+
return execSync('wsl -d ' + DISTRO_NAME + ' -- ' + cmd, {
|
|
53
53
|
encoding: 'utf8',
|
|
54
54
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
55
55
|
}).trim();
|
|
@@ -58,10 +58,21 @@ function wslExec(cmd) {
|
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
//
|
|
62
|
-
|
|
61
|
+
// 写临时 shell 脚本到 WSL 内,然后以 root 执行
|
|
62
|
+
// 这样避免 Windows cmd.exe 对管道/重定向的干扰
|
|
63
|
+
function wslRunScriptAsRoot(scriptContent) {
|
|
64
|
+
// 把脚本写到 WSL 的 /tmp 下
|
|
65
|
+
const tmpScript = '/tmp/myclaw_safe_setup.sh';
|
|
66
|
+
const b64 = Buffer.from(scriptContent).toString('base64');
|
|
67
|
+
|
|
63
68
|
try {
|
|
64
|
-
|
|
69
|
+
// 写入脚本
|
|
70
|
+
execSync('wsl -d ' + DISTRO_NAME + ' -u root -- bash -c "echo ' + b64 + ' | base64 -d > ' + tmpScript + '"', {
|
|
71
|
+
encoding: 'utf8',
|
|
72
|
+
stdio: 'pipe',
|
|
73
|
+
});
|
|
74
|
+
// 执行脚本
|
|
75
|
+
execSync('wsl -d ' + DISTRO_NAME + ' -u root -- bash ' + tmpScript, {
|
|
65
76
|
encoding: 'utf8',
|
|
66
77
|
stdio: 'pipe',
|
|
67
78
|
});
|
|
@@ -81,7 +92,6 @@ function checkPrerequisites() {
|
|
|
81
92
|
process.exit(1);
|
|
82
93
|
}
|
|
83
94
|
|
|
84
|
-
// 检查 wsl 命令
|
|
85
95
|
try {
|
|
86
96
|
execSync('wsl --version', { stdio: 'pipe' });
|
|
87
97
|
} catch {
|
|
@@ -89,7 +99,6 @@ function checkPrerequisites() {
|
|
|
89
99
|
process.exit(1);
|
|
90
100
|
}
|
|
91
101
|
|
|
92
|
-
// 检查 OpenClaw 发行版
|
|
93
102
|
try {
|
|
94
103
|
const list = execSync('wsl -l -q', { encoding: 'utf16le' });
|
|
95
104
|
if (!list.includes(DISTRO_NAME)) {
|
|
@@ -129,28 +138,30 @@ function step1_createWorkspace() {
|
|
|
129
138
|
function step2_disableAutomount() {
|
|
130
139
|
printStep('步骤 2/3: 禁用自动挂载 Windows 盘符');
|
|
131
140
|
|
|
132
|
-
// 备份
|
|
133
|
-
wslExecRoot('cp /etc/wsl.conf /etc/wsl.conf.bak 2>/dev/null || true');
|
|
134
|
-
|
|
135
141
|
// 读取现有配置
|
|
136
142
|
const existing = wslExec('cat /etc/wsl.conf 2>/dev/null') || '';
|
|
137
143
|
|
|
138
144
|
let newContent;
|
|
139
145
|
if (existing.includes('[automount]')) {
|
|
140
|
-
// 替换已有 automount 段
|
|
141
146
|
newContent = existing.replace(
|
|
142
147
|
/\[automount\][^\[]*/,
|
|
143
148
|
'[automount]\nenabled = false\n'
|
|
144
149
|
);
|
|
145
150
|
} else {
|
|
146
|
-
// 追加
|
|
147
151
|
newContent = existing + (existing.endsWith('\n') ? '' : '\n') + '[automount]\nenabled = false\n';
|
|
148
152
|
}
|
|
149
153
|
|
|
150
|
-
//
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
|
|
154
|
+
// 构建一个完整的 shell 脚本,在 WSL 内执行
|
|
155
|
+
const script = [
|
|
156
|
+
'#!/bin/bash',
|
|
157
|
+
'cp /etc/wsl.conf /etc/wsl.conf.bak 2>/dev/null || true',
|
|
158
|
+
'cat > /etc/wsl.conf << \'MYCLAW_EOF\'',
|
|
159
|
+
newContent,
|
|
160
|
+
'MYCLAW_EOF',
|
|
161
|
+
].join('\n');
|
|
162
|
+
|
|
163
|
+
printInfo('正在写入 /etc/wsl.conf ...');
|
|
164
|
+
const ok = wslRunScriptAsRoot(script);
|
|
154
165
|
|
|
155
166
|
if (!ok) {
|
|
156
167
|
printError('写入 wsl.conf 失败');
|
|
@@ -161,10 +172,16 @@ function step2_disableAutomount() {
|
|
|
161
172
|
const verify = wslExec('cat /etc/wsl.conf 2>/dev/null') || '';
|
|
162
173
|
if (verify.includes('enabled = false') || verify.includes('enabled=false')) {
|
|
163
174
|
printSuccess('automount 已禁用');
|
|
175
|
+
printInfo('/etc/wsl.conf 内容:');
|
|
176
|
+
console.log('---');
|
|
177
|
+
console.log(verify);
|
|
178
|
+
console.log('---');
|
|
164
179
|
return true;
|
|
165
180
|
}
|
|
166
181
|
|
|
167
|
-
printError('
|
|
182
|
+
printError('配置验证失败,写入可能不完整');
|
|
183
|
+
printInfo('实际内容:');
|
|
184
|
+
console.log(verify || '(空)');
|
|
168
185
|
return false;
|
|
169
186
|
}
|
|
170
187
|
|
|
@@ -175,10 +192,8 @@ function step2_disableAutomount() {
|
|
|
175
192
|
function step3_createShortcut() {
|
|
176
193
|
printStep('步骤 3/3: 创建桌面快捷方式');
|
|
177
194
|
|
|
178
|
-
// \\wsl.localhost\OpenClaw\root\.openclaw\workspace
|
|
179
195
|
const wslPath = '\\\\wsl.localhost\\' + DISTRO_NAME + '\\' + SHORTCUT_TARGET.replace(/\//g, '\\');
|
|
180
196
|
|
|
181
|
-
// 找桌面路径(兼容中英文)
|
|
182
197
|
const desktopPath = path.join(os.homedir(), 'Desktop');
|
|
183
198
|
const desktopPathCN = path.join(os.homedir(), '桌面');
|
|
184
199
|
const shortcutDir = fs.existsSync(desktopPath) ? desktopPath
|
|
@@ -189,9 +204,8 @@ function step3_createShortcut() {
|
|
|
189
204
|
return false;
|
|
190
205
|
}
|
|
191
206
|
|
|
192
|
-
const shortcutPath = path.join(shortcutDir, '
|
|
207
|
+
const shortcutPath = path.join(shortcutDir, '我的私人龙虾.lnk');
|
|
193
208
|
|
|
194
|
-
// 写临时 .ps1 文件来创建快捷方式(避免复杂的命令行转义)
|
|
195
209
|
const tmpDir = path.join(process.env.LOCALAPPDATA || os.tmpdir(), 'myclaw');
|
|
196
210
|
try { fs.mkdirSync(tmpDir, { recursive: true }); } catch {}
|
|
197
211
|
const psFile = path.join(tmpDir, 'create-shortcut.ps1');
|
|
@@ -203,22 +217,12 @@ function step3_createShortcut() {
|
|
|
203
217
|
'$sc.Arguments = "' + wslPath + '"',
|
|
204
218
|
'$sc.WorkingDirectory = "' + wslPath + '"',
|
|
205
219
|
'$sc.Description = "OpenClaw Workspace"',
|
|
220
|
+
'$sc.IconLocation = "C:\\Windows\\explorer.exe,0"',
|
|
206
221
|
'$sc.Save()',
|
|
207
222
|
'',
|
|
208
|
-
'# 尝试下载图标',
|
|
209
|
-
'$iconDir = "' + tmpDir + '"',
|
|
210
|
-
'$iconPath = "$iconDir\\openclaw.ico"',
|
|
211
|
-
'try {',
|
|
212
|
-
' Invoke-WebRequest -Uri "https://cdn.yiranlaoshi.com/software/myclaw/openclaw.ico" -OutFile $iconPath -UseBasicParsing',
|
|
213
|
-
' $sc2 = $ws.CreateShortcut("' + shortcutPath + '")',
|
|
214
|
-
' $sc2.IconLocation = "$iconPath,0"',
|
|
215
|
-
' $sc2.Save()',
|
|
216
|
-
'} catch {}',
|
|
217
|
-
'',
|
|
218
223
|
'Write-Host "OK"',
|
|
219
224
|
].join('\r\n');
|
|
220
225
|
|
|
221
|
-
// UTF-8 BOM
|
|
222
226
|
fs.writeFileSync(psFile, '\uFEFF' + psContent, 'utf8');
|
|
223
227
|
|
|
224
228
|
try {
|
|
@@ -228,15 +232,14 @@ function step3_createShortcut() {
|
|
|
228
232
|
).trim();
|
|
229
233
|
|
|
230
234
|
if (result.includes('OK')) {
|
|
231
|
-
printSuccess('桌面快捷方式已创建:
|
|
235
|
+
printSuccess('桌面快捷方式已创建: 我的私人龙虾');
|
|
232
236
|
printInfo('双击即可打开工作目录');
|
|
233
237
|
return true;
|
|
234
238
|
}
|
|
235
239
|
} catch {
|
|
236
|
-
// 回退:创建 .url 文件
|
|
237
240
|
try {
|
|
238
241
|
const urlContent = '[InternetShortcut]\r\nURL=file:///' + wslPath.replace(/\\/g, '/') + '\r\n';
|
|
239
|
-
fs.writeFileSync(path.join(shortcutDir, '
|
|
242
|
+
fs.writeFileSync(path.join(shortcutDir, '我的私人龙虾.url'), urlContent, 'utf8');
|
|
240
243
|
printSuccess('桌面快捷方式已创建 (.url)');
|
|
241
244
|
return true;
|
|
242
245
|
} catch (err2) {
|
|
@@ -255,13 +258,13 @@ function step3_createShortcut() {
|
|
|
255
258
|
function run() {
|
|
256
259
|
console.log('');
|
|
257
260
|
console.log('========================================');
|
|
258
|
-
console.log(' MyClaw
|
|
261
|
+
console.log(' MyClaw 虚拟机屏蔽');
|
|
259
262
|
console.log('========================================');
|
|
260
263
|
console.log('');
|
|
261
264
|
console.log('此操作将:');
|
|
262
265
|
console.log(' 1. 在 WSL 内创建工作目录');
|
|
263
266
|
console.log(' 2. 禁用 WSL 自动挂载 Windows 盘符');
|
|
264
|
-
console.log(' 3. 在桌面创建快捷方式
|
|
267
|
+
console.log(' 3. 在桌面创建快捷方式');
|
|
265
268
|
console.log('');
|
|
266
269
|
console.log('效果:Linux 看不到 Windows 文件,但 Windows');
|
|
267
270
|
console.log(' 可以通过桌面快捷方式访问 WSL 工作目录。');
|
|
@@ -277,21 +280,37 @@ function run() {
|
|
|
277
280
|
printWarning('快捷方式创建失败,但不影响权限封锁');
|
|
278
281
|
}
|
|
279
282
|
|
|
280
|
-
// 完成提示
|
|
281
283
|
console.log('');
|
|
282
284
|
console.log('========================================');
|
|
283
|
-
printSuccess('
|
|
285
|
+
printSuccess('虚拟机屏蔽配置完成!');
|
|
284
286
|
console.log('========================================');
|
|
285
287
|
console.log('');
|
|
286
|
-
|
|
288
|
+
printInfo('正在重启 WSL2 使配置生效...');
|
|
287
289
|
console.log('');
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
290
|
+
|
|
291
|
+
try {
|
|
292
|
+
execSync('wsl --shutdown', { stdio: 'pipe', timeout: 15000 });
|
|
293
|
+
printSuccess('WSL2 已重启');
|
|
294
|
+
} catch {
|
|
295
|
+
printWarning('自动重启失败,请手动运行: wsl --shutdown');
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// 验证
|
|
299
|
+
console.log('');
|
|
300
|
+
console.log('验证中...');
|
|
301
|
+
try {
|
|
302
|
+
const check = wslExec('ls /mnt/c 2>&1');
|
|
303
|
+
if (!check || check.includes('cannot access') || check.includes('No such file')) {
|
|
304
|
+
printSuccess('验证通过: /mnt/c 不可访问,屏蔽生效!');
|
|
305
|
+
} else {
|
|
306
|
+
printWarning('/mnt/c 仍然可访问,可能需要再次 wsl --shutdown');
|
|
307
|
+
}
|
|
308
|
+
} catch {
|
|
309
|
+
printSuccess('验证通过: /mnt/c 不可访问');
|
|
310
|
+
}
|
|
311
|
+
|
|
291
312
|
console.log('');
|
|
292
|
-
|
|
293
|
-
console.log(' - WSL 内 ls /mnt/c → 应显示不存在');
|
|
294
|
-
console.log(' - 双击桌面「myclaw」→ 打开工作文件夹');
|
|
313
|
+
printInfo('双击桌面「我的私人龙虾」可打开工作文件夹');
|
|
295
314
|
console.log('');
|
|
296
315
|
}
|
|
297
316
|
|