qskills 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 +512 -0
- package/bin/qskills.js +10 -0
- package/dist/commands/config.d.ts +3 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +142 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/knowledge/add.d.ts +14 -0
- package/dist/commands/knowledge/add.d.ts.map +1 -0
- package/dist/commands/knowledge/add.js +89 -0
- package/dist/commands/knowledge/add.js.map +1 -0
- package/dist/commands/knowledge/index.d.ts +3 -0
- package/dist/commands/knowledge/index.d.ts.map +1 -0
- package/dist/commands/knowledge/index.js +46 -0
- package/dist/commands/knowledge/index.js.map +1 -0
- package/dist/commands/knowledge/list.d.ts +10 -0
- package/dist/commands/knowledge/list.d.ts.map +1 -0
- package/dist/commands/knowledge/list.js +55 -0
- package/dist/commands/knowledge/list.js.map +1 -0
- package/dist/commands/knowledge/remove.d.ts +6 -0
- package/dist/commands/knowledge/remove.d.ts.map +1 -0
- package/dist/commands/knowledge/remove.js +33 -0
- package/dist/commands/knowledge/remove.js.map +1 -0
- package/dist/commands/knowledge/search.d.ts +9 -0
- package/dist/commands/knowledge/search.d.ts.map +1 -0
- package/dist/commands/knowledge/search.js +59 -0
- package/dist/commands/knowledge/search.js.map +1 -0
- package/dist/commands/skill/add.d.ts +11 -0
- package/dist/commands/skill/add.d.ts.map +1 -0
- package/dist/commands/skill/add.js +100 -0
- package/dist/commands/skill/add.js.map +1 -0
- package/dist/commands/skill/index.d.ts +3 -0
- package/dist/commands/skill/index.d.ts.map +1 -0
- package/dist/commands/skill/index.js +51 -0
- package/dist/commands/skill/index.js.map +1 -0
- package/dist/commands/skill/list.d.ts +8 -0
- package/dist/commands/skill/list.d.ts.map +1 -0
- package/dist/commands/skill/list.js +52 -0
- package/dist/commands/skill/list.js.map +1 -0
- package/dist/commands/skill/remove.d.ts +7 -0
- package/dist/commands/skill/remove.d.ts.map +1 -0
- package/dist/commands/skill/remove.js +33 -0
- package/dist/commands/skill/remove.js.map +1 -0
- package/dist/commands/skill/search.d.ts +7 -0
- package/dist/commands/skill/search.d.ts.map +1 -0
- package/dist/commands/skill/search.js +57 -0
- package/dist/commands/skill/search.js.map +1 -0
- package/dist/commands/skill/sync.d.ts +7 -0
- package/dist/commands/skill/sync.d.ts.map +1 -0
- package/dist/commands/skill/sync.js +83 -0
- package/dist/commands/skill/sync.js.map +1 -0
- package/dist/commands/sync.d.ts +3 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +63 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/core/config.d.ts +16 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +68 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/git-sync.d.ts +31 -0
- package/dist/core/git-sync.d.ts.map +1 -0
- package/dist/core/git-sync.js +240 -0
- package/dist/core/git-sync.js.map +1 -0
- package/dist/core/init.d.ts +3 -0
- package/dist/core/init.d.ts.map +1 -0
- package/dist/core/init.js +134 -0
- package/dist/core/init.js.map +1 -0
- package/dist/core/scanner.d.ts +27 -0
- package/dist/core/scanner.d.ts.map +1 -0
- package/dist/core/scanner.js +126 -0
- package/dist/core/scanner.js.map +1 -0
- package/dist/core/storage.d.ts +41 -0
- package/dist/core/storage.d.ts.map +1 -0
- package/dist/core/storage.js +293 -0
- package/dist/core/storage.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/types/index.d.ts +134 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +26 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/file.d.ts +16 -0
- package/dist/utils/file.d.ts.map +1 -0
- package/dist/utils/file.js +102 -0
- package/dist/utils/file.js.map +1 -0
- package/dist/utils/helpers.d.ts +7 -0
- package/dist/utils/helpers.d.ts.map +1 -0
- package/dist/utils/helpers.js +27 -0
- package/dist/utils/helpers.js.map +1 -0
- package/dist/utils/logger.d.ts +12 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +50 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +72 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026
|
|
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,512 @@
|
|
|
1
|
+
# Qcli-Skills (qskills)
|
|
2
|
+
|
|
3
|
+
一款面向个人开发者的 CLI 技能管理工具,支持公共技能、私人技能和知识库的统一管理与多源同步。
|
|
4
|
+
|
|
5
|
+
## 特性
|
|
6
|
+
|
|
7
|
+
- **一站式管理** - 将分散的技能脚本、代码片段、知识笔记统一管理
|
|
8
|
+
- **多源同步** - 通过 Git 仓库实现公共资源与私人资源的分类同步
|
|
9
|
+
- **即取即用** - 通过 npx 一键调用,无需全局安装
|
|
10
|
+
- **安全可控** - 敏感信息检测机制,防止意外泄露
|
|
11
|
+
- **跨平台** - 支持 Windows、macOS、Linux
|
|
12
|
+
|
|
13
|
+
## 快速开始
|
|
14
|
+
|
|
15
|
+
### 使用 npx(推荐)
|
|
16
|
+
|
|
17
|
+
无需安装,直接使用:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# 查看帮助
|
|
21
|
+
npx qskills --help
|
|
22
|
+
|
|
23
|
+
# 初始化配置
|
|
24
|
+
npx qskills config init
|
|
25
|
+
|
|
26
|
+
# 添加技能
|
|
27
|
+
npx qskills skill add ./my-script.js --name my-script
|
|
28
|
+
|
|
29
|
+
# 列出所有技能
|
|
30
|
+
npx qskills skill list
|
|
31
|
+
|
|
32
|
+
# 同步到远程仓库
|
|
33
|
+
npx qskills sync
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### 全局安装
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm install -g qskills
|
|
40
|
+
|
|
41
|
+
# 然后可以直接使用
|
|
42
|
+
qskills --help
|
|
43
|
+
qskills skill list
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 从 GitHub 直接使用
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
# 使用最新版本
|
|
50
|
+
npx github:your-username/qskills skill list
|
|
51
|
+
|
|
52
|
+
# 指定版本/分支
|
|
53
|
+
npx github:your-username/qskills#v1.0.0 skill list
|
|
54
|
+
npx github:your-username/qskills#main skill add ./my-skill
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## 安装要求
|
|
58
|
+
|
|
59
|
+
- Node.js 16.0.0 或更高版本
|
|
60
|
+
- npm 8.0.0 或更高版本
|
|
61
|
+
|
|
62
|
+
## 命令详解
|
|
63
|
+
|
|
64
|
+
### 技能管理 (skill)
|
|
65
|
+
|
|
66
|
+
#### 添加技能
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
# 添加单文件技能
|
|
70
|
+
npx qskills skill add ./script.js --name my-script
|
|
71
|
+
|
|
72
|
+
# 添加文件夹技能
|
|
73
|
+
npx qskills skill add ./my-project --name my-project --type folder
|
|
74
|
+
|
|
75
|
+
# 指定来源和标签
|
|
76
|
+
npx qskills skill add ./tool.py \
|
|
77
|
+
--name my-tool \
|
|
78
|
+
--source private \
|
|
79
|
+
--tags python,automation,tool \
|
|
80
|
+
--description "A useful automation tool"
|
|
81
|
+
|
|
82
|
+
# 跳过安全扫描(需确认)
|
|
83
|
+
npx qskills skill add ./config.json --name my-config --skip-scan
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**参数说明:**
|
|
87
|
+
|
|
88
|
+
| 参数 | 简写 | 说明 | 默认值 |
|
|
89
|
+
|------|------|------|--------|
|
|
90
|
+
| `--name` | `-n` | 技能名称 | 必填 |
|
|
91
|
+
| `--type` | `-t` | 类型:single 或 folder | single |
|
|
92
|
+
| `--source` | `-s` | 来源:public 或 private | private |
|
|
93
|
+
| `--tags` | | 标签(逗号分隔) | |
|
|
94
|
+
| `--description` | | 描述 | |
|
|
95
|
+
| `--skip-scan` | | 跳过安全扫描 | false |
|
|
96
|
+
|
|
97
|
+
#### 列出技能
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
# 列出所有技能
|
|
101
|
+
npx qskills skill list
|
|
102
|
+
|
|
103
|
+
# 按来源筛选
|
|
104
|
+
npx qskills skill list --source public
|
|
105
|
+
|
|
106
|
+
# 按标签筛选
|
|
107
|
+
npx qskills skill list --tags python,automation
|
|
108
|
+
|
|
109
|
+
# JSON 格式输出
|
|
110
|
+
npx qskills skill list --json
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
#### 搜索技能
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
# 按关键词搜索
|
|
117
|
+
npx qskills skill search python
|
|
118
|
+
|
|
119
|
+
# 按标签搜索
|
|
120
|
+
npx qskills skill search api --tags automation
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
#### 删除技能
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
# 删除技能(需确认)
|
|
127
|
+
npx qskills skill remove my-script
|
|
128
|
+
|
|
129
|
+
# 强制删除
|
|
130
|
+
npx qskills skill remove my-script --force
|
|
131
|
+
|
|
132
|
+
# 指定来源删除
|
|
133
|
+
npx qskills skill remove my-script --source private
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
#### 同步技能
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
# 同步所有仓库
|
|
140
|
+
npx qskills skill sync
|
|
141
|
+
|
|
142
|
+
# 同步指定来源
|
|
143
|
+
npx qskills skill sync --source public
|
|
144
|
+
|
|
145
|
+
# 强制覆盖本地
|
|
146
|
+
npx qskills skill sync --force
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### 知识库管理 (knowledge)
|
|
150
|
+
|
|
151
|
+
#### 添加知识条目
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
# 添加文档
|
|
155
|
+
npx qskills knowledge add ./article.md \
|
|
156
|
+
--title "API 设计指南" \
|
|
157
|
+
--type document \
|
|
158
|
+
--category api \
|
|
159
|
+
--tags api,design
|
|
160
|
+
|
|
161
|
+
# 添加代码片段
|
|
162
|
+
npx qskills knowledge add ./snippet.js \
|
|
163
|
+
--title "工具函数集合" \
|
|
164
|
+
--type code-snippet \
|
|
165
|
+
--category utils \
|
|
166
|
+
--tags javascript,utils
|
|
167
|
+
|
|
168
|
+
# 添加模板
|
|
169
|
+
npx qskills knowledge add ./template/ \
|
|
170
|
+
--title "React 项目模板" \
|
|
171
|
+
--type template \
|
|
172
|
+
--category frontend \
|
|
173
|
+
--tags react,template
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
**知识类型:**
|
|
177
|
+
|
|
178
|
+
| 类型 | 说明 |
|
|
179
|
+
|------|------|
|
|
180
|
+
| `document` | 文档、笔记 |
|
|
181
|
+
| `code-snippet` | 代码片段 |
|
|
182
|
+
| `template` | 项目模板 |
|
|
183
|
+
| `note` | 快速笔记 |
|
|
184
|
+
|
|
185
|
+
#### 列出知识条目
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
# 列出所有
|
|
189
|
+
npx qskills knowledge list
|
|
190
|
+
|
|
191
|
+
# 按类型筛选
|
|
192
|
+
npx qskills knowledge list --type code-snippet
|
|
193
|
+
|
|
194
|
+
# 按分类筛选
|
|
195
|
+
npx qskills knowledge list --category api
|
|
196
|
+
|
|
197
|
+
# JSON 输出
|
|
198
|
+
npx qskills knowledge list --json
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
#### 搜索知识条目
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
npx qskills knowledge search "API" --category backend
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
#### 删除知识条目
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
npx qskills knowledge remove <id>
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### 配置管理 (config)
|
|
214
|
+
|
|
215
|
+
#### 初始化配置
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
# 交互式初始化
|
|
219
|
+
npx qskills config init
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
初始化过程会引导你完成:
|
|
223
|
+
1. 配置存储路径
|
|
224
|
+
2. 配置 Git 仓库(可选)
|
|
225
|
+
3. 权限和安全设置
|
|
226
|
+
|
|
227
|
+
#### 查看配置
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
# 列出所有配置
|
|
231
|
+
npx qskills config list
|
|
232
|
+
|
|
233
|
+
# 获取单个配置项
|
|
234
|
+
npx qskills config get storage.baseDir
|
|
235
|
+
|
|
236
|
+
# JSON 输出
|
|
237
|
+
npx qskills config list --json
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
#### 修改配置
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
# 设置配置项
|
|
244
|
+
npx qskills config set storage.baseDir ~/.my-skills
|
|
245
|
+
|
|
246
|
+
# 启用自动同步
|
|
247
|
+
npx qskills config set sync.autoSync true
|
|
248
|
+
|
|
249
|
+
# 配置远程仓库
|
|
250
|
+
npx qskills config set remotes.public.url https://github.com/user/public-skills.git
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### 同步命令 (sync)
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
# 同步所有仓库
|
|
257
|
+
npx qskills sync
|
|
258
|
+
|
|
259
|
+
# 同步指定来源
|
|
260
|
+
npx qskills sync --source private
|
|
261
|
+
|
|
262
|
+
# 预览变更(不实际同步)
|
|
263
|
+
npx qskills sync --dry-run
|
|
264
|
+
|
|
265
|
+
# 强制覆盖
|
|
266
|
+
npx qskills sync --force
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
## 安全功能
|
|
270
|
+
|
|
271
|
+
### 敏感信息扫描
|
|
272
|
+
|
|
273
|
+
添加技能时自动扫描以下敏感信息:
|
|
274
|
+
|
|
275
|
+
| 类型 | 说明 |
|
|
276
|
+
|------|------|
|
|
277
|
+
| AWS Access Key | AKIA 开头的密钥 |
|
|
278
|
+
| GitHub Token | ghp_/gho_/ghu_/ghs_ 开头的令牌 |
|
|
279
|
+
| 私钥文件 | PEM 格式私钥 |
|
|
280
|
+
| API Key | api_key/secret_key 等模式 |
|
|
281
|
+
| JWT Token | eyJ 开头的 JWT |
|
|
282
|
+
| 数据库 URL | 包含密码的连接字符串 |
|
|
283
|
+
| Slack Token | xox 开头的 Slack 令牌 |
|
|
284
|
+
|
|
285
|
+
### 扫描示例
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
# 正常添加(自动扫描)
|
|
289
|
+
npx qskills skill add ./config.js --name my-config
|
|
290
|
+
|
|
291
|
+
# 发现敏感信息时会提示
|
|
292
|
+
# ⚠️ Sensitive information detected:
|
|
293
|
+
# [HIGH] aws-access-key in config.js:10
|
|
294
|
+
# [MED] api-key-generic in config.js:15
|
|
295
|
+
|
|
296
|
+
# 确认后可继续或取消
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### 跳过扫描
|
|
300
|
+
|
|
301
|
+
```bash
|
|
302
|
+
# 明确跳过(需二次确认)
|
|
303
|
+
npx qskills skill add ./public-config.json --name public-config --skip-scan
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
## 配置文件
|
|
307
|
+
|
|
308
|
+
配置文件位于 `~/.qcli/config.json`:
|
|
309
|
+
|
|
310
|
+
```json
|
|
311
|
+
{
|
|
312
|
+
"version": "1.0.0",
|
|
313
|
+
"initialized": true,
|
|
314
|
+
"storage": {
|
|
315
|
+
"baseDir": "~/.qcli/data",
|
|
316
|
+
"skillsDir": "skills",
|
|
317
|
+
"knowledgeDir": "knowledge"
|
|
318
|
+
},
|
|
319
|
+
"remotes": {
|
|
320
|
+
"public": {
|
|
321
|
+
"url": "https://github.com/user/public-skills.git",
|
|
322
|
+
"branch": "main",
|
|
323
|
+
"enabled": true
|
|
324
|
+
},
|
|
325
|
+
"private": {
|
|
326
|
+
"url": "git@github.com:user/private-skills.git",
|
|
327
|
+
"branch": "main",
|
|
328
|
+
"enabled": true
|
|
329
|
+
}
|
|
330
|
+
},
|
|
331
|
+
"sync": {
|
|
332
|
+
"autoSync": false,
|
|
333
|
+
"syncInterval": 0,
|
|
334
|
+
"confirmBeforeSync": true
|
|
335
|
+
},
|
|
336
|
+
"scanner": {
|
|
337
|
+
"enabled": true,
|
|
338
|
+
"skipPatterns": ["*.md", "docs/**"]
|
|
339
|
+
},
|
|
340
|
+
"security": {
|
|
341
|
+
"scanBeforePush": true,
|
|
342
|
+
"warnPublicRepo": true
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
## Git 认证
|
|
348
|
+
|
|
349
|
+
### 使用 Personal Access Token
|
|
350
|
+
|
|
351
|
+
```bash
|
|
352
|
+
# 设置环境变量
|
|
353
|
+
export QSKILLS_TOKEN=ghp_your_token_here
|
|
354
|
+
|
|
355
|
+
# 或在 Windows CMD
|
|
356
|
+
set QSKILLS_TOKEN=ghp_your_token_here
|
|
357
|
+
|
|
358
|
+
# 或在 Windows PowerShell
|
|
359
|
+
$env:QSKILLS_TOKEN="ghp_your_token_here"
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### 创建 GitHub Token
|
|
363
|
+
|
|
364
|
+
1. 访问 GitHub Settings → Developer settings → Personal access tokens
|
|
365
|
+
2. 创建新 Token,勾选 `repo` 权限
|
|
366
|
+
3. 复制 Token 并设置环境变量
|
|
367
|
+
|
|
368
|
+
## 存储结构
|
|
369
|
+
|
|
370
|
+
```
|
|
371
|
+
~/.qcli/
|
|
372
|
+
├── config.json # 配置文件
|
|
373
|
+
├── data/
|
|
374
|
+
│ ├── index.json # 本地索引
|
|
375
|
+
│ ├── skills/
|
|
376
|
+
│ │ ├── public/ # 公共技能
|
|
377
|
+
│ │ │ └── skill-name/
|
|
378
|
+
│ │ │ ├── skill.json
|
|
379
|
+
│ │ │ └── ...
|
|
380
|
+
│ │ └── private/ # 私人技能
|
|
381
|
+
│ │ └── skill-name/
|
|
382
|
+
│ │ ├── skill.json
|
|
383
|
+
│ │ └── ...
|
|
384
|
+
│ └── knowledge/
|
|
385
|
+
│ ├── public/
|
|
386
|
+
│ └── private/
|
|
387
|
+
├── public-repo/ # 公共仓库克隆
|
|
388
|
+
└── private-repo/ # 私人仓库克隆
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
## 开发
|
|
392
|
+
|
|
393
|
+
### 克隆与构建
|
|
394
|
+
|
|
395
|
+
```bash
|
|
396
|
+
git clone https://github.com/your-username/qskills.git
|
|
397
|
+
cd qskills
|
|
398
|
+
|
|
399
|
+
# 安装依赖
|
|
400
|
+
npm install
|
|
401
|
+
|
|
402
|
+
# 构建
|
|
403
|
+
npm run build
|
|
404
|
+
|
|
405
|
+
# 测试
|
|
406
|
+
npm test
|
|
407
|
+
|
|
408
|
+
# 本地运行
|
|
409
|
+
node bin/qskills.js --help
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
### 开发脚本
|
|
413
|
+
|
|
414
|
+
```bash
|
|
415
|
+
# 使用开发脚本(推荐)
|
|
416
|
+
./docs/scripts/dev-start.sh # Linux/macOS
|
|
417
|
+
docs\scripts\dev-start.bat # Windows
|
|
418
|
+
|
|
419
|
+
# 或手动执行
|
|
420
|
+
npm run dev # 监听模式编译
|
|
421
|
+
npm run test:watch # 监听模式测试
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
### 运行测试
|
|
425
|
+
|
|
426
|
+
```bash
|
|
427
|
+
npm test # 运行所有测试
|
|
428
|
+
npm run test:watch # 监听模式
|
|
429
|
+
npm run test:coverage # 生成覆盖率报告
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
## 发布
|
|
433
|
+
|
|
434
|
+
### 发布到 npm
|
|
435
|
+
|
|
436
|
+
```bash
|
|
437
|
+
# 1. 登录 npm
|
|
438
|
+
npm login
|
|
439
|
+
|
|
440
|
+
# 2. 检查发布内容
|
|
441
|
+
npm pack --dry-run
|
|
442
|
+
|
|
443
|
+
# 3. 发布
|
|
444
|
+
npm publish
|
|
445
|
+
|
|
446
|
+
# 4. 发布 beta 版本
|
|
447
|
+
npm publish --tag beta
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
### 版本管理
|
|
451
|
+
|
|
452
|
+
```bash
|
|
453
|
+
npm version patch # 1.0.0 -> 1.0.1
|
|
454
|
+
npm version minor # 1.0.0 -> 1.1.0
|
|
455
|
+
npm version major # 1.0.0 -> 2.0.0
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
## 常见问题
|
|
459
|
+
|
|
460
|
+
### Q: npx 提示找不到命令?
|
|
461
|
+
|
|
462
|
+
确保使用 Node.js 16+:
|
|
463
|
+
```bash
|
|
464
|
+
node -v # 应该 >= 16.0.0
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
### Q: 同步失败,提示认证错误?
|
|
468
|
+
|
|
469
|
+
设置 GitHub Token:
|
|
470
|
+
```bash
|
|
471
|
+
export QSKILLS_TOKEN=your_token
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
### Q: 如何修改默认存储路径?
|
|
475
|
+
|
|
476
|
+
```bash
|
|
477
|
+
npx qskills config set storage.baseDir ~/custom-path
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
### Q: 如何查看详细日志?
|
|
481
|
+
|
|
482
|
+
命令添加 `--verbose` 参数(开发中)
|
|
483
|
+
|
|
484
|
+
### Q: Windows 下路径问题?
|
|
485
|
+
|
|
486
|
+
使用正斜杠或双反斜杠:
|
|
487
|
+
```bash
|
|
488
|
+
npx qskills skill add "./scripts/tool.js"
|
|
489
|
+
# 或
|
|
490
|
+
npx qskills skill add ".\\scripts\\tool.js"
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
## 贡献
|
|
494
|
+
|
|
495
|
+
欢迎提交 Issue 和 Pull Request!
|
|
496
|
+
|
|
497
|
+
1. Fork 本仓库
|
|
498
|
+
2. 创建功能分支:`git checkout -b feature/my-feature`
|
|
499
|
+
3. 提交更改:`git commit -am 'Add my feature'`
|
|
500
|
+
4. 推送分支:`git push origin feature/my-feature`
|
|
501
|
+
5. 创建 Pull Request
|
|
502
|
+
|
|
503
|
+
## 许可证
|
|
504
|
+
|
|
505
|
+
[MIT](LICENSE)
|
|
506
|
+
|
|
507
|
+
## 相关链接
|
|
508
|
+
|
|
509
|
+
- [产品需求文档 (PRD)](docs/PRD_Qcli-Skills_20260409.md)
|
|
510
|
+
- [技术规格文档](docs/TECH_SPEC_Qcli-Skills_20260409.md)
|
|
511
|
+
- [验收测试报告](docs/ACCEPTANCE_TEST_REPORT.md)
|
|
512
|
+
- [脚本说明](docs/scripts/README.md)
|
package/bin/qskills.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA+IzD"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { getConfigManager } from '../core/config.js';
|
|
2
|
+
import { runFirstTimeSetup } from '../core/init.js';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import Table from 'cli-table3';
|
|
5
|
+
export function initConfigCommands(program) {
|
|
6
|
+
const config = program.command('config').description('Configuration management commands');
|
|
7
|
+
// config init
|
|
8
|
+
config
|
|
9
|
+
.command('init')
|
|
10
|
+
.description('Initialize configuration')
|
|
11
|
+
.action(async () => {
|
|
12
|
+
await runFirstTimeSetup();
|
|
13
|
+
});
|
|
14
|
+
// config set
|
|
15
|
+
config
|
|
16
|
+
.command('set <key> <value>')
|
|
17
|
+
.description('Set a configuration value')
|
|
18
|
+
.action(async (key, value) => {
|
|
19
|
+
try {
|
|
20
|
+
const manager = getConfigManager();
|
|
21
|
+
await manager.load();
|
|
22
|
+
// 解析值
|
|
23
|
+
let parsedValue = value;
|
|
24
|
+
if (value === 'true')
|
|
25
|
+
parsedValue = true;
|
|
26
|
+
else if (value === 'false')
|
|
27
|
+
parsedValue = false;
|
|
28
|
+
else if (!isNaN(Number(value)))
|
|
29
|
+
parsedValue = Number(value);
|
|
30
|
+
else if (value.startsWith('{') || value.startsWith('[')) {
|
|
31
|
+
try {
|
|
32
|
+
parsedValue = JSON.parse(value);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// 保持字符串
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// 解析嵌套 key (如 storage.baseDir)
|
|
39
|
+
const keys = key.split('.');
|
|
40
|
+
if (keys.length === 1) {
|
|
41
|
+
await manager.set(key, parsedValue);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
const currentConfig = manager.getConfig();
|
|
45
|
+
if (currentConfig) {
|
|
46
|
+
let obj = currentConfig;
|
|
47
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
48
|
+
obj = obj[keys[i]];
|
|
49
|
+
}
|
|
50
|
+
obj[keys[keys.length - 1]] = parsedValue;
|
|
51
|
+
await manager.save(currentConfig);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
console.log(chalk.green(`\n✓ Configuration updated: ${key} = ${JSON.stringify(parsedValue)}\n`));
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
console.error(chalk.red(`Error: ${error}`));
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
// config get
|
|
62
|
+
config
|
|
63
|
+
.command('get <key>')
|
|
64
|
+
.description('Get a configuration value')
|
|
65
|
+
.action(async (key) => {
|
|
66
|
+
try {
|
|
67
|
+
const manager = getConfigManager();
|
|
68
|
+
await manager.load();
|
|
69
|
+
const currentConfig = manager.getConfig();
|
|
70
|
+
if (!currentConfig) {
|
|
71
|
+
console.log(chalk.gray('No configuration found.'));
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
// 解析嵌套 key
|
|
75
|
+
const keys = key.split('.');
|
|
76
|
+
let value = currentConfig;
|
|
77
|
+
for (const k of keys) {
|
|
78
|
+
value = value?.[k];
|
|
79
|
+
}
|
|
80
|
+
if (value === undefined) {
|
|
81
|
+
console.log(chalk.gray(`Key "${key}" not found.`));
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
console.log(JSON.stringify(value, null, 2));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
console.error(chalk.red(`Error: ${error}`));
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
// config list
|
|
93
|
+
config
|
|
94
|
+
.command('list')
|
|
95
|
+
.alias('ls')
|
|
96
|
+
.description('List all configuration values')
|
|
97
|
+
.option('--json', 'output as JSON')
|
|
98
|
+
.action(async (options) => {
|
|
99
|
+
try {
|
|
100
|
+
const manager = getConfigManager();
|
|
101
|
+
await manager.load();
|
|
102
|
+
const currentConfig = manager.getConfig();
|
|
103
|
+
if (!currentConfig) {
|
|
104
|
+
console.log(chalk.gray('No configuration found.'));
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
if (options.json) {
|
|
108
|
+
console.log(JSON.stringify(currentConfig, null, 2));
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
console.log(chalk.cyan('\nConfiguration\n'));
|
|
112
|
+
console.log(chalk.gray(`Config file: ${manager.getConfigPath()}\n`));
|
|
113
|
+
const table = new Table({
|
|
114
|
+
head: [chalk.cyan('Key'), chalk.cyan('Value')],
|
|
115
|
+
colWidths: [25, 60]
|
|
116
|
+
});
|
|
117
|
+
function flattenObject(obj, prefix = '') {
|
|
118
|
+
const result = [];
|
|
119
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
120
|
+
const fullKey = prefix ? `${prefix}.${key}` : key;
|
|
121
|
+
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
122
|
+
result.push(...flattenObject(value, fullKey));
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
result.push([fullKey, JSON.stringify(value)]);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return result;
|
|
129
|
+
}
|
|
130
|
+
const entries = flattenObject(currentConfig);
|
|
131
|
+
for (const [key, value] of entries) {
|
|
132
|
+
table.push([key, value]);
|
|
133
|
+
}
|
|
134
|
+
console.log(table.toString() + '\n');
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
console.error(chalk.red(`Error: ${error}`));
|
|
138
|
+
process.exit(1);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"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"}
|