feat: 初始化 getskills 技能
添加 SKILL.md 文件,将 getskills 工具转换为标准技能格式 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
69
.gitignore
vendored
Normal file
69
.gitignore
vendored
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
# Node modules
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Directory for instrumented libs
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory
|
||||||
|
coverage
|
||||||
|
*.lcov
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Build output
|
||||||
|
dist/
|
||||||
|
build/
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
jspm_packages/
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# dotenv environment variables file
|
||||||
|
.env
|
||||||
|
.env.test
|
||||||
|
.env.local
|
||||||
|
|
||||||
|
# IDEs and editors
|
||||||
|
.idea/
|
||||||
|
.vscode/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# OS
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Test files
|
||||||
|
test/
|
||||||
|
*.test.js
|
||||||
|
*.spec.js
|
||||||
0
.history/npmuser_20260321181042
Normal file
0
.history/npmuser_20260321181042
Normal file
2
.history/npmuser_20260321181118
Normal file
2
.history/npmuser_20260321181118
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
username:workskills
|
||||||
|
password:zlei@800999
|
||||||
2
.history/npmuser_20260321181149
Normal file
2
.history/npmuser_20260321181149
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
username:workskills
|
||||||
|
password:zlei@800999
|
||||||
2
.history/npmuser_20260321181247.txt
Normal file
2
.history/npmuser_20260321181247.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
username:workskills
|
||||||
|
password:zlei@800999
|
||||||
2
.history/npmuser_20260321181318
Normal file
2
.history/npmuser_20260321181318
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
username:workskills
|
||||||
|
password:zlei@800999
|
||||||
4
.history/npmuser_20260321192251.txt
Normal file
4
.history/npmuser_20260321192251.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
username:workskills
|
||||||
|
password:zlei@800999
|
||||||
|
|
||||||
|
token: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
|
||||||
4
.history/npmuser_20260321193132.txt
Normal file
4
.history/npmuser_20260321193132.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
username:workskills
|
||||||
|
password:zlei@800999
|
||||||
|
|
||||||
|
token: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
|
||||||
0
.history/package_20260321181302.json
Normal file
0
.history/package_20260321181302.json
Normal file
14
.history/package_20260321181345.json
Normal file
14
.history/package_20260321181345.json
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"name": "my-package", // 包名必须唯一,不含大写字母和空格
|
||||||
|
"version": "1.0.0", // 首次发布建议1.0.0
|
||||||
|
"main": "index.js", // 入口文件
|
||||||
|
"description": "包描述",
|
||||||
|
"author": "你的名字",
|
||||||
|
"license": "MIT",
|
||||||
|
"keywords": [
|
||||||
|
"关键词"
|
||||||
|
],
|
||||||
|
"files": [
|
||||||
|
"index.js"
|
||||||
|
] // 明确要发布的文件
|
||||||
|
}
|
||||||
14
.history/package_20260321181417.json
Normal file
14
.history/package_20260321181417.json
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"name": "@workskills/getskill",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "index.js", // 入口文件
|
||||||
|
"description": "包描述",
|
||||||
|
"author": "你的名字",
|
||||||
|
"license": "MIT",
|
||||||
|
"keywords": [
|
||||||
|
"关键词"
|
||||||
|
],
|
||||||
|
"files": [
|
||||||
|
"index.js"
|
||||||
|
] // 明确要发布的文件
|
||||||
|
}
|
||||||
14
.history/package_20260321181447.json
Normal file
14
.history/package_20260321181447.json
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"name": "@workskills/getskill",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "index.js",
|
||||||
|
"description": "search skills",
|
||||||
|
"author": "你的名字",
|
||||||
|
"license": "MIT",
|
||||||
|
"keywords": [
|
||||||
|
"关键词"
|
||||||
|
],
|
||||||
|
"files": [
|
||||||
|
"index.js"
|
||||||
|
] // 明确要发布的文件
|
||||||
|
}
|
||||||
14
.history/package_20260321181522.json
Normal file
14
.history/package_20260321181522.json
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"name": "@workskills/getskill",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "index.js",
|
||||||
|
"description": "search skills, get skills, update skills",
|
||||||
|
"author": "你的名字",
|
||||||
|
"license": "MIT",
|
||||||
|
"keywords": [
|
||||||
|
"关键词"
|
||||||
|
],
|
||||||
|
"files": [
|
||||||
|
"index.js"
|
||||||
|
] // 明确要发布的文件
|
||||||
|
}
|
||||||
14
.history/package_20260321181553.json
Normal file
14
.history/package_20260321181553.json
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"name": "@workskills/getskill",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "index.js",
|
||||||
|
"description": "search skills, get skills, update skills",
|
||||||
|
"author": "workskills.store",
|
||||||
|
"license": "MIT",
|
||||||
|
"keywords": [
|
||||||
|
"openclaw,"
|
||||||
|
],
|
||||||
|
"files": [
|
||||||
|
"index.js"
|
||||||
|
] // 明确要发布的文件
|
||||||
|
}
|
||||||
14
.history/package_20260321181624.json
Normal file
14
.history/package_20260321181624.json
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"name": "@workskills/getskill",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "index.js",
|
||||||
|
"description": "search skills, get skills, update skills",
|
||||||
|
"author": "workskills.store",
|
||||||
|
"license": "MIT",
|
||||||
|
"keywords": [
|
||||||
|
"openclaw", "workskills", "skill", "search", "get", "update"
|
||||||
|
],
|
||||||
|
"files": [
|
||||||
|
"index.js"
|
||||||
|
]
|
||||||
|
}
|
||||||
38
.npmignore
Normal file
38
.npmignore
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
# Development files
|
||||||
|
.git/
|
||||||
|
.gitignore
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
# Test files
|
||||||
|
test/
|
||||||
|
*.test.js
|
||||||
|
*.spec.js
|
||||||
|
coverage/
|
||||||
|
|
||||||
|
# Documentation drafts
|
||||||
|
docs/drafts/
|
||||||
|
|
||||||
|
# CI/CD
|
||||||
|
.github/
|
||||||
|
.gitlab-ci.yml
|
||||||
|
.travis.yml
|
||||||
|
|
||||||
|
# Environment files
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
|
||||||
|
# Temporary files
|
||||||
|
*.log
|
||||||
|
*.tmp
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Node
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Keep these files in the package
|
||||||
|
!README.md
|
||||||
|
!EXAMPLES.md
|
||||||
|
!LICENSE
|
||||||
|
!index.js
|
||||||
59
CHANGELOG.md
Normal file
59
CHANGELOG.md
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [1.0.0] - 2026-03-21
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Initial release of GetSkill CLI tool
|
||||||
|
- Search skills from getskill.work API
|
||||||
|
- Install skills via Git clone
|
||||||
|
- Update skills via Git pull
|
||||||
|
- Automatic Git detection and installation guide
|
||||||
|
- Windows: Auto-download Git installer
|
||||||
|
- macOS: Homebrew installation guide
|
||||||
|
- Linux: Package manager installation guide
|
||||||
|
- Cross-platform support (Windows, macOS, Linux)
|
||||||
|
- Automatic skill file management to OpenClaw skills directory
|
||||||
|
- Skills cache directory for Git repositories
|
||||||
|
- Command-line interface with the following commands:
|
||||||
|
- `search` - Search for skills
|
||||||
|
- `install` - Install a skill
|
||||||
|
- `update` - Update an existing skill
|
||||||
|
- `list` - List locally installed skills
|
||||||
|
- `path` - Show directory paths
|
||||||
|
- `clean` - Clean Git cache
|
||||||
|
- Programming API for Node.js integration
|
||||||
|
- Comprehensive documentation (README, EXAMPLES)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
- Zero external dependencies (uses only Node.js built-in modules)
|
||||||
|
- Progress indicator for Git installer download
|
||||||
|
- Smart skill file detection (excludes README files)
|
||||||
|
- Automatic directory creation
|
||||||
|
- Error handling and user-friendly messages
|
||||||
|
|
||||||
|
### Documentation
|
||||||
|
- README.md with full usage guide
|
||||||
|
- EXAMPLES.md with real-world usage scenarios
|
||||||
|
- API interface specification
|
||||||
|
- Installation guides for all platforms
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Planned
|
||||||
|
- Unit tests
|
||||||
|
- Skills version management
|
||||||
|
- Skill dependency resolution
|
||||||
|
- Configuration file support
|
||||||
|
- Offline mode
|
||||||
|
- Skill backup and restore
|
||||||
|
- Interactive skill selection
|
||||||
|
- Shell completion scripts
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
[1.0.0]: https://github.com/workskills/getskill/releases/tag/v1.0.0
|
||||||
138
CONTRIBUTING.md
Normal file
138
CONTRIBUTING.md
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
# Contributing to GetSkill
|
||||||
|
|
||||||
|
感谢您考虑为 GetSkill 做出贡献!
|
||||||
|
|
||||||
|
## 开发环境设置
|
||||||
|
|
||||||
|
1. Fork 本仓库
|
||||||
|
2. 克隆您的 fork:
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/YOUR_USERNAME/getskill.git
|
||||||
|
cd getskill
|
||||||
|
```
|
||||||
|
|
||||||
|
3. 安装依赖(本项目无外部依赖):
|
||||||
|
```bash
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
4. 运行验证测试:
|
||||||
|
```bash
|
||||||
|
npm test
|
||||||
|
```
|
||||||
|
|
||||||
|
## 开发流程
|
||||||
|
|
||||||
|
1. 创建功能分支:
|
||||||
|
```bash
|
||||||
|
git checkout -b feature/your-feature-name
|
||||||
|
```
|
||||||
|
|
||||||
|
2. 进行更改并测试:
|
||||||
|
```bash
|
||||||
|
node verify.js
|
||||||
|
node index.js [command]
|
||||||
|
```
|
||||||
|
|
||||||
|
3. 提交更改:
|
||||||
|
```bash
|
||||||
|
git add .
|
||||||
|
git commit -m "描述您的更改"
|
||||||
|
```
|
||||||
|
|
||||||
|
4. 推送到您的 fork:
|
||||||
|
```bash
|
||||||
|
git push origin feature/your-feature-name
|
||||||
|
```
|
||||||
|
|
||||||
|
5. 创建 Pull Request
|
||||||
|
|
||||||
|
## 代码规范
|
||||||
|
|
||||||
|
- 使用 Node.js 内置模块(避免外部依赖)
|
||||||
|
- 遵循现有的代码风格
|
||||||
|
- 添加适当的注释和文档
|
||||||
|
- 保持跨平台兼容性(Windows/macOS/Linux)
|
||||||
|
- 函数应包含 JSDoc 注释
|
||||||
|
|
||||||
|
## 提交信息规范
|
||||||
|
|
||||||
|
遵循 [Conventional Commits](https://www.conventionalcommits.org/) 规范:
|
||||||
|
|
||||||
|
- `feat:` 新功能
|
||||||
|
- `fix:` 错误修复
|
||||||
|
- `docs:` 文档更新
|
||||||
|
- `style:` 代码格式化
|
||||||
|
- `refactor:` 代码重构
|
||||||
|
- `test:` 测试相关
|
||||||
|
- `chore:` 构建/工具相关
|
||||||
|
|
||||||
|
示例:
|
||||||
|
```
|
||||||
|
feat: add support for private Git repositories
|
||||||
|
fix: handle network timeout errors
|
||||||
|
docs: update installation guide
|
||||||
|
```
|
||||||
|
|
||||||
|
## 测试
|
||||||
|
|
||||||
|
在提交 PR 前,请确保:
|
||||||
|
|
||||||
|
1. 运行验证脚本:
|
||||||
|
```bash
|
||||||
|
npm test
|
||||||
|
```
|
||||||
|
|
||||||
|
2. 在不同平台测试(如果可能):
|
||||||
|
- Windows
|
||||||
|
- macOS
|
||||||
|
- Linux
|
||||||
|
|
||||||
|
3. 测试所有命令:
|
||||||
|
- `search`
|
||||||
|
- `install`
|
||||||
|
- `update`
|
||||||
|
- `list`
|
||||||
|
- `path`
|
||||||
|
- `clean`
|
||||||
|
|
||||||
|
## 报告问题
|
||||||
|
|
||||||
|
如果您发现 bug 或有功能建议:
|
||||||
|
|
||||||
|
1. 检查 [Issues](https://github.com/workskills/getskill/issues) 中是否已存在
|
||||||
|
2. 创建新 Issue,包含:
|
||||||
|
- 清晰的标题和描述
|
||||||
|
- 复现步骤(针对 bug)
|
||||||
|
- 预期行为和实际行为
|
||||||
|
- 系统信息(OS、Node.js 版本)
|
||||||
|
- 相关日志或截图
|
||||||
|
|
||||||
|
## 功能建议
|
||||||
|
|
||||||
|
我们欢迎新功能建议!在开始开发前:
|
||||||
|
|
||||||
|
1. 创建 Issue 讨论您的想法
|
||||||
|
2. 等待维护者的反馈
|
||||||
|
3. 获得批准后再开始开发
|
||||||
|
|
||||||
|
## 文档
|
||||||
|
|
||||||
|
文档改进非常重要:
|
||||||
|
|
||||||
|
- README.md - 主要文档
|
||||||
|
- EXAMPLES.md - 使用示例
|
||||||
|
- CHANGELOG.md - 变更日志
|
||||||
|
- 代码内的 JSDoc 注释
|
||||||
|
|
||||||
|
## 许可证
|
||||||
|
|
||||||
|
通过贡献,您同意您的贡献将在 MIT 许可证下发布。
|
||||||
|
|
||||||
|
## 问题?
|
||||||
|
|
||||||
|
如有任何问题,请:
|
||||||
|
- 创建 Issue
|
||||||
|
- 发送邮件至 support@workskills.store
|
||||||
|
|
||||||
|
感谢您的贡献!🎉
|
||||||
292
EXAMPLES.md
Normal file
292
EXAMPLES.md
Normal file
@@ -0,0 +1,292 @@
|
|||||||
|
# GetSkill 使用示例
|
||||||
|
|
||||||
|
## 场景 1: 首次使用(未安装 Git)
|
||||||
|
|
||||||
|
### Windows 用户
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 第一次运行安装命令
|
||||||
|
$ getskill install commit-helper
|
||||||
|
|
||||||
|
检测到系统未安装 Git,正在准备安装...
|
||||||
|
|
||||||
|
Windows 系统检测到未安装 Git
|
||||||
|
正在下载 Git 安装程序...
|
||||||
|
|
||||||
|
下载进度: 100%
|
||||||
|
下载完成!
|
||||||
|
|
||||||
|
Git 安装程序已下载到: C:\Users\...\AppData\Local\Temp\git-installer.exe
|
||||||
|
|
||||||
|
正在启动安装程序,请按照提示完成安装...
|
||||||
|
安装完成后,请重新运行此命令。
|
||||||
|
|
||||||
|
# Git 安装完成后,再次运行
|
||||||
|
$ getskill install commit-helper
|
||||||
|
|
||||||
|
获取技能信息: commit-helper...
|
||||||
|
克隆仓库: https://github.com/workskills/commit-helper.git...
|
||||||
|
仓库克隆成功: C:\Users\...\\.claude\skills-cache\commit-helper
|
||||||
|
|
||||||
|
技能已安装到 skills 目录:
|
||||||
|
- C:\Users\...\.claude\skills\commit-helper.md
|
||||||
|
|
||||||
|
Git 仓库缓存: C:\Users\...\.claude\skills-cache\commit-helper
|
||||||
|
```
|
||||||
|
|
||||||
|
### macOS 用户
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ getskill install commit-helper
|
||||||
|
|
||||||
|
检测到系统未安装 Git,正在准备安装...
|
||||||
|
|
||||||
|
macOS 系统检测到未安装 Git
|
||||||
|
请使用以下命令安装 Git:
|
||||||
|
|
||||||
|
brew install git
|
||||||
|
|
||||||
|
如果未安装 Homebrew,请访问: https://brew.sh/
|
||||||
|
|
||||||
|
# 安装 Git
|
||||||
|
$ brew install git
|
||||||
|
|
||||||
|
# 再次运行
|
||||||
|
$ getskill install commit-helper
|
||||||
|
✓ 安装成功
|
||||||
|
```
|
||||||
|
|
||||||
|
### Linux 用户
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ getskill install commit-helper
|
||||||
|
|
||||||
|
检测到系统未安装 Git,正在准备安装...
|
||||||
|
|
||||||
|
Linux 系统检测到未安装 Git
|
||||||
|
请使用系统包管理器安装 Git:
|
||||||
|
|
||||||
|
Ubuntu/Debian: sudo apt-get install git
|
||||||
|
CentOS/RHEL: sudo yum install git
|
||||||
|
Fedora: sudo dnf install git
|
||||||
|
Arch: sudo pacman -S git
|
||||||
|
|
||||||
|
# Ubuntu/Debian 用户
|
||||||
|
$ sudo apt-get install git
|
||||||
|
|
||||||
|
# 再次运行
|
||||||
|
$ getskill install commit-helper
|
||||||
|
✓ 安装成功
|
||||||
|
```
|
||||||
|
|
||||||
|
## 场景 2: 已安装 Git(正常使用)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 搜索技能
|
||||||
|
$ getskill search commit
|
||||||
|
|
||||||
|
找到 3 个技能:
|
||||||
|
|
||||||
|
1. commit-helper
|
||||||
|
描述: 帮助生成规范的 git commit 信息
|
||||||
|
Git: https://github.com/workskills/commit-helper.git
|
||||||
|
作者: workskills
|
||||||
|
|
||||||
|
2. commit-lint
|
||||||
|
描述: 检查 commit 信息是否符合规范
|
||||||
|
Git: https://github.com/workskills/commit-lint.git
|
||||||
|
作者: workskills
|
||||||
|
|
||||||
|
# 安装技能
|
||||||
|
$ getskill install commit-helper
|
||||||
|
|
||||||
|
获取技能信息: commit-helper...
|
||||||
|
克隆仓库: https://github.com/workskills/commit-helper.git...
|
||||||
|
仓库克隆成功: ~/.claude/skills-cache/commit-helper
|
||||||
|
已复制: commit-helper.md -> ~/.claude/skills/commit-helper.md
|
||||||
|
|
||||||
|
技能已安装到 skills 目录:
|
||||||
|
- ~/.claude/skills/commit-helper.md
|
||||||
|
|
||||||
|
Git 仓库缓存: ~/.claude/skills-cache/commit-helper
|
||||||
|
|
||||||
|
# 列出已安装的技能
|
||||||
|
$ getskill list
|
||||||
|
|
||||||
|
本地已安装的技能 (1):
|
||||||
|
1. commit-helper.md
|
||||||
|
|
||||||
|
# 更新技能
|
||||||
|
$ getskill update commit-helper
|
||||||
|
|
||||||
|
正在更新技能: commit-helper...
|
||||||
|
更新仓库: commit-helper...
|
||||||
|
Already up to date.
|
||||||
|
仓库更新成功: ~/.claude/skills-cache/commit-helper
|
||||||
|
已复制: commit-helper.md -> ~/.claude/skills/commit-helper.md
|
||||||
|
|
||||||
|
技能已更新到 skills 目录:
|
||||||
|
- ~/.claude/skills/commit-helper.md
|
||||||
|
|
||||||
|
# 查看目录路径
|
||||||
|
$ getskill path
|
||||||
|
|
||||||
|
技能目录: ~/.claude/skills
|
||||||
|
缓存目录: ~/.claude/skills-cache
|
||||||
|
|
||||||
|
# 清理缓存
|
||||||
|
$ getskill clean
|
||||||
|
|
||||||
|
已清理缓存目录: ~/.claude/skills-cache
|
||||||
|
```
|
||||||
|
|
||||||
|
## 场景 3: 编程接口使用
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const getskill = require('@workskills/getskill');
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
// 设置自定义 API 地址(可选)
|
||||||
|
getskill.setBaseUrl('https://getskills.certer');
|
||||||
|
|
||||||
|
// 查看当前 API 地址
|
||||||
|
console.log('当前 API:', getskill.getBaseUrl());
|
||||||
|
|
||||||
|
// 检查 Git 是否已安装
|
||||||
|
const isGitInstalled = await getskill.checkGitInstalled();
|
||||||
|
console.log('Git 已安装:', isGitInstalled);
|
||||||
|
|
||||||
|
if (!isGitInstalled) {
|
||||||
|
console.log('正在引导安装 Git...');
|
||||||
|
await getskill.ensureGitInstalled();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 搜索技能
|
||||||
|
const results = await getskill.searchSkills('commit');
|
||||||
|
console.log('搜索结果:', results);
|
||||||
|
|
||||||
|
// 安装技能
|
||||||
|
const result = await getskill.downloadSkill('skills/commit-helper');
|
||||||
|
console.log('安装成功:', result.files);
|
||||||
|
|
||||||
|
// 更新技能
|
||||||
|
await getskill.updateSkill('commit-helper');
|
||||||
|
console.log('更新成功');
|
||||||
|
|
||||||
|
// 列出本地技能
|
||||||
|
const localSkills = getskill.listLocalSkills();
|
||||||
|
console.log('本地技能:', localSkills);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('错误:', error.message);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
```
|
||||||
|
|
||||||
|
## 场景 4: 批量安装技能
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 创建脚本 install-skills.sh
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
skills=(
|
||||||
|
"commit-helper"
|
||||||
|
"code-review"
|
||||||
|
"test-generator"
|
||||||
|
"doc-writer"
|
||||||
|
)
|
||||||
|
|
||||||
|
for skill in "${skills[@]}"; do
|
||||||
|
echo "正在安装: $skill"
|
||||||
|
getskill install "$skill"
|
||||||
|
echo "---"
|
||||||
|
done
|
||||||
|
|
||||||
|
# 运行脚本
|
||||||
|
$ chmod +x install-skills.sh
|
||||||
|
$ ./install-skills.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## 场景 5: 错误处理
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 技能不存在
|
||||||
|
$ getskill install non-existent-skill
|
||||||
|
获取技能信息: non-existent-skill...
|
||||||
|
搜索技能失败: Request failed with status code 404
|
||||||
|
执行命令时出错: Request failed with status code 404
|
||||||
|
|
||||||
|
# Git URL 无效
|
||||||
|
$ getskill install invalid-git-skill
|
||||||
|
获取技能信息: invalid-git-skill...
|
||||||
|
克隆仓库: https://invalid-url.git...
|
||||||
|
克隆失败: fatal: repository 'https://invalid-url.git/' not found
|
||||||
|
执行命令时出错: Command failed: git clone...
|
||||||
|
|
||||||
|
# 网络问题
|
||||||
|
$ getskill search commit
|
||||||
|
搜索技能失败: connect ETIMEDOUT
|
||||||
|
执行命令时出错: connect ETIMEDOUT
|
||||||
|
```
|
||||||
|
|
||||||
|
## 场景 6: 配置自定义 API 地址
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 查看当前 API 地址
|
||||||
|
$ getskill config get
|
||||||
|
当前 BASE_URL: https://getskills.certer
|
||||||
|
|
||||||
|
# 设置自定义 API 地址
|
||||||
|
$ getskill config set https://custom-api.example.com
|
||||||
|
BASE_URL 已设置为: https://custom-api.example.com
|
||||||
|
|
||||||
|
# 通过环境变量设置
|
||||||
|
$ GETSKILL_BASE_URL=https://another-api.com getskill search commit
|
||||||
|
找到 2 个技能:
|
||||||
|
...
|
||||||
|
|
||||||
|
# 验证配置
|
||||||
|
$ getskill config get
|
||||||
|
当前 BASE_URL: https://custom-api.example.com
|
||||||
|
```
|
||||||
|
|
||||||
|
## 场景 7: 目录结构查看
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 安装几个技能后查看目录结构
|
||||||
|
$ tree ~/.claude
|
||||||
|
|
||||||
|
~/.claude/
|
||||||
|
├── skills/
|
||||||
|
│ ├── commit-helper.md
|
||||||
|
│ ├── code-review.md
|
||||||
|
│ └── test-generator.md
|
||||||
|
└── skills-cache/
|
||||||
|
├── commit-helper/
|
||||||
|
│ ├── commit-helper.md
|
||||||
|
│ ├── README.md
|
||||||
|
│ └── .git/
|
||||||
|
├── code-review/
|
||||||
|
│ ├── code-review.md
|
||||||
|
│ ├── README.md
|
||||||
|
│ └── .git/
|
||||||
|
└── test-generator/
|
||||||
|
├── test-generator.md
|
||||||
|
├── README.md
|
||||||
|
└── .git/
|
||||||
|
```
|
||||||
|
|
||||||
|
## 常见问题
|
||||||
|
|
||||||
|
### Q: Git 安装后仍提示未安装?
|
||||||
|
A: Windows 用户需要重启终端或系统,以便环境变量生效。
|
||||||
|
|
||||||
|
### Q: 如何卸载技能?
|
||||||
|
A: 直接删除 `~/.claude/skills/` 目录下的对应 `.md` 文件即可。
|
||||||
|
|
||||||
|
### Q: 缓存目录可以删除吗?
|
||||||
|
A: 可以使用 `getskill clean` 清理缓存,下次更新技能时会重新克隆。
|
||||||
|
|
||||||
|
### Q: 如何手动指定 Git 路径?
|
||||||
|
A: 确保 `git` 命令在系统 PATH 中,或修改 `~/.bashrc` / `~/.zshrc` 添加 Git 路径。
|
||||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2026 workskills.store
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
253
PROJECT_SUMMARY.md
Normal file
253
PROJECT_SUMMARY.md
Normal file
@@ -0,0 +1,253 @@
|
|||||||
|
# GetSkill 项目总结
|
||||||
|
|
||||||
|
## 项目概述
|
||||||
|
|
||||||
|
**GetSkill** 是一个用于管理 OpenClaw 技能的命令行工具,支持从 getskill.work 搜索、安装和更新技能文件。
|
||||||
|
|
||||||
|
## 核心特性
|
||||||
|
|
||||||
|
### 1. 零外部依赖
|
||||||
|
- 仅使用 Node.js 内置模块
|
||||||
|
- 轻量级,安装快速
|
||||||
|
- 无需担心依赖冲突
|
||||||
|
|
||||||
|
### 2. Git 集成
|
||||||
|
- 自动检测 Git 安装状态
|
||||||
|
- Windows 平台自动下载 Git 安装程序
|
||||||
|
- macOS/Linux 提供安装指南
|
||||||
|
- 通过 Git 管理技能版本
|
||||||
|
|
||||||
|
### 3. 跨平台支持
|
||||||
|
- Windows (32/64位)
|
||||||
|
- macOS
|
||||||
|
- Linux (多发行版)
|
||||||
|
- 自动适配操作系统路径
|
||||||
|
|
||||||
|
### 4. 双目录架构
|
||||||
|
```
|
||||||
|
~/.claude/
|
||||||
|
├── skills/ # 技能文件(.md)
|
||||||
|
└── skills-cache/ # Git 仓库缓存
|
||||||
|
```
|
||||||
|
|
||||||
|
## 技术架构
|
||||||
|
|
||||||
|
### 依赖模块(全部为 Node.js 内置)
|
||||||
|
|
||||||
|
| 模块 | 用途 |
|
||||||
|
|------|------|
|
||||||
|
| `https/http` | API 请求和文件下载 |
|
||||||
|
| `fs` | 文件系统操作 |
|
||||||
|
| `path` | 路径处理 |
|
||||||
|
| `os` | 系统信息获取 |
|
||||||
|
| `child_process` | 执行 Git 命令 |
|
||||||
|
|
||||||
|
### 核心函数
|
||||||
|
|
||||||
|
| 函数 | 功能 |
|
||||||
|
|------|------|
|
||||||
|
| `searchSkills()` | 从 API 搜索技能 |
|
||||||
|
| `downloadSkill()` | 安装技能(Git clone) |
|
||||||
|
| `updateSkill()` | 更新技能(Git pull) |
|
||||||
|
| `checkGitInstalled()` | 检测 Git |
|
||||||
|
| `ensureGitInstalled()` | 确保 Git 可用 |
|
||||||
|
| `cloneOrUpdateRepo()` | Git 仓库管理 |
|
||||||
|
| `copySkillFiles()` | 复制技能文件 |
|
||||||
|
|
||||||
|
## API 接口设计
|
||||||
|
|
||||||
|
### 搜索接口
|
||||||
|
```
|
||||||
|
GET https://getskill.work/api/skills/search?q=<关键词>
|
||||||
|
|
||||||
|
Response:
|
||||||
|
{
|
||||||
|
"skills": [
|
||||||
|
{
|
||||||
|
"id": "skill-id",
|
||||||
|
"name": "skill-name",
|
||||||
|
"description": "描述",
|
||||||
|
"git_url": "https://github.com/...",
|
||||||
|
"author": "作者"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 详情接口
|
||||||
|
```
|
||||||
|
GET https://getskill.work/api/skills/<技能ID>
|
||||||
|
|
||||||
|
Response:
|
||||||
|
{
|
||||||
|
"id": "skill-id",
|
||||||
|
"name": "skill-name",
|
||||||
|
"git_url": "https://github.com/...",
|
||||||
|
"description": "描述",
|
||||||
|
"files": ["skill.md"],
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 命令行界面
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 搜索
|
||||||
|
getskill search <关键词>
|
||||||
|
|
||||||
|
# 安装
|
||||||
|
getskill install <技能名称>
|
||||||
|
|
||||||
|
# 更新
|
||||||
|
getskill update <技能名称>
|
||||||
|
|
||||||
|
# 列出
|
||||||
|
getskill list
|
||||||
|
|
||||||
|
# 路径
|
||||||
|
getskill path
|
||||||
|
|
||||||
|
# 清理
|
||||||
|
getskill clean
|
||||||
|
```
|
||||||
|
|
||||||
|
## 文件结构
|
||||||
|
|
||||||
|
```
|
||||||
|
getskill/
|
||||||
|
├── index.js # 主程序(578 行)
|
||||||
|
├── package.json # 项目配置
|
||||||
|
├── README.md # 使用文档
|
||||||
|
├── EXAMPLES.md # 使用示例
|
||||||
|
├── CONTRIBUTING.md # 贡献指南
|
||||||
|
├── CHANGELOG.md # 变更日志
|
||||||
|
├── LICENSE # MIT 许可证
|
||||||
|
├── verify.js # 验证脚本
|
||||||
|
├── .gitignore # Git 忽略文件
|
||||||
|
└── .npmignore # NPM 忽略文件
|
||||||
|
```
|
||||||
|
|
||||||
|
## 开发统计
|
||||||
|
|
||||||
|
- **总代码行数**: ~580 行(index.js)
|
||||||
|
- **函数数量**: 15+ 个
|
||||||
|
- **支持的命令**: 6 个
|
||||||
|
- **支持的平台**: 3 个(Windows/macOS/Linux)
|
||||||
|
- **外部依赖**: 0 个
|
||||||
|
|
||||||
|
## 工作流程
|
||||||
|
|
||||||
|
### 安装流程
|
||||||
|
```
|
||||||
|
用户执行: getskill install commit-helper
|
||||||
|
↓
|
||||||
|
检查 Git 是否安装
|
||||||
|
↓
|
||||||
|
调用 API 获取技能详情(含 git_url)
|
||||||
|
↓
|
||||||
|
执行 git clone 到缓存目录
|
||||||
|
↓
|
||||||
|
复制 .md 文件到 skills 目录
|
||||||
|
↓
|
||||||
|
完成
|
||||||
|
```
|
||||||
|
|
||||||
|
### 更新流程
|
||||||
|
```
|
||||||
|
用户执行: getskill update commit-helper
|
||||||
|
↓
|
||||||
|
检查缓存目录是否存在仓库
|
||||||
|
↓
|
||||||
|
进入仓库目录
|
||||||
|
↓
|
||||||
|
执行 git pull
|
||||||
|
↓
|
||||||
|
重新复制 .md 文件
|
||||||
|
↓
|
||||||
|
完成
|
||||||
|
```
|
||||||
|
|
||||||
|
## 特殊处理
|
||||||
|
|
||||||
|
### Git 自动安装
|
||||||
|
|
||||||
|
#### Windows
|
||||||
|
1. 检测系统架构(32/64位)
|
||||||
|
2. 下载对应的 Git 安装程序
|
||||||
|
3. 显示下载进度
|
||||||
|
4. 启动安装向导
|
||||||
|
5. 提示用户完成安装后重新运行
|
||||||
|
|
||||||
|
#### macOS
|
||||||
|
- 提示使用 Homebrew: `brew install git`
|
||||||
|
- 提供 Homebrew 安装链接
|
||||||
|
|
||||||
|
#### Linux
|
||||||
|
- 根据发行版提供对应命令
|
||||||
|
- 支持 apt、yum、dnf、pacman
|
||||||
|
|
||||||
|
## 错误处理
|
||||||
|
|
||||||
|
- 网络错误:捕获并提示
|
||||||
|
- Git 未安装:自动引导安装
|
||||||
|
- API 失败:显示错误信息
|
||||||
|
- 文件不存在:创建目录
|
||||||
|
- 仓库克隆失败:显示 Git 错误
|
||||||
|
|
||||||
|
## 使用场景
|
||||||
|
|
||||||
|
1. **开发者**: 快速安装和更新技能
|
||||||
|
2. **团队**: 统一技能版本管理
|
||||||
|
3. **CI/CD**: 自动化技能部署
|
||||||
|
4. **学习者**: 探索可用技能
|
||||||
|
|
||||||
|
## 性能特点
|
||||||
|
|
||||||
|
- 轻量级:无外部依赖
|
||||||
|
- 快速:直接使用 Git
|
||||||
|
- 可靠:Git 版本控制
|
||||||
|
- 缓存:避免重复下载
|
||||||
|
|
||||||
|
## 安全考虑
|
||||||
|
|
||||||
|
- 仅使用 HTTPS 连接
|
||||||
|
- 不存储敏感信息
|
||||||
|
- Git URL 验证
|
||||||
|
- 沙箱化技能目录
|
||||||
|
|
||||||
|
## 未来计划
|
||||||
|
|
||||||
|
- [ ] 技能版本管理
|
||||||
|
- [ ] 依赖解析
|
||||||
|
- [ ] 离线模式
|
||||||
|
- [ ] 配置文件支持
|
||||||
|
- [ ] Shell 自动补全
|
||||||
|
- [ ] 技能备份/恢复
|
||||||
|
- [ ] 交互式安装
|
||||||
|
- [ ] 单元测试
|
||||||
|
|
||||||
|
## 发布清单
|
||||||
|
|
||||||
|
- [x] 核心功能实现
|
||||||
|
- [x] Git 自动检测
|
||||||
|
- [x] 跨平台支持
|
||||||
|
- [x] 文档完善
|
||||||
|
- [x] 验证脚本
|
||||||
|
- [x] 示例文档
|
||||||
|
- [ ] 单元测试
|
||||||
|
- [ ] CI/CD 集成
|
||||||
|
- [ ] NPM 发布
|
||||||
|
|
||||||
|
## 贡献者
|
||||||
|
|
||||||
|
- workskills.store - 初始开发
|
||||||
|
|
||||||
|
## 许可证
|
||||||
|
|
||||||
|
MIT License - 详见 LICENSE 文件
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**项目状态**: ✅ 功能完整,准备发布 v1.0.0
|
||||||
|
|
||||||
|
**最后更新**: 2026-03-21
|
||||||
282
README.md
Normal file
282
README.md
Normal file
@@ -0,0 +1,282 @@
|
|||||||
|
# GetSkill
|
||||||
|
|
||||||
|
OpenClaw 技能管理工具 - 从 getskills.certer 搜索、下载和更新技能文件
|
||||||
|
|
||||||
|
## 功能特性
|
||||||
|
|
||||||
|
- 🔍 从 getskills.certer API 搜索技能
|
||||||
|
- 📥 通过 Git 克隆技能仓库
|
||||||
|
- 🔄 通过 Git pull 更新已安装的技能
|
||||||
|
- 🛠️ 自动检测并引导安装 Git(如未安装)
|
||||||
|
- 📂 跨平台支持(Windows/macOS/Linux)
|
||||||
|
- 💾 自动管理技能文件到 OpenClaw skills 目录
|
||||||
|
- ⚙️ 支持自定义 API 地址
|
||||||
|
|
||||||
|
## 工作原理
|
||||||
|
|
||||||
|
1. **搜索**: 从 `getskills.certer` API 获取技能列表,包含 Git 仓库地址
|
||||||
|
2. **安装**: 使用 `git clone` 克隆技能仓库到缓存目录
|
||||||
|
3. **复制**: 将仓库中的 `.md` 技能文件复制到 OpenClaw skills 目录
|
||||||
|
4. **更新**: 使用 `git pull` 更新仓库,并重新复制文件
|
||||||
|
|
||||||
|
## 目录结构
|
||||||
|
|
||||||
|
```
|
||||||
|
~/.claude/
|
||||||
|
├── skills/ # OpenClaw 技能文件目录
|
||||||
|
│ ├── skill1.md
|
||||||
|
│ └── skill2.md
|
||||||
|
└── skills-cache/ # Git 仓库缓存
|
||||||
|
├── skill1/
|
||||||
|
└── skill2/
|
||||||
|
```
|
||||||
|
|
||||||
|
### 平台路径
|
||||||
|
|
||||||
|
- **Windows**: `%USERPROFILE%\.claude\skills`
|
||||||
|
- **macOS**: `~/.claude/skills`
|
||||||
|
- **Linux**: `~/.claude/skills`
|
||||||
|
|
||||||
|
## 安装
|
||||||
|
|
||||||
|
### 全局安装(推荐)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install -g @workskills/getskill
|
||||||
|
```
|
||||||
|
|
||||||
|
安装后,可以在任何位置使用 `getskill` 命令。
|
||||||
|
|
||||||
|
### 本地安装
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install @workskills/getskill
|
||||||
|
```
|
||||||
|
|
||||||
|
本地安装后,可以通过 npx 运行:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx getskill search <关键词>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 从源码安装
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/workskills/getskill.git
|
||||||
|
cd getskill
|
||||||
|
npm install
|
||||||
|
npm link
|
||||||
|
```
|
||||||
|
|
||||||
|
## 使用方法
|
||||||
|
|
||||||
|
### 搜索技能
|
||||||
|
|
||||||
|
```bash
|
||||||
|
getskill search <关键词>
|
||||||
|
```
|
||||||
|
|
||||||
|
示例输出:
|
||||||
|
```
|
||||||
|
找到 3 个技能:
|
||||||
|
|
||||||
|
1. commit-helper
|
||||||
|
描述: 帮助生成规范的 git commit 信息
|
||||||
|
Git: https://github.com/workskills/commit-helper.git
|
||||||
|
作者: workskills
|
||||||
|
|
||||||
|
2. code-review
|
||||||
|
描述: AI 代码审查助手
|
||||||
|
Git: https://github.com/workskills/code-review.git
|
||||||
|
作者: workskills
|
||||||
|
```
|
||||||
|
|
||||||
|
### 安装技能
|
||||||
|
|
||||||
|
```bash
|
||||||
|
getskill install <技能名称>
|
||||||
|
```
|
||||||
|
|
||||||
|
示例:
|
||||||
|
```bash
|
||||||
|
getskill install commit-helper
|
||||||
|
```
|
||||||
|
|
||||||
|
操作流程:
|
||||||
|
1. 调用 API 获取技能详情(包含 git_url)
|
||||||
|
2. 执行 `git clone` 到 `~/.claude/skills-cache/commit-helper`
|
||||||
|
3. 复制 `.md` 文件到 `~/.claude/skills/`
|
||||||
|
|
||||||
|
### 更新技能
|
||||||
|
|
||||||
|
```bash
|
||||||
|
getskill update <技能名称>
|
||||||
|
```
|
||||||
|
|
||||||
|
示例:
|
||||||
|
```bash
|
||||||
|
getskill update commit-helper
|
||||||
|
```
|
||||||
|
|
||||||
|
操作流程:
|
||||||
|
1. 进入缓存目录 `~/.claude/skills-cache/commit-helper`
|
||||||
|
2. 执行 `git pull`
|
||||||
|
3. 重新复制最新的 `.md` 文件
|
||||||
|
|
||||||
|
### 列出本地技能
|
||||||
|
|
||||||
|
```bash
|
||||||
|
getskill list
|
||||||
|
```
|
||||||
|
|
||||||
|
### 查看目录路径
|
||||||
|
|
||||||
|
```bash
|
||||||
|
getskill path
|
||||||
|
```
|
||||||
|
|
||||||
|
### 清理缓存
|
||||||
|
|
||||||
|
```bash
|
||||||
|
getskill clean
|
||||||
|
```
|
||||||
|
|
||||||
|
清理所有 Git 仓库缓存(不影响 skills 目录中的文件)
|
||||||
|
|
||||||
|
### 配置 API 地址
|
||||||
|
|
||||||
|
查看当前 API 地址:
|
||||||
|
```bash
|
||||||
|
getskill config get
|
||||||
|
```
|
||||||
|
|
||||||
|
设置自定义 API 地址:
|
||||||
|
```bash
|
||||||
|
getskill config set https://your-custom-api.com
|
||||||
|
```
|
||||||
|
|
||||||
|
通过环境变量设置:
|
||||||
|
```bash
|
||||||
|
GETSKILL_BASE_URL=https://your-custom-api.com getskill search keyword
|
||||||
|
```
|
||||||
|
|
||||||
|
## API 接口规范
|
||||||
|
|
||||||
|
### 搜索 API
|
||||||
|
|
||||||
|
```
|
||||||
|
GET https://getskills.certer/repo/search?sort=updated&order=desc&q=<关键词>&page=1&limit=20
|
||||||
|
```
|
||||||
|
|
||||||
|
响应格式:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"ok": true,
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"repository": {
|
||||||
|
"id": 1,
|
||||||
|
"full_name": "skills/commit-helper",
|
||||||
|
"description": "帮助生成规范的 git commit 信息",
|
||||||
|
"html_url": "https://getskills.certer/skills/commit-helper",
|
||||||
|
"clone_url": "https://getskills.certer/skills/commit-helper.git"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 详情 API
|
||||||
|
|
||||||
|
```
|
||||||
|
GET https://getskills.certer/repo/<技能名称>
|
||||||
|
```
|
||||||
|
|
||||||
|
响应格式:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"repository": {
|
||||||
|
"id": 1,
|
||||||
|
"full_name": "skills/commit-helper",
|
||||||
|
"description": "帮助生成规范的 git commit 信息",
|
||||||
|
"html_url": "https://getskills.certer/skills/commit-helper",
|
||||||
|
"clone_url": "https://getskills.certer/skills/commit-helper.git"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 编程接口
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const getskill = require('@workskills/getskill');
|
||||||
|
|
||||||
|
// 设置自定义 API 地址(可选)
|
||||||
|
getskill.setBaseUrl('https://your-custom-api.com');
|
||||||
|
|
||||||
|
// 搜索技能
|
||||||
|
const results = await getskill.searchSkills('commit');
|
||||||
|
|
||||||
|
// 安装技能
|
||||||
|
const result = await getskill.downloadSkill('skills/commit-helper');
|
||||||
|
console.log(result.files); // 已复制的文件列表
|
||||||
|
|
||||||
|
// 更新技能
|
||||||
|
await getskill.updateSkill('commit-helper');
|
||||||
|
|
||||||
|
// 列出本地技能
|
||||||
|
const skills = getskill.listLocalSkills();
|
||||||
|
|
||||||
|
// 获取目录
|
||||||
|
const skillsDir = getskill.getSkillsDirectory();
|
||||||
|
const cacheDir = getskill.getSkillsCacheDirectory();
|
||||||
|
|
||||||
|
// 获取当前 API 地址
|
||||||
|
const baseUrl = getskill.getBaseUrl();
|
||||||
|
```
|
||||||
|
|
||||||
|
## 技能仓库规范
|
||||||
|
|
||||||
|
技能 Git 仓库应包含:
|
||||||
|
- 一个或多个 `.md` 技能文件(非 README)
|
||||||
|
- 可选的 `README.md` 说明文档
|
||||||
|
- 可选的示例代码或配置文件
|
||||||
|
|
||||||
|
示例结构:
|
||||||
|
```
|
||||||
|
commit-helper/
|
||||||
|
├── commit-helper.md # 主技能文件(会被复制)
|
||||||
|
├── README.md # 说明文档(不会被复制)
|
||||||
|
└── examples/ # 示例(不会被复制)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 依赖
|
||||||
|
|
||||||
|
- Node.js >= 12
|
||||||
|
- Git 命令行工具(如未安装,程序会自动引导安装)
|
||||||
|
|
||||||
|
## Git 自动检测与安装
|
||||||
|
|
||||||
|
首次运行 `install` 或 `update` 命令时,程序会自动检测系统是否已安装 Git:
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
- **自动下载**: 自动下载 Git 安装程序并启动安装向导
|
||||||
|
- **手动安装**: 如果自动下载失败,会提示访问 https://git-scm.com/download/win
|
||||||
|
|
||||||
|
### macOS
|
||||||
|
- 提示使用 Homebrew 安装:`brew install git`
|
||||||
|
- 如未安装 Homebrew,会提示访问 https://brew.sh/
|
||||||
|
|
||||||
|
### Linux
|
||||||
|
- 提示使用系统包管理器安装:
|
||||||
|
- Ubuntu/Debian: `sudo apt-get install git`
|
||||||
|
- CentOS/RHEL: `sudo yum install git`
|
||||||
|
- Fedora: `sudo dnf install git`
|
||||||
|
- Arch: `sudo pacman -S git`
|
||||||
|
|
||||||
|
## 许可证
|
||||||
|
|
||||||
|
MIT
|
||||||
|
|
||||||
|
## 作者
|
||||||
|
|
||||||
|
workskills.store
|
||||||
204
SKILL.md
Normal file
204
SKILL.md
Normal file
@@ -0,0 +1,204 @@
|
|||||||
|
---
|
||||||
|
name: getskills
|
||||||
|
description: OpenClaw 技能管理工具。从 getskills.certer 搜索、下载和更新技能文件。当用户想要搜索、安装、更新或管理 OpenClaw 技能时使用此技能。支持通过 Git 克隆技能仓库、更新已安装的技能、列出本地技能等操作。
|
||||||
|
license: MIT
|
||||||
|
---
|
||||||
|
|
||||||
|
# GetSkill - OpenClaw 技能管理工具
|
||||||
|
|
||||||
|
这是一个用于管理 OpenClaw 技能的命令行工具。它允许你从 getskills.certer API 搜索、下载和更新技能文件。
|
||||||
|
|
||||||
|
## 触发条件
|
||||||
|
|
||||||
|
当用户提到以下内容时使用此技能:
|
||||||
|
- 搜索技能 / search skills
|
||||||
|
- 安装技能 / install skills / download skills
|
||||||
|
- 更新技能 / update skills
|
||||||
|
- 列出本地技能 / list local skills
|
||||||
|
- 管理技能 / manage skills
|
||||||
|
- getskills / getskill 命令
|
||||||
|
|
||||||
|
## 功能特性
|
||||||
|
|
||||||
|
### 🔍 搜索技能
|
||||||
|
从 getskills.certer API 搜索可用的技能,支持关键词搜索。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
getskill search <关键词>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 📥 安装技能
|
||||||
|
通过 Git 克隆技能仓库到本地缓存目录,并将技能文件复制到 OpenClaw skills 目录。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
getskill install <技能名称>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 🔄 更新技能
|
||||||
|
通过 Git pull 更新已安装的技能到最新版本。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
getskill update <技能名称>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 📂 列出技能
|
||||||
|
列出所有已安装的本地技能。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
getskill list
|
||||||
|
```
|
||||||
|
|
||||||
|
### 🛠️ 其他功能
|
||||||
|
|
||||||
|
查看目录路径:
|
||||||
|
```bash
|
||||||
|
getskill path
|
||||||
|
```
|
||||||
|
|
||||||
|
清理缓存:
|
||||||
|
```bash
|
||||||
|
getskill clean
|
||||||
|
```
|
||||||
|
|
||||||
|
配置 API 地址:
|
||||||
|
```bash
|
||||||
|
getskill config get
|
||||||
|
getskill config set <新API地址>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 工作原理
|
||||||
|
|
||||||
|
1. **搜索**: 从 `getskills.certer` API 获取技能列表,包含 Git 仓库地址
|
||||||
|
2. **安装**: 使用 `git clone` 克隆技能仓库到缓存目录 `~/.claude/skills-cache/`
|
||||||
|
3. **复制**: 将仓库中的 `.md` 技能文件复制到 OpenClaw skills 目录 `~/.claude/skills/`
|
||||||
|
4. **更新**: 使用 `git pull` 更新仓库,并重新复制文件
|
||||||
|
|
||||||
|
## 目录结构
|
||||||
|
|
||||||
|
```
|
||||||
|
~/.claude/
|
||||||
|
├── skills/ # OpenClaw 技能文件目录
|
||||||
|
│ ├── skill1.md
|
||||||
|
│ └── skill2.md
|
||||||
|
└── skills-cache/ # Git 仓库缓存
|
||||||
|
├── skill1/
|
||||||
|
└── skill2/
|
||||||
|
```
|
||||||
|
|
||||||
|
### 平台路径
|
||||||
|
|
||||||
|
- **Windows**: `%USERPROFILE%\.claude\skills`
|
||||||
|
- **macOS**: `~/.claude/skills`
|
||||||
|
- **Linux**: `~/.claude/skills`
|
||||||
|
|
||||||
|
## 安装要求
|
||||||
|
|
||||||
|
- Node.js >= 12
|
||||||
|
- Git 命令行工具(如未安装,程序会自动引导安装)
|
||||||
|
|
||||||
|
## 使用示例
|
||||||
|
|
||||||
|
### 搜索 commit 相关的技能
|
||||||
|
```bash
|
||||||
|
getskill search commit
|
||||||
|
```
|
||||||
|
|
||||||
|
### 安装 commit-helper 技能
|
||||||
|
```bash
|
||||||
|
getskill install commit-helper
|
||||||
|
```
|
||||||
|
|
||||||
|
### 更新 commit-helper 技能
|
||||||
|
```bash
|
||||||
|
getskill update commit-helper
|
||||||
|
```
|
||||||
|
|
||||||
|
### 列出所有已安装的技能
|
||||||
|
```bash
|
||||||
|
getskill list
|
||||||
|
```
|
||||||
|
|
||||||
|
## API 接口规范
|
||||||
|
|
||||||
|
### 搜索 API
|
||||||
|
```
|
||||||
|
GET https://getskills.certer/repo/search?sort=updated&order=desc&q=<关键词>&page=1&limit=20
|
||||||
|
```
|
||||||
|
|
||||||
|
### 详情 API
|
||||||
|
```
|
||||||
|
GET https://getskills.certer/repo/<技能名称>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 编程接口
|
||||||
|
|
||||||
|
如果需要在代码中使用,可以通过以下方式:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const getskill = require('@workskills/getskill');
|
||||||
|
|
||||||
|
// 搜索技能
|
||||||
|
const results = await getskill.searchSkills('commit');
|
||||||
|
|
||||||
|
// 安装技能
|
||||||
|
const result = await getskill.downloadSkill('skills/commit-helper');
|
||||||
|
|
||||||
|
// 更新技能
|
||||||
|
await getskill.updateSkill('commit-helper');
|
||||||
|
|
||||||
|
// 列出本地技能
|
||||||
|
const skills = getskill.listLocalSkills();
|
||||||
|
```
|
||||||
|
|
||||||
|
## Git 自动检测与安装
|
||||||
|
|
||||||
|
首次运行时,程序会自动检测系统是否已安装 Git:
|
||||||
|
|
||||||
|
- **Windows**: 自动下载 Git 安装程序并启动安装向导
|
||||||
|
- **macOS**: 提示使用 Homebrew 安装 Git
|
||||||
|
- **Linux**: 提示使用系统包管理器安装 Git
|
||||||
|
|
||||||
|
## 技能仓库规范
|
||||||
|
|
||||||
|
技能 Git 仓库应包含:
|
||||||
|
- 一个或多个 `.md` 技能文件(非 README)
|
||||||
|
- 可选的 `README.md` 说明文档
|
||||||
|
- 可选的示例代码或配置文件
|
||||||
|
|
||||||
|
示例结构:
|
||||||
|
```
|
||||||
|
commit-helper/
|
||||||
|
├── commit-helper.md # 主技能文件(会被复制)
|
||||||
|
├── README.md # 说明文档(不会被复制)
|
||||||
|
└── examples/ # 示例(不会被复制)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 配置自定义 API
|
||||||
|
|
||||||
|
可以通过以下方式配置自定义 API 地址:
|
||||||
|
|
||||||
|
1. 使用命令行配置:
|
||||||
|
```bash
|
||||||
|
getskill config set https://your-custom-api.com
|
||||||
|
```
|
||||||
|
|
||||||
|
2. 使用环境变量:
|
||||||
|
```bash
|
||||||
|
GETSKILL_BASE_URL=https://your-custom-api.com getskill search keyword
|
||||||
|
```
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
- 技能文件会被复制到用户的 `~/.claude/skills/` 目录
|
||||||
|
- Git 仓库缓存保存在 `~/.claude/skills-cache/` 目录
|
||||||
|
- 只有 `.md` 文件(非 README.md)会被复制到 skills 目录
|
||||||
|
- 更新技能时会覆盖已存在的技能文件
|
||||||
|
- 清理缓存不会删除已安装的技能文件,只删除 Git 仓库缓存
|
||||||
|
|
||||||
|
## 许可证
|
||||||
|
|
||||||
|
MIT
|
||||||
|
|
||||||
|
## 作者
|
||||||
|
|
||||||
|
workskills.store
|
||||||
666
index.js
Normal file
666
index.js
Normal file
@@ -0,0 +1,666 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const https = require('https');
|
||||||
|
const http = require('http');
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
const os = require('os');
|
||||||
|
const { exec } = require('child_process');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 基础 URL 配置
|
||||||
|
* 可以通过环境变量 GETSKILL_BASE_URL 自定义
|
||||||
|
*/
|
||||||
|
let BASE_URL = process.env.GETSKILL_BASE_URL || 'https://getskills.certer';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置自定义 BASE_URL
|
||||||
|
* @param {string} url - 自定义的基础 URL
|
||||||
|
*/
|
||||||
|
function setBaseUrl(url) {
|
||||||
|
BASE_URL = url.replace(/\/$/, ''); // 移除末尾的斜杠
|
||||||
|
console.log(`BASE_URL 已设置为: ${BASE_URL}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前 BASE_URL
|
||||||
|
* @returns {string} 当前的基础 URL
|
||||||
|
*/
|
||||||
|
function getBaseUrl() {
|
||||||
|
return BASE_URL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查 Git 是否已安装
|
||||||
|
*/
|
||||||
|
async function checkGitInstalled() {
|
||||||
|
try {
|
||||||
|
await executeCommand('git --version');
|
||||||
|
return true;
|
||||||
|
} catch (error) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 Git 下载链接(根据操作系统)
|
||||||
|
*/
|
||||||
|
function getGitDownloadUrl() {
|
||||||
|
const platform = os.platform();
|
||||||
|
const arch = os.arch();
|
||||||
|
|
||||||
|
switch (platform) {
|
||||||
|
case 'win32':
|
||||||
|
// Windows
|
||||||
|
if (arch === 'x64') {
|
||||||
|
return 'https://github.com/git-for-windows/git/releases/download/v2.44.0.windows.1/Git-2.44.0-64-bit.exe';
|
||||||
|
} else {
|
||||||
|
return 'https://github.com/git-for-windows/git/releases/download/v2.44.0.windows.1/Git-2.44.0-32-bit.exe';
|
||||||
|
}
|
||||||
|
case 'darwin':
|
||||||
|
// macOS - 提示使用 Homebrew
|
||||||
|
return 'homebrew'; // 特殊标记
|
||||||
|
case 'linux':
|
||||||
|
// Linux - 提示使用包管理器
|
||||||
|
return 'package-manager'; // 特殊标记
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载文件
|
||||||
|
*/
|
||||||
|
function downloadFile(url, destPath) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const urlObj = new URL(url);
|
||||||
|
const protocol = urlObj.protocol === 'https:' ? https : http;
|
||||||
|
|
||||||
|
const file = fs.createWriteStream(destPath);
|
||||||
|
|
||||||
|
protocol.get(url, (response) => {
|
||||||
|
// 处理重定向
|
||||||
|
if (response.statusCode === 301 || response.statusCode === 302) {
|
||||||
|
file.close();
|
||||||
|
fs.unlinkSync(destPath);
|
||||||
|
return downloadFile(response.headers.location, destPath)
|
||||||
|
.then(resolve)
|
||||||
|
.catch(reject);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.statusCode !== 200) {
|
||||||
|
file.close();
|
||||||
|
fs.unlinkSync(destPath);
|
||||||
|
return reject(new Error(`下载失败,状态码: ${response.statusCode}`));
|
||||||
|
}
|
||||||
|
|
||||||
|
const totalSize = parseInt(response.headers['content-length'], 10);
|
||||||
|
let downloadedSize = 0;
|
||||||
|
|
||||||
|
response.on('data', (chunk) => {
|
||||||
|
downloadedSize += chunk.length;
|
||||||
|
const percent = ((downloadedSize / totalSize) * 100).toFixed(2);
|
||||||
|
process.stdout.write(`\r下载进度: ${percent}%`);
|
||||||
|
});
|
||||||
|
|
||||||
|
response.pipe(file);
|
||||||
|
|
||||||
|
file.on('finish', () => {
|
||||||
|
file.close();
|
||||||
|
console.log('\n下载完成!');
|
||||||
|
resolve(destPath);
|
||||||
|
});
|
||||||
|
}).on('error', (err) => {
|
||||||
|
file.close();
|
||||||
|
fs.unlinkSync(destPath);
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 安装 Git
|
||||||
|
*/
|
||||||
|
async function installGit() {
|
||||||
|
const platform = os.platform();
|
||||||
|
const downloadUrl = getGitDownloadUrl();
|
||||||
|
|
||||||
|
console.log('检测到系统未安装 Git,正在准备安装...\n');
|
||||||
|
|
||||||
|
if (downloadUrl === 'homebrew') {
|
||||||
|
console.log('macOS 系统检测到未安装 Git');
|
||||||
|
console.log('请使用以下命令安装 Git:\n');
|
||||||
|
console.log(' brew install git');
|
||||||
|
console.log('\n如果未安装 Homebrew,请访问: https://brew.sh/');
|
||||||
|
throw new Error('请先安装 Git 后再运行此命令');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (downloadUrl === 'package-manager') {
|
||||||
|
console.log('Linux 系统检测到未安装 Git');
|
||||||
|
console.log('请使用系统包管理器安装 Git:\n');
|
||||||
|
console.log(' Ubuntu/Debian: sudo apt-get install git');
|
||||||
|
console.log(' CentOS/RHEL: sudo yum install git');
|
||||||
|
console.log(' Fedora: sudo dnf install git');
|
||||||
|
console.log(' Arch: sudo pacman -S git');
|
||||||
|
throw new Error('请先安装 Git 后再运行此命令');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (platform === 'win32') {
|
||||||
|
console.log('Windows 系统检测到未安装 Git');
|
||||||
|
console.log('正在下载 Git 安装程序...\n');
|
||||||
|
|
||||||
|
const tempDir = os.tmpdir();
|
||||||
|
const installerPath = path.join(tempDir, 'git-installer.exe');
|
||||||
|
|
||||||
|
try {
|
||||||
|
await downloadFile(downloadUrl, installerPath);
|
||||||
|
console.log(`\nGit 安装程序已下载到: ${installerPath}`);
|
||||||
|
console.log('\n正在启动安装程序,请按照提示完成安装...');
|
||||||
|
console.log('安装完成后,请重新运行此命令。\n');
|
||||||
|
|
||||||
|
// 启动安装程序
|
||||||
|
exec(`"${installerPath}"`, (error) => {
|
||||||
|
if (error) {
|
||||||
|
console.error('启动安装程序失败:', error.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
throw new Error('请完成 Git 安装后重新运行此命令');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('\n下载 Git 安装程序失败:', error.message);
|
||||||
|
console.log('\n您可以手动访问以下网址下载 Git:');
|
||||||
|
console.log('https://git-scm.com/download/win');
|
||||||
|
throw new Error('请先安装 Git 后再运行此命令');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确保 Git 已安装
|
||||||
|
*/
|
||||||
|
async function ensureGitInstalled() {
|
||||||
|
const isInstalled = await checkGitInstalled();
|
||||||
|
if (!isInstalled) {
|
||||||
|
await installGit();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 OpenClaw skills 目录路径(根据操作系统)
|
||||||
|
*/
|
||||||
|
function getSkillsDirectory() {
|
||||||
|
const platform = os.platform();
|
||||||
|
const homeDir = os.homedir();
|
||||||
|
|
||||||
|
switch (platform) {
|
||||||
|
case 'win32':
|
||||||
|
// Windows: %USERPROFILE%\.claude\skills
|
||||||
|
return path.join(homeDir, '.claude', 'skills');
|
||||||
|
case 'darwin':
|
||||||
|
// macOS: ~/.claude/skills
|
||||||
|
return path.join(homeDir, '.claude', 'skills');
|
||||||
|
case 'linux':
|
||||||
|
// Linux: ~/.claude/skills
|
||||||
|
return path.join(homeDir, '.claude', 'skills');
|
||||||
|
default:
|
||||||
|
// 默认使用 ~/.claude/skills
|
||||||
|
return path.join(homeDir, '.claude', 'skills');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确保目录存在
|
||||||
|
*/
|
||||||
|
function ensureDirectoryExists(dirPath) {
|
||||||
|
if (!fs.existsSync(dirPath)) {
|
||||||
|
fs.mkdirSync(dirPath, { recursive: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTTP/HTTPS 请求封装
|
||||||
|
*/
|
||||||
|
function request(url, options = {}) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const urlObj = new URL(url);
|
||||||
|
const protocol = urlObj.protocol === 'https:' ? https : http;
|
||||||
|
|
||||||
|
const reqOptions = {
|
||||||
|
hostname: urlObj.hostname,
|
||||||
|
port: urlObj.port,
|
||||||
|
path: urlObj.pathname + urlObj.search,
|
||||||
|
method: options.method || 'GET',
|
||||||
|
headers: options.headers || {}
|
||||||
|
};
|
||||||
|
|
||||||
|
const req = protocol.request(reqOptions, (res) => {
|
||||||
|
let data = '';
|
||||||
|
|
||||||
|
res.on('data', (chunk) => {
|
||||||
|
data += chunk;
|
||||||
|
});
|
||||||
|
|
||||||
|
res.on('end', () => {
|
||||||
|
if (res.statusCode >= 200 && res.statusCode < 300) {
|
||||||
|
resolve({
|
||||||
|
statusCode: res.statusCode,
|
||||||
|
headers: res.headers,
|
||||||
|
body: data
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
reject(new Error(`Request failed with status code ${res.statusCode}`));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
req.on('error', (err) => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (options.body) {
|
||||||
|
req.write(options.body);
|
||||||
|
}
|
||||||
|
|
||||||
|
req.end();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行命令
|
||||||
|
*/
|
||||||
|
function executeCommand(command, cwd) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
exec(command, { cwd, maxBuffer: 10 * 1024 * 1024 }, (error, stdout, stderr) => {
|
||||||
|
if (error) {
|
||||||
|
reject(error);
|
||||||
|
} else {
|
||||||
|
resolve({ stdout, stderr });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 搜索技能(从配置的 BASE_URL API)
|
||||||
|
* @param {string} keyword - 搜索关键词
|
||||||
|
* @param {Object} options - 搜索选项
|
||||||
|
* @param {string} options.sort - 排序字段,默认 'updated'
|
||||||
|
* @param {string} options.order - 排序顺序,默认 'desc'
|
||||||
|
* @param {number} options.page - 页码,默认 1
|
||||||
|
* @param {number} options.limit - 每页数量,默认 20
|
||||||
|
* @returns {Promise<Array>} 技能列表(包含 git 地址)
|
||||||
|
*/
|
||||||
|
async function searchSkills(keyword, options = {}) {
|
||||||
|
const {
|
||||||
|
sort = 'updated',
|
||||||
|
order = 'desc',
|
||||||
|
page = 1,
|
||||||
|
limit = 20
|
||||||
|
} = options;
|
||||||
|
|
||||||
|
const url = `${BASE_URL}/repo/search?sort=${sort}&order=${order}&q=${encodeURIComponent(keyword)}&page=${page}&limit=${limit}`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await request(url);
|
||||||
|
const result = JSON.parse(response.body);
|
||||||
|
|
||||||
|
// 解析返回格式: { ok: true, data: [{ repository: {...} }] }
|
||||||
|
if (!result.ok || !result.data) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提取需要的字段
|
||||||
|
return result.data.map(item => {
|
||||||
|
const repo = item.repository || {};
|
||||||
|
return {
|
||||||
|
name: repo.full_name || '',
|
||||||
|
full_name: repo.full_name || '',
|
||||||
|
description: repo.description || '',
|
||||||
|
html_url: repo.html_url || '',
|
||||||
|
git_url: repo.html_url ? `${repo.html_url}.git` : '',
|
||||||
|
clone_url: repo.clone_url || ''
|
||||||
|
};
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('搜索技能失败:', error.message);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取技能详情(包含 git 地址)
|
||||||
|
* @param {string} skillId - 技能ID或名称
|
||||||
|
* @returns {Promise<Object>} 技能详情
|
||||||
|
*/
|
||||||
|
async function getSkillDetail(skillId) {
|
||||||
|
const url = `${BASE_URL}/repo/${encodeURIComponent(skillId)}`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await request(url);
|
||||||
|
const result = JSON.parse(response.body);
|
||||||
|
|
||||||
|
// 如果返回的数据格式类似搜索接口,需要解析 repository
|
||||||
|
if (result.repository) {
|
||||||
|
const repo = result.repository;
|
||||||
|
return {
|
||||||
|
name: repo.full_name || repo.name || skillId,
|
||||||
|
full_name: repo.full_name || '',
|
||||||
|
description: repo.description || '',
|
||||||
|
html_url: repo.html_url || '',
|
||||||
|
git_url: repo.html_url ? `${repo.html_url}.git` : '',
|
||||||
|
clone_url: repo.clone_url || ''
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果是直接返回数据(向后兼容)
|
||||||
|
return {
|
||||||
|
name: result.full_name || result.name || skillId,
|
||||||
|
full_name: result.full_name || '',
|
||||||
|
description: result.description || '',
|
||||||
|
html_url: result.html_url || '',
|
||||||
|
git_url: result.html_url ? `${result.html_url}.git` : (result.git_url || ''),
|
||||||
|
clone_url: result.clone_url || ''
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取技能详情失败:', error.message);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取技能仓库缓存目录
|
||||||
|
*/
|
||||||
|
function getSkillsCacheDirectory() {
|
||||||
|
const homeDir = os.homedir();
|
||||||
|
return path.join(homeDir, '.claude', 'skills-cache');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 克隆或更新 Git 仓库
|
||||||
|
* @param {string} gitUrl - Git 仓库地址
|
||||||
|
* @param {string} skillName - 技能名称
|
||||||
|
* @returns {Promise<string>} 本地仓库路径
|
||||||
|
*/
|
||||||
|
async function cloneOrUpdateRepo(gitUrl, skillName) {
|
||||||
|
// 首先检查并确保 Git 已安装
|
||||||
|
await ensureGitInstalled();
|
||||||
|
|
||||||
|
const cacheDir = getSkillsCacheDirectory();
|
||||||
|
ensureDirectoryExists(cacheDir);
|
||||||
|
|
||||||
|
const repoPath = path.join(cacheDir, skillName);
|
||||||
|
|
||||||
|
if (fs.existsSync(repoPath)) {
|
||||||
|
// 仓库已存在,执行 git pull
|
||||||
|
console.log(`更新仓库: ${skillName}...`);
|
||||||
|
try {
|
||||||
|
await executeCommand('git pull', repoPath);
|
||||||
|
console.log(`仓库更新成功: ${repoPath}`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`更新失败: ${error.message}`);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 克隆新仓库
|
||||||
|
console.log(`克隆仓库: ${gitUrl}...`);
|
||||||
|
try {
|
||||||
|
await executeCommand(`git clone "${gitUrl}" "${skillName}"`, cacheDir);
|
||||||
|
console.log(`仓库克隆成功: ${repoPath}`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`克隆失败: ${error.message}`);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return repoPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从仓库复制技能文件到 skills 目录
|
||||||
|
* @param {string} repoPath - 仓库路径
|
||||||
|
* @param {string} skillName - 技能名称
|
||||||
|
*/
|
||||||
|
function copySkillFiles(repoPath) {
|
||||||
|
const skillsDir = getSkillsDirectory();
|
||||||
|
ensureDirectoryExists(skillsDir);
|
||||||
|
|
||||||
|
// 查找仓库中的 .md 文件
|
||||||
|
const files = fs.readdirSync(repoPath);
|
||||||
|
const mdFiles = files.filter(file =>
|
||||||
|
file.endsWith('.md') &&
|
||||||
|
!file.toLowerCase().startsWith('readme')
|
||||||
|
);
|
||||||
|
|
||||||
|
if (mdFiles.length === 0) {
|
||||||
|
throw new Error(`在仓库中未找到技能 .md 文件`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const copiedFiles = [];
|
||||||
|
mdFiles.forEach(file => {
|
||||||
|
const sourcePath = path.join(repoPath, file);
|
||||||
|
const targetPath = path.join(skillsDir, file);
|
||||||
|
|
||||||
|
fs.copyFileSync(sourcePath, targetPath);
|
||||||
|
console.log(`已复制: ${file} -> ${targetPath}`);
|
||||||
|
copiedFiles.push(targetPath);
|
||||||
|
});
|
||||||
|
|
||||||
|
return copiedFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载技能(通过 Git)
|
||||||
|
* @param {string} skillIdOrName - 技能ID或名称
|
||||||
|
*/
|
||||||
|
async function downloadSkill(skillIdOrName) {
|
||||||
|
try {
|
||||||
|
console.log(`获取技能信息: ${skillIdOrName}...`);
|
||||||
|
const skillDetail = await getSkillDetail(skillIdOrName);
|
||||||
|
|
||||||
|
// 支持 clone_url 或 git_url
|
||||||
|
const gitUrl = skillDetail.clone_url || skillDetail.git_url;
|
||||||
|
if (!gitUrl) {
|
||||||
|
throw new Error('技能信息中未包含 git_url 或 clone_url');
|
||||||
|
}
|
||||||
|
|
||||||
|
const skillName = skillDetail.name || skillIdOrName;
|
||||||
|
const repoPath = await cloneOrUpdateRepo(gitUrl, skillName);
|
||||||
|
const copiedFiles = copySkillFiles(repoPath);
|
||||||
|
|
||||||
|
return {
|
||||||
|
skillName,
|
||||||
|
repoPath,
|
||||||
|
files: copiedFiles
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`下载技能失败: ${error.message}`);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新技能(通过 Git)
|
||||||
|
* @param {string} skillName - 技能名称
|
||||||
|
*/
|
||||||
|
async function updateSkill(skillName) {
|
||||||
|
try {
|
||||||
|
console.log(`正在更新技能: ${skillName}...`);
|
||||||
|
|
||||||
|
const cacheDir = getSkillsCacheDirectory();
|
||||||
|
const repoPath = path.join(cacheDir, skillName);
|
||||||
|
|
||||||
|
if (!fs.existsSync(repoPath)) {
|
||||||
|
console.log(`技能仓库不存在,将重新下载...`);
|
||||||
|
return await downloadSkill(skillName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 执行 git pull
|
||||||
|
await executeCommand('git pull', repoPath);
|
||||||
|
console.log(`Git 仓库已更新`);
|
||||||
|
|
||||||
|
// 复制文件到 skills 目录
|
||||||
|
const copiedFiles = copySkillFiles(repoPath);
|
||||||
|
|
||||||
|
console.log(`技能 ${skillName} 更新成功!`);
|
||||||
|
return {
|
||||||
|
skillName,
|
||||||
|
repoPath,
|
||||||
|
files: copiedFiles
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`更新技能 ${skillName} 失败:`, error.message);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 列出本地已安装的技能
|
||||||
|
*/
|
||||||
|
function listLocalSkills() {
|
||||||
|
const skillsDir = getSkillsDirectory();
|
||||||
|
|
||||||
|
if (!fs.existsSync(skillsDir)) {
|
||||||
|
console.log('技能目录不存在');
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const files = fs.readdirSync(skillsDir);
|
||||||
|
const skillFiles = files.filter(file => file.endsWith('.md'));
|
||||||
|
|
||||||
|
return skillFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 命令行接口
|
||||||
|
*/
|
||||||
|
async function cli() {
|
||||||
|
const args = process.argv.slice(2);
|
||||||
|
const command = args[0];
|
||||||
|
|
||||||
|
try {
|
||||||
|
switch (command) {
|
||||||
|
case 'search':
|
||||||
|
if (!args[1]) {
|
||||||
|
console.error('请提供搜索关键词');
|
||||||
|
console.log('用法: getskill search <关键词>');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
const results = await searchSkills(args[1]);
|
||||||
|
console.log(`找到 ${results.length} 个技能:\n`);
|
||||||
|
results.forEach((skill, index) => {
|
||||||
|
console.log(`${index + 1}. ${skill.full_name}`);
|
||||||
|
if (skill.description) {
|
||||||
|
console.log(` 描述: ${skill.description}`);
|
||||||
|
}
|
||||||
|
if (skill.git_url) {
|
||||||
|
console.log(` Git: ${skill.git_url}`);
|
||||||
|
}
|
||||||
|
console.log('');
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'install':
|
||||||
|
case 'get':
|
||||||
|
case 'download':
|
||||||
|
if (!args[1]) {
|
||||||
|
console.error('请提供技能ID或名称');
|
||||||
|
console.log('用法: getskill install <技能名称>');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
const result = await downloadSkill(args[1]);
|
||||||
|
console.log(`\n技能已安装到 skills 目录:`);
|
||||||
|
result.files.forEach(file => console.log(` - ${file}`));
|
||||||
|
console.log(`\nGit 仓库缓存: ${result.repoPath}`);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'update':
|
||||||
|
if (!args[1]) {
|
||||||
|
console.error('请提供技能名称');
|
||||||
|
console.log('用法: getskill update <技能名称>');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
const updateResult = await updateSkill(args[1]);
|
||||||
|
console.log(`\n技能已更新到 skills 目录:`);
|
||||||
|
updateResult.files.forEach(file => console.log(` - ${file}`));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'list':
|
||||||
|
const skills = listLocalSkills();
|
||||||
|
console.log(`本地已安装的技能 (${skills.length}):`);
|
||||||
|
skills.forEach((skill, index) => {
|
||||||
|
console.log(`${index + 1}. ${skill}`);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'path':
|
||||||
|
console.log(`技能目录: ${getSkillsDirectory()}`);
|
||||||
|
console.log(`缓存目录: ${getSkillsCacheDirectory()}`);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'config':
|
||||||
|
if (args[1] === 'set' && args[2]) {
|
||||||
|
setBaseUrl(args[2]);
|
||||||
|
} else if (args[1] === 'get') {
|
||||||
|
console.log(`当前 BASE_URL: ${getBaseUrl()}`);
|
||||||
|
} else {
|
||||||
|
console.log('用法:');
|
||||||
|
console.log(' getskill config set <URL> - 设置自定义 API 地址');
|
||||||
|
console.log(' getskill config get - 查看当前 API 地址');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'clean':
|
||||||
|
const cacheDir = getSkillsCacheDirectory();
|
||||||
|
if (fs.existsSync(cacheDir)) {
|
||||||
|
fs.rmSync(cacheDir, { recursive: true, force: true });
|
||||||
|
console.log(`已清理缓存目录: ${cacheDir}`);
|
||||||
|
} else {
|
||||||
|
console.log('缓存目录不存在');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
console.log('GetSkill - OpenClaw 技能管理工具');
|
||||||
|
console.log('');
|
||||||
|
console.log('用法:');
|
||||||
|
console.log(' getskill search <关键词> - 从 API 搜索技能');
|
||||||
|
console.log(' getskill install <技能名称> - 通过 git clone 安装技能');
|
||||||
|
console.log(' getskill update <技能名称> - 通过 git pull 更新技能');
|
||||||
|
console.log(' getskill list - 列出本地技能');
|
||||||
|
console.log(' getskill path - 显示目录路径');
|
||||||
|
console.log(' getskill config set <URL> - 设置自定义 API 地址');
|
||||||
|
console.log(' getskill config get - 查看当前 API 地址');
|
||||||
|
console.log(' getskill clean - 清理 git 缓存');
|
||||||
|
console.log('');
|
||||||
|
console.log(`当前 API: ${getBaseUrl()}`);
|
||||||
|
console.log(`技能目录: ${getSkillsDirectory()}`);
|
||||||
|
console.log(`缓存目录: ${getSkillsCacheDirectory()}`);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('执行命令时出错:', error.message);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 导出模块函数
|
||||||
|
module.exports = {
|
||||||
|
searchSkills,
|
||||||
|
getSkillDetail,
|
||||||
|
downloadSkill,
|
||||||
|
updateSkill,
|
||||||
|
listLocalSkills,
|
||||||
|
getSkillsDirectory,
|
||||||
|
getSkillsCacheDirectory,
|
||||||
|
cloneOrUpdateRepo,
|
||||||
|
copySkillFiles,
|
||||||
|
checkGitInstalled,
|
||||||
|
ensureGitInstalled,
|
||||||
|
setBaseUrl,
|
||||||
|
getBaseUrl
|
||||||
|
};
|
||||||
|
|
||||||
|
// 如果直接运行此文件,执行 CLI
|
||||||
|
if (require.main === module) {
|
||||||
|
cli();
|
||||||
|
}
|
||||||
4
npmuser.txt
Normal file
4
npmuser.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
username:workskills
|
||||||
|
password:zlei@800999
|
||||||
|
|
||||||
|
token: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
|
||||||
58
package.json
Normal file
58
package.json
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
{
|
||||||
|
"name": "@workskills/getskill",
|
||||||
|
"version": "1.1.0",
|
||||||
|
"description": "Search, install, and update OpenClaw skills with automatic Git integration and configurable API endpoint",
|
||||||
|
"main": "index.js",
|
||||||
|
"bin": {
|
||||||
|
"getskill": "./index.js"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"test": "node verify.js",
|
||||||
|
"verify": "node verify.js",
|
||||||
|
"start": "node index.js",
|
||||||
|
"prepublishOnly": "npm run verify"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/workskills/getskill.git"
|
||||||
|
},
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/workskills/getskill/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/workskills/getskill#readme",
|
||||||
|
"keywords": [
|
||||||
|
"openclaw",
|
||||||
|
"workskills",
|
||||||
|
"skill",
|
||||||
|
"skills",
|
||||||
|
"search",
|
||||||
|
"install",
|
||||||
|
"update",
|
||||||
|
"git",
|
||||||
|
"cli",
|
||||||
|
"claude",
|
||||||
|
"ai",
|
||||||
|
"automation"
|
||||||
|
],
|
||||||
|
"author": {
|
||||||
|
"name": "workskills.store",
|
||||||
|
"url": "https://workskills.store"
|
||||||
|
},
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.0.0"
|
||||||
|
},
|
||||||
|
"os": [
|
||||||
|
"darwin",
|
||||||
|
"linux",
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"files": [
|
||||||
|
"index.js",
|
||||||
|
"README.md",
|
||||||
|
"EXAMPLES.md",
|
||||||
|
"LICENSE"
|
||||||
|
],
|
||||||
|
"dependencies": {},
|
||||||
|
"devDependencies": {}
|
||||||
|
}
|
||||||
101
verify.js
Normal file
101
verify.js
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetSkill 基本验证脚本
|
||||||
|
* 用于验证模块是否正确加载和基本功能是否正常
|
||||||
|
*/
|
||||||
|
|
||||||
|
const getskill = require('./index.js');
|
||||||
|
const os = require('os');
|
||||||
|
|
||||||
|
console.log('=== GetSkill 验证测试 ===\n');
|
||||||
|
|
||||||
|
// 测试 1: 模块导出验证
|
||||||
|
console.log('✓ 测试 1: 验证模块导出');
|
||||||
|
const requiredExports = [
|
||||||
|
'searchSkills',
|
||||||
|
'getSkillDetail',
|
||||||
|
'downloadSkill',
|
||||||
|
'updateSkill',
|
||||||
|
'listLocalSkills',
|
||||||
|
'getSkillsDirectory',
|
||||||
|
'getSkillsCacheDirectory',
|
||||||
|
'checkGitInstalled',
|
||||||
|
'ensureGitInstalled',
|
||||||
|
'cloneOrUpdateRepo',
|
||||||
|
'copySkillFiles'
|
||||||
|
];
|
||||||
|
|
||||||
|
let allExportsPresent = true;
|
||||||
|
requiredExports.forEach(exportName => {
|
||||||
|
if (typeof getskill[exportName] !== 'function') {
|
||||||
|
console.error(` ✗ 缺少导出函数: ${exportName}`);
|
||||||
|
allExportsPresent = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (allExportsPresent) {
|
||||||
|
console.log(` ✓ 所有 ${requiredExports.length} 个导出函数都存在\n`);
|
||||||
|
} else {
|
||||||
|
console.error(' ✗ 部分导出函数缺失\n');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 测试 2: 目录路径验证
|
||||||
|
console.log('✓ 测试 2: 验证目录路径');
|
||||||
|
try {
|
||||||
|
const skillsDir = getskill.getSkillsDirectory();
|
||||||
|
const cacheDir = getskill.getSkillsCacheDirectory();
|
||||||
|
|
||||||
|
console.log(` 技能目录: ${skillsDir}`);
|
||||||
|
console.log(` 缓存目录: ${cacheDir}`);
|
||||||
|
|
||||||
|
const homeDir = os.homedir();
|
||||||
|
if (!skillsDir.includes(homeDir)) {
|
||||||
|
throw new Error('技能目录路径不包含用户主目录');
|
||||||
|
}
|
||||||
|
if (!cacheDir.includes(homeDir)) {
|
||||||
|
throw new Error('缓存目录路径不包含用户主目录');
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(' ✓ 目录路径正确\n');
|
||||||
|
} catch (error) {
|
||||||
|
console.error(` ✗ 目录路径验证失败: ${error.message}\n`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 测试 3: Git 检测
|
||||||
|
console.log('✓ 测试 3: Git 安装检测');
|
||||||
|
getskill.checkGitInstalled()
|
||||||
|
.then(isInstalled => {
|
||||||
|
if (isInstalled) {
|
||||||
|
console.log(' ✓ Git 已安装\n');
|
||||||
|
} else {
|
||||||
|
console.log(' ⚠ Git 未安装(功能正常,但需要安装 Git 才能使用 install/update 命令)\n');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error(` ✗ Git 检测失败: ${error.message}\n`);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
// 测试 4: 列出本地技能
|
||||||
|
console.log('✓ 测试 4: 列出本地技能');
|
||||||
|
try {
|
||||||
|
const localSkills = getskill.listLocalSkills();
|
||||||
|
console.log(` 本地技能数量: ${localSkills.length}`);
|
||||||
|
if (localSkills.length > 0) {
|
||||||
|
console.log(' 已安装的技能:');
|
||||||
|
localSkills.forEach(skill => {
|
||||||
|
console.log(` - ${skill}`);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.log(' (未安装任何技能)');
|
||||||
|
}
|
||||||
|
console.log(' ✓ 列出本地技能功能正常\n');
|
||||||
|
} catch (error) {
|
||||||
|
console.error(` ✗ 列出本地技能失败: ${error.message}\n`);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('=== 验证完成 ===');
|
||||||
|
console.log('\n提示: 运行 "node index.js" 或 "getskill" 查看完整命令帮助');
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user