eskill 1.2.4 → 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 +38 -3
- package/lib/completion.js +171 -21
- package/lib/installer.js +110 -0
- package/package.json +1 -1
package/cli.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Command } from 'commander';
|
|
3
3
|
import ora from 'ora';
|
|
4
|
-
import { installFromGitUrl, listSkills, removeSkill, linkSkill, cleanupAllSkills, cleanupAll, updateSkill, updateAllSkills } from './lib/installer.js';
|
|
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.2
|
|
16
|
+
.version('1.3.2')
|
|
17
17
|
.option('-g, --global', '使用全局技能目录(~/.eskill/skills/),否则使用当前目录(./.claude/skills/)', false);
|
|
18
18
|
|
|
19
19
|
// 安装命令
|
|
@@ -141,6 +141,25 @@ program
|
|
|
141
141
|
}
|
|
142
142
|
});
|
|
143
143
|
|
|
144
|
+
// 上传命令
|
|
145
|
+
program
|
|
146
|
+
.command('upload')
|
|
147
|
+
.description('上传本地技能到全局仓库')
|
|
148
|
+
.argument('<name>', '技能名称(支持 name@author 格式)')
|
|
149
|
+
.action(async (name) => {
|
|
150
|
+
try {
|
|
151
|
+
const result = await uploadSkill(name);
|
|
152
|
+
|
|
153
|
+
// 如果用户取消上传,正常退出
|
|
154
|
+
if (result && result.cancelled) {
|
|
155
|
+
process.exit(0);
|
|
156
|
+
}
|
|
157
|
+
} catch (error) {
|
|
158
|
+
console.error(`\n❌ 上传失败: ${error.message}`);
|
|
159
|
+
process.exit(1);
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
|
|
144
163
|
// 更新命令
|
|
145
164
|
program
|
|
146
165
|
.command('update')
|
|
@@ -412,4 +431,20 @@ program
|
|
|
412
431
|
await listSkillsForCompletion();
|
|
413
432
|
});
|
|
414
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
|
+
|
|
415
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 "-
|
|
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
|
|
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
|
|
54
|
-
' \'add
|
|
55
|
-
' \'list:列出已安装的技能\'\n' +
|
|
56
|
-
' \'ls:列出已安装的技能(别名)\'\n' +
|
|
107
|
+
' \'install:从 Git URL 或名称安装技能\'\n' +
|
|
108
|
+
' \'add:安装技能(别名)\'\n' +
|
|
57
109
|
' \'remove:删除已安装的技能\'\n' +
|
|
58
|
-
' \'rm
|
|
59
|
-
' \'uninstall
|
|
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
|
-
' \'
|
|
121
|
+
' \'completion:生成自动补全脚本\'\n' +
|
|
62
122
|
' \'help:显示帮助信息\'\n' +
|
|
63
123
|
' )\n\n' +
|
|
64
|
-
'
|
|
65
|
-
'
|
|
66
|
-
'
|
|
67
|
-
'
|
|
68
|
-
'
|
|
69
|
-
'
|
|
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
|
|
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
|
@@ -842,6 +842,116 @@ export async function linkSkill(skillName) {
|
|
|
842
842
|
}
|
|
843
843
|
}
|
|
844
844
|
|
|
845
|
+
/**
|
|
846
|
+
* 上传本地技能到全局仓库
|
|
847
|
+
*/
|
|
848
|
+
export async function uploadSkill(skillName) {
|
|
849
|
+
// 解析 skill-name@author 格式,提取实际技能名
|
|
850
|
+
let actualSkillName = skillName;
|
|
851
|
+
const match = skillName.match(/^([^@]+)@([^@]+)$/);
|
|
852
|
+
if (match) {
|
|
853
|
+
actualSkillName = match[1];
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
const localSkillsDir = getSkillsDir(false);
|
|
857
|
+
const globalSkillsDir = getSkillsDir(true);
|
|
858
|
+
|
|
859
|
+
const localSkillPath = join(localSkillsDir, actualSkillName);
|
|
860
|
+
const globalSkillPath = join(globalSkillsDir, actualSkillName);
|
|
861
|
+
|
|
862
|
+
// 检查本地是否存在该技能
|
|
863
|
+
if (!existsSync(localSkillPath)) {
|
|
864
|
+
console.log(`\n❌ 本地不存在技能: ${actualSkillName}`);
|
|
865
|
+
console.log(` 位置: ${localSkillPath}\n`);
|
|
866
|
+
console.log(`💡 提示:`);
|
|
867
|
+
console.log(` - 使用 "eskill list" 查看本地已安装的技能`);
|
|
868
|
+
console.log(` - 使用 "eskill install" 先安装技能到本地\n`);
|
|
869
|
+
throw new Error(`本地不存在技能: ${actualSkillName}`);
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
// 检查是否为符号链接
|
|
873
|
+
try {
|
|
874
|
+
const stat = lstatSync(localSkillPath);
|
|
875
|
+
if (stat.isSymbolicLink()) {
|
|
876
|
+
console.log(`\n❌ 无法上传软链接技能: ${actualSkillName}`);
|
|
877
|
+
console.log(` 软链接指向全局仓库,无法上传\n`);
|
|
878
|
+
console.log(`💡 提示:`);
|
|
879
|
+
console.log(` - 软链接技能已经存在于全局仓库`);
|
|
880
|
+
console.log(` - 如需更新全局技能,请直接在全局仓库中使用 eskill update\n`);
|
|
881
|
+
throw new Error(`无法上传软链接技能`);
|
|
882
|
+
}
|
|
883
|
+
} catch (error) {
|
|
884
|
+
console.error(`检测技能类型失败: ${error.message}`);
|
|
885
|
+
throw error;
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
// 确保全局技能目录存在
|
|
889
|
+
if (!existsSync(globalSkillsDir)) {
|
|
890
|
+
mkdirSync(globalSkillsDir, { recursive: true });
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
// 检查全局是否已存在同名技能
|
|
894
|
+
if (existsSync(globalSkillPath)) {
|
|
895
|
+
console.log(`\n⚠️ 全局仓库已存在同名技能: ${actualSkillName}`);
|
|
896
|
+
console.log(` 位置: ${globalSkillPath}\n`);
|
|
897
|
+
|
|
898
|
+
const overwrite = await confirmAction('是否覆盖全局仓库中的技能?');
|
|
899
|
+
if (!overwrite) {
|
|
900
|
+
console.log('\n已取消上传\n');
|
|
901
|
+
return { success: false, cancelled: true };
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
console.log(`删除全局仓库中已存在的技能: ${globalSkillPath}`);
|
|
905
|
+
rmSync(globalSkillPath, { recursive: true, force: true });
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
// 复制技能到全局仓库
|
|
909
|
+
console.log(`\n上传技能到全局仓库: ${actualSkillName}`);
|
|
910
|
+
console.log(` 源: ${localSkillPath}`);
|
|
911
|
+
console.log(` 目标: ${globalSkillPath}\n`);
|
|
912
|
+
|
|
913
|
+
// 使用 -L 选项解引用符号链接
|
|
914
|
+
if (process.platform === 'win32') {
|
|
915
|
+
execSync(`xcopy "${localSkillPath}" "${globalSkillPath}" /E /I /H /Y`, { stdio: 'inherit' });
|
|
916
|
+
} else {
|
|
917
|
+
execSync(`cp -rL "${localSkillPath}" "${globalSkillPath}"`, { stdio: 'inherit' });
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
// 读取本地元数据
|
|
921
|
+
const localMeta = getSkillMeta(actualSkillName, false);
|
|
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
|
+
|
|
930
|
+
// 保存/更新全局元数据
|
|
931
|
+
if (localMeta) {
|
|
932
|
+
saveSkillMeta(actualSkillName, {
|
|
933
|
+
...localMeta,
|
|
934
|
+
source: uploadSource,
|
|
935
|
+
updatedAt: new Date().toISOString()
|
|
936
|
+
}, true);
|
|
937
|
+
} else {
|
|
938
|
+
// 如果本地没有元数据,创建基础元数据
|
|
939
|
+
saveSkillMeta(actualSkillName, {
|
|
940
|
+
name: actualSkillName,
|
|
941
|
+
source: uploadSource,
|
|
942
|
+
installedAt: new Date().toISOString(),
|
|
943
|
+
updatedAt: new Date().toISOString()
|
|
944
|
+
}, true);
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
console.log(`\n✓ 技能已上传到全局仓库`);
|
|
948
|
+
console.log(` 技能: ${actualSkillName}`);
|
|
949
|
+
console.log(` 全局位置: ${globalSkillPath}`);
|
|
950
|
+
console.log(` 说明: 技现已可在全局仓库中使用\n`);
|
|
951
|
+
|
|
952
|
+
return { success: true, path: globalSkillPath };
|
|
953
|
+
}
|
|
954
|
+
|
|
845
955
|
/**
|
|
846
956
|
* 清理所有技能(用于卸载)
|
|
847
957
|
*/
|