@aiyiran/myclaw 1.0.161 → 1.0.162
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/index.js +2 -2
- package/package.json +1 -1
- package/restrict.js +107 -184
- package/scripts/restrict-wsl-access.sh +42 -150
- package/start.js +2 -2
package/index.js
CHANGED
|
@@ -1132,7 +1132,7 @@ function showHelp() {
|
|
|
1132
1132
|
console.log(' open 打开浏览器控制台(自动带 token)');
|
|
1133
1133
|
console.log(' fix 兜底修复(自动补装 WSL + Chrome,仅限 Windows)');
|
|
1134
1134
|
console.log(' wsl2 WSL2 一键安装/修复 (仅限 Windows, 可选: --cli)');
|
|
1135
|
-
console.log('
|
|
1135
|
+
console.log(' safe 开启虚拟机屏蔽 (禁止自动挂载 Windows 盘符)');
|
|
1136
1136
|
console.log(' bat 在桌面生成一键启动脚本 (仅限 Windows)');
|
|
1137
1137
|
console.log(' list 查看注入资源管理列表(智能体/技能/配置)');
|
|
1138
1138
|
console.log(' pull 从 ~/.openclaw 拉取最新资源到源目录(开发用)');
|
|
@@ -1208,7 +1208,7 @@ if (!command) {
|
|
|
1208
1208
|
runFix();
|
|
1209
1209
|
} else if (command === 'wsl2') {
|
|
1210
1210
|
runWsl2();
|
|
1211
|
-
} else if (command === '
|
|
1211
|
+
} else if (command === 'safe') {
|
|
1212
1212
|
runRestrict();
|
|
1213
1213
|
} else if (command === 'launch') {
|
|
1214
1214
|
runLaunch();
|
package/package.json
CHANGED
package/restrict.js
CHANGED
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
* ============================================================================
|
|
7
7
|
*
|
|
8
8
|
* 从 Windows 一次性完成:
|
|
9
|
-
* 步骤 1: 在 WSL 内创建工作目录
|
|
9
|
+
* 步骤 1: 在 WSL 内创建工作目录 /root/.openclaw/workspace/myclaw
|
|
10
10
|
* 步骤 2: 编辑 /etc/wsl.conf 禁用 automount(Linux 看不到 Windows 盘符)
|
|
11
|
-
* 步骤 3: 在 Windows 桌面创建快捷方式,指向 \\wsl.localhost\OpenClaw
|
|
11
|
+
* 步骤 3: 在 Windows 桌面创建快捷方式,指向 \\wsl.localhost\OpenClaw\root\.openclaw\workspace
|
|
12
12
|
*
|
|
13
13
|
* 使用方法:
|
|
14
14
|
* myclaw restrict
|
|
@@ -33,65 +33,41 @@ 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
|
|
36
|
+
const WORKSPACE_PATH = '/root/.openclaw/workspace/myclaw'; // 实际创建的目录
|
|
37
|
+
const SHORTCUT_TARGET = '/root/.openclaw/workspace'; // 快捷方式导航到这里
|
|
37
38
|
|
|
38
39
|
// ============================================================================
|
|
39
40
|
// 工具函数
|
|
40
41
|
// ============================================================================
|
|
41
42
|
|
|
42
|
-
function printStep(msg) {
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function
|
|
47
|
-
console.log(C.b + '[信息]' + C.nc + ' ' + msg);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function printSuccess(msg) {
|
|
51
|
-
console.log(C.g + '[成功]' + C.nc + ' ' + msg);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function printWarning(msg) {
|
|
55
|
-
console.log(C.y + '[警告]' + C.nc + ' ' + msg);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function printError(msg) {
|
|
59
|
-
console.error(C.r + '[错误]' + C.nc + ' ' + msg);
|
|
60
|
-
}
|
|
43
|
+
function printStep(msg) { console.log(C.g + '==>' + C.nc + ' ' + msg); }
|
|
44
|
+
function printInfo(msg) { console.log(C.b + '[信息]' + C.nc + ' ' + msg); }
|
|
45
|
+
function printSuccess(msg) { console.log(C.g + '[成功]' + C.nc + ' ' + msg); }
|
|
46
|
+
function printWarning(msg) { console.log(C.y + '[警告]' + C.nc + ' ' + msg); }
|
|
47
|
+
function printError(msg) { console.error(C.r + '[错误]' + C.nc + ' ' + msg); }
|
|
61
48
|
|
|
62
|
-
// 在 WSL
|
|
49
|
+
// 在 WSL 中执行命令,返回输出(stdout)
|
|
63
50
|
function wslExec(cmd) {
|
|
64
51
|
try {
|
|
65
|
-
return execSync(
|
|
52
|
+
return execSync('wsl -d ' + DISTRO_NAME + ' -- bash -c "' + cmd + '"', {
|
|
66
53
|
encoding: 'utf8',
|
|
67
54
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
68
55
|
}).trim();
|
|
69
|
-
} catch
|
|
56
|
+
} catch {
|
|
70
57
|
return null;
|
|
71
58
|
}
|
|
72
59
|
}
|
|
73
60
|
|
|
74
|
-
// 在 WSL 中以 root
|
|
75
|
-
function
|
|
61
|
+
// 在 WSL 中以 root 执行命令(不关心输出)
|
|
62
|
+
function wslExecRoot(cmd) {
|
|
76
63
|
try {
|
|
77
|
-
|
|
78
|
-
execSync(`wsl -d ${DISTRO_NAME} --user root -- bash -c "${cmd}"`, {
|
|
64
|
+
execSync('wsl -d ' + DISTRO_NAME + ' -u root -- bash -c "' + cmd + '"', {
|
|
79
65
|
encoding: 'utf8',
|
|
80
66
|
stdio: 'pipe',
|
|
81
67
|
});
|
|
82
68
|
return true;
|
|
83
69
|
} catch (err) {
|
|
84
|
-
|
|
85
|
-
try {
|
|
86
|
-
execSync(`wsl -d ${DISTRO_NAME} -- bash -c "sudo ${cmd}"`, {
|
|
87
|
-
encoding: 'utf8',
|
|
88
|
-
stdio: 'pipe',
|
|
89
|
-
});
|
|
90
|
-
return true;
|
|
91
|
-
} catch (err2) {
|
|
92
|
-
printError('WSL 命令执行失败: ' + (err2.stderr || err2.message));
|
|
93
|
-
return false;
|
|
94
|
-
}
|
|
70
|
+
return false;
|
|
95
71
|
}
|
|
96
72
|
}
|
|
97
73
|
|
|
@@ -102,12 +78,10 @@ function wslExecSudo(cmd) {
|
|
|
102
78
|
function checkPrerequisites() {
|
|
103
79
|
if (!isWindows) {
|
|
104
80
|
printError('此命令只能在 Windows 上运行');
|
|
105
|
-
console.log('');
|
|
106
|
-
console.log('Mac/Linux 不需要 WSL2 权限封锁。');
|
|
107
81
|
process.exit(1);
|
|
108
82
|
}
|
|
109
83
|
|
|
110
|
-
// 检查 wsl
|
|
84
|
+
// 检查 wsl 命令
|
|
111
85
|
try {
|
|
112
86
|
execSync('wsl --version', { stdio: 'pipe' });
|
|
113
87
|
} catch {
|
|
@@ -115,9 +89,9 @@ function checkPrerequisites() {
|
|
|
115
89
|
process.exit(1);
|
|
116
90
|
}
|
|
117
91
|
|
|
118
|
-
// 检查 OpenClaw
|
|
92
|
+
// 检查 OpenClaw 发行版
|
|
119
93
|
try {
|
|
120
|
-
const list = execSync('wsl -l -q', { encoding: 'utf16le' })
|
|
94
|
+
const list = execSync('wsl -l -q', { encoding: 'utf16le' });
|
|
121
95
|
if (!list.includes(DISTRO_NAME)) {
|
|
122
96
|
printError('未找到 ' + DISTRO_NAME + ' 发行版。请先运行: myclaw wsl2');
|
|
123
97
|
process.exit(1);
|
|
@@ -137,69 +111,50 @@ function checkPrerequisites() {
|
|
|
137
111
|
function step1_createWorkspace() {
|
|
138
112
|
printStep('步骤 1/3: 在 WSL 内创建工作目录');
|
|
139
113
|
|
|
140
|
-
|
|
141
|
-
const wslUser = wslExec('whoami');
|
|
142
|
-
if (!wslUser) {
|
|
143
|
-
printError('无法获取 WSL 用户名');
|
|
144
|
-
return null;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
printInfo('WSL 用户: ' + wslUser);
|
|
148
|
-
|
|
149
|
-
// 创建工作目录
|
|
150
|
-
const workspacePath = `/home/${wslUser}/${WORKSPACE_DIR}`;
|
|
151
|
-
const result = wslExec(`mkdir -p ${workspacePath} && echo ${workspacePath}`);
|
|
114
|
+
const ok = wslExec('mkdir -p ' + WORKSPACE_PATH + ' && echo ok');
|
|
152
115
|
|
|
153
|
-
if (!
|
|
116
|
+
if (!ok || !ok.includes('ok')) {
|
|
154
117
|
printError('创建工作目录失败');
|
|
155
|
-
return
|
|
118
|
+
return false;
|
|
156
119
|
}
|
|
157
120
|
|
|
158
|
-
printSuccess('工作目录已创建: ' +
|
|
159
|
-
return
|
|
121
|
+
printSuccess('工作目录已创建: ' + WORKSPACE_PATH);
|
|
122
|
+
return true;
|
|
160
123
|
}
|
|
161
124
|
|
|
162
125
|
// ============================================================================
|
|
163
|
-
// 步骤 2: 禁用 automount
|
|
126
|
+
// 步骤 2: 禁用 automount — 写 /etc/wsl.conf
|
|
164
127
|
// ============================================================================
|
|
165
128
|
|
|
166
|
-
function step2_disableAutomount(
|
|
129
|
+
function step2_disableAutomount() {
|
|
167
130
|
printStep('步骤 2/3: 禁用自动挂载 Windows 盘符');
|
|
168
131
|
|
|
169
|
-
//
|
|
170
|
-
|
|
132
|
+
// 备份
|
|
133
|
+
wslExecRoot('cp /etc/wsl.conf /etc/wsl.conf.bak 2>/dev/null || true');
|
|
171
134
|
|
|
172
|
-
//
|
|
173
|
-
const
|
|
135
|
+
// 读取现有配置
|
|
136
|
+
const existing = wslExec('cat /etc/wsl.conf 2>/dev/null') || '';
|
|
174
137
|
|
|
175
138
|
let newContent;
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
newContent = existingConf.replace(
|
|
139
|
+
if (existing.includes('[automount]')) {
|
|
140
|
+
// 替换已有 automount 段
|
|
141
|
+
newContent = existing.replace(
|
|
180
142
|
/\[automount\][^\[]*/,
|
|
181
143
|
'[automount]\nenabled = false\n'
|
|
182
144
|
);
|
|
183
145
|
} else {
|
|
184
|
-
// 追加
|
|
185
|
-
newContent =
|
|
146
|
+
// 追加
|
|
147
|
+
newContent = existing + (existing.endsWith('\n') ? '' : '\n') + '[automount]\nenabled = false\n';
|
|
186
148
|
}
|
|
187
149
|
|
|
188
|
-
//
|
|
189
|
-
const
|
|
190
|
-
const writeCmd =
|
|
191
|
-
|
|
192
|
-
const ok = wslExecSudo(`bash -c '${writeCmd.replace(/'/g, "'\\''")}'`);
|
|
150
|
+
// 用 heredoc 写入(通过 base64 传递内容,避免 shell 转义问题)
|
|
151
|
+
const b64 = Buffer.from(newContent).toString('base64');
|
|
152
|
+
const writeCmd = "echo '" + b64 + "' | base64 -d > /etc/wsl.conf";
|
|
153
|
+
const ok = wslExecRoot(writeCmd);
|
|
193
154
|
|
|
194
155
|
if (!ok) {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
`bash -c "echo '${escaped}' > /etc/wsl.conf"`
|
|
198
|
-
);
|
|
199
|
-
if (!heredocOk) {
|
|
200
|
-
printError('写入 wsl.conf 失败');
|
|
201
|
-
return false;
|
|
202
|
-
}
|
|
156
|
+
printError('写入 wsl.conf 失败');
|
|
157
|
+
return false;
|
|
203
158
|
}
|
|
204
159
|
|
|
205
160
|
// 验证
|
|
@@ -207,102 +162,81 @@ function step2_disableAutomount(wslUser) {
|
|
|
207
162
|
if (verify.includes('enabled = false') || verify.includes('enabled=false')) {
|
|
208
163
|
printSuccess('automount 已禁用');
|
|
209
164
|
return true;
|
|
210
|
-
} else {
|
|
211
|
-
printError('配置验证失败,请手动检查 /etc/wsl.conf');
|
|
212
|
-
return false;
|
|
213
165
|
}
|
|
166
|
+
|
|
167
|
+
printError('配置验证失败');
|
|
168
|
+
return false;
|
|
214
169
|
}
|
|
215
170
|
|
|
216
171
|
// ============================================================================
|
|
217
172
|
// 步骤 3: 在桌面创建快捷方式
|
|
218
173
|
// ============================================================================
|
|
219
174
|
|
|
220
|
-
function step3_createShortcut(
|
|
175
|
+
function step3_createShortcut() {
|
|
221
176
|
printStep('步骤 3/3: 创建桌面快捷方式');
|
|
222
177
|
|
|
223
|
-
|
|
178
|
+
// \\wsl.localhost\OpenClaw\root\.openclaw\workspace
|
|
179
|
+
const wslPath = '\\\\wsl.localhost\\' + DISTRO_NAME + '\\' + SHORTCUT_TARGET.replace(/\//g, '\\');
|
|
180
|
+
|
|
181
|
+
// 找桌面路径(兼容中英文)
|
|
224
182
|
const desktopPath = path.join(os.homedir(), 'Desktop');
|
|
183
|
+
const desktopPathCN = path.join(os.homedir(), '桌面');
|
|
184
|
+
const shortcutDir = fs.existsSync(desktopPath) ? desktopPath
|
|
185
|
+
: fs.existsSync(desktopPathCN) ? desktopPathCN : null;
|
|
225
186
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
const desktopPathCN = path.join(os.homedir(), '桌面');
|
|
230
|
-
if (fs.existsSync(desktopPathCN)) {
|
|
231
|
-
var shortcutDir = desktopPathCN;
|
|
232
|
-
} else {
|
|
233
|
-
printError('找不到桌面目录');
|
|
234
|
-
return false;
|
|
235
|
-
}
|
|
236
|
-
} else {
|
|
237
|
-
var shortcutDir = desktopPath;
|
|
187
|
+
if (!shortcutDir) {
|
|
188
|
+
printError('找不到桌面目录');
|
|
189
|
+
return false;
|
|
238
190
|
}
|
|
239
191
|
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
$
|
|
249
|
-
$sc
|
|
250
|
-
$sc.
|
|
251
|
-
$sc.
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
$
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
$
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
[System.Type] [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer)))
|
|
272
|
-
))
|
|
273
|
-
)
|
|
274
|
-
|
|
275
|
-
Write-Host "OK"
|
|
276
|
-
`.trim();
|
|
277
|
-
|
|
278
|
-
// 简化:直接用 PowerShell 创建
|
|
279
|
-
const psCmd = `
|
|
280
|
-
$ws = New-Object -ComObject WScript.Shell
|
|
281
|
-
$sc = $ws.CreateShortcut("${shortcutPath.replace(/\\/g, '\\\\')}")
|
|
282
|
-
$sc.TargetPath = "explorer.exe"
|
|
283
|
-
$sc.Arguments = "${wslPath}"
|
|
284
|
-
$sc.WorkingDirectory = "${wslPath}"
|
|
285
|
-
$sc.Description = "OpenClaw Workspace"
|
|
286
|
-
$sc.Save()
|
|
287
|
-
Write-Host "OK"
|
|
288
|
-
`;
|
|
192
|
+
const shortcutPath = path.join(shortcutDir, 'myclaw.lnk');
|
|
193
|
+
|
|
194
|
+
// 写临时 .ps1 文件来创建快捷方式(避免复杂的命令行转义)
|
|
195
|
+
const tmpDir = path.join(process.env.LOCALAPPDATA || os.tmpdir(), 'myclaw');
|
|
196
|
+
try { fs.mkdirSync(tmpDir, { recursive: true }); } catch {}
|
|
197
|
+
const psFile = path.join(tmpDir, 'create-shortcut.ps1');
|
|
198
|
+
|
|
199
|
+
const psContent = [
|
|
200
|
+
'$ws = New-Object -ComObject WScript.Shell',
|
|
201
|
+
'$sc = $ws.CreateShortcut("' + shortcutPath + '")',
|
|
202
|
+
'$sc.TargetPath = "explorer.exe"',
|
|
203
|
+
'$sc.Arguments = "' + wslPath + '"',
|
|
204
|
+
'$sc.WorkingDirectory = "' + wslPath + '"',
|
|
205
|
+
'$sc.Description = "OpenClaw Workspace"',
|
|
206
|
+
'$sc.Save()',
|
|
207
|
+
'',
|
|
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
|
+
'Write-Host "OK"',
|
|
219
|
+
].join('\r\n');
|
|
220
|
+
|
|
221
|
+
// UTF-8 BOM
|
|
222
|
+
fs.writeFileSync(psFile, '\uFEFF' + psContent, 'utf8');
|
|
289
223
|
|
|
290
224
|
try {
|
|
291
|
-
const result = execSync(
|
|
292
|
-
|
|
293
|
-
stdio: 'pipe'
|
|
294
|
-
|
|
225
|
+
const result = execSync(
|
|
226
|
+
'powershell -NoProfile -ExecutionPolicy Bypass -File "' + psFile + '"',
|
|
227
|
+
{ encoding: 'utf8', stdio: 'pipe' }
|
|
228
|
+
).trim();
|
|
295
229
|
|
|
296
230
|
if (result.includes('OK')) {
|
|
297
|
-
printSuccess('桌面快捷方式已创建: '
|
|
298
|
-
printInfo('
|
|
231
|
+
printSuccess('桌面快捷方式已创建: myclaw');
|
|
232
|
+
printInfo('双击即可打开工作目录');
|
|
299
233
|
return true;
|
|
300
234
|
}
|
|
301
|
-
} catch
|
|
302
|
-
//
|
|
235
|
+
} catch {
|
|
236
|
+
// 回退:创建 .url 文件
|
|
303
237
|
try {
|
|
304
|
-
const urlContent =
|
|
305
|
-
fs.writeFileSync(path.join(shortcutDir, '
|
|
238
|
+
const urlContent = '[InternetShortcut]\r\nURL=file:///' + wslPath.replace(/\\/g, '/') + '\r\n';
|
|
239
|
+
fs.writeFileSync(path.join(shortcutDir, 'myclaw.url'), urlContent, 'utf8');
|
|
306
240
|
printSuccess('桌面快捷方式已创建 (.url)');
|
|
307
241
|
return true;
|
|
308
242
|
} catch (err2) {
|
|
@@ -325,33 +259,22 @@ function run() {
|
|
|
325
259
|
console.log('========================================');
|
|
326
260
|
console.log('');
|
|
327
261
|
console.log('此操作将:');
|
|
328
|
-
console.log(' 1. 在 WSL 内创建工作目录
|
|
262
|
+
console.log(' 1. 在 WSL 内创建工作目录');
|
|
329
263
|
console.log(' 2. 禁用 WSL 自动挂载 Windows 盘符');
|
|
330
|
-
console.log(' 3.
|
|
264
|
+
console.log(' 3. 在桌面创建快捷方式 myclaw');
|
|
331
265
|
console.log('');
|
|
332
266
|
console.log('效果:Linux 看不到 Windows 文件,但 Windows');
|
|
333
|
-
console.log('
|
|
267
|
+
console.log(' 可以通过桌面快捷方式访问 WSL 工作目录。');
|
|
334
268
|
console.log('');
|
|
335
269
|
|
|
336
|
-
// 前置检查
|
|
337
270
|
checkPrerequisites();
|
|
338
271
|
|
|
339
|
-
|
|
340
|
-
const info = step1_createWorkspace();
|
|
341
|
-
if (!info) {
|
|
342
|
-
printError('步骤 1 失败,终止');
|
|
343
|
-
process.exit(1);
|
|
344
|
-
}
|
|
272
|
+
if (!step1_createWorkspace()) { printError('步骤 1 失败'); process.exit(1); }
|
|
345
273
|
|
|
346
|
-
|
|
347
|
-
if (!step2_disableAutomount(info.wslUser)) {
|
|
348
|
-
printError('步骤 2 失败,终止');
|
|
349
|
-
process.exit(1);
|
|
350
|
-
}
|
|
274
|
+
if (!step2_disableAutomount()) { printError('步骤 2 失败'); process.exit(1); }
|
|
351
275
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
printWarning('步骤 3 失败,但不影响权限封锁');
|
|
276
|
+
if (!step3_createShortcut()) {
|
|
277
|
+
printWarning('快捷方式创建失败,但不影响权限封锁');
|
|
355
278
|
}
|
|
356
279
|
|
|
357
280
|
// 完成提示
|
|
@@ -362,13 +285,13 @@ function run() {
|
|
|
362
285
|
console.log('');
|
|
363
286
|
printWarning('需要重启 WSL2 才能使禁用挂载生效!');
|
|
364
287
|
console.log('');
|
|
365
|
-
console.log('
|
|
288
|
+
console.log(' 在 PowerShell 中运行:');
|
|
366
289
|
console.log(' ' + C.y + 'wsl --shutdown' + C.nc);
|
|
367
290
|
console.log(' 然后重新点击桌面图标启动。');
|
|
368
291
|
console.log('');
|
|
369
|
-
console.log('
|
|
370
|
-
console.log(' - WSL 内 ls /mnt/c
|
|
371
|
-
console.log(' - 双击桌面「
|
|
292
|
+
console.log('验证:');
|
|
293
|
+
console.log(' - WSL 内 ls /mnt/c → 应显示不存在');
|
|
294
|
+
console.log(' - 双击桌面「myclaw」→ 打开工作文件夹');
|
|
372
295
|
console.log('');
|
|
373
296
|
}
|
|
374
297
|
|
|
@@ -1,170 +1,62 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
|
|
3
3
|
###############################################################################
|
|
4
|
-
# MyClaw WSL2
|
|
4
|
+
# MyClaw WSL2 权限封锁 — 独立手动版
|
|
5
5
|
#
|
|
6
|
-
#
|
|
6
|
+
# 在 WSL2 内手动运行(通常通过 myclaw restrict 从 Windows 自动调用)
|
|
7
7
|
#
|
|
8
|
-
#
|
|
8
|
+
# 功能:编辑 /etc/wsl.conf,设置 [automount] enabled = false
|
|
9
|
+
#
|
|
10
|
+
# 手动使用:
|
|
9
11
|
# bash scripts/restrict-wsl-access.sh
|
|
10
12
|
#
|
|
11
13
|
###############################################################################
|
|
12
14
|
|
|
13
15
|
set -e
|
|
14
16
|
|
|
15
|
-
# 颜色定义
|
|
16
|
-
RED='\033[0;31m'
|
|
17
|
-
GREEN='\033[0;32m'
|
|
18
|
-
YELLOW='\033[1;33m'
|
|
19
|
-
BLUE='\033[0;34m'
|
|
20
|
-
NC='\033[0m' # No Color
|
|
21
|
-
|
|
22
17
|
WSL_CONF="/etc/wsl.conf"
|
|
23
|
-
BACKUP_DIR="/tmp/wsl_conf_backup_$(date +%Y%m%d_%H%M%S)"
|
|
24
|
-
|
|
25
|
-
# 打印带颜色的消息
|
|
26
|
-
print_info() {
|
|
27
|
-
echo -e "${BLUE}[信息]${NC} $1"
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
print_success() {
|
|
31
|
-
echo -e "${GREEN}[成功]${NC} $1"
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
print_warning() {
|
|
35
|
-
echo -e "${YELLOW}[警告]${NC} $1"
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
print_error() {
|
|
39
|
-
echo -e "${RED}[错误]${NC} $1"
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
print_step() {
|
|
43
|
-
echo -e "${GREEN}==>${NC} $1"
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
# 检查是否在 WSL 环境中运行
|
|
47
|
-
check_wsl_environment() {
|
|
48
|
-
if [[ ! -f /proc/version ]] || ! grep -qi "microsoft\|wsl" /proc/version 2>/dev/null; then
|
|
49
|
-
print_error "此脚本必须在 WSL2 环境中运行"
|
|
50
|
-
exit 1
|
|
51
|
-
fi
|
|
52
|
-
print_success "检测到 WSL2 环境"
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
# 备份现有配置
|
|
56
|
-
backup_existing_config() {
|
|
57
|
-
if [[ -f "$WSL_CONF" ]]; then
|
|
58
|
-
print_info "备份现有配置到: $BACKUP_DIR"
|
|
59
|
-
mkdir -p "$BACKUP_DIR"
|
|
60
|
-
sudo cp "$WSL_CONF" "$BACKUP_DIR/wsl.conf.bak"
|
|
61
|
-
print_success "配置已备份"
|
|
62
|
-
else
|
|
63
|
-
print_info "没有现有配置需要备份"
|
|
64
|
-
fi
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
# 步骤 A: 禁止自动挂载整个盘
|
|
68
|
-
step_a_disable_automount() {
|
|
69
|
-
print_step "步骤 A: 禁止自动挂载 Windows 盘符"
|
|
70
|
-
|
|
71
|
-
echo ""
|
|
72
|
-
echo "此操作将:"
|
|
73
|
-
echo " 1. 编辑 /etc/wsl.conf"
|
|
74
|
-
echo " 2. 设置 [automount] enabled = false"
|
|
75
|
-
echo " 3. 使 Linux 默认看不到 /mnt/c 等盘符"
|
|
76
|
-
echo ""
|
|
77
|
-
|
|
78
|
-
# 创建临时文件
|
|
79
|
-
local temp_file=$(mktemp)
|
|
80
|
-
|
|
81
|
-
# 如果原文件存在,保留非 automount 部分的内容
|
|
82
|
-
if [[ -f "$WSL_CONF" ]]; then
|
|
83
|
-
# 移除现有的 [automount] 部分
|
|
84
|
-
awk '
|
|
85
|
-
BEGIN { in_automount = 0; skip = 0 }
|
|
86
|
-
/^\[automount\]/ { in_automount = 1; skip = 1; next }
|
|
87
|
-
/^\[/ { if (in_automount) { in_automount = 0; skip = 0 } }
|
|
88
|
-
{ if (!skip) print }
|
|
89
|
-
' "$WSL_CONF" > "$temp_file"
|
|
90
|
-
fi
|
|
91
|
-
|
|
92
|
-
# 添加 automount 配置
|
|
93
|
-
cat >> "$temp_file" << EOF
|
|
94
18
|
|
|
19
|
+
# 检查 WSL 环境
|
|
20
|
+
if [[ ! -f /proc/version ]] || ! grep -qi "microsoft\|wsl" /proc/version 2>/dev/null; then
|
|
21
|
+
echo "[错误] 此脚本必须在 WSL2 环境中运行"
|
|
22
|
+
exit 1
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
# 备份
|
|
26
|
+
if [[ -f "$WSL_CONF" ]]; then
|
|
27
|
+
sudo cp "$WSL_CONF" /etc/wsl.conf.bak
|
|
28
|
+
echo "[信息] 已备份到 /etc/wsl.conf.bak"
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
# 读取现有配置
|
|
32
|
+
existing=$(cat "$WSL_CONF" 2>/dev/null || echo "")
|
|
33
|
+
|
|
34
|
+
# 构建新配置
|
|
35
|
+
if echo "$existing" | grep -q '\[automount\]'; then
|
|
36
|
+
new_content=$(echo "$existing" | sed '/\[automount\]/,/^\[/ s/enabled.*/enabled = false/')
|
|
37
|
+
else
|
|
38
|
+
new_content="${existing}
|
|
95
39
|
[automount]
|
|
96
40
|
enabled = false
|
|
97
|
-
|
|
41
|
+
"
|
|
42
|
+
fi
|
|
98
43
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
44
|
+
# 用 base64 避免转义问题
|
|
45
|
+
echo "$new_content" | base64 -d > /dev/null 2>&1 || true
|
|
46
|
+
echo "$new_content" | sudo tee "$WSL_CONF" > /dev/null
|
|
47
|
+
sudo chmod 644 "$WSL_CONF"
|
|
103
48
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
49
|
+
# 验证
|
|
50
|
+
if grep -q 'enabled = false\|enabled=false' "$WSL_CONF"; then
|
|
51
|
+
echo "[成功] automount 已禁用"
|
|
107
52
|
echo ""
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
print_info "当前 /etc/wsl.conf 内容:"
|
|
111
|
-
echo "----------------------------------------"
|
|
53
|
+
echo "当前 /etc/wsl.conf 内容:"
|
|
54
|
+
echo "---"
|
|
112
55
|
sudo cat "$WSL_CONF"
|
|
113
|
-
echo "
|
|
56
|
+
echo "---"
|
|
114
57
|
echo ""
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
show_restart_instructions() {
|
|
121
|
-
echo ""
|
|
122
|
-
echo "========================================"
|
|
123
|
-
print_warning "重要提示"
|
|
124
|
-
echo "========================================"
|
|
125
|
-
echo ""
|
|
126
|
-
echo "配置已完成,但需要重启 WSL2 才能生效!"
|
|
127
|
-
echo ""
|
|
128
|
-
echo "重启方法:"
|
|
129
|
-
echo ""
|
|
130
|
-
echo " 方法 1 (推荐): 在 Windows PowerShell 中运行"
|
|
131
|
-
echo -e " ${YELLOW}wsl --shutdown${NC}"
|
|
132
|
-
echo " 然后重新打开 WSL2 终端"
|
|
133
|
-
echo ""
|
|
134
|
-
echo " 方法 2: 在 Windows 命令提示符中运行"
|
|
135
|
-
echo -e " ${YELLOW}wsl --terminate OpenClaw${NC}"
|
|
136
|
-
echo " (替换 OpenClaw 为你的发行版名称)"
|
|
137
|
-
echo ""
|
|
138
|
-
echo "重启后验证:"
|
|
139
|
-
echo " - ls /mnt/c 应该显示目录不存在或为空"
|
|
140
|
-
echo " - Windows 文件系统对 Linux 不可见"
|
|
141
|
-
echo ""
|
|
142
|
-
echo "========================================"
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
# 主函数
|
|
146
|
-
main() {
|
|
147
|
-
echo ""
|
|
148
|
-
echo "========================================"
|
|
149
|
-
echo " MyClaw WSL2 权限封锁脚本"
|
|
150
|
-
echo "========================================"
|
|
151
|
-
echo ""
|
|
152
|
-
|
|
153
|
-
# 检查环境
|
|
154
|
-
check_wsl_environment
|
|
155
|
-
|
|
156
|
-
# 备份现有配置
|
|
157
|
-
backup_existing_config
|
|
158
|
-
|
|
159
|
-
# 执行步骤 A
|
|
160
|
-
step_a_disable_automount
|
|
161
|
-
|
|
162
|
-
# 显示重启说明
|
|
163
|
-
show_restart_instructions
|
|
164
|
-
|
|
165
|
-
print_success "步骤 A 配置完成!"
|
|
166
|
-
echo ""
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
# 运行主函数
|
|
170
|
-
main "$@"
|
|
58
|
+
echo "[提示] 需要重启 WSL2 才能生效: wsl --shutdown"
|
|
59
|
+
else
|
|
60
|
+
echo "[错误] 配置写入失败"
|
|
61
|
+
exit 1
|
|
62
|
+
fi
|
package/start.js
CHANGED
|
@@ -83,9 +83,9 @@ function startWindows() {
|
|
|
83
83
|
try { execSync('myclaw update', { stdio: 'inherit', timeout: 120000 }); } catch {}
|
|
84
84
|
console.log('');
|
|
85
85
|
|
|
86
|
-
console.log('[
|
|
86
|
+
console.log('[mc up] WSL 内更新 MyClaw + 刷新配置...');
|
|
87
87
|
try {
|
|
88
|
-
execSync('wsl -d OpenClaw --
|
|
88
|
+
execSync('wsl -d OpenClaw -- mc up', { stdio: 'inherit', timeout: 120000 });
|
|
89
89
|
} catch {}
|
|
90
90
|
console.log('');
|
|
91
91
|
|