@aiyiran/myclaw 1.0.145 → 1.0.152

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 CHANGED
@@ -26,6 +26,7 @@
26
26
  const { execSync } = require('child_process');
27
27
  const os = require('os');
28
28
  const path = require('path');
29
+ const readline = require('readline');
29
30
  const { createAgent } = require('./create_agent');
30
31
  const { version } = require(path.join(__dirname, 'package.json'));
31
32
  const { TOKEN, DEFAULT_URL } = require(path.join(__dirname, 'config'));
@@ -52,13 +53,17 @@ const isWindows = detectPlatform() === 'windows';
52
53
 
53
54
  function makeColors() {
54
55
  if (isWindows) {
55
- return { red: '', green: '', yellow: '', blue: '', nc: '' };
56
+ return { red: '', green: '', yellow: '', blue: '', cyan: '', white: '', bold: '', dim: '', nc: '' };
56
57
  }
57
58
  return {
58
59
  red: '\x1b[31m',
59
60
  green: '\x1b[32m',
60
61
  yellow: '\x1b[33m',
61
62
  blue: '\x1b[34m',
63
+ cyan: '\x1b[36m',
64
+ white: '\x1b[37m\x1b[1m',
65
+ bold: '\x1b[1m',
66
+ dim: '\x1b[2m',
62
67
  nc: '\x1b[0m'
63
68
  };
64
69
  }
@@ -99,257 +104,230 @@ function runInstall() {
99
104
  }
100
105
 
101
106
  // ============================================================================
102
- // 状态命令
107
+ // 重装命令 (mci)
103
108
  // ============================================================================
104
109
 
105
- function runStatus() {
106
- const bar = '----------------------------------------';
107
-
110
+ const OPENCLAW_VERSION = '2026.4.5';
111
+
112
+ function runReinstall() {
113
+ const bar = '────────────────────────────────────────';
108
114
  console.log('');
109
- console.log('[' + colors.blue + 'MyClaw' + colors.nc + '] ' + colors.blue + '状态面板' + colors.nc);
115
+ console.log(bar);
116
+ console.log(' 🔄 OpenClaw 重装工具 (锁定版本: ' + colors.green + OPENCLAW_VERSION + colors.nc + ')');
110
117
  console.log(bar);
111
118
  console.log('');
112
-
113
- // Gateway 状态
114
- console.log('[Gateway]');
119
+
120
+ // 1. 安装前升级 MyClaw
121
+ console.log('[1/8] ⬆️ 升级 MyClaw (安装前)...');
115
122
  try {
116
- execSync('openclaw health', { stdio: 'pipe' });
117
- console.log(' 状态: ' + colors.green + '[OK] 运行中' + colors.nc);
118
- try {
119
- const statusOutput = execSync('openclaw status 2>/dev/null', { encoding: 'utf8' });
120
- const dashboardMatch = statusOutput.match(/Dashboard[^\n]*?(http:\/\/[^\s]+)/);
121
- console.log(' 控制台: ' + (dashboardMatch ? dashboardMatch[1] : 'http://127.0.0.1:18789'));
122
- } catch {
123
- console.log(' 控制台: http://127.0.0.1:18789');
124
- }
123
+ runUpdate();
125
124
  } catch (err) {
126
- console.log(' 状态: ' + colors.red + '[ERROR] 未运行' + colors.nc);
127
- console.log(' 启动命令: ' + colors.yellow + 'openclaw gateway' + colors.nc);
125
+ console.log(' ' + colors.yellow + ' 升级跳过' + colors.nc);
128
126
  }
129
127
  console.log('');
130
-
131
- // Session 数量
132
- console.log('[Sessions]');
133
- try {
134
- const sessionsOutput = execSync('openclaw sessions list 2>/dev/null', { encoding: 'utf8' });
135
- const sessionCount = (sessionsOutput.match(/agent:/g) || []).length;
136
- console.log(' 活跃会话: ' + colors.green + sessionCount + colors.nc + ' 个');
137
- } catch {
138
- console.log(' 活跃会话: ' + colors.red + '0' + colors.nc + ' 个');
139
- }
140
- console.log('');
141
-
142
- // Agent 数量
143
- console.log('[Agents]');
128
+
129
+ // 2. 设置中国镜像
130
+ console.log('[2/8] 🌐 设置 npm 中国镜像...');
144
131
  try {
145
- const agentsOutput = execSync('openclaw agents list 2>/dev/null', { encoding: 'utf8' });
146
- const agentCount = (agentsOutput.match(/agent:/g) || []).length;
147
- console.log(' 已注册 Agent: ' + colors.green + agentCount + colors.nc + ' 个');
148
- } catch {
149
- console.log(' 已注册 Agent: ' + colors.red + '0' + colors.nc + ' 个');
132
+ execSync('npm config set registry https://registry.npmmirror.com', { stdio: 'inherit' });
133
+ console.log(' ' + colors.green + '✓ 已切换到淘宝镜像' + colors.nc);
134
+ } catch (err) {
135
+ console.log(' ' + colors.yellow + '⚠ 镜像设置跳过' + colors.nc);
150
136
  }
151
137
  console.log('');
152
-
153
- // 最近活动
154
- console.log('[最近活动]');
138
+
139
+ // 3. 清理 npm 缓存
140
+ console.log('[3/8] 🧹 清理 npm 缓存...');
155
141
  try {
156
- const sessionsOutput = execSync('openclaw sessions list 2>/dev/null', { encoding: 'utf8' });
157
- const lines = sessionsOutput.split('\n').filter(line =>
158
- line.includes('just now') || /\d+m ago/.test(line) || /\d+h ago/.test(line)
159
- ).slice(0, 3);
160
-
161
- if (lines.length > 0) {
162
- lines.forEach(line => {
163
- console.log(' ' + line.trim());
164
- });
165
- } else {
166
- console.log(' 无最近活动');
167
- }
168
- } catch {
169
- console.log(' 无最近活动');
142
+ execSync('npm cache clean --force', { stdio: 'inherit' });
143
+ console.log(' ' + colors.green + '✓ 缓存清理完成' + colors.nc);
144
+ } catch (err) {
145
+ console.log(' ' + colors.yellow + '⚠ 缓存清理跳过' + colors.nc);
170
146
  }
171
147
  console.log('');
172
-
173
- console.log(bar);
174
- console.log('提示: 运行 ' + colors.yellow + 'openclaw status' + colors.nc + ' 查看完整状态');
175
- console.log(' 运行 ' + colors.yellow + 'myclaw help' + colors.nc + ' 查看所有命令');
176
- console.log('');
177
- }
178
-
179
- // ============================================================================
180
- // 创建新 Agent
181
- // ============================================================================
182
148
 
183
- function runNew() {
184
- const rawName = args[1];
185
-
186
- // 无参数 向导模式
187
- if (!rawName) {
188
- const { runNewAgent } = require('./wizards/index');
189
- runNewAgent();
190
- return;
149
+ // 4. 卸载旧版本
150
+ console.log('[4/8] 🗑️ 卸载旧版本...');
151
+ try {
152
+ execSync('npm uninstall -g openclaw', { stdio: 'inherit' });
153
+ console.log(' ' + colors.green + '✓ 卸载完成' + colors.nc);
154
+ } catch (err) {
155
+ console.log(' ' + colors.yellow + '⚠ 卸载跳过(可能未安装)' + colors.nc);
191
156
  }
192
-
193
- // 有参数 → 一键创建模式(带分步日志)
194
- // myclaw new haha → 默认出生文案
195
- // myclaw new haha 你好见到你很高兴 → 自定义首条消息
196
- const firstMessage = args.slice(2).join(' ').trim() || null;
197
-
198
- const bar = '────────────────────────────────────────';
199
- const G = colors.green;
200
- const Y = colors.yellow;
201
- const R = colors.red;
202
- const B = colors.blue;
203
- const NC = colors.nc;
204
-
205
- console.log('');
206
- console.log('[' + B + 'MyClaw' + NC + '] ' + B + '创建 Agent: ' + rawName + NC);
207
- console.log(bar);
208
157
  console.log('');
209
158
 
210
- const { normalizeAgentId, validateAgentId } = require('./create_agent');
211
- const fs = require('fs');
212
- const path = require('path');
213
- const os = require('os');
214
- const { execSync } = require('child_process');
215
-
216
- const homeDir = os.homedir();
217
- const openclawDir = path.join(homeDir, '.openclaw');
218
- const configPath = path.join(openclawDir, 'openclaw.json');
219
-
220
- // ── Step 1: 名称标准化 ──
221
- console.log(B + '[1/6]' + NC + ' 标准化名称...');
222
- console.log(' ' + G + '▶ 发起:' + NC + ' normalizeAgentId("' + rawName + '")');
223
- let agentId;
159
+ // 5. 重新安装特定版本
160
+ console.log('[5/8] 📦 安装 openclaw@' + OPENCLAW_VERSION + '...');
224
161
  try {
225
- agentId = normalizeAgentId(rawName);
226
- validateAgentId(agentId);
227
- console.log(' ' + G + '◀ 返回:' + NC + ' agentId = "' + agentId + '" ✅');
162
+ execSync('npm install -g openclaw@' + OPENCLAW_VERSION, {
163
+ stdio: 'inherit',
164
+ env: { ...process.env, npm_config_progress: 'true' }
165
+ });
166
+ console.log(' ' + colors.green + '✓ 安装完成' + colors.nc);
228
167
  } catch (err) {
229
- console.log(' ' + R + ' 返回:' + NC + ' ❌ ' + err.message);
168
+ console.error(' ' + colors.red + ' 安装失败: ' + err.message + colors.nc);
230
169
  process.exit(1);
231
170
  }
232
171
  console.log('');
233
172
 
234
- // ── Step 2: 环境检查 ──
235
- console.log(B + '[2/6]' + NC + ' 环境检查(查重 + 目录冲突)...');
236
- console.log(' ' + G + '▶ 发起:' + NC + ' 读取 ' + configPath);
237
- let configData;
173
+ // 6. 安装后升级 MyClaw
174
+ console.log('[6/8] ⬆️ 升级 MyClaw (安装后)...');
238
175
  try {
239
- configData = JSON.parse(fs.readFileSync(configPath, 'utf8'));
240
- if (!configData.agents) configData.agents = {};
241
- if (!Array.isArray(configData.agents.list)) configData.agents.list = [];
242
-
243
- const exists = configData.agents.list.find(a => a && a.id === agentId);
244
- if (exists) {
245
- console.log(' ' + R + '◀ 返回:' + NC + ' ❌ Agent "' + agentId + '" 已存在');
246
- process.exit(1);
247
- }
248
- const workspaceDir = path.join(openclawDir, 'workspace-' + agentId);
249
- const agentDir = path.join(openclawDir, 'agents', agentId, 'agent');
250
- if (fs.existsSync(workspaceDir) || fs.existsSync(agentDir)) {
251
- console.log(' ' + R + '◀ 返回:' + NC + ' ❌ 目录已存在');
252
- process.exit(1);
253
- }
254
- console.log(' ' + G + '◀ 返回:' + NC + ' 名称无冲突,目录可用 ✅');
176
+ runUpdate();
255
177
  } catch (err) {
256
- console.log(' ' + R + ' 返回:' + NC + ' ❌ ' + err.message);
257
- process.exit(1);
178
+ console.log(' ' + colors.yellow + ' 升级跳过' + colors.nc);
258
179
  }
259
180
  console.log('');
260
181
 
261
- // ── Step 3: 创建工作空间 ──
262
- console.log(B + '[3/6]' + NC + ' 创建工作空间(SOUL.md / AGENTS.md / USER.md ...)...');
263
- const workspaceDir = path.join(openclawDir, 'workspace-' + agentId);
264
- const agentDir = path.join(openclawDir, 'agents', agentId, 'agent');
265
- const sessionsDir = path.join(openclawDir, 'agents', agentId, 'sessions');
266
- console.log(' ' + G + '▶ 发起:' + NC + ' mkdir + writeFile → ' + workspaceDir);
182
+ // 7. 验证安装
183
+ console.log('[7/8] ✔️ 验证安装...');
267
184
  try {
268
- fs.mkdirSync(workspaceDir, { recursive: true });
269
- fs.mkdirSync(agentDir, { recursive: true });
270
- fs.mkdirSync(sessionsDir, { recursive: true });
271
- // 写入默认文件
272
- const defaultFiles = {
273
- 'AGENTS.md': '# AGENTS.md - ' + agentId + '\n\nThis workspace belongs to the `' + agentId + '` agent.\n\n## Startup\n- Read `SOUL.md`\n- Read `USER.md`\n\n## Rules\n- Be helpful, careful, and concise.\n',
274
- 'SOUL.md': '# SOUL.md\n\nYou are `' + agentId + '`.\n\nBe useful, calm, direct, and trustworthy.\n',
275
- 'USER.md': '# USER.md\n\n- Name: 孙依然\n- What to call them: 依然\n- Timezone: Asia/Shanghai\n',
276
- 'IDENTITY.md': '# IDENTITY.md\n\n- Name: ' + agentId + '\n- Role: OpenClaw agent\n',
277
- 'BOOTSTRAP.md': '# BOOTSTRAP.md\n\nYou are a newly created agent named `' + agentId + '`.\nOn first runs, learn your workspace files and begin helping.\n',
278
- };
279
- for (const [fn, content] of Object.entries(defaultFiles)) {
280
- const fp = path.join(workspaceDir, fn);
281
- if (!fs.existsSync(fp)) fs.writeFileSync(fp, content, 'utf8');
282
- }
283
- console.log(' ' + G + '◀ 返回:' + NC + ' 已创建 ' + Object.keys(defaultFiles).length + ' 个基础文件 ✅');
185
+ const version = execSync('openclaw --version', { encoding: 'utf8' }).trim();
186
+ console.log(' ' + colors.green + '✓ ' + version + colors.nc);
284
187
  } catch (err) {
285
- console.log(' ' + R + ' 返回:' + NC + ' ❌ ' + err.message);
188
+ console.error(' ' + colors.red + ' 验证失败' + colors.nc);
286
189
  process.exit(1);
287
190
  }
288
191
  console.log('');
289
192
 
290
- // ── Step 4: 注册到配置 ──
291
- console.log(B + '[4/6]' + NC + ' 注册到 openclaw.json(agents.list)...');
292
- const backupPath = configPath + '.bak.agent-birth.' + new Date().toISOString().replace(/[:.]/g, '-').slice(0, 26) + 'Z';
293
- console.log(' ' + G + '▶ 发起:' + NC + ' 备份 → ' + path.basename(backupPath));
193
+ // 8. 启动 Gateway
194
+ console.log('[8/8] 🚀 启动 Gateway...');
294
195
  try {
295
- fs.copyFileSync(configPath, backupPath);
296
- configData.agents.list.push({
297
- id: agentId,
298
- name: agentId,
299
- workspace: workspaceDir.replace(/\\/g, '/'),
300
- agentDir: agentDir.replace(/\\/g, '/'),
301
- });
302
- fs.writeFileSync(configPath, JSON.stringify(configData, null, 2) + '\n', 'utf8');
303
- console.log(' ' + G + '◀ 返回:' + NC + ' 配置已写入,备份已保存 ✅');
196
+ const start = require('./start');
197
+ start.run();
304
198
  } catch (err) {
305
- console.log(' ' + R + ' 返回:' + NC + ' ❌ ' + err.message);
306
- process.exit(1);
199
+ console.log(' ' + colors.yellow + ' 启动跳过' + colors.nc);
307
200
  }
308
201
  console.log('');
309
202
 
310
- // ── Step 5: 发送首条消息 ──
311
- console.log(B + '[5/6]' + NC + ' 发送首条消息(唤醒 Agent)...');
312
- const nowUtc = new Date();
313
- const nowBj = new Date(nowUtc.getTime() + 8 * 60 * 60 * 1000);
314
- const ts = nowBj.getUTCFullYear() + '年' + (nowBj.getUTCMonth() + 1) + '月' + nowBj.getUTCDate() + '日' + String(nowBj.getUTCHours()).padStart(2, '0') + ':' + String(nowBj.getUTCMinutes()).padStart(2, '0');
315
- const birthMessage = firstMessage || ('你好,你的生日是北京时间' + ts + ',请记录这个信息。\n欢迎你来到这个世界,我是你的造物主,我们是伙伴,我叫做孙依然,你可以叫我依然,请多多指教,共同成长。');
203
+ console.log(bar);
204
+ console.log(colors.green + ' ✅ 重装完成!' + colors.nc);
205
+ console.log(bar);
206
+ console.log('');
207
+ }
316
208
 
317
- const cmd = 'openclaw agent --agent ' + agentId + ' --message ' + JSON.stringify(birthMessage) + ' --json';
318
- console.log(' ' + G + '▶ 发起:' + NC + ' $ ' + G + cmd.substring(0, 80) + (cmd.length > 80 ? '...' : '') + NC);
319
- console.log(' ' + Y + ' ⏳ 等待大模型响应(可能需要 5~15 秒)...' + NC);
209
+ // ============================================================================
210
+ // 状态命令
211
+ // ============================================================================
320
212
 
321
- let firstMessageSent = false;
322
- try {
323
- execSync(cmd + ' 2>&1', { encoding: 'utf8', timeout: 45000 });
324
- firstMessageSent = true;
325
- console.log(' ' + G + '◀ 返回:' + NC + ' 唤醒成功,Session 已建立 ✅');
326
- } catch (err) {
327
- console.log(' ' + Y + '◀ 返回:' + NC + ' ⚠️ 唤醒超时或失败(非致命)');
328
- console.log(' ' + '手动重试: ' + Y + 'openclaw agent --agent ' + agentId + ' --message "你好"' + NC);
329
- }
213
+ function runStatus() {
214
+ const url = 'http://127.0.0.1:18789?token=' + TOKEN;
215
+ console.log('');
216
+ console.log(' ' + colors.green + url + colors.nc);
330
217
  console.log('');
218
+ console.log(' ' + colors.dim + '打开方式:' + colors.nc);
219
+ console.log(' ' + colors.dim + ' 1. 按住 ' + colors.yellow + 'Control' + colors.dim + ' + 点击链接' + colors.nc);
220
+ console.log(' ' + colors.dim + ' 2. 复制链接,在浏览器地址栏打开' + colors.nc);
221
+ console.log(' ' + colors.dim + ' 3. ' + colors.yellow + 'mc restart' + colors.dim + ' 后重启自动打开' + colors.nc);
222
+ console.log('');
223
+ }
331
224
 
332
- // ── Step 6: 验证 ──
333
- console.log(B + '[6/6]' + NC + ' 验证创建结果...');
334
- console.log(' ' + G + '▶ 发起:' + NC + ' 检查 agents.list 是否包含 "' + agentId + '"');
335
- try {
336
- const verify = JSON.parse(fs.readFileSync(configPath, 'utf8'));
337
- const found = verify.agents && verify.agents.list && verify.agents.list.find(a => a.id === agentId);
338
- if (found) {
339
- console.log(' ' + G + '◀ 返回:' + NC + ' Agent "' + agentId + '" 已成功登记 ✅');
340
- } else {
341
- console.log(' ' + R + '◀ 返回:' + NC + ' ⚠️ 未在配置中找到,请检查');
342
- }
343
- } catch (err) {
344
- console.log(' ' + Y + '◀ 返回:' + NC + ' ⚠️ 验证读取失败(非致命)');
225
+ // ============================================================================
226
+ // 创建新 Agent
227
+ // ============================================================================
228
+
229
+ function runNew() {
230
+ const G = colors.green;
231
+ const Y = colors.yellow;
232
+ const R = colors.red;
233
+ const B = colors.blue;
234
+ const NC = colors.nc;
235
+
236
+ // 支持两种调用:
237
+ // mc new → 交互输入名字
238
+ // mc new <name> → 直接使用传入的名字
239
+ const rawName = args[1];
240
+
241
+ if (rawName) {
242
+ doCreate(rawName);
243
+ return;
345
244
  }
346
245
 
246
+ // 交互模式:readline 询问名字(校验不通过则重试)
347
247
  console.log('');
348
- console.log(bar);
349
- console.log(G + '🎉 Agent "' + agentId + '" 创建完成!' + NC);
350
- console.log('');
351
- console.log('下一步: ' + Y + 'openclaw agent --agent ' + agentId + ' --message "你好"' + NC);
352
- console.log('');
248
+ if (process.stdin.isTTY) process.stdin.resume();
249
+ askName();
250
+
251
+ function askName() {
252
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
253
+ rl.question(B + '请输入 Agent 名字(英文、数字、连字符): ' + NC, function (answer) {
254
+ rl.close();
255
+ const name = (answer || '').trim();
256
+ if (!name) {
257
+ console.log(R + '名字不能为空,请重新输入。' + NC);
258
+ askName();
259
+ return;
260
+ }
261
+ // 预检:必须包含英文字母或数字
262
+ if (!/[a-zA-Z0-9]/.test(name)) {
263
+ console.log(R + '名字必须包含英文或数字,请重新输入(如 my-agent)。' + NC);
264
+ askName();
265
+ return;
266
+ }
267
+ doCreate(name);
268
+ });
269
+ }
270
+
271
+ function doCreate(input) {
272
+ const { normalizeAgentId } = require('./create_agent');
273
+
274
+ // 校验 1:中文名 / 非法字符
275
+ var agentId = normalizeAgentId(input);
276
+ if (!agentId || !/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(agentId)) {
277
+ console.log(R + '名字必须是英文、数字或连字符(如 my-agent),请重新输入。' + NC);
278
+ console.log('');
279
+ askName();
280
+ return;
281
+ }
282
+
283
+ // 校验 2:重名检查(不依赖 createAgent,避免它内部 process.exit)
284
+ const fs = require('fs');
285
+ const path = require('path');
286
+ const os = require('os');
287
+ const configPath = path.join(os.homedir(), '.openclaw', 'openclaw.json');
288
+ try {
289
+ var configData = JSON.parse(fs.readFileSync(configPath, 'utf8'));
290
+ var list = (configData.agents && configData.agents.list) || [];
291
+ if (list.some(function (a) { return a && a.id === agentId; })) {
292
+ console.log(R + 'Agent "' + agentId + '" 已存在,请换一个名字。' + NC);
293
+ console.log('');
294
+ askName();
295
+ return;
296
+ }
297
+ } catch (e) {
298
+ // 配置文件读不到就算了,交给 createAgent 处理
299
+ }
300
+
301
+ // 校验通过,开始创建
302
+ console.log(Y + '正在创建 Agent "' + agentId + '"...' + NC);
303
+ console.log('');
304
+
305
+ var result;
306
+ try {
307
+ result = require('./create_agent').createAgent(input);
308
+ } catch (err) {
309
+ console.log(R + '创建失败: ' + err.message + NC);
310
+ process.exit(1);
311
+ }
312
+
313
+ // 打印结果
314
+ console.log(G + '✅' + NC + ' Agent "' + agentId + '" 创建完成');
315
+ console.log('');
316
+ console.log(' ' + G + '✅' + NC + ' 名称标准化 ' + agentId);
317
+ console.log(' ' + G + '✅' + NC + ' 环境检查 无冲突');
318
+ console.log(' ' + G + '✅' + NC + ' 创建工作空间 已就绪');
319
+ console.log(' ' + G + '✅' + NC + ' 注册配置 已写入');
320
+ console.log(' ' + Y + '⏳' + NC + ' 唤醒 Agent 发送中...');
321
+ console.log('');
322
+ console.log('下一步: 进入龙虾,选择最上面的助手,去和她对话吧~');
323
+ console.log('');
324
+ console.log(' ' + colors.dim + 'http://127.0.0.1:18789?token=' + TOKEN + NC);
325
+ console.log('');
326
+ console.log(colors.dim + '如果唤醒失败,可手动发送命令:' + NC);
327
+ console.log(' ' + Y + 'openclaw agent --agent ' + agentId + ' --message "你好"' + NC);
328
+ console.log('');
329
+ process.exit(0);
330
+ }
353
331
  }
354
332
 
355
333
  // ============================================================================
@@ -701,7 +679,7 @@ function runPatch() {
701
679
  if (config && config.exec) {
702
680
  delete config.exec;
703
681
  requireSave = true;
704
- console.log('[myclaw-config] 🧹 已清理历史遗留的错误顶层 "exec" 常驻配置');
682
+ console.log('[myclaw-config] 已清理历史遗留的错误顶层 "exec" 常驻配置');
705
683
  }
706
684
 
707
685
  if (requireSave) {
@@ -713,11 +691,11 @@ function runPatch() {
713
691
  console.log('[myclaw-config] ✅ ' + key + ' → ' + JSON.stringify(value));
714
692
  }
715
693
  } else {
716
- console.log('[myclaw-config] ⏭️ Config 补丁已禁用 [disabled]');
694
+ console.log('[myclaw-config] Config 补丁已禁用 [disabled]');
717
695
  }
718
696
  }
719
697
  } catch (err) {
720
- console.log('[myclaw-config] ⚠️ 配置补丁失败: ' + err.message);
698
+ console.log('[myclaw-config] 配置补丁失败: ' + err.message);
721
699
  }
722
700
 
723
701
  // 5. 自定义注入脚本执行引擎 (Manifest `run` 数组)
@@ -733,16 +711,16 @@ function runPatch() {
733
711
  const strategy = entry.strategy || 'auto';
734
712
  const desc = entry.description || entry.module;
735
713
  if (strategy === 'off') {
736
- console.log('[myclaw-run] ⏭️ 跳过: ' + desc + ' [off]');
714
+ console.log('[myclaw-run] 跳过: ' + desc + ' [off]');
737
715
  continue;
738
716
  }
739
717
  try {
740
- console.log('[myclaw-run] ▶️ 执行: ' + desc);
718
+ console.log('[myclaw-run] 执行: ' + desc);
741
719
  const mod = require(entry.module);
742
720
  mod.run([]);
743
721
  console.log('[myclaw-run] ✅ 完成: ' + desc);
744
722
  } catch (err) {
745
- console.log('[myclaw-run] ⚠️ 失败: ' + desc + ' — ' + err.message);
723
+ console.log('[myclaw-run] 失败: ' + desc + ' — ' + err.message);
746
724
  }
747
725
  }
748
726
  }
@@ -795,6 +773,52 @@ function runRestart() {
795
773
  console.log('');
796
774
  }
797
775
 
776
+ // ============================================================================
777
+ // 卸载命令
778
+ // ============================================================================
779
+
780
+ function runUninstall() {
781
+ const bar = '----------------------------------------';
782
+
783
+ console.log('');
784
+ console.log('[' + colors.yellow + 'MyClaw 卸载' + colors.nc + ']');
785
+ console.log(bar);
786
+ console.log('');
787
+ console.log(' ' + colors.yellow + '⚠️ 即将执行以下操作:' + colors.nc);
788
+ console.log(' • 将 npm 仓库地址恢复为官方源');
789
+ console.log(' • ' + colors.dim + '(不会删除本程序文件)' + colors.nc);
790
+ console.log('');
791
+
792
+ const rl = readline.createInterface({
793
+ input: process.stdin,
794
+ output: process.stdout
795
+ });
796
+
797
+ rl.question(' 确认卸载?' + colors.cyan + '(y/n)' + colors.nc + ': ', (answer) => {
798
+ rl.close();
799
+
800
+ if (answer.toLowerCase() === 'y') {
801
+ console.log('');
802
+ console.log(' ' + colors.blue + '正在恢复 npm 官方源...' + colors.nc);
803
+ try {
804
+ execSync('npm config set registry https://registry.npmjs.org/', { stdio: 'inherit' });
805
+ console.log(' ' + colors.green + '✓ npm 源已恢复为官方地址' + colors.nc);
806
+ } catch (err) {
807
+ console.log(' ' + colors.red + '✗ 恢复失败: ' + err.message + colors.nc);
808
+ }
809
+ console.log('');
810
+ console.log(bar);
811
+ console.log('');
812
+ } else {
813
+ console.log('');
814
+ console.log(' ' + colors.dim + '已取消卸载' + colors.nc);
815
+ console.log('');
816
+ console.log(bar);
817
+ console.log('');
818
+ }
819
+ });
820
+ }
821
+
798
822
  // ============================================================================
799
823
  // 强制更新命令
800
824
  // ============================================================================
@@ -954,6 +978,126 @@ function padRight(str, len) {
954
978
  return str + ' '.repeat(len - str.length);
955
979
  }
956
980
 
981
+ // ============================================================================
982
+ // 交互式菜单(上下键选择)
983
+ // ============================================================================
984
+
985
+ const MENU_ITEMS = [
986
+ { key: 'start', label: '🦞启动🦞', cmd: 'mc start', desc: '把你的 AI 助手叫醒,让它开始工作', action: () => { const start = require('./start'); start.run(); } },
987
+ { key: 'restart', label: '重启', cmd: 'mc restart', desc: 'AI 助手卡住了?让它重新启动一下', action: runRestart },
988
+ { key: 'new', label: '😊新伙伴', cmd: 'mc new', desc: '创建一个新的 AI 助手,给它取个名字', action: runNew },
989
+ { key: 'status', label: '网址', cmd: 'mc status', desc: '获取控制台链接,复制到浏览器打开', action: runStatus },
990
+ { key: 'update', label: '升级', cmd: 'mc up', desc: '让 MyClaw 工具升级到最新版本', action: () => {
991
+ runUpdate();
992
+ console.log('');
993
+ console.log('🔧 自动执行 patch 以恢复自定义配置...');
994
+ runPatch();
995
+ if (detectPlatform() === 'windows') runBat();
996
+ }},
997
+ { key: 'patch', label: '修复', cmd: 'mc patch', desc: '给 AI 助手装上新技能和好看的外衣', action: runPatch },
998
+ { key: 'reinstall', label: '重装', cmd: 'mc longxia', desc: '出了大问题?把 AI 助手删了重新安装', action: runReinstall },
999
+ { key: 'uninstall', label: '卸载', cmd: 'mc uninstall', desc: '卸载 MyClaw,恢复 npm 源地址', action: runUninstall },
1000
+ { key: 'quit', label: '退出', cmd: 'Ctrl+C', desc: '不玩了,下次见', action: () => { console.log(' 👋 再见!\n'); process.exit(0); } },
1001
+ ];
1002
+
1003
+ function runInteractiveMenu() {
1004
+ let cursor = 0;
1005
+ let handler = null;
1006
+ let resizeHandler = null;
1007
+
1008
+ function render() {
1009
+ // 清屏
1010
+ process.stdout.write('\x1b[2J\x1b[H');
1011
+
1012
+ const bar = '────────────────────────────────────────';
1013
+ console.log('');
1014
+ console.log(bar);
1015
+ console.log(' ' + colors.blue + 'MyClaw v' + version + colors.nc + ' - 快捷菜单');
1016
+ console.log(bar);
1017
+ console.log(' ' + colors.dim + '(↑↓ 移动 Enter 选择 Ctrl+C 退出)' + colors.nc);
1018
+ console.log('');
1019
+
1020
+ MENU_ITEMS.forEach((item, i) => {
1021
+ const sel = i === cursor;
1022
+ const arrow = sel ? colors.cyan + '▶ ' + colors.nc : ' ';
1023
+ const num = colors.dim + String(i + 1) + '.' + colors.nc;
1024
+ const label = sel ? colors.bold + item.label + colors.nc : item.label;
1025
+ const cmdHint = colors.dim + item.cmd + colors.nc;
1026
+ console.log(' ' + arrow + num + ' ' + label + ' ' + cmdHint);
1027
+ });
1028
+
1029
+ console.log('');
1030
+ console.log(bar);
1031
+ console.log('');
1032
+
1033
+ // 说明区:显示选中项的描述
1034
+ const cur = MENU_ITEMS[cursor];
1035
+ console.log(' ' + colors.yellow + '📖 ' + cur.label + colors.nc);
1036
+ console.log('');
1037
+ console.log(' ' + colors.dim + cur.desc + colors.nc);
1038
+ console.log('');
1039
+ console.log(bar);
1040
+ }
1041
+
1042
+ function onData(buf) {
1043
+ const k = buf.toString();
1044
+
1045
+ if (k === '\x1b[A') { // 上
1046
+ cursor = Math.max(0, cursor - 1);
1047
+ render();
1048
+ } else if (k === '\x1b[B') { // 下
1049
+ cursor = Math.min(MENU_ITEMS.length - 1, cursor + 1);
1050
+ render();
1051
+ } else if (k === '\r' || k === '\n') { // Enter
1052
+ // 暂停菜单键盘监听,执行完后恢复
1053
+ process.stdin.removeListener('data', handler);
1054
+ process.stdin.setRawMode(false);
1055
+ process.stdin.pause();
1056
+
1057
+ const item = MENU_ITEMS[cursor];
1058
+ if (item.key === 'quit') {
1059
+ item.action();
1060
+ return;
1061
+ }
1062
+
1063
+ console.log('');
1064
+ item.action();
1065
+
1066
+ // 等待用户按回车再返回菜单
1067
+ console.log('');
1068
+ console.log(colors.dim + ' → 按回车键返回菜单...' + colors.nc);
1069
+
1070
+ process.stdin.setRawMode(true);
1071
+ process.stdin.resume();
1072
+ const waitHandler = (buf) => {
1073
+ const wk = buf.toString();
1074
+ if (wk === '\r' || wk === '\n') {
1075
+ process.stdin.removeListener('data', waitHandler);
1076
+ process.stdin.on('data', handler);
1077
+ render();
1078
+ }
1079
+ };
1080
+ process.stdin.on('data', waitHandler);
1081
+ } else if (k === '\x03') {
1082
+ process.stdin.setRawMode(false);
1083
+ process.stdin.removeListener('data', handler);
1084
+ if (resizeHandler) process.stdout.removeListener('resize', resizeHandler);
1085
+ console.log('\n 👋 再见!\n');
1086
+ process.exit(0);
1087
+ }
1088
+ }
1089
+
1090
+ process.stdin.setRawMode(true);
1091
+ process.stdin.resume();
1092
+ handler = onData;
1093
+ process.stdin.on('data', handler);
1094
+
1095
+ resizeHandler = () => render();
1096
+ process.stdout.on('resize', resizeHandler);
1097
+
1098
+ render();
1099
+ }
1100
+
957
1101
  // ============================================================================
958
1102
  // 帮助信息
959
1103
  // ============================================================================
@@ -974,8 +1118,10 @@ function showHelp() {
974
1118
  console.log('');
975
1119
  console.log('命令:');
976
1120
  console.log(' start 智能启动(图标 & 命令行通用入口)');
977
- console.log(' install 安装 OpenClaw 服务');
978
- console.log(' status 简化版状态查看(学生友好)');
1121
+ console.log(' install,i 安装 OpenClaw 服务');
1122
+ console.log(' longxia 重装 OpenClaw (清理缓存 + 锁定版本)');
1123
+ console.log(' uninstall 卸载 MyClaw (恢复 npm 官方源)');
1124
+ console.log(' status 获取控制台网址');
979
1125
  console.log(' update 自动升级 MyClaw 到最新版本');
980
1126
  console.log(' up 升级 + 刷新桌面快捷方式 (= update + bat)');
981
1127
  console.log(' open 打开浏览器控制台(自动带 token)');
@@ -986,11 +1132,11 @@ function showHelp() {
986
1132
  console.log(' pull 从 ~/.openclaw 拉取最新资源到源目录(开发用)');
987
1133
  console.log(' patch 注入 MyClaw UI + 技能 + 智能体 + 配置');
988
1134
  console.log(' unpatch 回滚 UI 注入(恢复原版)');
989
- console.log(' minimax 注入 MiniMax 模型配置 (可选: --key sk-xxx)');
990
- console.log(' zai 注入智谱 GLM 模型配置 (可选: --key xxx)');
1135
+ console.log(' minimax 注入 MiniMax 模型配置 (可选: --key sk-xxx, -f 强制清理其他模型)');
1136
+ console.log(' zai 注入智谱 GLM 模型配置 (可选: --key xxx, -f 强制清理其他模型)');
991
1137
  console.log(' image 注入图像生成模型配置 (基于 vveai)');
992
1138
  console.log(' token 设置 Gateway Token 为 aiyiran');
993
- console.log(' plus 增强功能 (子命令: search)');
1139
+ console.log(' websearch 注入 Tavily 搜索插件配置');
994
1140
  console.log(' restart 重启 OpenClaw Gateway');
995
1141
  console.log(' help 显示帮助信息');
996
1142
  console.log('');
@@ -998,12 +1144,13 @@ function showHelp() {
998
1144
  console.log(' myclaw prepare # 智能初始化(推荐新用户首先执行)');
999
1145
  console.log(' myclaw weixin # 打开微信接入向导');
1000
1146
  console.log(' myclaw install # 安装 OpenClaw');
1001
- console.log(' myclaw status # 查看状态');
1147
+ console.log(' myclaw status # 获取控制台网址');
1002
1148
  console.log(' myclaw new helper # 创建名为 helper 的 Agent');
1003
1149
  console.log(' myclaw open # 打开控制台(自动读取 token)');
1004
1150
  console.log(' myclaw open --token kakaxi-2026 # 指定 token 打开');
1005
1151
  console.log(' myclaw open http://x.x.x.x:18789 # 打开指定 URL');
1006
1152
  console.log(' myclaw patch # 注入 UI 扩展');
1153
+ console.log(' myclaw uninstall # 卸载 MyClaw(恢复 npm 源)');
1007
1154
  console.log(' myclaw restart # 重启 Gateway');
1008
1155
  console.log('');
1009
1156
  console.log('跨平台: macOS / Linux / Windows (PowerShell/CMD)');
@@ -1016,7 +1163,10 @@ function showHelp() {
1016
1163
 
1017
1164
  console.log(colors.blue + 'MyClaw v' + version + colors.nc);
1018
1165
 
1019
- if (!command || command === 'help' || command === '--help' || command === '-h') {
1166
+ if (!command) {
1167
+ // 无参数 → 进入交互式菜单
1168
+ runInteractiveMenu();
1169
+ } else if (command === 'help' || command === '--help' || command === '-h') {
1020
1170
  showHelp();
1021
1171
  } else if (command === 'prepare') {
1022
1172
  runPrepare();
@@ -1024,8 +1174,10 @@ if (!command || command === 'help' || command === '--help' || command === '-h')
1024
1174
  runWeixin();
1025
1175
  } else if (command === 'rebind') {
1026
1176
  runRebind();
1027
- } else if (command === 'install') {
1177
+ } else if (command === 'install' || command === 'i') {
1028
1178
  runInstall();
1179
+ } else if (command === 'longxia') {
1180
+ runReinstall();
1029
1181
  } else if (command === 'status') {
1030
1182
  runStatus();
1031
1183
  } else if (command === 'new') {
@@ -1062,6 +1214,8 @@ if (!command || command === 'help' || command === '--help' || command === '-h')
1062
1214
  runPatch();
1063
1215
  } else if (command === 'unpatch') {
1064
1216
  runUnpatch();
1217
+ } else if (command === 'uninstall') {
1218
+ runUninstall();
1065
1219
  } else if (command === 'restart') {
1066
1220
  runRestart();
1067
1221
  } else if (command === 'minimax') {
@@ -1089,21 +1243,12 @@ if (!command || command === 'help' || command === '--help' || command === '-h')
1089
1243
  console.log('🔄 正在重启 Gateway 使配置生效...');
1090
1244
  console.log('');
1091
1245
  runRestart();
1092
- } else if (command === 'plus') {
1093
- const subCmd = args[1];
1094
- if (subCmd === 'search') {
1095
- const search = require('./inject-search');
1096
- search.run(args.slice(2));
1097
- console.log('🔄 正在重启 Gateway 使配置生效...');
1098
- console.log('');
1099
- runRestart();
1100
- } else {
1101
- console.log('用法: myclaw plus <子命令>');
1102
- console.log('');
1103
- console.log('子命令:');
1104
- console.log(' search 注入 Tavily 搜索插件配置');
1105
- process.exit(1);
1106
- }
1246
+ } else if (command === 'websearch') {
1247
+ const search = require('./inject-search');
1248
+ search.run(args.slice(1));
1249
+ console.log('🔄 正在重启 Gateway 使配置生效...');
1250
+ console.log('');
1251
+ runRestart();
1107
1252
  } else {
1108
1253
  console.error('[' + colors.red + '错误' + colors.nc + '] 未知命令: ' + command);
1109
1254
  showHelp();