eskill 1.2.1 → 1.2.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 +2 -2
- package/lib/installer.js +30 -12
- package/package.json +1 -1
package/cli.js
CHANGED
|
@@ -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.2.3')
|
|
17
17
|
.option('-g, --global', '使用全局技能目录(~/.eskill/skills/),否则使用当前目录(./.claude/skills/)', false);
|
|
18
18
|
|
|
19
19
|
// 安装命令
|
|
@@ -126,7 +126,7 @@ program
|
|
|
126
126
|
program
|
|
127
127
|
.command('link')
|
|
128
128
|
.description('将全局技能软链接到本地')
|
|
129
|
-
.argument('<name>', '
|
|
129
|
+
.argument('<name>', '技能名称(支持 name@author 格式)')
|
|
130
130
|
.action(async (name) => {
|
|
131
131
|
try {
|
|
132
132
|
const result = await linkSkill(name);
|
package/lib/installer.js
CHANGED
|
@@ -485,9 +485,11 @@ function confirmAction(message) {
|
|
|
485
485
|
export async function installFromGitUrl(gitUrl, options = {}) {
|
|
486
486
|
const { agent = 'claude', link = false, force = false, global = false } = options;
|
|
487
487
|
|
|
488
|
+
let actualUrl;
|
|
489
|
+
|
|
488
490
|
try {
|
|
489
491
|
// 检测并处理 name@author 格式
|
|
490
|
-
|
|
492
|
+
actualUrl = await handleSkillAtAuthorFormat(gitUrl, global);
|
|
491
493
|
|
|
492
494
|
// 如果是从全局复制
|
|
493
495
|
if (actualUrl.startsWith('GLOBAL:')) {
|
|
@@ -742,20 +744,27 @@ export function removeSkill(skillName, agent = 'claude', global = false) {
|
|
|
742
744
|
* 链接全局技能到本地
|
|
743
745
|
*/
|
|
744
746
|
export async function linkSkill(skillName) {
|
|
747
|
+
// 解析 skill-name@author 格式,提取实际技能名
|
|
748
|
+
let actualSkillName = skillName;
|
|
749
|
+
const match = skillName.match(/^([^@]+)@([^@]+)$/);
|
|
750
|
+
if (match) {
|
|
751
|
+
actualSkillName = match[1];
|
|
752
|
+
}
|
|
753
|
+
|
|
745
754
|
const globalSkillsDir = getSkillsDir(true);
|
|
746
755
|
const localSkillsDir = getSkillsDir(false);
|
|
747
756
|
|
|
748
|
-
const globalSkillPath = join(globalSkillsDir,
|
|
749
|
-
const localSkillPath = join(localSkillsDir,
|
|
757
|
+
const globalSkillPath = join(globalSkillsDir, actualSkillName);
|
|
758
|
+
const localSkillPath = join(localSkillsDir, actualSkillName);
|
|
750
759
|
|
|
751
760
|
// 检查全局是否存在该技能
|
|
752
761
|
if (!existsSync(globalSkillPath)) {
|
|
753
|
-
console.log(`\n❌ 全局仓库中不存在技能: ${
|
|
754
|
-
console.log(` 位置: ~/.eskill/skills/${
|
|
762
|
+
console.log(`\n❌ 全局仓库中不存在技能: ${actualSkillName}`);
|
|
763
|
+
console.log(` 位置: ~/.eskill/skills/${actualSkillName}\n`);
|
|
755
764
|
console.log(`💡 提示:`);
|
|
756
765
|
console.log(` - 使用 "eskill install -g ${skillName}" 先安装到全局仓库`);
|
|
757
766
|
console.log(` - 或使用 "eskill install" 直接安装到本地\n`);
|
|
758
|
-
throw new Error(`全局仓库中不存在技能: ${
|
|
767
|
+
throw new Error(`全局仓库中不存在技能: ${actualSkillName}`);
|
|
759
768
|
}
|
|
760
769
|
|
|
761
770
|
// 检查本地技能目录是否存在
|
|
@@ -775,7 +784,7 @@ export async function linkSkill(skillName) {
|
|
|
775
784
|
|
|
776
785
|
// 检查本地是否已存在同名技能
|
|
777
786
|
if (existsSync(localSkillPath)) {
|
|
778
|
-
console.log(`\n⚠️ 本地已存在同名技能: ${
|
|
787
|
+
console.log(`\n⚠️ 本地已存在同名技能: ${actualSkillName}`);
|
|
779
788
|
console.log(` 位置: ${localSkillPath}\n`);
|
|
780
789
|
|
|
781
790
|
const overwrite = await confirmAction('是否删除本地技能并创建软链接?');
|
|
@@ -797,15 +806,15 @@ export async function linkSkill(skillName) {
|
|
|
797
806
|
symlinkSync(globalSkillPath, localSkillPath, 'dir');
|
|
798
807
|
|
|
799
808
|
console.log(`✓ 软链接创建成功`);
|
|
800
|
-
console.log(` 技能: ${
|
|
809
|
+
console.log(` 技能: ${actualSkillName}`);
|
|
801
810
|
console.log(` 本地路径: ${localSkillPath}`);
|
|
802
811
|
console.log(` 全局路径: ${globalSkillPath}`);
|
|
803
812
|
console.log(` 说明: 本地技能指向全局仓库,全局更新会自动同步\n`);
|
|
804
813
|
|
|
805
814
|
// 保存元数据,标记来源为软链接
|
|
806
|
-
const globalMeta = getSkillMeta(
|
|
815
|
+
const globalMeta = getSkillMeta(actualSkillName, true);
|
|
807
816
|
if (globalMeta) {
|
|
808
|
-
saveSkillMeta(
|
|
817
|
+
saveSkillMeta(actualSkillName, {
|
|
809
818
|
...globalMeta,
|
|
810
819
|
source: 'symlink',
|
|
811
820
|
installedAt: new Date().toISOString(),
|
|
@@ -813,8 +822,8 @@ export async function linkSkill(skillName) {
|
|
|
813
822
|
}, false);
|
|
814
823
|
} else {
|
|
815
824
|
// 如果全局没有元数据,创建基础元数据
|
|
816
|
-
saveSkillMeta(
|
|
817
|
-
name:
|
|
825
|
+
saveSkillMeta(actualSkillName, {
|
|
826
|
+
name: actualSkillName,
|
|
818
827
|
source: 'symlink',
|
|
819
828
|
installedAt: new Date().toISOString(),
|
|
820
829
|
updatedAt: new Date().toISOString()
|
|
@@ -845,6 +854,15 @@ export function cleanupAllSkills(global = false) {
|
|
|
845
854
|
console.error(`清理失败: ${error.message}`);
|
|
846
855
|
throw error;
|
|
847
856
|
}
|
|
857
|
+
|
|
858
|
+
// 清空元数据文件
|
|
859
|
+
try {
|
|
860
|
+
saveAllSkillsMeta([], global);
|
|
861
|
+
const metaLocation = global ? '~/.eskill/skills/.eskill-meta.json' : './.eskill-meta.json';
|
|
862
|
+
console.log(`✓ 已清空元数据: ${metaLocation}`);
|
|
863
|
+
} catch (error) {
|
|
864
|
+
console.error(`清空元数据失败: ${error.message}`);
|
|
865
|
+
}
|
|
848
866
|
}
|
|
849
867
|
|
|
850
868
|
/**
|