eskill 1.3.0 → 1.3.3
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/cli.js +18 -2
- package/lib/completion.js +239 -20
- package/lib/installer.js +9 -2
- package/package.json +1 -1
package/cli.js
CHANGED
|
@@ -3,7 +3,7 @@ import { Command } from 'commander';
|
|
|
3
3
|
import ora from 'ora';
|
|
4
4
|
import { installFromGitUrl, listSkills, removeSkill, linkSkill, uploadSkill, cleanupAllSkills, cleanupAll, updateSkill, updateAllSkills } from './lib/installer.js';
|
|
5
5
|
import { AGENTS, getDefaultAgent } from './lib/agent-config.js';
|
|
6
|
-
import { bashCompletionScript, zshCompletionScript, listSkillsForCompletion } from './lib/completion.js';
|
|
6
|
+
import { bashCompletionScript, zshCompletionScript, listSkillsForCompletion, listLocalSkillsForCompletion, listGlobalSkillsForCompletion } from './lib/completion.js';
|
|
7
7
|
import { searchSkills, formatSkillList } from './lib/search.js';
|
|
8
8
|
import { setApiKey, showConfigStatus } from './lib/config.js';
|
|
9
9
|
import readline from 'readline';
|
|
@@ -13,7 +13,7 @@ const program = new Command();
|
|
|
13
13
|
program
|
|
14
14
|
.name('eskill')
|
|
15
15
|
.description('Unified AI Agent Skills Management - Install skills from Git URLs')
|
|
16
|
-
.version('1.3.
|
|
16
|
+
.version('1.3.3')
|
|
17
17
|
.option('-g, --global', '使用全局技能目录(~/.eskill/skills/),否则使用当前目录(./.claude/skills/)', false);
|
|
18
18
|
|
|
19
19
|
// 安装命令
|
|
@@ -431,4 +431,20 @@ program
|
|
|
431
431
|
await listSkillsForCompletion();
|
|
432
432
|
});
|
|
433
433
|
|
|
434
|
+
// 内部命令:列出本地技能(用于自动补全)
|
|
435
|
+
program
|
|
436
|
+
.command('_list_local_skills')
|
|
437
|
+
.description('(内部命令) 列出本地技能名称')
|
|
438
|
+
.action(async () => {
|
|
439
|
+
await listLocalSkillsForCompletion();
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
// 内部命令:列出全局技能(用于自动补全)
|
|
443
|
+
program
|
|
444
|
+
.command('_list_global_skills')
|
|
445
|
+
.description('(内部命令) 列出全局技能名称')
|
|
446
|
+
.action(async () => {
|
|
447
|
+
await listGlobalSkillsForCompletion();
|
|
448
|
+
});
|
|
449
|
+
|
|
434
450
|
program.parse();
|
package/lib/completion.js
CHANGED
|
@@ -9,33 +9,129 @@ import { listSkills } from './installer.js';
|
|
|
9
9
|
import { getDefaultAgent } from './agent-config.js';
|
|
10
10
|
|
|
11
11
|
// 获取已安装的技能列表
|
|
12
|
-
async function getSkillList() {
|
|
12
|
+
async function getSkillList(global = false) {
|
|
13
13
|
try {
|
|
14
14
|
const agent = getDefaultAgent();
|
|
15
|
-
const skills = await listSkills(agent);
|
|
15
|
+
const skills = await listSkills(agent, global);
|
|
16
16
|
return skills.map(s => s.name);
|
|
17
17
|
} catch {
|
|
18
18
|
return [];
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
// 获取本地技能列表
|
|
23
|
+
async function getLocalSkills() {
|
|
24
|
+
return await getSkillList(false);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// 获取全局技能列表
|
|
28
|
+
async function getGlobalSkills() {
|
|
29
|
+
return await getSkillList(true);
|
|
30
|
+
}
|
|
31
|
+
|
|
22
32
|
// Bash 补全脚本
|
|
23
33
|
export function bashCompletionScript() {
|
|
24
34
|
return '\n_eskill_completion() {\n' +
|
|
25
35
|
' local cur prev words cword\n' +
|
|
26
36
|
' _init_completion || return\n\n' +
|
|
37
|
+
' # 检测是否使用了 -g/--global 选项\n' +
|
|
38
|
+
' local global_mode=""\n' +
|
|
39
|
+
' for word in "${words[@]}"; do\n' +
|
|
40
|
+
' if [[ "$word" == "-g" || "$word" == "--global" ]]; then\n' +
|
|
41
|
+
' global_mode="-g"\n' +
|
|
42
|
+
' break\n' +
|
|
43
|
+
' fi\n' +
|
|
44
|
+
' done\n\n' +
|
|
45
|
+
' # 检测当前命令\n' +
|
|
46
|
+
' local cmd=""\n' +
|
|
47
|
+
' for word in "${words[@]}"; do\n' +
|
|
48
|
+
' case ${word} in\n' +
|
|
49
|
+
' install|add|remove|rm|uninstall|update|list|ls|link|upload|search|cleanup|config|completion|agents|help)\n' +
|
|
50
|
+
' cmd="${word}"\n' +
|
|
51
|
+
' break\n' +
|
|
52
|
+
' ;;\n' +
|
|
53
|
+
' esac\n' +
|
|
54
|
+
' done\n\n' +
|
|
27
55
|
' case ${prev} in\n' +
|
|
56
|
+
' install|add)\n' +
|
|
57
|
+
' COMPREPLY=($(compgen -W "-a --agent -l --link -f --force" -- "${cur}"))\n' +
|
|
58
|
+
' return\n' +
|
|
59
|
+
' ;;\n' +
|
|
28
60
|
' remove|rm|uninstall)\n' +
|
|
29
|
-
' local skills=$(eskill _list_skills 2>/dev/null)\n' +
|
|
61
|
+
' local skills=$(eskill _list_skills ${global_mode} 2>/dev/null)\n' +
|
|
62
|
+
' COMPREPLY=($(compgen -W "${skills} -a --agent" -- "${cur}"))\n' +
|
|
63
|
+
' return\n' +
|
|
64
|
+
' ;;\n' +
|
|
65
|
+
' link)\n' +
|
|
66
|
+
' local skills=$(eskill _list_global_skills 2>/dev/null)\n' +
|
|
30
67
|
' COMPREPLY=($(compgen -W "${skills}" -- "${cur}"))\n' +
|
|
68
|
+
' return\n' +
|
|
69
|
+
' ;;\n' +
|
|
70
|
+
' upload)\n' +
|
|
71
|
+
' local skills=$(eskill _list_local_skills 2>/dev/null)\n' +
|
|
72
|
+
' COMPREPLY=($(compgen -W "${skills}" -- "${cur}"))\n' +
|
|
73
|
+
' return\n' +
|
|
74
|
+
' ;;\n' +
|
|
75
|
+
' update)\n' +
|
|
76
|
+
' local skills=$(eskill _list_skills ${global_mode} 2>/dev/null)\n' +
|
|
77
|
+
' COMPREPLY=($(compgen -W "${skills} all -f --force" -- "${cur}"))\n' +
|
|
78
|
+
' return\n' +
|
|
79
|
+
' ;;\n' +
|
|
80
|
+
' list|ls)\n' +
|
|
81
|
+
' COMPREPLY=($(compgen -W "-a --agent" -- "${cur}"))\n' +
|
|
82
|
+
' return\n' +
|
|
83
|
+
' ;;\n' +
|
|
84
|
+
' search)\n' +
|
|
85
|
+
' COMPREPLY=($(compgen -W "-p --page -l --limit -s --sort --ai" -- "${cur}"))\n' +
|
|
86
|
+
' return\n' +
|
|
87
|
+
' ;;\n' +
|
|
88
|
+
' cleanup)\n' +
|
|
89
|
+
' COMPREPLY=($(compgen -W "-a --all" -- "${cur}"))\n' +
|
|
90
|
+
' return\n' +
|
|
91
|
+
' ;;\n' +
|
|
92
|
+
' config)\n' +
|
|
93
|
+
' COMPREPLY=($(compgen -W "set-api-key status" -- "${cur}"))\n' +
|
|
94
|
+
' return\n' +
|
|
95
|
+
' ;;\n' +
|
|
96
|
+
' completion)\n' +
|
|
97
|
+
' COMPREPLY=($(compgen -W "-s --shell" -- "${cur}"))\n' +
|
|
98
|
+
' return\n' +
|
|
31
99
|
' ;;\n' +
|
|
32
100
|
' *)\n' +
|
|
33
101
|
' case ${cur} in\n' +
|
|
34
102
|
' -*)\n' +
|
|
35
|
-
'
|
|
103
|
+
' # 根据当前命令显示对应选项\n' +
|
|
104
|
+
' case ${cmd} in\n' +
|
|
105
|
+
' install|add)\n' +
|
|
106
|
+
' COMPREPLY=($(compgen -W "-a --agent -l --link -f --force" -- "${cur}"))\n' +
|
|
107
|
+
' ;;\n' +
|
|
108
|
+
' remove|rm|uninstall)\n' +
|
|
109
|
+
' COMPREPLY=($(compgen -W "-a --agent" -- "${cur}"))\n' +
|
|
110
|
+
' ;;\n' +
|
|
111
|
+
' update)\n' +
|
|
112
|
+
' COMPREPLY=($(compgen -W "-f --force" -- "${cur}"))\n' +
|
|
113
|
+
' ;;\n' +
|
|
114
|
+
' list|ls)\n' +
|
|
115
|
+
' COMPREPLY=($(compgen -W "-a --agent" -- "${cur}"))\n' +
|
|
116
|
+
' ;;\n' +
|
|
117
|
+
' search)\n' +
|
|
118
|
+
' COMPREPLY=($(compgen -W "-p --page -l --limit -s --sort --ai" -- "${cur}"))\n' +
|
|
119
|
+
' ;;\n' +
|
|
120
|
+
' cleanup)\n' +
|
|
121
|
+
' COMPREPLY=($(compgen -W "-a --all" -- "${cur}"))\n' +
|
|
122
|
+
' ;;\n' +
|
|
123
|
+
' completion)\n' +
|
|
124
|
+
' COMPREPLY=($(compgen -W "-s --shell" -- "${cur}"))\n' +
|
|
125
|
+
' ;;\n' +
|
|
126
|
+
' *)\n' +
|
|
127
|
+
' COMPREPLY=($(compgen -W "-g --global -h --help -V --version" -- "${cur}"))\n' +
|
|
128
|
+
' ;;\n' +
|
|
129
|
+
' esac\n' +
|
|
130
|
+
' return\n' +
|
|
36
131
|
' ;;\n' +
|
|
37
132
|
' *)\n' +
|
|
38
|
-
' COMPREPLY=($(compgen -W "install add list ls
|
|
133
|
+
' COMPREPLY=($(compgen -W "install add remove rm uninstall update list ls link upload search cleanup config agents completion help" -- "${cur}"))\n' +
|
|
134
|
+
' return\n' +
|
|
39
135
|
' ;;\n' +
|
|
40
136
|
' esac\n' +
|
|
41
137
|
' ;;\n' +
|
|
@@ -50,29 +146,152 @@ export function zshCompletionScript() {
|
|
|
50
146
|
'_eskill() {\n' +
|
|
51
147
|
' local -a commands\n' +
|
|
52
148
|
' commands=(\n' +
|
|
53
|
-
' \'install:从 Git URL
|
|
54
|
-
' \'add
|
|
55
|
-
' \'list:列出已安装的技能\'\n' +
|
|
56
|
-
' \'ls:列出已安装的技能(别名)\'\n' +
|
|
149
|
+
' \'install:从 Git URL 或名称安装技能\'\n' +
|
|
150
|
+
' \'add:安装技能(别名)\'\n' +
|
|
57
151
|
' \'remove:删除已安装的技能\'\n' +
|
|
58
|
-
' \'rm
|
|
59
|
-
' \'uninstall
|
|
152
|
+
' \'rm:删除技能(别名)\'\n' +
|
|
153
|
+
' \'uninstall:删除技能(别名)\'\n' +
|
|
154
|
+
' \'update:更新技能\'\n' +
|
|
155
|
+
' \'list:列出已安装的技能\'\n' +
|
|
156
|
+
' \'ls:列出技能(别名)\'\n' +
|
|
157
|
+
' \'link:将全局技能软链接到本地\'\n' +
|
|
158
|
+
' \'upload:上传本地技能到全局仓库\'\n' +
|
|
159
|
+
' \'search:搜索技能\'\n' +
|
|
160
|
+
' \'cleanup:清理技能数据\'\n' +
|
|
161
|
+
' \'config:配置管理\'\n' +
|
|
60
162
|
' \'agents:列出支持的 agents\'\n' +
|
|
61
|
-
' \'
|
|
163
|
+
' \'completion:生成自动补全脚本\'\n' +
|
|
62
164
|
' \'help:显示帮助信息\'\n' +
|
|
63
165
|
' )\n\n' +
|
|
64
|
-
'
|
|
65
|
-
'
|
|
66
|
-
'
|
|
67
|
-
'
|
|
68
|
-
'
|
|
69
|
-
'
|
|
166
|
+
' local -a install_options\n' +
|
|
167
|
+
' install_options=(\n' +
|
|
168
|
+
' \'--agent[目标 agent]\'\n' +
|
|
169
|
+
' \'{-a,--agent}[目标 agent]\'\n' +
|
|
170
|
+
' \'--link[使用符号链接而非复制]\'\n' +
|
|
171
|
+
' \'{-l,--link}[使用符号链接而非复制]\'\n' +
|
|
172
|
+
' \'--force[强制覆盖已存在的技能]\'\n' +
|
|
173
|
+
' \'{-f,--force}[强制覆盖已存在的技能]\'\n' +
|
|
174
|
+
' )\n\n' +
|
|
175
|
+
' local -a list_options\n' +
|
|
176
|
+
' list_options=(\n' +
|
|
177
|
+
' \'--agent[目标 agent]\'\n' +
|
|
178
|
+
' \'{-a,--agent}[目标 agent]\'\n' +
|
|
179
|
+
' )\n\n' +
|
|
180
|
+
' local -a update_options\n' +
|
|
181
|
+
' update_options=(\n' +
|
|
182
|
+
' \'--force[强制更新(即使版本相同)]\'\n' +
|
|
183
|
+
' \'{-f,--force}[强制更新(即使版本相同)]\'\n' +
|
|
184
|
+
' )\n\n' +
|
|
185
|
+
' local -a search_options\n' +
|
|
186
|
+
' search_options=(\n' +
|
|
187
|
+
' \'--page[页码]\'\n' +
|
|
188
|
+
' \'{-p,--page}[页码]\'\n' +
|
|
189
|
+
' \'--limit[每页数量(max: 100)]\'\n' +
|
|
190
|
+
' \'{-l,--limit}[每页数量(max: 100)]\'\n' +
|
|
191
|
+
' \'--sort[排序方式(stars/recent)]\'\n' +
|
|
192
|
+
' \'{-s,--sort}[排序方式(stars/recent)]\'\n' +
|
|
193
|
+
' \'--ai[使用 AI 语义搜索]\'\n' +
|
|
194
|
+
' )\n\n' +
|
|
195
|
+
' local -a cleanup_options\n' +
|
|
196
|
+
' cleanup_options=(\n' +
|
|
197
|
+
' \'--all[清理所有数据(包括配置和技能)]\'\n' +
|
|
198
|
+
' \'{-a,--all}[清理所有数据(包括配置和技能)]\'\n' +
|
|
199
|
+
' )\n\n' +
|
|
200
|
+
' local -a completion_options\n' +
|
|
201
|
+
' completion_options=(\n' +
|
|
202
|
+
' \'--shell[Shell 类型(bash/zsh)]\'\n' +
|
|
203
|
+
' \'{-s,--shell}[Shell 类型(bash/zsh)]\'\n' +
|
|
204
|
+
' )\n\n' +
|
|
205
|
+
' local -a config_commands\n' +
|
|
206
|
+
' config_commands=(\n' +
|
|
207
|
+
' \'set-api-key:设置 API Key\'\n' +
|
|
208
|
+
' \'status:查看配置状态\'\n' +
|
|
209
|
+
' )\n\n' +
|
|
210
|
+
' _arguments -C \\\n' +
|
|
211
|
+
' \'(-g --global)'{-g,--global}\'[使用全局技能目录] \\\n' +
|
|
212
|
+
' \'1: :_eskill_commands\' \\\n' +
|
|
213
|
+
' \'*::arg:->args\'\n\n' +
|
|
214
|
+
' case $words[1] in\n' +
|
|
215
|
+
' install|add)\n' +
|
|
216
|
+
' _describe \'options\' install_options\n' +
|
|
217
|
+
' ;;\n' +
|
|
218
|
+
' remove|rm|uninstall)\n' +
|
|
219
|
+
' local skills=($(eskill _list_skills -g 2>/dev/null))\n' +
|
|
220
|
+
' _alternative \'args:option:(--agent -a)\' \'skills:skills:($skills)\'\n' +
|
|
221
|
+
' ;;\n' +
|
|
222
|
+
' list|ls)\n' +
|
|
223
|
+
' _describe \'options\' list_options\n' +
|
|
224
|
+
' ;;\n' +
|
|
225
|
+
' link)\n' +
|
|
226
|
+
' local skills=($(eskill _list_global_skills 2>/dev/null))\n' +
|
|
227
|
+
' _describe \'global skills\' skills\n' +
|
|
228
|
+
' ;;\n' +
|
|
229
|
+
' upload)\n' +
|
|
230
|
+
' local skills=($(eskill _list_local_skills 2>/dev/null))\n' +
|
|
231
|
+
' _describe \'local skills\' skills\n' +
|
|
232
|
+
' ;;\n' +
|
|
233
|
+
' update)\n' +
|
|
234
|
+
' local skills=($(eskill _list_skills -g 2>/dev/null))\n' +
|
|
235
|
+
' _alternative \'args:options:(--force -f)\' \'skills:skills:(all ${skills})\'\n' +
|
|
236
|
+
' ;;\n' +
|
|
237
|
+
' search)\n' +
|
|
238
|
+
' _describe \'options\' search_options\n' +
|
|
239
|
+
' ;;\n' +
|
|
240
|
+
' cleanup)\n' +
|
|
241
|
+
' _describe \'options\' cleanup_options\n' +
|
|
242
|
+
' ;;\n' +
|
|
243
|
+
' config)\n' +
|
|
244
|
+
' _describe \'actions\' config_commands\n' +
|
|
245
|
+
' ;;\n' +
|
|
246
|
+
' completion)\n' +
|
|
247
|
+
' _describe \'options\' completion_options\n' +
|
|
248
|
+
' ;;\n' +
|
|
249
|
+
' *)\n' +
|
|
250
|
+
' _describe \'command\' commands\n' +
|
|
251
|
+
' ;;\n' +
|
|
252
|
+
' esac\n' +
|
|
253
|
+
'}\n\n' +
|
|
254
|
+
'_eskill_commands() {\n' +
|
|
255
|
+
' local -a commands\n' +
|
|
256
|
+
' commands=(\n' +
|
|
257
|
+
' \'install:从 Git URL 或名称安装技能\'\n' +
|
|
258
|
+
' \'add:安装技能(别名)\'\n' +
|
|
259
|
+
' \'remove:删除已安装的技能\'\n' +
|
|
260
|
+
' \'rm:删除技能(别名)\'\n' +
|
|
261
|
+
' \'uninstall:删除技能(别名)\'\n' +
|
|
262
|
+
' \'update:更新技能\'\n' +
|
|
263
|
+
' \'list:列出已安装的技能\'\n' +
|
|
264
|
+
' \'ls:列出技能(别名)\'\n' +
|
|
265
|
+
' \'link:将全局技能软链接到本地\'\n' +
|
|
266
|
+
' \'upload:上传本地技能到全局仓库\'\n' +
|
|
267
|
+
' \'search:搜索技能\'\n' +
|
|
268
|
+
' \'cleanup:清理技能数据\'\n' +
|
|
269
|
+
' \'config:配置管理\'\n' +
|
|
270
|
+
' \'agents:列出支持的 agents\'\n' +
|
|
271
|
+
' \'completion:生成自动补全脚本\'\n' +
|
|
272
|
+
' \'help:显示帮助信息\'\n' +
|
|
273
|
+
' )\n' +
|
|
274
|
+
' _describe \'command\' commands\n' +
|
|
70
275
|
'}\n\n' +
|
|
71
276
|
'_eskill "$@"\n';
|
|
72
277
|
}
|
|
73
278
|
|
|
74
|
-
//
|
|
279
|
+
// 列出本地技能的内部命令
|
|
280
|
+
export async function listLocalSkillsForCompletion() {
|
|
281
|
+
const skills = await getLocalSkills();
|
|
282
|
+
console.log(skills.join(' '));
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// 列出全局技能的内部命令
|
|
286
|
+
export async function listGlobalSkillsForCompletion() {
|
|
287
|
+
const skills = await getGlobalSkills();
|
|
288
|
+
console.log(skills.join(' '));
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// 列出技能的内部命令(支持 -g 参数)
|
|
75
292
|
export async function listSkillsForCompletion() {
|
|
76
|
-
const
|
|
293
|
+
const args = process.argv.slice(2);
|
|
294
|
+
const global = args.includes('-g') || args.includes('--global');
|
|
295
|
+
const skills = await getSkillList(global);
|
|
77
296
|
console.log(skills.join(' '));
|
|
78
297
|
}
|
package/lib/installer.js
CHANGED
|
@@ -920,18 +920,25 @@ export async function uploadSkill(skillName) {
|
|
|
920
920
|
// 读取本地元数据
|
|
921
921
|
const localMeta = getSkillMeta(actualSkillName, false);
|
|
922
922
|
|
|
923
|
+
// 确定上传后的来源类型
|
|
924
|
+
let uploadSource = 'local'; // 默认为本地创建
|
|
925
|
+
if (localMeta?.source) {
|
|
926
|
+
// 保留原有的来源类型,但 'copied-from-global' 在全局仓库中改为 'github'
|
|
927
|
+
uploadSource = localMeta.source === 'copied-from-global' ? 'github' : localMeta.source;
|
|
928
|
+
}
|
|
929
|
+
|
|
923
930
|
// 保存/更新全局元数据
|
|
924
931
|
if (localMeta) {
|
|
925
932
|
saveSkillMeta(actualSkillName, {
|
|
926
933
|
...localMeta,
|
|
927
|
-
source:
|
|
934
|
+
source: uploadSource,
|
|
928
935
|
updatedAt: new Date().toISOString()
|
|
929
936
|
}, true);
|
|
930
937
|
} else {
|
|
931
938
|
// 如果本地没有元数据,创建基础元数据
|
|
932
939
|
saveSkillMeta(actualSkillName, {
|
|
933
940
|
name: actualSkillName,
|
|
934
|
-
source:
|
|
941
|
+
source: uploadSource,
|
|
935
942
|
installedAt: new Date().toISOString(),
|
|
936
943
|
updatedAt: new Date().toISOString()
|
|
937
944
|
}, true);
|