@aiyiran/myclaw 1.0.5 → 1.0.6

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/README.md ADDED
@@ -0,0 +1,126 @@
1
+ # MyClaw - 学生友好的 OpenClaw 工具
2
+
3
+ 一个简化 OpenClaw 日常操作的命令行工具,专为教学环境设计。
4
+
5
+ ## 跨平台要求 ⚠️
6
+
7
+ ```
8
+ ╔══════════════════════════════════════════════════════════════════════╗
9
+ ║ 跨平台兼容性说明 ║
10
+ ╠══════════════════════════════════════════════════════════════════════╣
11
+ ║ ║
12
+ ║ 支持系统: ║
13
+ ║ ✅ macOS - 完全支持,包括颜色和 Emoji ║
14
+ ║ ✅ Linux - 完全支持,包括颜色和 Emoji ║
15
+ ║ ✅ Windows 10/11 - 基本支持,推荐使用 Windows Terminal ║
16
+ ║ ⚠️ Windows 7/8 - 支持,但 Emoji 可能显示为方块 ║
17
+ ║ ║
18
+ ║ Windows 用户建议: ║
19
+ ║ • 安装 Windows Terminal (Microsoft Store 免费下载) ║
20
+ ║ • 或使用 PowerShell 7+ (https://aka.ms/powershell) ║
21
+ ║ ║
22
+ ║ 颜色说明: ║
23
+ ║ • macOS/Linux: 正常显示 ANSI 颜色 ║
24
+ ║ • Windows: 自动禁用颜色输出,避免乱码 ║
25
+ ║ ║
26
+ ╚══════════════════════════════════════════════════════════════════════╝
27
+ ```
28
+
29
+ ## 安装
30
+
31
+ ```bash
32
+ # 方式一: 直接运行
33
+ node myclaw/index.js <command>
34
+
35
+ # 方式二: 添加到 PATH (macOS/Linux)
36
+ ln -s /path/to/myclaw/index.js /usr/local/bin/myclaw
37
+ chmod +x /usr/local/bin/myclaw
38
+
39
+ # 方式三: Windows PowerShell
40
+ # 将 myclaw/index.js 路径添加到系统 PATH
41
+ ```
42
+
43
+ ## 使用方法
44
+
45
+ ### 查看状态
46
+ ```bash
47
+ myclaw status
48
+ ```
49
+ 简化版的 OpenClaw 状态面板,一眼看清 Gateway、Agents、Sessions 状态。
50
+
51
+ ### 创建新 Agent
52
+ ```bash
53
+ myclaw new <agent名称>
54
+ ```
55
+ 快速创建一个新的 OpenClaw Agent,自动完成:
56
+ - 创建 workspace 目录
57
+ - 配置 agent 文件
58
+ - 发送出生消息
59
+
60
+ 示例:
61
+ ```bash
62
+ myclaw new helper # 创建名为 helper 的 Agent
63
+ myclaw new testbot # 创建名为 testbot 的 Agent
64
+ ```
65
+
66
+ ### 安装 OpenClaw
67
+ ```bash
68
+ myclaw install
69
+ ```
70
+ 自动检测操作系统并执行对应的安装命令。
71
+
72
+ ### 帮助
73
+ ```bash
74
+ myclaw help
75
+ ```
76
+
77
+ ## 文件结构
78
+
79
+ ```
80
+ myclaw/
81
+ ├── index.js # 主入口,命令解析和输出
82
+ ├── create_agent.js # Agent 创建逻辑模块
83
+ └── README.md # 本文件
84
+ ```
85
+
86
+ ### 模块说明
87
+
88
+ | 文件 | 职责 |
89
+ |------|------|
90
+ | `index.js` | 主入口,解析命令、颜色输出、调用模块 |
91
+ | `create_agent.js` | Agent 创建的完整逻辑,可独立使用 |
92
+
93
+ ## 开发说明
94
+
95
+ ### 代码规范
96
+
97
+ 1. **跨平台兼容性** - 必须考虑 Windows 用户体验
98
+ - 使用 `os.platform()` 检测系统
99
+ - Windows 下禁用 ANSI 颜色输出
100
+ - 避免使用只在 Unix 系统有效的命令
101
+
102
+ 2. **错误处理**
103
+ - 所有 `execSync` 调用必须使用 `try-catch`
104
+ - 失败时提供清晰的错误信息和解决方案
105
+
106
+ 3. **模块化**
107
+ - 业务逻辑放入独立模块
108
+ - 主入口只做命令解析和输出
109
+
110
+ ### 测试清单
111
+
112
+ 发布前请在以下环境测试:
113
+ - [ ] macOS (Terminal)
114
+ - [ ] Linux (bash)
115
+ - [ ] Windows 10/11 (PowerShell)
116
+ - [ ] Windows 10/11 (CMD)
117
+ - [ ] Windows Terminal (如果可用)
118
+
119
+ ## 依赖
120
+
121
+ - Node.js 14+
122
+ - OpenClaw CLI (用于实际命令执行)
123
+
124
+ ## 许可证
125
+
126
+ 内部教学工具
@@ -0,0 +1,272 @@
1
+ /**
2
+ * ============================================================================
3
+ * MyClaw - Create Agent 模块
4
+ * ============================================================================
5
+ *
6
+ * 创建 OpenClaw Agent 的完整逻辑
7
+ *
8
+ * 功能:
9
+ * - 标准化 agent ID
10
+ * - 检查重复
11
+ * - 创建工作空间目录和默认文件
12
+ * - 更新 OpenClaw 配置文件
13
+ * - 发送出生消息
14
+ *
15
+ * ============================================================================
16
+ */
17
+
18
+ const { execSync } = require('child_process');
19
+ const fs = require('fs');
20
+ const path = require('path');
21
+ const os = require('os');
22
+
23
+ // ============================================================================
24
+ // 路径工具
25
+ // ============================================================================
26
+
27
+ function normalizePath(p) {
28
+ return p.replace(/\\/g, '/');
29
+ }
30
+
31
+ function ensureDir(dirPath) {
32
+ if (!fs.existsSync(dirPath)) {
33
+ fs.mkdirSync(dirPath, { recursive: true });
34
+ }
35
+ }
36
+
37
+ function writeIfAbsent(filePath, content) {
38
+ if (!fs.existsSync(filePath)) {
39
+ fs.writeFileSync(filePath, content, 'utf8');
40
+ }
41
+ }
42
+
43
+ // ============================================================================
44
+ // 工具函数
45
+ // ============================================================================
46
+
47
+ function fail(msg, code = 1) {
48
+ console.error('[错误] ' + msg);
49
+ process.exit(code);
50
+ }
51
+
52
+ /**
53
+ * 标准化 agent ID
54
+ * - 转小写
55
+ * - 非法字符替换为连字符
56
+ * - 去除多余连字符
57
+ */
58
+ function normalizeAgentId(raw) {
59
+ let value = raw.trim().toLowerCase();
60
+ value = value.replace(/[^a-z0-9-]/g, '-');
61
+ value = value.replace(/-{2,}/g, '-').replace(/^-|-$/g, '');
62
+ return value;
63
+ }
64
+
65
+ /**
66
+ * 验证 agent ID
67
+ */
68
+ function validateAgentId(agentId) {
69
+ if (!agentId) {
70
+ fail('Agent 名称标准化后为空,请检查输入。');
71
+ }
72
+ if (agentId.length > 64) {
73
+ fail('Agent ID 太长,请保持在 64 个字符以内。');
74
+ }
75
+ if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(agentId)) {
76
+ fail('Agent ID 只能包含小写字母、数字和连字符(不能以连字符开头或结尾)。');
77
+ }
78
+ }
79
+
80
+ /**
81
+ * 生成北京时间出生消息
82
+ */
83
+ function buildBirthMessage() {
84
+ const nowUtc = new Date();
85
+ const nowBj = new Date(nowUtc.getTime() + 8 * 60 * 60 * 1000);
86
+ const y = nowBj.getUTCFullYear();
87
+ const m = nowBj.getUTCMonth() + 1;
88
+ const d = nowBj.getUTCDate();
89
+ const h = String(nowBj.getUTCHours()).padStart(2, '0');
90
+ const min = String(nowBj.getUTCMinutes()).padStart(2, '0');
91
+ const ts = `${y}年${m}月${d}日${h}:${min}`;
92
+ return (
93
+ `你好,你的生日是北京时间${ts},请记录这个信息。\n` +
94
+ '欢迎你来到这个世界,我是你的造物主,我们是伙伴,我叫做孙依然,' +
95
+ '你可以叫我依然,请多多指教,共同成长。'
96
+ );
97
+ }
98
+
99
+ /**
100
+ * 默认工作空间文件内容
101
+ */
102
+ function defaultWorkspaceFiles(agentId) {
103
+ return {
104
+ 'AGENTS.md': (
105
+ `# AGENTS.md - ${agentId}\n\n` +
106
+ `This workspace belongs to the \`${agentId}\` agent.\n\n` +
107
+ '## Startup\n' +
108
+ '- Read `SOUL.md`\n' +
109
+ '- Read `USER.md`\n' +
110
+ '- Read recent memory if available\n\n' +
111
+ '## Rules\n' +
112
+ '- Be helpful, careful, and concise.\n' +
113
+ '- Prefer using the existing workspace and defaults.\n' +
114
+ '- Ask before destructive or external actions.\n'
115
+ ),
116
+ 'SOUL.md': (
117
+ `# SOUL.md\n\n` +
118
+ `You are \`${agentId}\`.\n\n` +
119
+ 'Be useful, calm, direct, and trustworthy.\n' +
120
+ 'Use the default OpenClaw behavior unless the user asks for something special.\n'
121
+ ),
122
+ 'USER.md': (
123
+ '# USER.md\n\n' +
124
+ '- Name: 孙依然\n' +
125
+ '- What to call them: 依然\n' +
126
+ '- Timezone: Asia/Shanghai\n\n' +
127
+ 'Build understanding gradually and respectfully.\n'
128
+ ),
129
+ 'IDENTITY.md': (
130
+ '# IDENTITY.md\n\n' +
131
+ `- Name: ${agentId}\n` +
132
+ '- Role: OpenClaw agent\n' +
133
+ '- Vibe: practical, reliable, clear\n'
134
+ ),
135
+ 'HEARTBEAT.md': (
136
+ '# HEARTBEAT.md\n\n' +
137
+ '# Keep empty unless periodic checks are needed.\n'
138
+ ),
139
+ 'BOOTSTRAP.md': (
140
+ `# BOOTSTRAP.md\n\n` +
141
+ `You are a newly created OpenClaw agent named \`${agentId}\`.\n\n` +
142
+ 'On first runs, learn your workspace files and begin helping.\n'
143
+ ),
144
+ };
145
+ }
146
+
147
+ // ============================================================================
148
+ // 主函数
149
+ // ============================================================================
150
+
151
+ /**
152
+ * 创建新的 OpenClaw Agent
153
+ *
154
+ * @param {string} rawName - 原始名称
155
+ * @returns {object} 创建结果
156
+ */
157
+ function createAgent(rawName) {
158
+ // 标准化 & 验证名称
159
+ const agentId = normalizeAgentId(rawName);
160
+ validateAgentId(agentId);
161
+
162
+ // 确定 OpenClaw 配置目录
163
+ const homeDir = os.homedir();
164
+ const openclawDir = path.join(homeDir, '.openclaw');
165
+ const configPath = path.join(openclawDir, 'openclaw.json');
166
+ const agentsDir = path.join(openclawDir, 'agents');
167
+ const workspaceDir = path.join(openclawDir, 'workspace-' + agentId);
168
+ const agentDir = path.join(agentsDir, agentId, 'agent');
169
+
170
+ // 检查配置是否存在
171
+ if (!fs.existsSync(configPath)) {
172
+ fail('配置文件不存在: ' + normalizePath(configPath) + '\n请先运行 openclaw onboard 完成初始化。');
173
+ }
174
+
175
+ // 加载配置
176
+ let configData;
177
+ try {
178
+ const raw = fs.readFileSync(configPath, 'utf8');
179
+ configData = JSON.parse(raw);
180
+ } catch (err) {
181
+ fail('配置文件读取失败: ' + err.message);
182
+ }
183
+
184
+ // 确保 agents 结构存在
185
+ if (!configData.agents) {
186
+ configData.agents = {};
187
+ }
188
+ if (!Array.isArray(configData.agents.list)) {
189
+ configData.agents.list = [];
190
+ }
191
+
192
+ // 检查重复 ID
193
+ const existingIds = new Set(
194
+ configData.agents.list
195
+ .filter(e => e && typeof e === 'object')
196
+ .map(e => e.id)
197
+ );
198
+ if (existingIds.has(agentId)) {
199
+ fail('Agent "' + agentId + '" 已存在,请使用其他名称。');
200
+ }
201
+
202
+ // 检查目录冲突
203
+ if (fs.existsSync(workspaceDir) || fs.existsSync(agentDir)) {
204
+ fail(
205
+ '工作空间或 Agent 目录已存在,请检查是否已有同名 Agent。\n' +
206
+ 'workspace=' + normalizePath(workspaceDir) + '\n' +
207
+ 'agentDir=' + normalizePath(agentDir)
208
+ );
209
+ }
210
+
211
+ // 创建目录结构
212
+ ensureDir(workspaceDir);
213
+ ensureDir(agentDir);
214
+ ensureDir(path.join(agentsDir, agentId, 'sessions'));
215
+
216
+ // 创建默认工作空间文件
217
+ const files = defaultWorkspaceFiles(agentId);
218
+ for (const [filename, content] of Object.entries(files)) {
219
+ writeIfAbsent(path.join(workspaceDir, filename), content);
220
+ }
221
+
222
+ // 备份配置
223
+ const backupPath = configPath + '.bak.agent-birth.' +
224
+ new Date().toISOString().replace(/[:.]/g, '-').slice(0, 26) + 'Z';
225
+ fs.copyFileSync(configPath, backupPath);
226
+
227
+ // 添加 Agent 条目
228
+ configData.agents.list.push({
229
+ id: agentId,
230
+ name: agentId,
231
+ workspace: workspaceDir,
232
+ agentDir: agentDir,
233
+ });
234
+
235
+ // 写入配置
236
+ try {
237
+ fs.writeFileSync(configPath, JSON.stringify(configData, null, 2) + '\n', 'utf8');
238
+ } catch (err) {
239
+ fail('配置文件写入失败: ' + err.message + '\n备份文件: ' + normalizePath(backupPath));
240
+ }
241
+
242
+ // 发送出生消息
243
+ const birthMessage = buildBirthMessage();
244
+ let firstMessageSent = false;
245
+ let firstMessageError = null;
246
+
247
+ try {
248
+ execSync(
249
+ 'openclaw agent --agent ' + agentId + ' --message ' + JSON.stringify(birthMessage) + ' --json 2>&1',
250
+ { encoding: 'utf8', timeout: 30000 }
251
+ );
252
+ firstMessageSent = true;
253
+ } catch (err) {
254
+ firstMessageSent = false;
255
+ firstMessageError = err.message;
256
+ }
257
+
258
+ // 返回结果
259
+ return {
260
+ ok: true,
261
+ agentId: agentId,
262
+ sessionKey: 'agent:' + agentId + ':main',
263
+ workspace: normalizePath(workspaceDir),
264
+ agentDir: normalizePath(agentDir),
265
+ configBackup: normalizePath(backupPath),
266
+ birthMessage: birthMessage,
267
+ firstMessageSent: firstMessageSent,
268
+ firstMessageError: firstMessageError,
269
+ };
270
+ }
271
+
272
+ module.exports = { createAgent, normalizeAgentId, validateAgentId };
package/index.js CHANGED
@@ -25,6 +25,7 @@
25
25
 
26
26
  const { execSync } = require('child_process');
27
27
  const os = require('os');
28
+ const { createAgent } = require('./create_agent');
28
29
 
29
30
  const args = process.argv.slice(2);
30
31
  const command = args[0];
@@ -46,22 +47,10 @@ const isWindows = detectPlatform() === 'windows';
46
47
  // 跨平台颜色输出
47
48
  // ============================================================================
48
49
 
49
- /**
50
- * 颜色输出函数 - 自动兼容 Windows
51
- * Windows 旧版本会 stripped ANSI 颜色代码,避免乱码
52
- */
53
50
  function makeColors() {
54
51
  if (isWindows) {
55
- // Windows: 禁用颜色,strip ANSI codes
56
- return {
57
- red: '',
58
- green: '',
59
- yellow: '',
60
- blue: '',
61
- nc: ''
62
- };
52
+ return { red: '', green: '', yellow: '', blue: '', nc: '' };
63
53
  }
64
- // macOS/Linux: 正常 ANSI 颜色
65
54
  return {
66
55
  red: '\x1b[31m',
67
56
  green: '\x1b[32m',
@@ -189,86 +178,124 @@ function runStatus() {
189
178
  // ============================================================================
190
179
 
191
180
  function runNew() {
192
- const agentName = args[1];
181
+ const rawName = args[1];
193
182
 
194
- if (!agentName) {
183
+ if (!rawName) {
195
184
  console.error('[' + colors.red + '错误' + colors.nc + '] 请提供 Agent 名称');
196
185
  console.log('');
197
186
  console.log('用法: myclaw new <agent名称>');
198
187
  console.log('');
199
188
  console.log('示例:');
200
189
  console.log(' myclaw new helper # 创建名为 helper 的 Agent');
201
- console.log(' myclaw new testbot # 创建名为 testbot 的 Agent');
202
- process.exit(1);
203
- }
204
-
205
- // 验证名称格式
206
- if (!/^[a-z0-9-]+$/.test(agentName)) {
207
- console.error('[' + colors.red + '错误' + colors.nc + '] Agent 名称只能包含小写字母、数字和连字符(-)');
208
- console.log('');
209
- console.log('示例:');
210
- console.log(' myclaw new helper');
211
- console.log(' myclaw new my-bot');
190
+ console.log(' myclaw new testbot # 创建名为 testbot 的 Agent');
212
191
  process.exit(1);
213
192
  }
214
193
 
215
194
  const bar = '----------------------------------------';
216
195
 
217
196
  console.log('');
218
- console.log('[' + colors.blue + 'MyClaw' + colors.nc + '] ' + colors.blue + '创建新 Agent: ' + agentName + colors.nc);
197
+ console.log('[' + colors.blue + 'MyClaw' + colors.nc + '] ' + colors.blue + '创建新 Agent' + colors.nc);
219
198
  console.log(bar);
220
199
  console.log('');
221
-
222
- // 检查是否已存在
223
- try {
224
- const agentsOutput = execSync('openclaw agents list 2>/dev/null', { encoding: 'utf8' });
225
- if (agentsOutput.includes(`agent:${agentName}:`)) {
226
- console.error('[' + colors.red + '错误' + colors.nc + '] Agent "' + agentName + '" 已存在');
227
- process.exit(1);
228
- }
229
- } catch (e) {
230
- // 继续创建
231
- }
232
-
233
- // 查找 yiran-agent-birth 脚本
234
- const birthScript = '/Users/yiran/.openclaw/workspace/skills/yiran-agent-birth/scripts/create_agent.py';
235
-
236
200
  console.log('[创建中] 正在创建 Agent...');
237
-
201
+ console.log('');
202
+
238
203
  try {
239
- const result = execSync(`python3 "${birthScript}" ${agentName}`, { encoding: 'utf8' });
240
- const jsonResult = JSON.parse(result);
204
+ const result = createAgent(rawName);
241
205
 
242
- console.log('');
243
206
  console.log('[' + colors.green + '成功' + colors.nc + '] Agent 创建成功!');
244
207
  console.log('');
245
- console.log(' 名称: ' + agentName);
246
- console.log(' Session: ' + jsonResult.sessionKey);
247
- console.log(' Workspace: ' + jsonResult.workspace);
208
+ console.log(' 名称: ' + result.agentId);
209
+ console.log(' Session: ' + result.sessionKey);
210
+ console.log(' Workspace: ' + result.workspace);
211
+ console.log(' 备份: ' + result.configBackup);
248
212
  console.log('');
249
213
 
250
- if (jsonResult.firstMessageSent) {
214
+ if (result.firstMessageSent) {
251
215
  console.log('[' + colors.green + 'OK' + colors.nc + '] 出生消息已发送');
252
216
  } else {
253
- console.log('[' + colors.yellow + '警告' + colors.nc + '] 出生消息发送失败,可手动重试');
217
+ console.log('[' + colors.yellow + '警告' + colors.nc + '] 出生消息发送失败');
218
+ if (result.firstMessageError) {
219
+ console.log(' 错误: ' + result.firstMessageError);
220
+ }
221
+ console.log(' 手动重试: ' + colors.yellow + 'openclaw agent --agent ' + result.agentId + ' --message "你好"' + colors.nc);
254
222
  }
255
223
 
256
224
  console.log('');
257
225
  console.log(bar);
258
- console.log('下一步: 运行 ' + colors.yellow + `openclaw agent --agent ${agentName} --message "你好"` + colors.nc + ' 与它对话');
226
+ console.log('下一步: 运行 ' + colors.yellow + 'openclaw agent --agent ' + result.agentId + ' --message "你好"' + colors.nc + ' 与它对话');
259
227
  console.log('');
260
228
 
261
229
  } catch (err) {
262
- console.error('[' + colors.red + '错误' + colors.nc + '] 创建失败:', err.message);
230
+ // create_agent.js 已经有错误信息输出
231
+ console.log('');
232
+ console.log('[' + colors.red + '失败' + colors.nc + '] Agent 创建失败');
263
233
  console.log('');
264
- console.log('常见问题:');
265
- console.log(' - Agent 名称已存在');
266
- console.log(' - 权限不足');
267
- console.log(' - OpenClaw 未运行');
268
234
  process.exit(1);
269
235
  }
270
236
  }
271
237
 
238
+ // ============================================================================
239
+ // 安装/修复 WSL2
240
+ // ============================================================================
241
+
242
+ function runWsl2() {
243
+ if (!isWindows) {
244
+ console.error('[' + colors.red + '提示' + colors.nc + '] 本命令主要用于 Windows 系统。在 Mac/Linux 下不需要安装 WSL2。');
245
+ process.exit(0);
246
+ }
247
+
248
+ const bar = '----------------------------------------';
249
+ console.log('');
250
+ console.log('[' + colors.blue + 'MyClaw' + colors.nc + '] ' + colors.blue + '修复/安装 Windows WSL2 环境' + colors.nc);
251
+ console.log(bar);
252
+ console.log('');
253
+ console.log('即将申请管理员权限以启用 Windows WSL2 和 虚拟机平台功能...');
254
+ console.log('这使用的是兼容性最好的"手动打补丁"底层方法,用来解决直接安装失败的问题。');
255
+ console.log('[' + colors.yellow + '注意' + colors.nc + '] 请在稍后弹出的 UAC 授权窗口中选【是】。');
256
+ console.log('');
257
+
258
+ const psCommand = `
259
+ Write-Host "============================";
260
+ Write-Host " MyClaw - WSL2 环境底座修复";
261
+ Write-Host "============================";
262
+ Write-Host "";
263
+ Write-Host "步骤 1/3: 正在启用 Windows Subsystem for Linux...";
264
+ dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart;
265
+ Write-Host "";
266
+ Write-Host "步骤 2/3: 正在启用 虚拟机平台...";
267
+ dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart;
268
+ Write-Host "";
269
+ Write-Host "步骤 3/3: 尝试设置 WSL2 为默认版本...";
270
+ try { wsl --set-default-version 2 2>$null } catch {}
271
+ Write-Host "";
272
+ Write-Host "============================";
273
+ Write-Host " 操作执行完毕!";
274
+ Write-Host " 注意:必须 [重新启动电脑] 才能生效!";
275
+ Write-Host "============================";
276
+ Write-Host " -> 若重启后运行 wsl 提示需要内核更新,";
277
+ Write-Host " -> 请浏览器访问下载并安装: https://aka.ms/wsl2kernel";
278
+ Write-Host " -> 最后去 Microsoft Store 搜索 Ubuntu 并安装即可。";
279
+ Write-Host "";
280
+ Write-Host "按任意键退出当前窗口...";
281
+ $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown");
282
+ `;
283
+
284
+ // 为了跨 PowerShell 调用避免引号转移错乱,转为 Base64 执行 (UTF-16LE 编码)
285
+ const b64Cmd = Buffer.from(psCommand, 'utf16le').toString('base64');
286
+
287
+ try {
288
+ execSync(`powershell -Command "Start-Process powershell -ArgumentList '-NoProfile -ExecutionPolicy Bypass -EncodedCommand ${b64Cmd}' -Verb RunAs"`, { stdio: 'inherit' });
289
+ console.log('[' + colors.green + '成功' + colors.nc + '] 修复命令已下发,请查看新弹出的蓝色 PowerShell 窗口。');
290
+ console.log('');
291
+ console.log('执行完后记得 ' + colors.yellow + '重启电脑' + colors.nc + ' 哦!');
292
+ console.log('');
293
+ } catch (err) {
294
+ console.error('[' + colors.red + '错误' + colors.nc + '] 执行提权脚本失败:', err.message);
295
+ console.log('建议右键点击终端,选择【以管理员身份运行】再重试。');
296
+ }
297
+ }
298
+
272
299
  // ============================================================================
273
300
  // 帮助信息
274
301
  // ============================================================================
@@ -285,6 +312,7 @@ function showHelp() {
285
312
  console.log(' install 安装 OpenClaw 服务');
286
313
  console.log(' status 简化版状态查看(学生友好)');
287
314
  console.log(' new 创建新的 Agent(学生练习用)');
315
+ console.log(' wsl2 修复 Windows 下 WSL2 安装失败的问题 (仅限 Windows)');
288
316
  console.log(' help 显示帮助信息');
289
317
  console.log('');
290
318
  console.log('示例:');
@@ -308,6 +336,8 @@ if (!command || command === 'help' || command === '--help' || command === '-h')
308
336
  runStatus();
309
337
  } else if (command === 'new') {
310
338
  runNew();
339
+ } else if (command === 'wsl2') {
340
+ runWsl2();
311
341
  } else {
312
342
  console.error('[' + colors.red + '错误' + colors.nc + '] 未知命令: ' + command);
313
343
  showHelp();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiyiran/myclaw",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "bin": {
package/publish.sh ADDED
@@ -0,0 +1,30 @@
1
+ #!/bin/bash
2
+ set -e # 遇到错误即停止
3
+
4
+ echo "📦 准备发布新版本..."
5
+
6
+ # 1. 添加所有变动
7
+ git add .
8
+
9
+ # 2. 检查是否有未提交的代码,如果有则先提交
10
+ if ! git diff-index --quiet HEAD; then
11
+ echo "📝 发现有修改的内容,正在自动提交..."
12
+ git commit -m "chore: auto update before publish"
13
+ else
14
+ echo "✅ 工作区很干净,不需要额外提交代码。"
15
+ fi
16
+
17
+ # 3. 自动更新最小版本号 (npm version patch 会自动再做一个改 package.json 的 commit 并且打上 Tag)
18
+ echo "📈 增加 Patch 版本号..."
19
+ npm version patch
20
+
21
+ # 4. 推送代码和 Tag 到 GitHub
22
+ echo "☁️ 推送代码和版本 Tag 到 GitHub..."
23
+ git push origin main
24
+ git push origin --tags
25
+
26
+ # 5. 发布到 npm
27
+ echo "🚀 发布到 npm 仓库..."
28
+ npm publish
29
+
30
+ echo "🎉 发布流执行完成!"