eskill 1.3.0 → 1.3.2

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 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.0')
16
+ .version('1.3.2')
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
@@ -5,37 +5,91 @@
5
5
  * eskill completion >> ~/.bashrc
6
6
  * eskill completion >> ~/.zshrc
7
7
  */
8
- import { listSkills } from './installer.js';
8
+ import { listSkills, getSkillsDir } from './installer.js';
9
+ import { existsSync } from 'fs';
9
10
  import { getDefaultAgent } from './agent-config.js';
10
11
 
11
12
  // 获取已安装的技能列表
12
- async function getSkillList() {
13
+ async function getSkillList(global = false) {
13
14
  try {
14
15
  const agent = getDefaultAgent();
15
- const skills = await listSkills(agent);
16
+ const skills = await listSkills(agent, global);
16
17
  return skills.map(s => s.name);
17
18
  } catch {
18
19
  return [];
19
20
  }
20
21
  }
21
22
 
23
+ // 获取本地技能列表
24
+ async function getLocalSkills() {
25
+ return await getSkillList(false);
26
+ }
27
+
28
+ // 获取全局技能列表
29
+ async function getGlobalSkills() {
30
+ return await getSkillList(true);
31
+ }
32
+
22
33
  // Bash 补全脚本
23
34
  export function bashCompletionScript() {
24
35
  return '\n_eskill_completion() {\n' +
25
36
  ' local cur prev words cword\n' +
26
37
  ' _init_completion || return\n\n' +
38
+ ' # 检测是否使用了 -g/--global 选项\n' +
39
+ ' local global_mode=""\n' +
40
+ ' for word in "${words[@]}"; do\n' +
41
+ ' if [[ "$word" == "-g" || "$word" == "--global" ]]; then\n' +
42
+ ' global_mode="-g"\n' +
43
+ ' break\n' +
44
+ ' fi\n' +
45
+ ' done\n\n' +
27
46
  ' case ${prev} in\n' +
28
47
  ' remove|rm|uninstall)\n' +
29
- ' local skills=$(eskill _list_skills 2>/dev/null)\n' +
48
+ ' local skills=$(eskill _list_skills ${global_mode} 2>/dev/null)\n' +
49
+ ' COMPREPLY=($(compgen -W "${skills}" -- "${cur}"))\n' +
50
+ ' return\n' +
51
+ ' ;;\n' +
52
+ ' link)\n' +
53
+ ' local skills=$(eskill _list_global_skills 2>/dev/null)\n' +
30
54
  ' COMPREPLY=($(compgen -W "${skills}" -- "${cur}"))\n' +
55
+ ' return\n' +
56
+ ' ;;\n' +
57
+ ' upload)\n' +
58
+ ' local skills=$(eskill _list_local_skills 2>/dev/null)\n' +
59
+ ' COMPREPLY=($(compgen -W "${skills}" -- "${cur}"))\n' +
60
+ ' return\n' +
61
+ ' ;;\n' +
62
+ ' update)\n' +
63
+ ' local skills=$(eskill _list_skills ${global_mode} 2>/dev/null)\n' +
64
+ ' local all="all"\n' +
65
+ ' COMPREPLY=($(compgen -W "${skills} ${all}" -- "${cur}"))\n' +
66
+ ' return\n' +
67
+ ' ;;\n' +
68
+ ' cleanup)\n' +
69
+ ' COMPREPLY=($(compgen -W "--all -a" -- "${cur}"))\n' +
70
+ ' return\n' +
71
+ ' ;;\n' +
72
+ ' search)\n' +
73
+ ' COMPREPLY=($(compgen -W "--page --limit --sort --ai -p -l -s" -- "${cur}"))\n' +
74
+ ' return\n' +
75
+ ' ;;\n' +
76
+ ' config)\n' +
77
+ ' COMPREPLY=($(compgen -W "set-api-key status" -- "${cur}"))\n' +
78
+ ' return\n' +
79
+ ' ;;\n' +
80
+ ' completion)\n' +
81
+ ' COMPREPLY=($(compgen -W "--shell -s" -- "${cur}"))\n' +
82
+ ' return\n' +
31
83
  ' ;;\n' +
32
84
  ' *)\n' +
33
85
  ' case ${cur} in\n' +
34
86
  ' -*)\n' +
35
- ' COMPREPLY=($(compgen -W "-a --agent -l --link -f --force -h --help -V --version" -- "${cur}"))\n' +
87
+ ' COMPREPLY=($(compgen -W "-g --global -h --help -V --version" -- "${cur}"))\n' +
88
+ ' return\n' +
36
89
  ' ;;\n' +
37
90
  ' *)\n' +
38
- ' COMPREPLY=($(compgen -W "install add list ls remove rm uninstall agents list-agents help" -- "${cur}"))\n' +
91
+ ' COMPREPLY=($(compgen -W "install add remove rm uninstall update list ls link upload search cleanup config agents completion help" -- "${cur}"))\n' +
92
+ ' return\n' +
39
93
  ' ;;\n' +
40
94
  ' esac\n' +
41
95
  ' ;;\n' +
@@ -50,29 +104,125 @@ export function zshCompletionScript() {
50
104
  '_eskill() {\n' +
51
105
  ' local -a commands\n' +
52
106
  ' commands=(\n' +
53
- ' \'install:从 Git URL 安装技能\'\n' +
54
- ' \'add:从 Git URL 安装技能(别名)\'\n' +
55
- ' \'list:列出已安装的技能\'\n' +
56
- ' \'ls:列出已安装的技能(别名)\'\n' +
107
+ ' \'install:从 Git URL 或名称安装技能\'\n' +
108
+ ' \'add:安装技能(别名)\'\n' +
57
109
  ' \'remove:删除已安装的技能\'\n' +
58
- ' \'rm:删除已安装的技能(别名)\'\n' +
59
- ' \'uninstall:删除已安装的技能(别名)\'\n' +
110
+ ' \'rm:删除技能(别名)\'\n' +
111
+ ' \'uninstall:删除技能(别名)\'\n' +
112
+ ' \'update:更新技能\'\n' +
113
+ ' \'list:列出已安装的技能\'\n' +
114
+ ' \'ls:列出技能(别名)\'\n' +
115
+ ' \'link:将全局技能软链接到本地\'\n' +
116
+ ' \'upload:上传本地技能到全局仓库\'\n' +
117
+ ' \'search:搜索技能\'\n' +
118
+ ' \'cleanup:清理技能数据\'\n' +
119
+ ' \'config:配置管理\'\n' +
60
120
  ' \'agents:列出支持的 agents\'\n' +
61
- ' \'list-agents:列出支持的 agents(别名)\'\n' +
121
+ ' \'completion:生成自动补全脚本\'\n' +
62
122
  ' \'help:显示帮助信息\'\n' +
63
123
  ' )\n\n' +
64
- ' if [[ ${words[(I)(remove|rm|uninstall)]} -gt 0 ]]; then\n' +
65
- ' local skills=($(eskill _list_skills 2>/dev/null))\n' +
66
- ' _describe \'skills\' skills\n' +
67
- ' else\n' +
68
- ' _describe \'command\' commands\n' +
69
- ' fi\n' +
124
+ ' local -a link_commands\n' +
125
+ ' link_commands=(\n' +
126
+ ' \'--global:使用全局技能目录\'\n' +
127
+ ' \'--help:显示帮助信息\'\n' +
128
+ ' )\n\n' +
129
+ ' local -a update_commands\n' +
130
+ ' update_commands=(\n' +
131
+ ' \'--force:强制更新\'\n' +
132
+ ' \'all:更新所有技能\'\n' +
133
+ ' )\n\n' +
134
+ ' local -a search_commands\n' +
135
+ ' search_commands=(\n' +
136
+ ' \'--page:页码\'\n' +
137
+ ' \'--limit:每页数量\'\n' +
138
+ ' \'--sort:排序方式\'\n' +
139
+ ' \'--ai:AI 语义搜索\'\n' +
140
+ ' )\n\n' +
141
+ ' local -a cleanup_commands\n' +
142
+ ' cleanup_commands=(\n' +
143
+ ' \'--all:清理所有数据\'\n' +
144
+ ' )\n\n' +
145
+ ' local -a config_commands\n' +
146
+ ' config_commands=(\n' +
147
+ ' \'set-api-key:设置 API Key\'\n' +
148
+ ' \'status:查看配置状态\'\n' +
149
+ ' )\n\n' +
150
+ ' _arguments -C \\\n' +
151
+ ' \'(-g --global)'{-g,--global}\'[使用全局技能目录] \\\n' +
152
+ ' \'1: :_eskill_commands\' \\\n' +
153
+ ' \'*::arg:->args\'\n\n' +
154
+ ' case $words[1] in\n' +
155
+ ' remove|rm|uninstall)\n' +
156
+ ' local skills=($(eskill _list_skills -g 2>/dev/null))\n' +
157
+ ' _describe \'skills\' skills\n' +
158
+ ' ;;\n' +
159
+ ' link)\n' +
160
+ ' local skills=($(eskill _list_global_skills 2>/dev/null))\n' +
161
+ ' _describe \'global skills\' skills\n' +
162
+ ' ;;\n' +
163
+ ' upload)\n' +
164
+ ' local skills=($(eskill _list_local_skills 2>/dev/null))\n' +
165
+ ' _describe \'local skills\' skills\n' +
166
+ ' ;;\n' +
167
+ ' update)\n' +
168
+ ' local skills=($(eskill _list_skills -g 2>/dev/null))\n' +
169
+ ' _values "skills" ${skills} "all"\n' +
170
+ ' ;;\n' +
171
+ ' search)\n' +
172
+ ' _describe \'options\' search_commands\n' +
173
+ ' ;;\n' +
174
+ ' cleanup)\n' +
175
+ ' _describe \'options\' cleanup_commands\n' +
176
+ ' ;;\n' +
177
+ ' config)\n' +
178
+ ' _describe \'actions\' config_commands\n' +
179
+ ' ;;\n' +
180
+ ' *)\n' +
181
+ ' _describe \'command\' commands\n' +
182
+ ' ;;\n' +
183
+ ' esac\n' +
184
+ '}\n\n' +
185
+ '_eskill_commands() {\n' +
186
+ ' local -a commands\n' +
187
+ ' commands=(\n' +
188
+ ' \'install:从 Git URL 或名称安装技能\'\n' +
189
+ ' \'add:安装技能(别名)\'\n' +
190
+ ' \'remove:删除已安装的技能\'\n' +
191
+ ' \'rm:删除技能(别名)\'\n' +
192
+ ' \'uninstall:删除技能(别名)\'\n' +
193
+ ' \'update:更新技能\'\n' +
194
+ ' \'list:列出已安装的技能\'\n' +
195
+ ' \'ls:列出技能(别名)\'\n' +
196
+ ' \'link:将全局技能软链接到本地\'\n' +
197
+ ' \'upload:上传本地技能到全局仓库\'\n' +
198
+ ' \'search:搜索技能\'\n' +
199
+ ' \'cleanup:清理技能数据\'\n' +
200
+ ' \'config:配置管理\'\n' +
201
+ ' \'agents:列出支持的 agents\'\n' +
202
+ ' \'completion:生成自动补全脚本\'\n' +
203
+ ' \'help:显示帮助信息\'\n' +
204
+ ' )\n' +
205
+ ' _describe \'command\' commands\n' +
70
206
  '}\n\n' +
71
207
  '_eskill "$@"\n';
72
208
  }
73
209
 
74
- // 列出技能的内部命令
210
+ // 列出本地技能的内部命令
211
+ export async function listLocalSkillsForCompletion() {
212
+ const skills = await getLocalSkills();
213
+ console.log(skills.join(' '));
214
+ }
215
+
216
+ // 列出全局技能的内部命令
217
+ export async function listGlobalSkillsForCompletion() {
218
+ const skills = await getGlobalSkills();
219
+ console.log(skills.join(' '));
220
+ }
221
+
222
+ // 列出技能的内部命令(支持 -g 参数)
75
223
  export async function listSkillsForCompletion() {
76
- const skills = await getSkillList();
224
+ const args = process.argv.slice(2);
225
+ const global = args.includes('-g') || args.includes('--global');
226
+ const skills = await getSkillList(global);
77
227
  console.log(skills.join(' '));
78
228
  }
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: 'github', // 上传到全局后,来源标记为 github
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: 'github',
941
+ source: uploadSource,
935
942
  installedAt: new Date().toISOString(),
936
943
  updatedAt: new Date().toISOString()
937
944
  }, true);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eskill",
3
- "version": "1.3.0",
3
+ "version": "1.3.2",
4
4
  "description": "Unified AI Agent Skills Management - Install skills from Git URLs",
5
5
  "main": "index.js",
6
6
  "type": "module",