@aiyiran/myclaw 1.0.61 → 1.0.63

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/find-config.js ADDED
@@ -0,0 +1,121 @@
1
+ /**
2
+ * find-config.js — OpenClaw 配置文件定位 & 读写工具
3
+ *
4
+ * 通用能力:跨平台自动查找 ~/.openclaw/openclaw.json
5
+ * 所有需要读写 openclaw.json 的模块都应该调用这个工具
6
+ *
7
+ * 使用:
8
+ * const { findConfig, readConfig, writeConfig, patchConfig } = require('./find-config');
9
+ *
10
+ * const configPath = findConfig(); // 返回路径或 null
11
+ * const config = readConfig(); // 读取 JSON 对象
12
+ * writeConfig(config); // 写回整个 JSON
13
+ * patchConfig({ session: { reset: { mode: 'idle' } } }); // 深度合并局部字段
14
+ */
15
+
16
+ const fs = require('fs');
17
+ const path = require('path');
18
+ const os = require('os');
19
+
20
+ const CONFIG_FILENAME = 'openclaw.json';
21
+
22
+ /**
23
+ * 查找 openclaw.json 的路径
24
+ * 按优先级尝试:
25
+ * 1. ~/.openclaw/openclaw.json(标准路径)
26
+ * 2. 环境变量 OPENCLAW_HOME 指定的目录
27
+ *
28
+ * @returns {string|null} 配置文件路径,未找到返回 null
29
+ */
30
+ function findConfig() {
31
+ const candidates = [];
32
+
33
+ // 1. 环境变量优先
34
+ if (process.env.OPENCLAW_HOME) {
35
+ candidates.push(path.join(process.env.OPENCLAW_HOME, CONFIG_FILENAME));
36
+ }
37
+
38
+ // 2. 标准路径 ~/.openclaw/
39
+ candidates.push(path.join(os.homedir(), '.openclaw', CONFIG_FILENAME));
40
+
41
+ // 3. Windows WSL 下 /root/.openclaw/
42
+ if (os.platform() === 'linux') {
43
+ candidates.push(path.join('/root', '.openclaw', CONFIG_FILENAME));
44
+ }
45
+
46
+ for (const p of candidates) {
47
+ try {
48
+ if (fs.existsSync(p)) {
49
+ return p;
50
+ }
51
+ } catch {}
52
+ }
53
+
54
+ return null;
55
+ }
56
+
57
+ /**
58
+ * 读取 openclaw.json 并解析为 JSON 对象
59
+ * @returns {{ config: object, configPath: string }}
60
+ * @throws {Error} 未找到或解析失败
61
+ */
62
+ function readConfig() {
63
+ const configPath = findConfig();
64
+ if (!configPath) {
65
+ throw new Error('未找到 openclaw.json,请确认 OpenClaw 已安装');
66
+ }
67
+
68
+ const raw = fs.readFileSync(configPath, 'utf8');
69
+ const config = JSON.parse(raw);
70
+ return { config, configPath };
71
+ }
72
+
73
+ /**
74
+ * 写入完整的 config 对象到 openclaw.json
75
+ * @param {object} config - 完整的配置对象
76
+ * @param {string} [configPath] - 可选路径,不传则自动查找
77
+ */
78
+ function writeConfig(config, configPath) {
79
+ if (!configPath) {
80
+ configPath = findConfig();
81
+ if (!configPath) {
82
+ throw new Error('未找到 openclaw.json,无法写入');
83
+ }
84
+ }
85
+
86
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n', 'utf8');
87
+ }
88
+
89
+ /**
90
+ * 深度合并 patch 到现有配置(只改指定字段,不影响其他)
91
+ * @param {object} patch - 要合并的局部配置
92
+ * @returns {{ config: object, configPath: string }} 合并后的结果
93
+ */
94
+ function patchConfig(patch) {
95
+ const { config, configPath } = readConfig();
96
+ deepMerge(config, patch);
97
+ writeConfig(config, configPath);
98
+ return { config, configPath };
99
+ }
100
+
101
+ /**
102
+ * 深度合并 source 到 target(就地修改)
103
+ */
104
+ function deepMerge(target, source) {
105
+ for (const key of Object.keys(source)) {
106
+ if (
107
+ source[key] !== null &&
108
+ typeof source[key] === 'object' &&
109
+ !Array.isArray(source[key]) &&
110
+ target[key] !== null &&
111
+ typeof target[key] === 'object' &&
112
+ !Array.isArray(target[key])
113
+ ) {
114
+ deepMerge(target[key], source[key]);
115
+ } else {
116
+ target[key] = source[key];
117
+ }
118
+ }
119
+ }
120
+
121
+ module.exports = { findConfig, readConfig, writeConfig, patchConfig, deepMerge };
package/index.js CHANGED
@@ -582,10 +582,11 @@ function runOpen() {
582
582
  function runPatch() {
583
583
  const { patch, status: patchStatus } = require('./patch');
584
584
  const { patchSkills } = require('./patch-skill');
585
+ const { patchConfig } = require('./find-config');
585
586
  const bar = '----------------------------------------';
586
587
 
587
588
  console.log('');
588
- console.log('[' + colors.blue + 'MyClaw' + colors.nc + '] ' + colors.blue + 'Patch (UI + Skills)' + colors.nc);
589
+ console.log('[' + colors.blue + 'MyClaw' + colors.nc + '] ' + colors.blue + 'Patch (UI + Skills + Config)' + colors.nc);
589
590
  console.log(bar);
590
591
  console.log('');
591
592
 
@@ -596,6 +597,22 @@ function runPatch() {
596
597
  console.log('');
597
598
  const skillResult = patchSkills();
598
599
 
600
+ // 3. Config 补丁(修改 openclaw.json 的特定字段)
601
+ console.log('');
602
+ try {
603
+ const { config, configPath } = patchConfig({
604
+ session: {
605
+ reset: {
606
+ mode: "idle",
607
+ idleMinutes: 90720
608
+ }
609
+ }
610
+ });
611
+ console.log('[myclaw-config] ✅ session.reset → idle (90720 分钟)');
612
+ } catch (err) {
613
+ console.log('[myclaw-config] ⚠️ 配置补丁失败: ' + err.message);
614
+ }
615
+
599
616
  if (uiResult.success || skillResult.success) {
600
617
  console.log('');
601
618
  console.log(bar);
package/inject-minimax.js CHANGED
@@ -4,15 +4,15 @@
4
4
  * inject-minimax.js
5
5
  *
6
6
  * 将 openclaw.json 中的模型配置清空,注入为唯一的 MiniMax 模型。
7
- * 自动查找 ~/.openclaw/openclaw.json
8
- * API Key 通过 openclaw onboard 管理,不写环境变量。
7
+ *
8
+ * 流程:
9
+ * 1. 先执行 openclaw onboard(设置 API Key,会覆盖 JSON)
10
+ * 2. 再写入我们的 JSON 配置(覆盖回来)
9
11
  *
10
12
  * 入口: myclaw minimax [--key sk-xxx]
11
13
  */
12
14
 
13
- const fs = require('fs');
14
- const path = require('path');
15
- const os = require('os');
15
+ const { readConfig, writeConfig } = require('./find-config');
16
16
 
17
17
  function run(cliArgs) {
18
18
  // 解析 --key 参数
@@ -24,23 +24,55 @@ function run(cliArgs) {
24
24
  }
25
25
  }
26
26
 
27
- // 自动查找 openclaw.json
28
- const openclawDir = path.join(os.homedir(), '.openclaw');
29
- const targetPath = path.join(openclawDir, 'openclaw.json');
30
-
31
- if (!fs.existsSync(targetPath)) {
32
- console.error('❌ 未找到 openclaw.json');
33
- console.error(' 期望路径: ' + targetPath);
34
- console.error(' 请先安装 OpenClaw: myclaw install');
27
+ // 查找配置
28
+ let configPath;
29
+ try {
30
+ ({ configPath } = readConfig());
31
+ } catch (err) {
32
+ console.error('❌ ' + err.message);
35
33
  process.exit(1);
36
34
  }
37
35
 
38
- console.log('📍 找到配置: ' + targetPath);
36
+ console.log('📍 找到配置: ' + configPath);
37
+
38
+ // ============================================================
39
+ // 第一步:先执行 onboard(它会覆盖 JSON,所以必须先跑)
40
+ // ============================================================
41
+
42
+ if (apiKey) {
43
+ console.log('');
44
+ console.log('🔑 [Step 1] 执行 openclaw onboard (设置 API Key)...');
45
+ try {
46
+ const { execSync } = require('child_process');
47
+ execSync([
48
+ 'openclaw onboard',
49
+ '--non-interactive',
50
+ '--accept-risk',
51
+ '--skip-health',
52
+ '--auth-choice minimax-cn-api',
53
+ '--token "' + apiKey + '"',
54
+ '--minimax-api-key "' + apiKey + '"',
55
+ ].join(' '), { stdio: 'inherit' });
56
+ console.log('✅ API Key 已通过 onboard 设置');
57
+ } catch (err) {
58
+ console.log('⚠️ onboard 失败 (继续注入 JSON): ' + err.message);
59
+ }
60
+ } else {
61
+ console.log('');
62
+ console.log('💡 未传入 --key,跳过 onboard');
63
+ console.log(' 设置方法: myclaw minimax --key sk-xxx');
64
+ }
65
+
66
+ // ============================================================
67
+ // 第二步:写入我们的 JSON 配置(覆盖 onboard 的修改)
68
+ // ============================================================
39
69
 
40
- // 读取并修改
41
- const config = JSON.parse(fs.readFileSync(targetPath, 'utf8'));
70
+ console.log('');
71
+ console.log('📝 [Step 2] 注入 MiniMax 模型配置...');
72
+
73
+ // 重新读取(onboard 可能已改过)
74
+ const { config } = readConfig();
42
75
 
43
- // 1. auth.profiles → 只保留 minimax
44
76
  config.auth = {
45
77
  profiles: {
46
78
  "minimax:cn": {
@@ -50,7 +82,6 @@ function run(cliArgs) {
50
82
  }
51
83
  };
52
84
 
53
- // 2. models.providers → 只保留 minimax(key 由 onboard 管理)
54
85
  config.models = {
55
86
  mode: "merge",
56
87
  providers: {
@@ -78,7 +109,6 @@ function run(cliArgs) {
78
109
  }
79
110
  };
80
111
 
81
- // 3. agents.defaults → 使用 minimax 模型
82
112
  if (!config.agents) config.agents = {};
83
113
  if (!config.agents.defaults) config.agents.defaults = {};
84
114
 
@@ -94,53 +124,16 @@ function run(cliArgs) {
94
124
  "minimax/MiniMax-M2.7-highspeed": {}
95
125
  };
96
126
 
97
- // 写回文件
98
- fs.writeFileSync(targetPath, JSON.stringify(config, null, 2) + '\n', 'utf8');
127
+ writeConfig(config, configPath);
99
128
 
100
129
  // 验证写入
101
- const verify = JSON.parse(fs.readFileSync(targetPath, 'utf8'));
102
- const writtenModelId = verify.models?.providers?.minimax?.models?.[0]?.id || '???';
103
- const writtenDefault = verify.agents?.defaults?.model?.primary || '???';
104
-
105
- console.log('✅ MiniMax 模型配置已注入');
106
- console.log('');
107
- console.log(' [验证] 写入的 model ID: ' + writtenModelId);
108
- console.log(' [验证] 写入的 default: ' + writtenDefault);
109
- console.log(' [验证] 文件路径: ' + targetPath);
130
+ const verify = readConfig();
131
+ const writtenModelId = verify.config.models?.providers?.minimax?.models?.[0]?.id || '???';
132
+ const writtenDefault = verify.config.agents?.defaults?.model?.primary || '???';
110
133
 
111
- // 4. 通过 openclaw onboard 设置 API Key
112
- if (apiKey) {
113
- console.log('');
114
- console.log('🔑 执行 openclaw onboard (设置 API Key)...');
115
- try {
116
- const { execSync } = require('child_process');
117
- execSync([
118
- 'openclaw onboard',
119
- '--non-interactive',
120
- '--accept-risk',
121
- '--skip-health',
122
- '--auth-choice minimax-cn-api',
123
- '--token "' + apiKey + '"',
124
- '--minimax-api-key "' + apiKey + '"',
125
- ].join(' '), { stdio: 'inherit' });
126
- console.log('✅ API Key 已通过 onboard 设置');
127
-
128
- // 再次验证
129
- const reVerify = JSON.parse(fs.readFileSync(targetPath, 'utf8'));
130
- const finalModelId = reVerify.models?.providers?.minimax?.models?.[0]?.id || '???';
131
- const finalDefault = reVerify.agents?.defaults?.model?.primary || '???';
132
-
133
- if (finalModelId !== "MiniMax-M2.7-highspeed") {
134
- console.log('⚠️ [警告] onboard 命令覆盖了你配置的模型 ID: ' + finalModelId);
135
- }
136
- } catch (err) {
137
- console.log('⚠️ onboard 失败: ' + err.message);
138
- }
139
- } else {
140
- console.log('');
141
- console.log('💡 未传入 --key,跳过 API Key 设置');
142
- console.log(' 设置方法: myclaw minimax --key sk-xxx');
143
- }
134
+ console.log('✅ 配置已注入');
135
+ console.log(' [验证] model ID: ' + writtenModelId);
136
+ console.log(' [验证] default: ' + writtenDefault);
144
137
 
145
138
  console.log('');
146
139
  }
package/launch.js ADDED
@@ -0,0 +1,154 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * ============================================================================
5
+ * MyClaw Launch - 统一启动流程
6
+ * ============================================================================
7
+ *
8
+ * 使用: myclaw launch
9
+ *
10
+ * 统一的启动链条,被 bat 脚本和 wsl2 安装器共同复用:
11
+ * Step 1: 更新 MyClaw 到最新版
12
+ * Step 2: 执行 Patch(UI + Skills + Config)
13
+ * Step 3: 后台启动 OpenClaw Gateway
14
+ * Step 4: 打开浏览器控制台
15
+ * Step 5: 等待 Gateway 进程(关闭终端 = 停止服务)
16
+ * ============================================================================
17
+ */
18
+
19
+ const { execSync, spawn } = require('child_process');
20
+ const os = require('os');
21
+ const path = require('path');
22
+
23
+ const isWindows = os.platform() === 'win32';
24
+ const C = isWindows
25
+ ? { r: '', g: '', y: '', b: '', nc: '' }
26
+ : { r: '\x1b[31m', g: '\x1b[32m', y: '\x1b[33m', b: '\x1b[34m', nc: '\x1b[0m' };
27
+
28
+ const BAR = '============================================';
29
+
30
+ // ============================================================================
31
+ // Step 1: 更新 MyClaw
32
+ // ============================================================================
33
+
34
+ function stepUpdate() {
35
+ console.log('[1/4] 更新 MyClaw...');
36
+
37
+ try {
38
+ const registry = 'https://registry.npmjs.org';
39
+ const pkg = '@aiyiran/myclaw';
40
+ const currentVersion = require('./package.json').version;
41
+
42
+ const latestVersion = execSync(
43
+ 'npm view ' + pkg + ' version --registry ' + registry,
44
+ { encoding: 'utf8', timeout: 15000 }
45
+ ).trim();
46
+
47
+ if (currentVersion === latestVersion) {
48
+ console.log(' ' + C.g + '[OK]' + C.nc + ' 已是最新 v' + currentVersion);
49
+ } else {
50
+ console.log(' v' + currentVersion + ' → v' + latestVersion);
51
+ const tarball = execSync(
52
+ 'npm view ' + pkg + ' dist.tarball --registry ' + registry,
53
+ { encoding: 'utf8', timeout: 15000 }
54
+ ).trim();
55
+ execSync('npm install -g ' + tarball, { stdio: 'pipe', timeout: 60000 });
56
+ console.log(' ' + C.g + '[OK]' + C.nc + ' 已升级到 v' + latestVersion);
57
+ }
58
+ } catch (err) {
59
+ console.log(' ' + C.y + '[跳过]' + C.nc + ' 更新失败 (非致命)');
60
+ }
61
+ console.log('');
62
+ }
63
+
64
+ // ============================================================================
65
+ // Step 2: 执行 Patch
66
+ // ============================================================================
67
+
68
+ function stepPatch() {
69
+ console.log('[2/4] Patch...');
70
+
71
+ try {
72
+ const { patch } = require('./patch');
73
+ const { patchSkills } = require('./patch-skill');
74
+ const { patchConfig } = require('./find-config');
75
+
76
+ patch();
77
+ patchSkills();
78
+ patchConfig({
79
+ session: {
80
+ reset: {
81
+ mode: 'idle',
82
+ idleMinutes: 90720,
83
+ },
84
+ },
85
+ });
86
+
87
+ console.log(' ' + C.g + '[OK]' + C.nc);
88
+ } catch (err) {
89
+ console.log(' ' + C.y + '[跳过]' + C.nc + ' ' + err.message);
90
+ }
91
+ console.log('');
92
+ }
93
+
94
+ // ============================================================================
95
+ // Step 3 & 4: 启动 Gateway + 打开浏览器
96
+ // ============================================================================
97
+
98
+ function stepGatewayAndOpen() {
99
+ console.log('[3/4] 启动 Gateway...');
100
+ console.log('');
101
+ console.log(BAR);
102
+ console.log(' Gateway starting...');
103
+ console.log(' 关闭此窗口 = 停止服务');
104
+ console.log(BAR);
105
+ console.log('');
106
+
107
+ // 后台启动 gateway
108
+ const gateway = spawn('openclaw', ['gateway'], {
109
+ stdio: 'inherit',
110
+ detached: false,
111
+ });
112
+
113
+ // 打开浏览器(不阻塞)
114
+ console.log('[4/4] 打开浏览器...');
115
+ try {
116
+ // 直接调用 runOpen 的逻辑
117
+ execSync('node "' + path.join(__dirname, 'index.js') + '" open', {
118
+ stdio: 'pipe',
119
+ timeout: 10000,
120
+ });
121
+ console.log(' ' + C.g + '[OK]' + C.nc);
122
+ } catch {
123
+ console.log(' ' + C.y + '[跳过]' + C.nc);
124
+ }
125
+ console.log('');
126
+
127
+ // 等待 gateway 进程退出(关闭终端会终止)
128
+ return new Promise((resolve) => {
129
+ gateway.on('close', (code) => {
130
+ console.log('');
131
+ console.log(' Gateway 已退出。');
132
+ resolve(code);
133
+ });
134
+ });
135
+ }
136
+
137
+ // ============================================================================
138
+ // 主入口
139
+ // ============================================================================
140
+
141
+ async function run() {
142
+ const bar = '----------------------------------------';
143
+
144
+ console.log('');
145
+ console.log('[' + C.b + 'MyClaw' + C.nc + '] ' + C.b + '启动流程' + C.nc);
146
+ console.log(bar);
147
+ console.log('');
148
+
149
+ stepUpdate();
150
+ stepPatch();
151
+ await stepGatewayAndOpen();
152
+ }
153
+
154
+ module.exports = { run };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiyiran/myclaw",
3
- "version": "1.0.61",
3
+ "version": "1.0.63",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "bin": {
package/patch-reset.js ADDED
@@ -0,0 +1,59 @@
1
+ /**
2
+ * patch-reset.js — 修改 openclaw.json 的 session.reset 字段
3
+ *
4
+ * 使用 patchConfig 精准修改,不影响其他配置。
5
+ *
6
+ * 入口: myclaw reset-idle [--minutes N]
7
+ */
8
+
9
+ const { patchConfig, readConfig } = require('./find-config');
10
+
11
+ /**
12
+ * 将 session.reset 设为 idle 模式,默认 90720 分钟(≈63 天)
13
+ * @param {number} [idleMinutes=90720] - idle 超时分钟数
14
+ */
15
+ function run(cliArgs) {
16
+ // 解析 --minutes 参数
17
+ let idleMinutes = 90720;
18
+ if (cliArgs) {
19
+ for (let i = 0; i < cliArgs.length; i++) {
20
+ if (cliArgs[i] === '--minutes' && cliArgs[i + 1]) {
21
+ idleMinutes = parseInt(cliArgs[i + 1], 10);
22
+ if (isNaN(idleMinutes) || idleMinutes <= 0) {
23
+ console.error('❌ --minutes 必须是正整数');
24
+ process.exit(1);
25
+ }
26
+ i++;
27
+ }
28
+ }
29
+ }
30
+
31
+ console.log('📝 修改 session.reset...');
32
+ console.log(' mode: idle');
33
+ console.log(' idleMinutes: ' + idleMinutes + ' (' + Math.round(idleMinutes / 1440) + ' 天)');
34
+ console.log('');
35
+
36
+ try {
37
+ const { config, configPath } = patchConfig({
38
+ session: {
39
+ reset: {
40
+ mode: "idle",
41
+ idleMinutes: idleMinutes
42
+ }
43
+ }
44
+ });
45
+
46
+ // 验证
47
+ const reset = config.session?.reset;
48
+ console.log('✅ 已修改: ' + configPath);
49
+ console.log(' [验证] session.reset.mode: ' + (reset?.mode || '???'));
50
+ console.log(' [验证] session.reset.idleMinutes: ' + (reset?.idleMinutes || '???'));
51
+ } catch (err) {
52
+ console.error('❌ ' + err.message);
53
+ process.exit(1);
54
+ }
55
+
56
+ console.log('');
57
+ }
58
+
59
+ module.exports = { run };
@@ -6,6 +6,10 @@
6
6
  * 独立运行,不依赖 myclaw CLI。
7
7
  * OpenClaw agent 可直接调用此脚本。
8
8
  *
9
+ * 流程:
10
+ * 1. 先执行 openclaw onboard(设置 API Key,会覆盖 JSON)
11
+ * 2. 再写入我们的 JSON 配置(覆盖回来)
12
+ *
9
13
  * 用法:
10
14
  * node inject.js # 只注入模型配置(不设 key)
11
15
  * node inject.js --key sk-xxx # 注入模型 + 通过 onboard 设置 key
@@ -44,9 +48,39 @@ if (!fs.existsSync(targetPath)) {
44
48
  console.log('📍 找到配置: ' + targetPath);
45
49
 
46
50
  // ============================================================================
47
- // 注入模型配置
51
+ // 第一步:先执行 onboard(它会覆盖 JSON,所以必须先跑)
52
+ // ============================================================================
53
+
54
+ if (apiKey) {
55
+ console.log('');
56
+ console.log('🔑 [Step 1] 执行 openclaw onboard (设置 API Key)...');
57
+ try {
58
+ execSync([
59
+ 'openclaw onboard',
60
+ '--non-interactive',
61
+ '--accept-risk',
62
+ '--skip-health',
63
+ '--auth-choice minimax-cn-api',
64
+ '--token "' + apiKey + '"',
65
+ '--minimax-api-key "' + apiKey + '"',
66
+ ].join(' '), { stdio: 'inherit' });
67
+ console.log('✅ API Key 已通过 onboard 设置');
68
+ } catch (err) {
69
+ console.log('⚠️ onboard 失败 (继续注入 JSON): ' + err.message);
70
+ }
71
+ } else {
72
+ console.log('');
73
+ console.log('💡 未传入 --key,跳过 onboard');
74
+ console.log(' 设置方法: node inject.js --key sk-xxx');
75
+ }
76
+
77
+ // ============================================================================
78
+ // 第二步:写入我们的 JSON 配置(覆盖 onboard 的修改)
48
79
  // ============================================================================
49
80
 
81
+ console.log('');
82
+ console.log('📝 [Step 2] 注入 MiniMax 模型配置...');
83
+
50
84
  const config = JSON.parse(fs.readFileSync(targetPath, 'utf8'));
51
85
 
52
86
  config.auth = {
@@ -102,37 +136,14 @@ config.agents.defaults.models = {
102
136
 
103
137
  fs.writeFileSync(targetPath, JSON.stringify(config, null, 2) + '\n', 'utf8');
104
138
 
105
- console.log('✅ MiniMax 模型配置已注入');
106
- console.log(' auth.profiles → minimax:cn');
107
- console.log(' models.providersminimax (MiniMax-M2.7)');
108
- console.log(' agents.defaults minimax/MiniMax-M2.7-highspeed');
109
-
110
- // ============================================================================
111
- // 通过 openclaw onboard 设置 API Key
112
- // ============================================================================
139
+ // 验证写入
140
+ const verify = JSON.parse(fs.readFileSync(targetPath, 'utf8'));
141
+ const writtenModelId = verify.models?.providers?.minimax?.models?.[0]?.id || '???';
142
+ const writtenDefault = verify.agents?.defaults?.model?.primary || '???';
113
143
 
114
- if (apiKey) {
115
- console.log('');
116
- console.log('🔑 执行 openclaw onboard (设置 API Key)...');
117
- try {
118
- execSync([
119
- 'openclaw onboard',
120
- '--non-interactive',
121
- '--accept-risk',
122
- '--skip-health',
123
- '--auth-choice minimax-cn-api',
124
- '--token "' + apiKey + '"',
125
- '--minimax-api-key "' + apiKey + '"',
126
- ].join(' '), { stdio: 'inherit' });
127
- console.log('✅ API Key 已通过 onboard 设置');
128
- } catch (err) {
129
- console.log('⚠️ onboard 失败: ' + err.message);
130
- }
131
- } else {
132
- console.log('');
133
- console.log('💡 未传入 --key,跳过 API Key 设置');
134
- console.log(' 设置方法: node inject.js --key sk-xxx');
135
- }
144
+ console.log('✅ 配置已注入');
145
+ console.log(' [验证] model ID: ' + writtenModelId);
146
+ console.log(' [验证] default: ' + writtenDefault);
136
147
 
137
148
  // ============================================================================
138
149
  // 重启 Gateway
package/wsl2.js CHANGED
@@ -13,7 +13,7 @@
13
13
  *
14
14
  * 自动检测安装状态,分两阶段完成:
15
15
  * Phase 1: 启用底层 Windows 功能 + 安装 WSL → 需要重启
16
- * Phase 2: 导入预制 Linux 环境 → 完成
16
+ * Phase 2: 导入预制 Linux 环境 → 自动启动 Gateway
17
17
  * ============================================================================
18
18
  */
19
19
 
@@ -200,7 +200,7 @@ Write-Host ' MyClaw WSL2 安装 - 阶段 1/2'
200
200
  Write-Host '========================================'
201
201
  Write-Host ''
202
202
 
203
- $dir = "$env:LOCALAPPDATA\\myclaw"
203
+ $dir = "$env:LOCALAPPDATA\\\\myclaw"
204
204
  New-Item -ItemType Directory -Force -Path $dir | Out-Null
205
205
 
206
206
  Write-Host '[1/4] 启用 Windows Subsystem for Linux...'
@@ -222,7 +222,7 @@ try {
222
222
  Write-Host ''
223
223
 
224
224
  Write-Host '[3/4] 获取 WSL 安装包...'
225
- $msi = "$dir\\wsl_full.msi"
225
+ $msi = "$dir\\\\wsl_full.msi"
226
226
  $wslInstalled = $false
227
227
  try {
228
228
  $ver = wsl --version 2>&1 | Out-String
@@ -238,7 +238,7 @@ ${askMsi}
238
238
  Write-Host ''
239
239
  Write-Host '[4/4] 安装 WSL...'
240
240
  try {
241
- Start-Process msiexec.exe -ArgumentList "/i \`"$msi\`" /quiet /norestart" -Wait -NoNewWindow
241
+ Start-Process msiexec.exe -ArgumentList "/i \\\`"$msi\\\`" /quiet /norestart" -Wait -NoNewWindow
242
242
  Write-Host ' [OK]'
243
243
  } catch {
244
244
  Write-Host ' [失败] 安装出错'
@@ -308,7 +308,7 @@ Write-Host ' 导入预制 Linux 环境'
308
308
  Write-Host '========================================'
309
309
  Write-Host ''
310
310
 
311
- $dir = "$env:LOCALAPPDATA\\myclaw"
311
+ $dir = "$env:LOCALAPPDATA\\\\myclaw"
312
312
  New-Item -ItemType Directory -Force -Path $dir | Out-Null
313
313
 
314
314
  Write-Host '[1/3] 设置 WSL2 为默认版本...'
@@ -317,9 +317,9 @@ Write-Host ' [OK]'
317
317
  Write-Host ''
318
318
 
319
319
  Write-Host '[2/3] 获取预制 Linux 环境...'
320
- $tarPath = "$dir\\openclaw-rootfs.tar"
320
+ $tarPath = "$dir\\\\openclaw-rootfs.tar"
321
321
  $distroName = 'OpenClaw'
322
- $installDir = "$dir\\OpenClaw"
322
+ $installDir = "$dir\\\\OpenClaw"
323
323
  $installed = $false
324
324
 
325
325
  ${askTar}
@@ -357,12 +357,15 @@ Write-Host ''
357
357
  Write-Host '========================================'
358
358
  if ($installed) {
359
359
  Write-Host ' [OK] WSL2 + OpenClaw Linux 安装完成!'
360
+ Write-Host '========================================'
360
361
  Write-Host ''
361
- Write-Host ' 输入 wsl 即可进入 Linux 环境'
362
+
363
+ # 统一启动流程:update + patch + gateway + open
364
+ wsl -d $distroName -- myclaw launch
362
365
  } else {
363
366
  Write-Host ' [失败] 请检查后重试: myclaw wsl2'
367
+ Write-Host '========================================'
364
368
  }
365
- Write-Host '========================================'
366
369
 
367
370
  } catch {
368
371
  Write-Host ''
@@ -380,7 +383,7 @@ Write-Host '========================================'
380
383
  if (launchElevatedPS(ps)) {
381
384
  console.log('[' + C.g + '已启动' + C.nc + '] 请查看新弹出的蓝色窗口');
382
385
  console.log('');
383
- console.log('安装完成后,输入 ' + C.y + 'wsl' + C.nc + ' 即可进入 Linux');
386
+ console.log('安装完成后会自动启动 Gateway 并打开浏览器');
384
387
  console.log('');
385
388
  }
386
389
  }