@workskills/getskill 1.0.0 → 1.1.1

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.
Files changed (4) hide show
  1. package/EXAMPLES.md +29 -2
  2. package/README.md +43 -18
  3. package/index.js +108 -20
  4. package/package.json +2 -2
package/EXAMPLES.md CHANGED
@@ -147,6 +147,12 @@ const getskill = require('@workskills/getskill');
147
147
 
148
148
  (async () => {
149
149
  try {
150
+ // 设置自定义 API 地址(可选)
151
+ getskill.setBaseUrl('https://getskill.work');
152
+
153
+ // 查看当前 API 地址
154
+ console.log('当前 API:', getskill.getBaseUrl());
155
+
150
156
  // 检查 Git 是否已安装
151
157
  const isGitInstalled = await getskill.checkGitInstalled();
152
158
  console.log('Git 已安装:', isGitInstalled);
@@ -161,7 +167,7 @@ const getskill = require('@workskills/getskill');
161
167
  console.log('搜索结果:', results);
162
168
 
163
169
  // 安装技能
164
- const result = await getskill.downloadSkill('commit-helper');
170
+ const result = await getskill.downloadSkill('skills/commit-helper');
165
171
  console.log('安装成功:', result.files);
166
172
 
167
173
  // 更新技能
@@ -224,7 +230,28 @@ $ getskill search commit
224
230
  执行命令时出错: connect ETIMEDOUT
225
231
  ```
226
232
 
227
- ## 场景 6: 目录结构查看
233
+ ## 场景 6: 配置自定义 API 地址
234
+
235
+ ```bash
236
+ # 查看当前 API 地址
237
+ $ getskill config get
238
+ 当前 BASE_URL: https://getskill.work
239
+
240
+ # 设置自定义 API 地址
241
+ $ getskill config set https://custom-api.example.com
242
+ BASE_URL 已设置为: https://custom-api.example.com
243
+
244
+ # 通过环境变量设置
245
+ $ GETSKILL_BASE_URL=https://another-api.com getskill search commit
246
+ 找到 2 个技能:
247
+ ...
248
+
249
+ # 验证配置
250
+ $ getskill config get
251
+ 当前 BASE_URL: https://custom-api.example.com
252
+ ```
253
+
254
+ ## 场景 7: 目录结构查看
228
255
 
229
256
  ```bash
230
257
  # 安装几个技能后查看目录结构
package/README.md CHANGED
@@ -10,6 +10,7 @@ OpenClaw 技能管理工具 - 从 getskill.work 搜索、下载和更新技能
10
10
  - 🛠️ 自动检测并引导安装 Git(如未安装)
11
11
  - 📂 跨平台支持(Windows/macOS/Linux)
12
12
  - 💾 自动管理技能文件到 OpenClaw skills 目录
13
+ - ⚙️ 支持自定义 API 地址
13
14
 
14
15
  ## 工作原理
15
16
 
@@ -142,25 +143,44 @@ getskill clean
142
143
 
143
144
  清理所有 Git 仓库缓存(不影响 skills 目录中的文件)
144
145
 
146
+ ### 配置 API 地址
147
+
148
+ 查看当前 API 地址:
149
+ ```bash
150
+ getskill config get
151
+ ```
152
+
153
+ 设置自定义 API 地址:
154
+ ```bash
155
+ getskill config set https://your-custom-api.com
156
+ ```
157
+
158
+ 通过环境变量设置:
159
+ ```bash
160
+ GETSKILL_BASE_URL=https://your-custom-api.com getskill search keyword
161
+ ```
162
+
145
163
  ## API 接口规范
146
164
 
147
165
  ### 搜索 API
148
166
 
149
167
  ```
150
- GET https://getskill.work/api/skills/search?q=<关键词>
168
+ GET https://getskill.work/repo/search?sort=updated&order=desc&q=<关键词>&page=1&limit=20
151
169
  ```
152
170
 
153
171
  响应格式:
154
172
  ```json
155
173
  {
156
- "skills": [
174
+ "ok": true,
175
+ "data": [
157
176
  {
158
- "id": "commit-helper",
159
- "name": "commit-helper",
160
- "description": "帮助生成规范的 git commit 信息",
161
- "git_url": "https://github.com/workskills/commit-helper.git",
162
- "author": "workskills",
163
- "version": "1.0.0"
177
+ "repository": {
178
+ "id": 1,
179
+ "full_name": "skills/commit-helper",
180
+ "description": "帮助生成规范的 git commit 信息",
181
+ "html_url": "https://getskill.work/skills/commit-helper",
182
+ "clone_url": "https://getskill.work/skills/commit-helper.git"
183
+ }
164
184
  }
165
185
  ]
166
186
  }
@@ -169,20 +189,19 @@ GET https://getskill.work/api/skills/search?q=<关键词>
169
189
  ### 详情 API
170
190
 
171
191
  ```
172
- GET https://getskill.work/api/skills/<技能ID>
192
+ GET https://getskill.work/repo/<技能名称>
173
193
  ```
174
194
 
175
195
  响应格式:
176
196
  ```json
177
197
  {
178
- "id": "commit-helper",
179
- "name": "commit-helper",
180
- "description": "帮助生成规范的 git commit 信息",
181
- "git_url": "https://github.com/workskills/commit-helper.git",
182
- "author": "workskills",
183
- "version": "1.0.0",
184
- "files": ["commit-helper.md"],
185
- "readme": "..."
198
+ "repository": {
199
+ "id": 1,
200
+ "full_name": "skills/commit-helper",
201
+ "description": "帮助生成规范的 git commit 信息",
202
+ "html_url": "https://getskill.work/skills/commit-helper",
203
+ "clone_url": "https://getskill.work/skills/commit-helper.git"
204
+ }
186
205
  }
187
206
  ```
188
207
 
@@ -191,11 +210,14 @@ GET https://getskill.work/api/skills/<技能ID>
191
210
  ```javascript
192
211
  const getskill = require('@workskills/getskill');
193
212
 
213
+ // 设置自定义 API 地址(可选)
214
+ getskill.setBaseUrl('https://your-custom-api.com');
215
+
194
216
  // 搜索技能
195
217
  const results = await getskill.searchSkills('commit');
196
218
 
197
219
  // 安装技能
198
- const result = await getskill.downloadSkill('commit-helper');
220
+ const result = await getskill.downloadSkill('skills/commit-helper');
199
221
  console.log(result.files); // 已复制的文件列表
200
222
 
201
223
  // 更新技能
@@ -207,6 +229,9 @@ const skills = getskill.listLocalSkills();
207
229
  // 获取目录
208
230
  const skillsDir = getskill.getSkillsDirectory();
209
231
  const cacheDir = getskill.getSkillsCacheDirectory();
232
+
233
+ // 获取当前 API 地址
234
+ const baseUrl = getskill.getBaseUrl();
210
235
  ```
211
236
 
212
237
  ## 技能仓库规范
package/index.js CHANGED
@@ -7,6 +7,29 @@ const path = require('path');
7
7
  const os = require('os');
8
8
  const { exec } = require('child_process');
9
9
 
10
+ /**
11
+ * 基础 URL 配置
12
+ * 可以通过环境变量 GETSKILL_BASE_URL 自定义
13
+ */
14
+ let BASE_URL = process.env.GETSKILL_BASE_URL || 'https://getskill.work';
15
+
16
+ /**
17
+ * 设置自定义 BASE_URL
18
+ * @param {string} url - 自定义的基础 URL
19
+ */
20
+ function setBaseUrl(url) {
21
+ BASE_URL = url.replace(/\/$/, ''); // 移除末尾的斜杠
22
+ console.log(`BASE_URL 已设置为: ${BASE_URL}`);
23
+ }
24
+
25
+ /**
26
+ * 获取当前 BASE_URL
27
+ * @returns {string} 当前的基础 URL
28
+ */
29
+ function getBaseUrl() {
30
+ return BASE_URL;
31
+ }
32
+
10
33
  /**
11
34
  * 检查 Git 是否已安装
12
35
  */
@@ -259,18 +282,46 @@ function executeCommand(command, cwd) {
259
282
  }
260
283
 
261
284
  /**
262
- * 搜索技能(从 getskill.work API)
285
+ * 搜索技能(从配置的 BASE_URL API)
263
286
  * @param {string} keyword - 搜索关键词
287
+ * @param {Object} options - 搜索选项
288
+ * @param {string} options.sort - 排序字段,默认 'updated'
289
+ * @param {string} options.order - 排序顺序,默认 'desc'
290
+ * @param {number} options.page - 页码,默认 1
291
+ * @param {number} options.limit - 每页数量,默认 20
264
292
  * @returns {Promise<Array>} 技能列表(包含 git 地址)
265
293
  */
266
- async function searchSkills(keyword) {
267
- const url = `https://getskill.work/api/skills/search?q=${encodeURIComponent(keyword)}`;
294
+ async function searchSkills(keyword, options = {}) {
295
+ const {
296
+ sort = 'updated',
297
+ order = 'desc',
298
+ page = 1,
299
+ limit = 20
300
+ } = options;
301
+
302
+ const url = `${BASE_URL}/repo/search?sort=${sort}&order=${order}&q=${encodeURIComponent(keyword)}&page=${page}&limit=${limit}`;
268
303
 
269
304
  try {
270
305
  const response = await request(url);
271
- const data = JSON.parse(response.body);
272
- // 返回格式: [{ name, description, git_url, author, ... }]
273
- return data.skills || [];
306
+ const result = JSON.parse(response.body);
307
+
308
+ // 解析返回格式: { ok: true, data: [{ repository: {...} }] }
309
+ if (!result.ok || !result.data) {
310
+ return [];
311
+ }
312
+
313
+ // 提取需要的字段
314
+ return result.data.map(item => {
315
+ const repo = item.repository || {};
316
+ return {
317
+ name: repo.full_name || '',
318
+ full_name: repo.full_name || '',
319
+ description: repo.description || '',
320
+ html_url: repo.html_url || '',
321
+ git_url: repo.html_url ? `${repo.html_url}.git` : '',
322
+ clone_url: repo.clone_url || ''
323
+ };
324
+ });
274
325
  } catch (error) {
275
326
  console.error('搜索技能失败:', error.message);
276
327
  throw error;
@@ -279,17 +330,38 @@ async function searchSkills(keyword) {
279
330
 
280
331
  /**
281
332
  * 获取技能详情(包含 git 地址)
282
- * @param {string} skillId - 技能ID
333
+ * @param {string} skillId - 技能ID或名称
283
334
  * @returns {Promise<Object>} 技能详情
284
335
  */
285
336
  async function getSkillDetail(skillId) {
286
- const url = `https://getskill.work/api/skills/${skillId}`;
337
+ const url = `${BASE_URL}/repo/${encodeURIComponent(skillId)}`;
287
338
 
288
339
  try {
289
340
  const response = await request(url);
290
- const data = JSON.parse(response.body);
291
- // 返回格式: { name, description, git_url, files, ... }
292
- return data;
341
+ const result = JSON.parse(response.body);
342
+
343
+ // 如果返回的数据格式类似搜索接口,需要解析 repository
344
+ if (result.repository) {
345
+ const repo = result.repository;
346
+ return {
347
+ name: repo.full_name || repo.name || skillId,
348
+ full_name: repo.full_name || '',
349
+ description: repo.description || '',
350
+ html_url: repo.html_url || '',
351
+ git_url: repo.html_url ? `${repo.html_url}.git` : '',
352
+ clone_url: repo.clone_url || ''
353
+ };
354
+ }
355
+
356
+ // 如果是直接返回数据(向后兼容)
357
+ return {
358
+ name: result.full_name || result.name || skillId,
359
+ full_name: result.full_name || '',
360
+ description: result.description || '',
361
+ html_url: result.html_url || '',
362
+ git_url: result.html_url ? `${result.html_url}.git` : (result.git_url || ''),
363
+ clone_url: result.clone_url || ''
364
+ };
293
365
  } catch (error) {
294
366
  console.error('获取技能详情失败:', error.message);
295
367
  throw error;
@@ -386,12 +458,14 @@ async function downloadSkill(skillIdOrName) {
386
458
  console.log(`获取技能信息: ${skillIdOrName}...`);
387
459
  const skillDetail = await getSkillDetail(skillIdOrName);
388
460
 
389
- if (!skillDetail.git_url) {
390
- throw new Error('技能信息中未包含 git_url');
461
+ // 支持 clone_url 或 git_url
462
+ const gitUrl = skillDetail.clone_url || skillDetail.git_url;
463
+ if (!gitUrl) {
464
+ throw new Error('技能信息中未包含 git_url 或 clone_url');
391
465
  }
392
466
 
393
467
  const skillName = skillDetail.name || skillIdOrName;
394
- const repoPath = await cloneOrUpdateRepo(skillDetail.git_url, skillName);
468
+ const repoPath = await cloneOrUpdateRepo(gitUrl, skillName);
395
469
  const copiedFiles = copySkillFiles(repoPath);
396
470
 
397
471
  return {
@@ -475,16 +549,13 @@ async function cli() {
475
549
  const results = await searchSkills(args[1]);
476
550
  console.log(`找到 ${results.length} 个技能:\n`);
477
551
  results.forEach((skill, index) => {
478
- console.log(`${index + 1}. ${skill.name}`);
552
+ console.log(`${index + 1}. ${skill.full_name}`);
479
553
  if (skill.description) {
480
554
  console.log(` 描述: ${skill.description}`);
481
555
  }
482
556
  if (skill.git_url) {
483
557
  console.log(` Git: ${skill.git_url}`);
484
558
  }
485
- if (skill.author) {
486
- console.log(` 作者: ${skill.author}`);
487
- }
488
559
  console.log('');
489
560
  });
490
561
  break;
@@ -527,6 +598,18 @@ async function cli() {
527
598
  console.log(`缓存目录: ${getSkillsCacheDirectory()}`);
528
599
  break;
529
600
 
601
+ case 'config':
602
+ if (args[1] === 'set' && args[2]) {
603
+ setBaseUrl(args[2]);
604
+ } else if (args[1] === 'get') {
605
+ console.log(`当前 BASE_URL: ${getBaseUrl()}`);
606
+ } else {
607
+ console.log('用法:');
608
+ console.log(' getskill config set <URL> - 设置自定义 API 地址');
609
+ console.log(' getskill config get - 查看当前 API 地址');
610
+ }
611
+ break;
612
+
530
613
  case 'clean':
531
614
  const cacheDir = getSkillsCacheDirectory();
532
615
  if (fs.existsSync(cacheDir)) {
@@ -541,13 +624,16 @@ async function cli() {
541
624
  console.log('GetSkill - OpenClaw 技能管理工具');
542
625
  console.log('');
543
626
  console.log('用法:');
544
- console.log(' getskill search <关键词> - 从 getskill.work 搜索技能');
627
+ console.log(' getskill search <关键词> - 从 API 搜索技能');
545
628
  console.log(' getskill install <技能名称> - 通过 git clone 安装技能');
546
629
  console.log(' getskill update <技能名称> - 通过 git pull 更新技能');
547
630
  console.log(' getskill list - 列出本地技能');
548
631
  console.log(' getskill path - 显示目录路径');
632
+ console.log(' getskill config set <URL> - 设置自定义 API 地址');
633
+ console.log(' getskill config get - 查看当前 API 地址');
549
634
  console.log(' getskill clean - 清理 git 缓存');
550
635
  console.log('');
636
+ console.log(`当前 API: ${getBaseUrl()}`);
551
637
  console.log(`技能目录: ${getSkillsDirectory()}`);
552
638
  console.log(`缓存目录: ${getSkillsCacheDirectory()}`);
553
639
  }
@@ -569,7 +655,9 @@ module.exports = {
569
655
  cloneOrUpdateRepo,
570
656
  copySkillFiles,
571
657
  checkGitInstalled,
572
- ensureGitInstalled
658
+ ensureGitInstalled,
659
+ setBaseUrl,
660
+ getBaseUrl
573
661
  };
574
662
 
575
663
  // 如果直接运行此文件,执行 CLI
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@workskills/getskill",
3
- "version": "1.0.0",
4
- "description": "Search, install, and update OpenClaw skills from getskill.work with automatic Git integration",
3
+ "version": "1.1.1",
4
+ "description": "Search, install, and update OpenClaw skills with automatic Git integration and configurable API endpoint",
5
5
  "main": "index.js",
6
6
  "bin": {
7
7
  "getskill": "./index.js"