openclaw-remote-skills 1.0.0
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/LICENSE +21 -0
- package/README.md +257 -0
- package/bin/install.js +122 -0
- package/index.js +306 -0
- package/package.json +48 -0
- package/skills/remote-node-skill/README.md +145 -0
- package/skills/remote-node-skill/SKILL.md +214 -0
- package/skills/remote-node-skill/examples.js +251 -0
- package/skills/remote-node-skill/package.json +28 -0
- package/skills/remote-wps365-skill/README.md +490 -0
- package/skills/remote-wps365-skill/SKILL.md +923 -0
- package/skills/remote-wps365-skill/agentspace-installer.js +419 -0
- package/skills/remote-wps365-skill/example-usage.js +487 -0
- package/skills/remote-wps365-skill/package.json +49 -0
- package/skills/remote-wps365-skill/test-agentspace-install.js +104 -0
- package/skills/remote-wps365-skill/test-simple.js +157 -0
- package/skills/remote-wps365-skill/wps365-remote.js +612 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 OpenClaw Assistant
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
# OpenClaw Remote Skills
|
|
2
|
+
|
|
3
|
+
一个包含两个强大远程技能的 OpenClaw 扩展包,让你可以远程操作 Windows 节点和 WPS365 功能。
|
|
4
|
+
|
|
5
|
+
## 📦 包含的技能
|
|
6
|
+
|
|
7
|
+
### 1. `remote-wps365-skill`
|
|
8
|
+
**远程调用 Windows 节点上的 WPS365 功能**
|
|
9
|
+
|
|
10
|
+
特性:
|
|
11
|
+
- ✅ 即时消息:搜索会话、发送消息、获取历史消息
|
|
12
|
+
- ✅ 日历管理:创建、查询、更新日历事件
|
|
13
|
+
- ✅ 联系人管理:搜索、查看联系人
|
|
14
|
+
- ✅ 云盘操作:上传、下载、搜索文件
|
|
15
|
+
- ✅ 数据表操作:读写数据表
|
|
16
|
+
- ✅ 会议管理:创建、加入会议
|
|
17
|
+
- ✅ **Agentspace 自动安装**:一键安装配置 agentspace 插件
|
|
18
|
+
- ✅ 批量消息发送
|
|
19
|
+
- ✅ 完整的错误处理和重试机制
|
|
20
|
+
|
|
21
|
+
### 2. `remote-node-skill`
|
|
22
|
+
**远程节点操作技能**
|
|
23
|
+
|
|
24
|
+
特性:
|
|
25
|
+
- ✅ 检查节点状态和连接
|
|
26
|
+
- ✅ 在远程节点上执行系统命令
|
|
27
|
+
- ✅ 读取远程文件内容
|
|
28
|
+
- ✅ 列出远程目录
|
|
29
|
+
- ✅ 获取系统信息
|
|
30
|
+
- ✅ 控制远程浏览器
|
|
31
|
+
- ✅ 支持 Windows 和 Linux/Mac 节点
|
|
32
|
+
|
|
33
|
+
## 🚀 快速安装
|
|
34
|
+
|
|
35
|
+
### 方法1:使用 npx(推荐)
|
|
36
|
+
```bash
|
|
37
|
+
# 一键安装
|
|
38
|
+
npx openclaw-remote-skills
|
|
39
|
+
|
|
40
|
+
# 显示详细安装信息
|
|
41
|
+
npx openclaw-remote-skills --verbose
|
|
42
|
+
|
|
43
|
+
# 强制重新安装
|
|
44
|
+
npx openclaw-remote-skills --force
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 方法2:全局安装
|
|
48
|
+
```bash
|
|
49
|
+
# 全局安装
|
|
50
|
+
npm install -g openclaw-remote-skills
|
|
51
|
+
|
|
52
|
+
# 安装技能
|
|
53
|
+
install-openclaw-skills
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 方法3:本地安装
|
|
57
|
+
```bash
|
|
58
|
+
# 作为项目依赖安装
|
|
59
|
+
npm install openclaw-remote-skills
|
|
60
|
+
|
|
61
|
+
# 运行安装脚本
|
|
62
|
+
npx install-openclaw-skills
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## 🔧 配置步骤
|
|
66
|
+
|
|
67
|
+
安装脚本会自动复制技能文件。你需要手动配置 OpenClaw:
|
|
68
|
+
|
|
69
|
+
### 1. 编辑 OpenClaw 配置文件
|
|
70
|
+
编辑 `~/.openclaw/openclaw.json`,在 `skills.load.extraDirs` 数组中添加:
|
|
71
|
+
|
|
72
|
+
```json
|
|
73
|
+
{
|
|
74
|
+
"skills": {
|
|
75
|
+
"load": {
|
|
76
|
+
"extraDirs": [
|
|
77
|
+
"/home/你的用户名/.openclaw/skills/remote-wps365-skill",
|
|
78
|
+
"/home/你的用户名/.openclaw/skills/remote-node-skill"
|
|
79
|
+
]
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**注意:** 将 `/home/你的用户名` 替换为你的实际用户目录。
|
|
86
|
+
|
|
87
|
+
### 2. 重启 OpenClaw
|
|
88
|
+
```bash
|
|
89
|
+
openclaw gateway restart
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### 3. 验证安装
|
|
93
|
+
在 OpenClaw 会话中询问:
|
|
94
|
+
```
|
|
95
|
+
你有哪些可用的skills
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
应该能看到 `remote-wps365-skill` 和 `remote-node-skill` 在列表中。
|
|
99
|
+
|
|
100
|
+
## 📖 使用指南
|
|
101
|
+
|
|
102
|
+
### remote-wps365-skill 使用示例
|
|
103
|
+
|
|
104
|
+
```javascript
|
|
105
|
+
// 在你的 OpenClaw 技能或脚本中使用
|
|
106
|
+
const { wps365 } = require('~/.openclaw/skills/remote-wps365-skill/wps365-remote.js')
|
|
107
|
+
|
|
108
|
+
// 发送消息到群聊
|
|
109
|
+
await wps365.sendMessageToGroup("个人测试告警群", "**系统通知**\n测试消息")
|
|
110
|
+
|
|
111
|
+
// 搜索会话
|
|
112
|
+
const chats = await wps365.runCommand("im", "search", {
|
|
113
|
+
keyword: "测试",
|
|
114
|
+
page_size: 10
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
// 一键安装 agentspace
|
|
118
|
+
const { installAgentspace } = require('~/.openclaw/skills/remote-wps365-skill/wps365-remote.js')
|
|
119
|
+
const result = await installAgentspace()
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### remote-node-skill 使用示例
|
|
123
|
+
|
|
124
|
+
```javascript
|
|
125
|
+
// 使用 OpenClaw 的 nodes 工具
|
|
126
|
+
const status = nodes(action="status")
|
|
127
|
+
|
|
128
|
+
// 获取 Windows 节点 ID
|
|
129
|
+
const windowsNode = status.nodes.find(node =>
|
|
130
|
+
node.platform === "win32" && node.connected === true
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
// 执行远程命令
|
|
134
|
+
const result = nodes(
|
|
135
|
+
action="invoke",
|
|
136
|
+
node=windowsNode.nodeId,
|
|
137
|
+
invokeCommand="system.run",
|
|
138
|
+
invokeParamsJson={"command": ["cmd.exe", "/c", "echo Hello from Windows"]}
|
|
139
|
+
)
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### 命令行使用
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
# 进入技能目录
|
|
146
|
+
cd ~/.openclaw/skills/remote-wps365-skill
|
|
147
|
+
|
|
148
|
+
# 运行演示
|
|
149
|
+
npm run demo
|
|
150
|
+
|
|
151
|
+
# 安装 agentspace
|
|
152
|
+
npm run install-agentspace
|
|
153
|
+
|
|
154
|
+
# 检查 agentspace 状态
|
|
155
|
+
npm run check-agentspace
|
|
156
|
+
|
|
157
|
+
# 发送消息
|
|
158
|
+
npm run send -- "群名" "消息内容"
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## 🛠️ 依赖和要求
|
|
162
|
+
|
|
163
|
+
### 系统要求
|
|
164
|
+
- Node.js >= 14.0.0
|
|
165
|
+
- OpenClaw >= 2026.3.7
|
|
166
|
+
- 网络连接(用于下载 agentspace 安装器)
|
|
167
|
+
|
|
168
|
+
### Windows 节点要求
|
|
169
|
+
- Windows 节点已与 OpenClaw 配对并连接
|
|
170
|
+
- Windows 节点上已安装 wps365-skill(路径:`C:\Users\KSG\.openclaw\skills\wps365-skill`)
|
|
171
|
+
- Windows 节点的 openclaw.json 中配置了正确的 wps_sid
|
|
172
|
+
- 节点具有 system.run 执行权限
|
|
173
|
+
|
|
174
|
+
## 🔍 故障排除
|
|
175
|
+
|
|
176
|
+
### 技能未显示
|
|
177
|
+
1. 检查技能路径是否正确配置在 `openclaw.json` 中
|
|
178
|
+
2. 确保 OpenClaw 已重启
|
|
179
|
+
3. 检查技能目录权限
|
|
180
|
+
4. 运行检查命令:`npx openclaw-remote-skills check`
|
|
181
|
+
|
|
182
|
+
### Windows 节点连接问题
|
|
183
|
+
1. 确认 Windows 节点已配对:`openclaw nodes status`
|
|
184
|
+
2. 确认节点在线并连接
|
|
185
|
+
3. 检查防火墙设置
|
|
186
|
+
|
|
187
|
+
### agentspace 安装失败
|
|
188
|
+
1. 确认网络连接正常
|
|
189
|
+
2. 确认 Windows 节点上有 agentspace 配置
|
|
190
|
+
3. 检查是否有权限写入 `openclaw.json`
|
|
191
|
+
4. 查看详细错误:`npx openclaw-remote-skills --verbose`
|
|
192
|
+
|
|
193
|
+
## 🔄 更新
|
|
194
|
+
|
|
195
|
+
### 更新 npm 包
|
|
196
|
+
```bash
|
|
197
|
+
# 如果是全局安装
|
|
198
|
+
npm update -g openclaw-remote-skills
|
|
199
|
+
|
|
200
|
+
# 如果是本地安装
|
|
201
|
+
npm update openclaw-remote-skills
|
|
202
|
+
|
|
203
|
+
# 重新运行安装
|
|
204
|
+
npx openclaw-remote-skills --force
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### 手动更新
|
|
208
|
+
```bash
|
|
209
|
+
# 备份旧版本
|
|
210
|
+
cp -r ~/.openclaw/skills/remote-wps365-skill ~/.openclaw/skills/remote-wps365-skill.backup
|
|
211
|
+
cp -r ~/.openclaw/skills/remote-node-skill ~/.openclaw/skills/remote-node-skill.backup
|
|
212
|
+
|
|
213
|
+
# 重新安装
|
|
214
|
+
npx openclaw-remote-skills --force
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## 📁 项目结构
|
|
218
|
+
|
|
219
|
+
```
|
|
220
|
+
openclaw-remote-skills/
|
|
221
|
+
├── bin/
|
|
222
|
+
│ └── install.js # 安装脚本(命令行入口)
|
|
223
|
+
├── skills/
|
|
224
|
+
│ ├── remote-wps365-skill/ # WPS365 远程技能
|
|
225
|
+
│ └── remote-node-skill/ # 远程节点技能
|
|
226
|
+
├── index.js # 主模块
|
|
227
|
+
├── package.json # npm 包配置
|
|
228
|
+
└── README.md # 本文档
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## 🤝 贡献
|
|
232
|
+
|
|
233
|
+
欢迎贡献代码!请遵循以下步骤:
|
|
234
|
+
|
|
235
|
+
1. Fork 仓库
|
|
236
|
+
2. 创建功能分支 (`git checkout -b feature/amazing-feature`)
|
|
237
|
+
3. 提交更改 (`git commit -m 'Add some amazing feature'`)
|
|
238
|
+
4. 推送分支 (`git push origin feature/amazing-feature`)
|
|
239
|
+
5. 创建 Pull Request
|
|
240
|
+
|
|
241
|
+
## 📄 许可证
|
|
242
|
+
|
|
243
|
+
本项目基于 MIT 许可证开源 - 查看 [LICENSE](LICENSE) 文件了解详情。
|
|
244
|
+
|
|
245
|
+
## 🙏 致谢
|
|
246
|
+
|
|
247
|
+
感谢 [OpenClaw](https://openclaw.ai) 社区的支持和贡献。
|
|
248
|
+
|
|
249
|
+
## 📞 支持
|
|
250
|
+
|
|
251
|
+
- **问题报告**: [GitHub Issues](https://github.com/your-username/openclaw-remote-skills/issues)
|
|
252
|
+
- **讨论**: [OpenClaw Discord](https://discord.com/invite/clawd)
|
|
253
|
+
- **文档**: [OpenClaw Docs](https://docs.openclaw.ai)
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
**提示**: 安装完成后,记得重启 OpenClaw 并检查技能是否出现在可用技能列表中!
|
package/bin/install.js
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* OpenClaw Remote Skills 安装脚本
|
|
4
|
+
* 这是包的 bin 入口,支持直接运行
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const path = require('path')
|
|
8
|
+
const { installSkills } = require('../index.js')
|
|
9
|
+
|
|
10
|
+
// 彩色输出
|
|
11
|
+
const colors = {
|
|
12
|
+
reset: '\x1b[0m',
|
|
13
|
+
red: '\x1b[31m',
|
|
14
|
+
green: '\x1b[32m',
|
|
15
|
+
yellow: '\x1b[33m',
|
|
16
|
+
blue: '\x1b[34m',
|
|
17
|
+
magenta: '\x1b[35m',
|
|
18
|
+
cyan: '\x1b[36m'
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function colorize(text, color) {
|
|
22
|
+
return colors[color] + text + colors.reset
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// 显示横幅
|
|
26
|
+
console.log(colorize(`
|
|
27
|
+
╔══════════════════════════════════════════════════════════╗
|
|
28
|
+
║ ║
|
|
29
|
+
║ ╔═╗┌─┐┌┬┐┌─┐┬ ┌─┐┬─┐ ╦═╗┌─┐┬ ┬┌┬┐┬┌┐┌┌─┐ ║
|
|
30
|
+
║ ╠═╝├┤ │ ├─┘│ ├┤ ├┬┘ ╠╦╝│ ││ │ │ ││││├┤ ║
|
|
31
|
+
║ ╩ └─┘ ┴ ┴ ┴─┘└─┘┴└─ ╩╚═└─┘└─┘ ┴ ┴┘└┘└─┘ ║
|
|
32
|
+
║ ║
|
|
33
|
+
║ Remote Skills Installer ║
|
|
34
|
+
║ ║
|
|
35
|
+
╚══════════════════════════════════════════════════════════╝
|
|
36
|
+
`, 'cyan'))
|
|
37
|
+
|
|
38
|
+
console.log(colorize('🚀 开始安装 OpenClaw Remote Skills...', 'yellow'))
|
|
39
|
+
console.log()
|
|
40
|
+
|
|
41
|
+
// 解析命令行参数
|
|
42
|
+
const args = process.argv.slice(2)
|
|
43
|
+
const options = {
|
|
44
|
+
verbose: args.includes('--verbose') || args.includes('-v'),
|
|
45
|
+
force: args.includes('--force') || args.includes('-f'),
|
|
46
|
+
help: args.includes('--help') || args.includes('-h')
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// 显示帮助
|
|
50
|
+
if (options.help) {
|
|
51
|
+
console.log(colorize('使用方法:', 'green'))
|
|
52
|
+
console.log(' npx openclaw-remote-skills')
|
|
53
|
+
console.log(' npx openclaw-remote-skills [选项]')
|
|
54
|
+
console.log()
|
|
55
|
+
console.log(colorize('选项:', 'green'))
|
|
56
|
+
console.log(' -v, --verbose 显示详细安装信息')
|
|
57
|
+
console.log(' -f, --force 强制重新安装已存在的技能')
|
|
58
|
+
console.log(' -h, --help 显示此帮助信息')
|
|
59
|
+
console.log()
|
|
60
|
+
console.log(colorize('示例:', 'green'))
|
|
61
|
+
console.log(' npx openclaw-remote-skills')
|
|
62
|
+
console.log(' npx openclaw-remote-skills --verbose')
|
|
63
|
+
console.log(' npx openclaw-remote-skills --force')
|
|
64
|
+
console.log()
|
|
65
|
+
process.exit(0)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// 执行安装
|
|
69
|
+
try {
|
|
70
|
+
console.log(colorize('📦 正在安装技能包...', 'blue'))
|
|
71
|
+
|
|
72
|
+
const result = installSkills(options)
|
|
73
|
+
|
|
74
|
+
console.log()
|
|
75
|
+
console.log(colorize('✅ 安装完成!', 'green'))
|
|
76
|
+
|
|
77
|
+
// 显示安装摘要
|
|
78
|
+
console.log(colorize('\n📊 安装摘要:', 'cyan'))
|
|
79
|
+
result.results.forEach(item => {
|
|
80
|
+
const statusIcon = item.status === 'installed' ? '✅' :
|
|
81
|
+
item.status === 'skipped' ? '⏭️' : '❌'
|
|
82
|
+
const statusColor = item.status === 'installed' ? 'green' :
|
|
83
|
+
item.status === 'skipped' ? 'yellow' : 'red'
|
|
84
|
+
|
|
85
|
+
console.log(` ${statusIcon} ${colorize(item.name, statusColor)}`)
|
|
86
|
+
if (item.status === 'failed') {
|
|
87
|
+
console.log(` 错误: ${colorize(item.error, 'red')}`)
|
|
88
|
+
}
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
// 显示配置提示
|
|
92
|
+
console.log(colorize('\n🔧 配置说明:', 'magenta'))
|
|
93
|
+
console.log(result.configPrompt)
|
|
94
|
+
|
|
95
|
+
// 显示使用提示
|
|
96
|
+
console.log(colorize('\n🎯 使用技能:', 'yellow'))
|
|
97
|
+
console.log(`
|
|
98
|
+
安装完成后,重启 OpenClaw 即可使用:
|
|
99
|
+
|
|
100
|
+
1. 重启 OpenClaw:
|
|
101
|
+
${colorize('openclaw gateway restart', 'cyan')}
|
|
102
|
+
|
|
103
|
+
2. 验证技能加载:
|
|
104
|
+
在 OpenClaw 会话中询问 "你有哪些可用的skills"
|
|
105
|
+
|
|
106
|
+
3. 使用技能:
|
|
107
|
+
• remote-wps365-skill: 远程 WPS365 操作
|
|
108
|
+
• remote-node-skill: 远程节点操作
|
|
109
|
+
`)
|
|
110
|
+
|
|
111
|
+
console.log(colorize('\n💡 提示:', 'blue'))
|
|
112
|
+
console.log(' 可以通过以下命令检查安装状态:')
|
|
113
|
+
console.log(` ${colorize('npx openclaw-remote-skills check', 'cyan')}`)
|
|
114
|
+
|
|
115
|
+
console.log(colorize('\n✨ 安装完成!重启 OpenClaw 后即可使用远程技能。', 'green'))
|
|
116
|
+
|
|
117
|
+
} catch (error) {
|
|
118
|
+
console.error(colorize(`\n❌ 安装失败: ${error.message}`, 'red'))
|
|
119
|
+
console.error(colorize('错误详情:', 'red'))
|
|
120
|
+
console.error(error.stack)
|
|
121
|
+
process.exit(1)
|
|
122
|
+
}
|
package/index.js
ADDED
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* OpenClaw Remote Skills 主入口文件
|
|
4
|
+
*
|
|
5
|
+
* 这个包提供两个强大的 OpenClaw 远程技能:
|
|
6
|
+
* 1. remote-wps365-skill - 远程调用 Windows 节点上的 WPS365 功能
|
|
7
|
+
* 2. remote-node-skill - 远程节点操作技能
|
|
8
|
+
*
|
|
9
|
+
* @file 主模块文件
|
|
10
|
+
* @module openclaw-remote-skills
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const path = require('path')
|
|
14
|
+
const fs = require('fs')
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* 获取技能安装信息
|
|
18
|
+
* @returns {Object} 技能信息
|
|
19
|
+
*/
|
|
20
|
+
function getSkillsInfo() {
|
|
21
|
+
return {
|
|
22
|
+
skills: [
|
|
23
|
+
{
|
|
24
|
+
name: 'remote-wps365-skill',
|
|
25
|
+
description: '远程调用 Windows 节点上的 WPS365 功能',
|
|
26
|
+
path: path.join(__dirname, 'skills', 'remote-wps365-skill'),
|
|
27
|
+
version: '1.0.0'
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: 'remote-node-skill',
|
|
31
|
+
description: '远程节点操作技能',
|
|
32
|
+
path: path.join(__dirname, 'skills', 'remote-node-skill'),
|
|
33
|
+
version: '1.0.0'
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
version: require('./package.json').version,
|
|
37
|
+
installPath: getOpenClawSkillsPath()
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* 获取 OpenClaw 技能路径
|
|
43
|
+
* @returns {string} 技能安装路径
|
|
44
|
+
*/
|
|
45
|
+
function getOpenClawSkillsPath() {
|
|
46
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE || '/home/' + process.env.USER
|
|
47
|
+
return path.join(homeDir, '.openclaw', 'skills')
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* 检查技能是否已安装
|
|
52
|
+
* @returns {Object} 检查结果
|
|
53
|
+
*/
|
|
54
|
+
function checkInstallation() {
|
|
55
|
+
const openclawSkillsPath = getOpenClawSkillsPath()
|
|
56
|
+
const skills = getSkillsInfo().skills
|
|
57
|
+
|
|
58
|
+
const results = skills.map(skill => {
|
|
59
|
+
const targetPath = path.join(openclawSkillsPath, skill.name)
|
|
60
|
+
return {
|
|
61
|
+
name: skill.name,
|
|
62
|
+
installed: fs.existsSync(targetPath),
|
|
63
|
+
path: targetPath
|
|
64
|
+
}
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
const allInstalled = results.every(r => r.installed)
|
|
68
|
+
|
|
69
|
+
return {
|
|
70
|
+
allInstalled,
|
|
71
|
+
skills: results,
|
|
72
|
+
openclawSkillsPath
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* 安装技能
|
|
78
|
+
* @param {Object} options - 安装选项
|
|
79
|
+
* @returns {Object} 安装结果
|
|
80
|
+
*/
|
|
81
|
+
function installSkills(options = {}) {
|
|
82
|
+
const { verbose = false, force = false } = options
|
|
83
|
+
const openclawSkillsPath = getOpenClawSkillsPath()
|
|
84
|
+
const skills = getSkillsInfo().skills
|
|
85
|
+
|
|
86
|
+
console.log('🚀 开始安装 OpenClaw Remote Skills...')
|
|
87
|
+
console.log(`目标目录: ${openclawSkillsPath}`)
|
|
88
|
+
|
|
89
|
+
// 创建目标目录
|
|
90
|
+
if (!fs.existsSync(openclawSkillsPath)) {
|
|
91
|
+
fs.mkdirSync(openclawSkillsPath, { recursive: true })
|
|
92
|
+
if (verbose) console.log(`✅ 创建目录: ${openclawSkillsPath}`)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const results = []
|
|
96
|
+
|
|
97
|
+
// 安装每个技能
|
|
98
|
+
skills.forEach(skill => {
|
|
99
|
+
const sourcePath = skill.path
|
|
100
|
+
const targetPath = path.join(openclawSkillsPath, skill.name)
|
|
101
|
+
|
|
102
|
+
if (fs.existsSync(targetPath) && !force) {
|
|
103
|
+
if (verbose) console.log(`⏭️ 跳过 ${skill.name} (已存在)`)
|
|
104
|
+
results.push({ name: skill.name, status: 'skipped', path: targetPath })
|
|
105
|
+
return
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
try {
|
|
109
|
+
// 复制技能
|
|
110
|
+
copyFolderSync(sourcePath, targetPath)
|
|
111
|
+
|
|
112
|
+
if (verbose) {
|
|
113
|
+
console.log(`✅ 安装 ${skill.name}`)
|
|
114
|
+
console.log(` 来源: ${sourcePath}`)
|
|
115
|
+
console.log(` 目标: ${targetPath}`)
|
|
116
|
+
} else {
|
|
117
|
+
console.log(`✅ ${skill.name}`)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
results.push({ name: skill.name, status: 'installed', path: targetPath })
|
|
121
|
+
} catch (error) {
|
|
122
|
+
console.error(`❌ 安装 ${skill.name} 失败: ${error.message}`)
|
|
123
|
+
results.push({ name: skill.name, status: 'failed', error: error.message })
|
|
124
|
+
}
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
// 生成配置提示
|
|
128
|
+
const installedSkills = results.filter(r => r.status === 'installed')
|
|
129
|
+
|
|
130
|
+
return {
|
|
131
|
+
success: results.every(r => r.status !== 'failed'),
|
|
132
|
+
results,
|
|
133
|
+
configPrompt: generateConfigPrompt(installedSkills)
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* 复制文件夹(同步)
|
|
139
|
+
* @param {string} src - 源路径
|
|
140
|
+
* @param {string} dest - 目标路径
|
|
141
|
+
*/
|
|
142
|
+
function copyFolderSync(src, dest) {
|
|
143
|
+
if (!fs.existsSync(src)) {
|
|
144
|
+
throw new Error(`源路径不存在: ${src}`)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// 确保目标目录存在
|
|
148
|
+
if (!fs.existsSync(dest)) {
|
|
149
|
+
fs.mkdirSync(dest, { recursive: true })
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// 复制目录内容
|
|
153
|
+
const items = fs.readdirSync(src)
|
|
154
|
+
|
|
155
|
+
items.forEach(item => {
|
|
156
|
+
const srcPath = path.join(src, item)
|
|
157
|
+
const destPath = path.join(dest, item)
|
|
158
|
+
|
|
159
|
+
const stat = fs.statSync(srcPath)
|
|
160
|
+
|
|
161
|
+
if (stat.isDirectory()) {
|
|
162
|
+
copyFolderSync(srcPath, destPath)
|
|
163
|
+
} else {
|
|
164
|
+
fs.copyFileSync(srcPath, destPath)
|
|
165
|
+
}
|
|
166
|
+
})
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* 生成配置提示信息
|
|
171
|
+
* @param {Array} installedSkills - 已安装的技能
|
|
172
|
+
* @returns {string} 配置提示
|
|
173
|
+
*/
|
|
174
|
+
function generateConfigPrompt(installedSkills) {
|
|
175
|
+
if (installedSkills.length === 0) {
|
|
176
|
+
return '没有需要配置的技能。'
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const openclawSkillsPath = getOpenClawSkillsPath()
|
|
180
|
+
const configLines = installedSkills.map(skill => {
|
|
181
|
+
const skillPath = path.join(openclawSkillsPath, skill.name)
|
|
182
|
+
return `"${skillPath}"`
|
|
183
|
+
})
|
|
184
|
+
|
|
185
|
+
return `
|
|
186
|
+
📋 下一步配置:
|
|
187
|
+
|
|
188
|
+
1. 编辑 OpenClaw 配置文件:
|
|
189
|
+
~/.openclaw/openclaw.json
|
|
190
|
+
|
|
191
|
+
2. 在 "skills.load.extraDirs" 数组中添加以下路径:
|
|
192
|
+
${configLines.map(line => ` - ${line}`).join('\n')}
|
|
193
|
+
|
|
194
|
+
3. 重启 OpenClaw:
|
|
195
|
+
openclaw gateway restart
|
|
196
|
+
|
|
197
|
+
安装完成后,技能会自动出现在 OpenClaw 的可用技能列表中。`
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* 显示使用帮助
|
|
202
|
+
*/
|
|
203
|
+
function showHelp() {
|
|
204
|
+
console.log(`
|
|
205
|
+
OpenClaw Remote Skills 工具
|
|
206
|
+
|
|
207
|
+
用法:
|
|
208
|
+
node index.js [命令] [选项]
|
|
209
|
+
|
|
210
|
+
命令:
|
|
211
|
+
install 安装技能
|
|
212
|
+
check 检查安装状态
|
|
213
|
+
info 显示包信息
|
|
214
|
+
help 显示此帮助信息
|
|
215
|
+
|
|
216
|
+
选项:
|
|
217
|
+
--verbose 显示详细输出
|
|
218
|
+
--force 强制重新安装
|
|
219
|
+
|
|
220
|
+
示例:
|
|
221
|
+
node index.js install --verbose
|
|
222
|
+
node index.js check
|
|
223
|
+
node index.js info
|
|
224
|
+
`)
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* 显示包信息
|
|
229
|
+
*/
|
|
230
|
+
function showInfo() {
|
|
231
|
+
const info = getSkillsInfo()
|
|
232
|
+
|
|
233
|
+
console.log(`
|
|
234
|
+
OpenClaw Remote Skills - v${info.version}
|
|
235
|
+
========================================
|
|
236
|
+
|
|
237
|
+
包含技能:
|
|
238
|
+
${info.skills.map(skill => ` • ${skill.name} - ${skill.description}`).join('\n')}
|
|
239
|
+
|
|
240
|
+
安装路径: ${info.installPath}
|
|
241
|
+
|
|
242
|
+
特性:
|
|
243
|
+
• 一键安装两个远程技能
|
|
244
|
+
• 自动配置提示
|
|
245
|
+
• 支持 Windows 节点远程操作
|
|
246
|
+
• 包含 WPS365 功能集成
|
|
247
|
+
• 包含 agentspace 自动安装
|
|
248
|
+
`)
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// 命令行接口
|
|
252
|
+
if (require.main === module) {
|
|
253
|
+
const args = process.argv.slice(2)
|
|
254
|
+
|
|
255
|
+
if (args.length === 0) {
|
|
256
|
+
showHelp()
|
|
257
|
+
process.exit(0)
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const command = args[0]
|
|
261
|
+
const options = {
|
|
262
|
+
verbose: args.includes('--verbose'),
|
|
263
|
+
force: args.includes('--force')
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
switch (command) {
|
|
267
|
+
case 'install':
|
|
268
|
+
const result = installSkills(options)
|
|
269
|
+
console.log('\n' + result.configPrompt)
|
|
270
|
+
process.exit(result.success ? 0 : 1)
|
|
271
|
+
break
|
|
272
|
+
|
|
273
|
+
case 'check':
|
|
274
|
+
const check = checkInstallation()
|
|
275
|
+
console.log('\n安装状态检查:')
|
|
276
|
+
check.skills.forEach(skill => {
|
|
277
|
+
console.log(` ${skill.name}: ${skill.installed ? '✅ 已安装' : '❌ 未安装'}`)
|
|
278
|
+
if (skill.installed) {
|
|
279
|
+
console.log(` 路径: ${skill.path}`)
|
|
280
|
+
}
|
|
281
|
+
})
|
|
282
|
+
console.log(`\nOpenClaw 技能目录: ${check.openclawSkillsPath}`)
|
|
283
|
+
break
|
|
284
|
+
|
|
285
|
+
case 'info':
|
|
286
|
+
showInfo()
|
|
287
|
+
break
|
|
288
|
+
|
|
289
|
+
case 'help':
|
|
290
|
+
showHelp()
|
|
291
|
+
break
|
|
292
|
+
|
|
293
|
+
default:
|
|
294
|
+
console.error(`未知命令: ${command}`)
|
|
295
|
+
showHelp()
|
|
296
|
+
process.exit(1)
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// 导出模块
|
|
301
|
+
module.exports = {
|
|
302
|
+
getSkillsInfo,
|
|
303
|
+
checkInstallation,
|
|
304
|
+
installSkills,
|
|
305
|
+
getOpenClawSkillsPath
|
|
306
|
+
}
|