reskill 0.1.0 → 0.11.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/README.md +161 -104
- package/README.zh-CN.md +257 -0
- package/dist/cli/commands/install.d.ts +11 -3
- package/dist/cli/commands/install.d.ts.map +1 -1
- package/dist/cli/index.js +658 -46
- package/dist/core/agent-registry.d.ts +54 -0
- package/dist/core/agent-registry.d.ts.map +1 -0
- package/dist/core/cache-manager.d.ts +4 -0
- package/dist/core/cache-manager.d.ts.map +1 -1
- package/dist/core/config-loader.d.ts.map +1 -1
- package/dist/core/index.d.ts +6 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/installer.d.ts +96 -0
- package/dist/core/installer.d.ts.map +1 -0
- package/dist/core/skill-manager.d.ts +41 -0
- package/dist/core/skill-manager.d.ts.map +1 -1
- package/dist/core/skill-parser.d.ts +116 -0
- package/dist/core/skill-parser.d.ts.map +1 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +596 -2
- package/dist/types/index.d.ts +23 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/fs.d.ts +30 -0
- package/dist/utils/fs.d.ts.map +1 -1
- package/package.json +12 -2
package/dist/index.js
CHANGED
|
@@ -3,6 +3,9 @@ import * as __WEBPACK_EXTERNAL_MODULE_semver__ from "semver";
|
|
|
3
3
|
import * as __WEBPACK_EXTERNAL_MODULE_node_child_process__ from "node:child_process";
|
|
4
4
|
import * as __WEBPACK_EXTERNAL_MODULE_node_util__ from "node:util";
|
|
5
5
|
import * as __WEBPACK_EXTERNAL_MODULE_node_path__ from "node:path";
|
|
6
|
+
import * as __WEBPACK_EXTERNAL_MODULE_os__ from "os";
|
|
7
|
+
import * as __WEBPACK_EXTERNAL_MODULE_path__ from "path";
|
|
8
|
+
import * as __WEBPACK_EXTERNAL_MODULE_fs__ from "fs";
|
|
6
9
|
import * as __WEBPACK_EXTERNAL_MODULE_chalk__ from "chalk";
|
|
7
10
|
var __webpack_modules__ = {
|
|
8
11
|
"node:fs": function(module) {
|
|
@@ -441,6 +444,36 @@ function getGlobalSkillsDir() {
|
|
|
441
444
|
const home = getHomeDir();
|
|
442
445
|
return __WEBPACK_EXTERNAL_MODULE_node_path__.join(home, '.claude', 'skills');
|
|
443
446
|
}
|
|
447
|
+
const AGENTS_DIR = '.agents';
|
|
448
|
+
const SKILLS_SUBDIR = 'skills';
|
|
449
|
+
function getCanonicalSkillsDir(options = {}) {
|
|
450
|
+
const { global: isGlobal = false, cwd } = options;
|
|
451
|
+
const baseDir = isGlobal ? getHomeDir() : cwd || process.cwd();
|
|
452
|
+
return __WEBPACK_EXTERNAL_MODULE_node_path__.join(baseDir, AGENTS_DIR, SKILLS_SUBDIR);
|
|
453
|
+
}
|
|
454
|
+
function getCanonicalSkillPath(skillName, options = {}) {
|
|
455
|
+
return __WEBPACK_EXTERNAL_MODULE_node_path__.join(getCanonicalSkillsDir(options), skillName);
|
|
456
|
+
}
|
|
457
|
+
function shortenPath(fullPath, cwd) {
|
|
458
|
+
const home = getHomeDir();
|
|
459
|
+
const currentDir = cwd || process.cwd();
|
|
460
|
+
if (fullPath.startsWith(home)) return fullPath.replace(home, '~');
|
|
461
|
+
if (fullPath.startsWith(currentDir)) return '.' + fullPath.slice(currentDir.length);
|
|
462
|
+
return fullPath;
|
|
463
|
+
}
|
|
464
|
+
function isPathSafe(basePath, targetPath) {
|
|
465
|
+
const normalizedBase = __WEBPACK_EXTERNAL_MODULE_node_path__.normalize(__WEBPACK_EXTERNAL_MODULE_node_path__.resolve(basePath));
|
|
466
|
+
const normalizedTarget = __WEBPACK_EXTERNAL_MODULE_node_path__.normalize(__WEBPACK_EXTERNAL_MODULE_node_path__.resolve(targetPath));
|
|
467
|
+
return normalizedTarget.startsWith(normalizedBase + __WEBPACK_EXTERNAL_MODULE_node_path__.sep) || normalizedTarget === normalizedBase;
|
|
468
|
+
}
|
|
469
|
+
function sanitizeName(name) {
|
|
470
|
+
let sanitized = name.replace(/[/\\:\0]/g, '');
|
|
471
|
+
sanitized = sanitized.replace(/^[.\s]+|[.\s]+$/g, '');
|
|
472
|
+
sanitized = sanitized.replace(/^\.+/, '');
|
|
473
|
+
if (!sanitized || 0 === sanitized.length) sanitized = 'unnamed-skill';
|
|
474
|
+
if (sanitized.length > 255) sanitized = sanitized.substring(0, 255);
|
|
475
|
+
return sanitized;
|
|
476
|
+
}
|
|
444
477
|
class CacheManager {
|
|
445
478
|
cacheDir;
|
|
446
479
|
constructor(cacheDir){
|
|
@@ -452,6 +485,9 @@ class CacheManager {
|
|
|
452
485
|
getSkillCachePath(parsed, version) {
|
|
453
486
|
return __WEBPACK_EXTERNAL_MODULE_node_path__.join(this.cacheDir, parsed.registry, parsed.owner, parsed.repo, version);
|
|
454
487
|
}
|
|
488
|
+
getCachePath(parsed, version) {
|
|
489
|
+
return this.getSkillCachePath(parsed, version);
|
|
490
|
+
}
|
|
455
491
|
isCached(parsed, version) {
|
|
456
492
|
const cachePath = this.getSkillCachePath(parsed, version);
|
|
457
493
|
return exists(cachePath) && isDirectory(cachePath);
|
|
@@ -614,7 +650,9 @@ class ConfigLoader {
|
|
|
614
650
|
const config = this.config || (this.exists() ? this.load() : DEFAULT_SKILLS_JSON);
|
|
615
651
|
return {
|
|
616
652
|
registry: config.defaults?.registry || DEFAULT_SKILLS_JSON.defaults.registry,
|
|
617
|
-
installDir: config.defaults?.installDir || DEFAULT_SKILLS_JSON.defaults.installDir
|
|
653
|
+
installDir: config.defaults?.installDir || DEFAULT_SKILLS_JSON.defaults.installDir,
|
|
654
|
+
targetAgents: config.defaults?.targetAgents || [],
|
|
655
|
+
installMode: config.defaults?.installMode || 'symlink'
|
|
618
656
|
};
|
|
619
657
|
}
|
|
620
658
|
getRegistryUrl(registryName) {
|
|
@@ -759,6 +797,341 @@ class LockManager {
|
|
|
759
797
|
this.lockData = null;
|
|
760
798
|
}
|
|
761
799
|
}
|
|
800
|
+
const agent_registry_home = (0, __WEBPACK_EXTERNAL_MODULE_os__.homedir)();
|
|
801
|
+
const agents = {
|
|
802
|
+
amp: {
|
|
803
|
+
name: 'amp',
|
|
804
|
+
displayName: 'Amp',
|
|
805
|
+
skillsDir: '.agents/skills',
|
|
806
|
+
globalSkillsDir: (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.config/agents/skills'),
|
|
807
|
+
detectInstalled: async ()=>(0, __WEBPACK_EXTERNAL_MODULE_fs__.existsSync)((0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.config/amp'))
|
|
808
|
+
},
|
|
809
|
+
antigravity: {
|
|
810
|
+
name: 'antigravity',
|
|
811
|
+
displayName: 'Antigravity',
|
|
812
|
+
skillsDir: '.agent/skills',
|
|
813
|
+
globalSkillsDir: (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.gemini/antigravity/skills'),
|
|
814
|
+
detectInstalled: async ()=>(0, __WEBPACK_EXTERNAL_MODULE_fs__.existsSync)((0, __WEBPACK_EXTERNAL_MODULE_path__.join)(process.cwd(), '.agent')) || (0, __WEBPACK_EXTERNAL_MODULE_fs__.existsSync)((0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.gemini/antigravity'))
|
|
815
|
+
},
|
|
816
|
+
'claude-code': {
|
|
817
|
+
name: 'claude-code',
|
|
818
|
+
displayName: 'Claude Code',
|
|
819
|
+
skillsDir: '.claude/skills',
|
|
820
|
+
globalSkillsDir: (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.claude/skills'),
|
|
821
|
+
detectInstalled: async ()=>(0, __WEBPACK_EXTERNAL_MODULE_fs__.existsSync)((0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.claude'))
|
|
822
|
+
},
|
|
823
|
+
clawdbot: {
|
|
824
|
+
name: 'clawdbot',
|
|
825
|
+
displayName: 'Clawdbot',
|
|
826
|
+
skillsDir: 'skills',
|
|
827
|
+
globalSkillsDir: (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.clawdbot/skills'),
|
|
828
|
+
detectInstalled: async ()=>(0, __WEBPACK_EXTERNAL_MODULE_fs__.existsSync)((0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.clawdbot'))
|
|
829
|
+
},
|
|
830
|
+
codex: {
|
|
831
|
+
name: 'codex',
|
|
832
|
+
displayName: 'Codex',
|
|
833
|
+
skillsDir: '.codex/skills',
|
|
834
|
+
globalSkillsDir: (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.codex/skills'),
|
|
835
|
+
detectInstalled: async ()=>(0, __WEBPACK_EXTERNAL_MODULE_fs__.existsSync)((0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.codex'))
|
|
836
|
+
},
|
|
837
|
+
cursor: {
|
|
838
|
+
name: 'cursor',
|
|
839
|
+
displayName: 'Cursor',
|
|
840
|
+
skillsDir: '.cursor/skills',
|
|
841
|
+
globalSkillsDir: (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.cursor/skills'),
|
|
842
|
+
detectInstalled: async ()=>(0, __WEBPACK_EXTERNAL_MODULE_fs__.existsSync)((0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.cursor'))
|
|
843
|
+
},
|
|
844
|
+
droid: {
|
|
845
|
+
name: 'droid',
|
|
846
|
+
displayName: 'Droid',
|
|
847
|
+
skillsDir: '.factory/skills',
|
|
848
|
+
globalSkillsDir: (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.factory/skills'),
|
|
849
|
+
detectInstalled: async ()=>(0, __WEBPACK_EXTERNAL_MODULE_fs__.existsSync)((0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.factory/skills'))
|
|
850
|
+
},
|
|
851
|
+
'gemini-cli': {
|
|
852
|
+
name: 'gemini-cli',
|
|
853
|
+
displayName: 'Gemini CLI',
|
|
854
|
+
skillsDir: '.gemini/skills',
|
|
855
|
+
globalSkillsDir: (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.gemini/skills'),
|
|
856
|
+
detectInstalled: async ()=>(0, __WEBPACK_EXTERNAL_MODULE_fs__.existsSync)((0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.gemini'))
|
|
857
|
+
},
|
|
858
|
+
'github-copilot': {
|
|
859
|
+
name: 'github-copilot',
|
|
860
|
+
displayName: 'GitHub Copilot',
|
|
861
|
+
skillsDir: '.github/skills',
|
|
862
|
+
globalSkillsDir: (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.copilot/skills'),
|
|
863
|
+
detectInstalled: async ()=>(0, __WEBPACK_EXTERNAL_MODULE_fs__.existsSync)((0, __WEBPACK_EXTERNAL_MODULE_path__.join)(process.cwd(), '.github')) || (0, __WEBPACK_EXTERNAL_MODULE_fs__.existsSync)((0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.copilot'))
|
|
864
|
+
},
|
|
865
|
+
goose: {
|
|
866
|
+
name: 'goose',
|
|
867
|
+
displayName: 'Goose',
|
|
868
|
+
skillsDir: '.goose/skills',
|
|
869
|
+
globalSkillsDir: (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.config/goose/skills'),
|
|
870
|
+
detectInstalled: async ()=>(0, __WEBPACK_EXTERNAL_MODULE_fs__.existsSync)((0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.config/goose'))
|
|
871
|
+
},
|
|
872
|
+
kilo: {
|
|
873
|
+
name: 'kilo',
|
|
874
|
+
displayName: 'Kilo Code',
|
|
875
|
+
skillsDir: '.kilocode/skills',
|
|
876
|
+
globalSkillsDir: (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.kilocode/skills'),
|
|
877
|
+
detectInstalled: async ()=>(0, __WEBPACK_EXTERNAL_MODULE_fs__.existsSync)((0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.kilocode'))
|
|
878
|
+
},
|
|
879
|
+
'kiro-cli': {
|
|
880
|
+
name: 'kiro-cli',
|
|
881
|
+
displayName: 'Kiro CLI',
|
|
882
|
+
skillsDir: '.kiro/skills',
|
|
883
|
+
globalSkillsDir: (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.kiro/skills'),
|
|
884
|
+
detectInstalled: async ()=>(0, __WEBPACK_EXTERNAL_MODULE_fs__.existsSync)((0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.kiro'))
|
|
885
|
+
},
|
|
886
|
+
opencode: {
|
|
887
|
+
name: 'opencode',
|
|
888
|
+
displayName: 'OpenCode',
|
|
889
|
+
skillsDir: '.opencode/skills',
|
|
890
|
+
globalSkillsDir: (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.config/opencode/skills'),
|
|
891
|
+
detectInstalled: async ()=>(0, __WEBPACK_EXTERNAL_MODULE_fs__.existsSync)((0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.config/opencode')) || (0, __WEBPACK_EXTERNAL_MODULE_fs__.existsSync)((0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.claude/skills'))
|
|
892
|
+
},
|
|
893
|
+
roo: {
|
|
894
|
+
name: 'roo',
|
|
895
|
+
displayName: 'Roo Code',
|
|
896
|
+
skillsDir: '.roo/skills',
|
|
897
|
+
globalSkillsDir: (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.roo/skills'),
|
|
898
|
+
detectInstalled: async ()=>(0, __WEBPACK_EXTERNAL_MODULE_fs__.existsSync)((0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.roo'))
|
|
899
|
+
},
|
|
900
|
+
trae: {
|
|
901
|
+
name: 'trae',
|
|
902
|
+
displayName: 'Trae',
|
|
903
|
+
skillsDir: '.trae/skills',
|
|
904
|
+
globalSkillsDir: (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.trae/skills'),
|
|
905
|
+
detectInstalled: async ()=>(0, __WEBPACK_EXTERNAL_MODULE_fs__.existsSync)((0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.trae'))
|
|
906
|
+
},
|
|
907
|
+
windsurf: {
|
|
908
|
+
name: 'windsurf',
|
|
909
|
+
displayName: 'Windsurf',
|
|
910
|
+
skillsDir: '.windsurf/skills',
|
|
911
|
+
globalSkillsDir: (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.codeium/windsurf/skills'),
|
|
912
|
+
detectInstalled: async ()=>(0, __WEBPACK_EXTERNAL_MODULE_fs__.existsSync)((0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.codeium/windsurf'))
|
|
913
|
+
},
|
|
914
|
+
neovate: {
|
|
915
|
+
name: 'neovate',
|
|
916
|
+
displayName: 'Neovate',
|
|
917
|
+
skillsDir: '.neovate/skills',
|
|
918
|
+
globalSkillsDir: (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.neovate/skills'),
|
|
919
|
+
detectInstalled: async ()=>(0, __WEBPACK_EXTERNAL_MODULE_fs__.existsSync)((0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.neovate'))
|
|
920
|
+
}
|
|
921
|
+
};
|
|
922
|
+
function getAllAgentTypes() {
|
|
923
|
+
return Object.keys(agents);
|
|
924
|
+
}
|
|
925
|
+
async function detectInstalledAgents() {
|
|
926
|
+
const installed = [];
|
|
927
|
+
for (const [type, config] of Object.entries(agents))if (await config.detectInstalled()) installed.push(type);
|
|
928
|
+
return installed;
|
|
929
|
+
}
|
|
930
|
+
function getAgentConfig(type) {
|
|
931
|
+
return agents[type];
|
|
932
|
+
}
|
|
933
|
+
function isValidAgentType(type) {
|
|
934
|
+
return type in agents;
|
|
935
|
+
}
|
|
936
|
+
function getAgentSkillsDir(type, options = {}) {
|
|
937
|
+
const config = agents[type];
|
|
938
|
+
if (options.global) return config.globalSkillsDir;
|
|
939
|
+
const cwd = options.cwd || process.cwd();
|
|
940
|
+
return (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(cwd, config.skillsDir);
|
|
941
|
+
}
|
|
942
|
+
const installer_AGENTS_DIR = '.agents';
|
|
943
|
+
const installer_SKILLS_SUBDIR = 'skills';
|
|
944
|
+
function installer_sanitizeName(name) {
|
|
945
|
+
let sanitized = name.replace(/[/\\:\0]/g, '');
|
|
946
|
+
sanitized = sanitized.replace(/^[.\s]+|[.\s]+$/g, '');
|
|
947
|
+
sanitized = sanitized.replace(/^\.+/, '');
|
|
948
|
+
if (!sanitized || 0 === sanitized.length) sanitized = 'unnamed-skill';
|
|
949
|
+
if (sanitized.length > 255) sanitized = sanitized.substring(0, 255);
|
|
950
|
+
return sanitized;
|
|
951
|
+
}
|
|
952
|
+
function installer_isPathSafe(basePath, targetPath) {
|
|
953
|
+
const normalizedBase = __WEBPACK_EXTERNAL_MODULE_node_path__.normalize(__WEBPACK_EXTERNAL_MODULE_node_path__.resolve(basePath));
|
|
954
|
+
const normalizedTarget = __WEBPACK_EXTERNAL_MODULE_node_path__.normalize(__WEBPACK_EXTERNAL_MODULE_node_path__.resolve(targetPath));
|
|
955
|
+
return normalizedTarget.startsWith(normalizedBase + __WEBPACK_EXTERNAL_MODULE_node_path__.sep) || normalizedTarget === normalizedBase;
|
|
956
|
+
}
|
|
957
|
+
function installer_getCanonicalSkillsDir(isGlobal, cwd) {
|
|
958
|
+
const baseDir = isGlobal ? (0, __WEBPACK_EXTERNAL_MODULE_os__.homedir)() : cwd || process.cwd();
|
|
959
|
+
return __WEBPACK_EXTERNAL_MODULE_node_path__.join(baseDir, installer_AGENTS_DIR, installer_SKILLS_SUBDIR);
|
|
960
|
+
}
|
|
961
|
+
function installer_ensureDir(dirPath) {
|
|
962
|
+
if (!external_node_fs_.existsSync(dirPath)) external_node_fs_.mkdirSync(dirPath, {
|
|
963
|
+
recursive: true
|
|
964
|
+
});
|
|
965
|
+
}
|
|
966
|
+
function installer_remove(targetPath) {
|
|
967
|
+
if (external_node_fs_.existsSync(targetPath)) external_node_fs_.rmSync(targetPath, {
|
|
968
|
+
recursive: true,
|
|
969
|
+
force: true
|
|
970
|
+
});
|
|
971
|
+
}
|
|
972
|
+
function copyDirectory(src, dest, options) {
|
|
973
|
+
const exclude = new Set(options?.exclude || [
|
|
974
|
+
'README.md',
|
|
975
|
+
'metadata.json'
|
|
976
|
+
]);
|
|
977
|
+
installer_ensureDir(dest);
|
|
978
|
+
const entries = external_node_fs_.readdirSync(src, {
|
|
979
|
+
withFileTypes: true
|
|
980
|
+
});
|
|
981
|
+
for (const entry of entries){
|
|
982
|
+
if (exclude.has(entry.name) || entry.name.startsWith('_')) continue;
|
|
983
|
+
const srcPath = __WEBPACK_EXTERNAL_MODULE_node_path__.join(src, entry.name);
|
|
984
|
+
const destPath = __WEBPACK_EXTERNAL_MODULE_node_path__.join(dest, entry.name);
|
|
985
|
+
if (entry.isDirectory()) copyDirectory(srcPath, destPath, options);
|
|
986
|
+
else external_node_fs_.copyFileSync(srcPath, destPath);
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
async function installer_createSymlink(target, linkPath) {
|
|
990
|
+
try {
|
|
991
|
+
try {
|
|
992
|
+
const stats = external_node_fs_.lstatSync(linkPath);
|
|
993
|
+
if (stats.isSymbolicLink()) {
|
|
994
|
+
const existingTarget = external_node_fs_.readlinkSync(linkPath);
|
|
995
|
+
if (__WEBPACK_EXTERNAL_MODULE_node_path__.resolve(existingTarget) === __WEBPACK_EXTERNAL_MODULE_node_path__.resolve(target)) return true;
|
|
996
|
+
external_node_fs_.rmSync(linkPath);
|
|
997
|
+
} else external_node_fs_.rmSync(linkPath, {
|
|
998
|
+
recursive: true
|
|
999
|
+
});
|
|
1000
|
+
} catch (err) {
|
|
1001
|
+
if (err && 'object' == typeof err && 'code' in err) {
|
|
1002
|
+
if ('ELOOP' === err.code) try {
|
|
1003
|
+
external_node_fs_.rmSync(linkPath, {
|
|
1004
|
+
force: true
|
|
1005
|
+
});
|
|
1006
|
+
} catch {}
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
const linkDir = __WEBPACK_EXTERNAL_MODULE_node_path__.dirname(linkPath);
|
|
1010
|
+
installer_ensureDir(linkDir);
|
|
1011
|
+
const relativePath = __WEBPACK_EXTERNAL_MODULE_node_path__.relative(linkDir, target);
|
|
1012
|
+
const symlinkType = 'win32' === (0, __WEBPACK_EXTERNAL_MODULE_os__.platform)() ? 'junction' : void 0;
|
|
1013
|
+
external_node_fs_.symlinkSync(relativePath, linkPath, symlinkType);
|
|
1014
|
+
return true;
|
|
1015
|
+
} catch {
|
|
1016
|
+
return false;
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
class Installer {
|
|
1020
|
+
cwd;
|
|
1021
|
+
isGlobal;
|
|
1022
|
+
constructor(options = {}){
|
|
1023
|
+
this.cwd = options.cwd || process.cwd();
|
|
1024
|
+
this.isGlobal = options.global || false;
|
|
1025
|
+
}
|
|
1026
|
+
getCanonicalPath(skillName) {
|
|
1027
|
+
const sanitized = installer_sanitizeName(skillName);
|
|
1028
|
+
const canonicalBase = installer_getCanonicalSkillsDir(this.isGlobal, this.cwd);
|
|
1029
|
+
return __WEBPACK_EXTERNAL_MODULE_node_path__.join(canonicalBase, sanitized);
|
|
1030
|
+
}
|
|
1031
|
+
getAgentSkillPath(skillName, agentType) {
|
|
1032
|
+
const agent = getAgentConfig(agentType);
|
|
1033
|
+
const sanitized = installer_sanitizeName(skillName);
|
|
1034
|
+
const agentBase = this.isGlobal ? agent.globalSkillsDir : __WEBPACK_EXTERNAL_MODULE_node_path__.join(this.cwd, agent.skillsDir);
|
|
1035
|
+
return __WEBPACK_EXTERNAL_MODULE_node_path__.join(agentBase, sanitized);
|
|
1036
|
+
}
|
|
1037
|
+
async installForAgent(sourcePath, skillName, agentType, options = {}) {
|
|
1038
|
+
const agent = getAgentConfig(agentType);
|
|
1039
|
+
const installMode = options.mode || 'symlink';
|
|
1040
|
+
const sanitized = installer_sanitizeName(skillName);
|
|
1041
|
+
const canonicalBase = installer_getCanonicalSkillsDir(this.isGlobal, this.cwd);
|
|
1042
|
+
const canonicalDir = __WEBPACK_EXTERNAL_MODULE_node_path__.join(canonicalBase, sanitized);
|
|
1043
|
+
const agentBase = this.isGlobal ? agent.globalSkillsDir : __WEBPACK_EXTERNAL_MODULE_node_path__.join(this.cwd, agent.skillsDir);
|
|
1044
|
+
const agentDir = __WEBPACK_EXTERNAL_MODULE_node_path__.join(agentBase, sanitized);
|
|
1045
|
+
if (!installer_isPathSafe(canonicalBase, canonicalDir)) return {
|
|
1046
|
+
success: false,
|
|
1047
|
+
path: agentDir,
|
|
1048
|
+
mode: installMode,
|
|
1049
|
+
error: 'Invalid skill name: potential path traversal detected'
|
|
1050
|
+
};
|
|
1051
|
+
if (!installer_isPathSafe(agentBase, agentDir)) return {
|
|
1052
|
+
success: false,
|
|
1053
|
+
path: agentDir,
|
|
1054
|
+
mode: installMode,
|
|
1055
|
+
error: 'Invalid skill name: potential path traversal detected'
|
|
1056
|
+
};
|
|
1057
|
+
try {
|
|
1058
|
+
if ('copy' === installMode) {
|
|
1059
|
+
installer_ensureDir(agentDir);
|
|
1060
|
+
installer_remove(agentDir);
|
|
1061
|
+
copyDirectory(sourcePath, agentDir);
|
|
1062
|
+
return {
|
|
1063
|
+
success: true,
|
|
1064
|
+
path: agentDir,
|
|
1065
|
+
mode: 'copy'
|
|
1066
|
+
};
|
|
1067
|
+
}
|
|
1068
|
+
installer_ensureDir(canonicalDir);
|
|
1069
|
+
installer_remove(canonicalDir);
|
|
1070
|
+
copyDirectory(sourcePath, canonicalDir);
|
|
1071
|
+
const symlinkCreated = await installer_createSymlink(canonicalDir, agentDir);
|
|
1072
|
+
if (!symlinkCreated) {
|
|
1073
|
+
try {
|
|
1074
|
+
installer_remove(agentDir);
|
|
1075
|
+
} catch {}
|
|
1076
|
+
installer_ensureDir(agentDir);
|
|
1077
|
+
copyDirectory(sourcePath, agentDir);
|
|
1078
|
+
return {
|
|
1079
|
+
success: true,
|
|
1080
|
+
path: agentDir,
|
|
1081
|
+
canonicalPath: canonicalDir,
|
|
1082
|
+
mode: 'symlink',
|
|
1083
|
+
symlinkFailed: true
|
|
1084
|
+
};
|
|
1085
|
+
}
|
|
1086
|
+
return {
|
|
1087
|
+
success: true,
|
|
1088
|
+
path: agentDir,
|
|
1089
|
+
canonicalPath: canonicalDir,
|
|
1090
|
+
mode: 'symlink'
|
|
1091
|
+
};
|
|
1092
|
+
} catch (error) {
|
|
1093
|
+
return {
|
|
1094
|
+
success: false,
|
|
1095
|
+
path: agentDir,
|
|
1096
|
+
mode: installMode,
|
|
1097
|
+
error: error instanceof Error ? error.message : 'Unknown error'
|
|
1098
|
+
};
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
async installToAgents(sourcePath, skillName, targetAgents, options = {}) {
|
|
1102
|
+
const results = new Map();
|
|
1103
|
+
for (const agent of targetAgents){
|
|
1104
|
+
const result = await this.installForAgent(sourcePath, skillName, agent, options);
|
|
1105
|
+
results.set(agent, result);
|
|
1106
|
+
}
|
|
1107
|
+
return results;
|
|
1108
|
+
}
|
|
1109
|
+
isInstalled(skillName, agentType) {
|
|
1110
|
+
const skillPath = this.getAgentSkillPath(skillName, agentType);
|
|
1111
|
+
return external_node_fs_.existsSync(skillPath);
|
|
1112
|
+
}
|
|
1113
|
+
uninstallFromAgent(skillName, agentType) {
|
|
1114
|
+
const skillPath = this.getAgentSkillPath(skillName, agentType);
|
|
1115
|
+
if (!external_node_fs_.existsSync(skillPath)) return false;
|
|
1116
|
+
installer_remove(skillPath);
|
|
1117
|
+
return true;
|
|
1118
|
+
}
|
|
1119
|
+
uninstallFromAgents(skillName, targetAgents) {
|
|
1120
|
+
const results = new Map();
|
|
1121
|
+
for (const agent of targetAgents)results.set(agent, this.uninstallFromAgent(skillName, agent));
|
|
1122
|
+
const canonicalPath = this.getCanonicalPath(skillName);
|
|
1123
|
+
if (external_node_fs_.existsSync(canonicalPath)) installer_remove(canonicalPath);
|
|
1124
|
+
return results;
|
|
1125
|
+
}
|
|
1126
|
+
listInstalledSkills(agentType) {
|
|
1127
|
+
const agent = getAgentConfig(agentType);
|
|
1128
|
+
const skillsDir = this.isGlobal ? agent.globalSkillsDir : __WEBPACK_EXTERNAL_MODULE_node_path__.join(this.cwd, agent.skillsDir);
|
|
1129
|
+
if (!external_node_fs_.existsSync(skillsDir)) return [];
|
|
1130
|
+
return external_node_fs_.readdirSync(skillsDir, {
|
|
1131
|
+
withFileTypes: true
|
|
1132
|
+
}).filter((entry)=>entry.isDirectory() || entry.isSymbolicLink()).map((entry)=>entry.name);
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
762
1135
|
const logger = {
|
|
763
1136
|
info (message) {
|
|
764
1137
|
console.log(__WEBPACK_EXTERNAL_MODULE_chalk__["default"].blue('ℹ'), message);
|
|
@@ -1029,5 +1402,226 @@ class SkillManager {
|
|
|
1029
1402
|
}
|
|
1030
1403
|
return results;
|
|
1031
1404
|
}
|
|
1405
|
+
async installToAgents(ref, targetAgents, options = {}) {
|
|
1406
|
+
const { save = true, mode = 'symlink' } = options;
|
|
1407
|
+
const resolved = await this.resolver.resolve(ref);
|
|
1408
|
+
const { parsed, repoUrl } = resolved;
|
|
1409
|
+
const version = resolved.ref;
|
|
1410
|
+
const skillName = parsed.subPath ? __WEBPACK_EXTERNAL_MODULE_node_path__.basename(parsed.subPath) : parsed.repo;
|
|
1411
|
+
logger["package"](`Installing ${skillName}@${version} to ${targetAgents.length} agent(s)...`);
|
|
1412
|
+
let cacheResult = await this.cache.get(parsed, version);
|
|
1413
|
+
if (cacheResult) logger.debug(`Using cached ${skillName}@${version}`);
|
|
1414
|
+
else {
|
|
1415
|
+
logger.debug(`Caching ${skillName}@${version} from ${repoUrl}`);
|
|
1416
|
+
cacheResult = await this.cache.cache(repoUrl, parsed, version, version);
|
|
1417
|
+
}
|
|
1418
|
+
const sourcePath = this.cache.getCachePath(parsed, version);
|
|
1419
|
+
const installer = new Installer({
|
|
1420
|
+
cwd: this.projectRoot,
|
|
1421
|
+
global: this.isGlobal
|
|
1422
|
+
});
|
|
1423
|
+
const results = await installer.installToAgents(sourcePath, skillName, targetAgents, {
|
|
1424
|
+
mode: mode
|
|
1425
|
+
});
|
|
1426
|
+
if (!this.isGlobal) this.lockManager.lockSkill(skillName, {
|
|
1427
|
+
source: `${parsed.registry}:${parsed.owner}/${parsed.repo}${parsed.subPath ? '/' + parsed.subPath : ''}`,
|
|
1428
|
+
version,
|
|
1429
|
+
resolved: repoUrl,
|
|
1430
|
+
commit: cacheResult.commit
|
|
1431
|
+
});
|
|
1432
|
+
if (!this.isGlobal && save && this.config.exists()) this.config.addSkill(skillName, ref);
|
|
1433
|
+
const successCount = Array.from(results.values()).filter((r)=>r.success).length;
|
|
1434
|
+
const failCount = results.size - successCount;
|
|
1435
|
+
if (0 === failCount) logger.success(`Installed ${skillName}@${version} to ${successCount} agent(s)`);
|
|
1436
|
+
else logger.warn(`Installed ${skillName}@${version} to ${successCount} agent(s), ${failCount} failed`);
|
|
1437
|
+
const skill = {
|
|
1438
|
+
name: skillName,
|
|
1439
|
+
path: sourcePath,
|
|
1440
|
+
version,
|
|
1441
|
+
source: `${parsed.registry}:${parsed.owner}/${parsed.repo}${parsed.subPath ? '/' + parsed.subPath : ''}`
|
|
1442
|
+
};
|
|
1443
|
+
return {
|
|
1444
|
+
skill,
|
|
1445
|
+
results
|
|
1446
|
+
};
|
|
1447
|
+
}
|
|
1448
|
+
async getDefaultTargetAgents() {
|
|
1449
|
+
const defaults = this.config.getDefaults();
|
|
1450
|
+
if (defaults.targetAgents && defaults.targetAgents.length > 0) return defaults.targetAgents.filter(isValidAgentType);
|
|
1451
|
+
return detectInstalledAgents();
|
|
1452
|
+
}
|
|
1453
|
+
getDefaultInstallMode() {
|
|
1454
|
+
const defaults = this.config.getDefaults();
|
|
1455
|
+
if ('copy' === defaults.installMode || 'symlink' === defaults.installMode) return defaults.installMode;
|
|
1456
|
+
return 'symlink';
|
|
1457
|
+
}
|
|
1458
|
+
validateAgentTypes(agentNames) {
|
|
1459
|
+
const valid = [];
|
|
1460
|
+
const invalid = [];
|
|
1461
|
+
for (const name of agentNames)if (isValidAgentType(name)) valid.push(name);
|
|
1462
|
+
else invalid.push(name);
|
|
1463
|
+
return {
|
|
1464
|
+
valid,
|
|
1465
|
+
invalid
|
|
1466
|
+
};
|
|
1467
|
+
}
|
|
1468
|
+
getAllAgentTypes() {
|
|
1469
|
+
return Object.keys(agents);
|
|
1470
|
+
}
|
|
1471
|
+
uninstallFromAgents(name, targetAgents) {
|
|
1472
|
+
const installer = new Installer({
|
|
1473
|
+
cwd: this.projectRoot,
|
|
1474
|
+
global: this.isGlobal
|
|
1475
|
+
});
|
|
1476
|
+
const results = installer.uninstallFromAgents(name, targetAgents);
|
|
1477
|
+
if (!this.isGlobal) this.lockManager.remove(name);
|
|
1478
|
+
if (!this.isGlobal && this.config.exists()) this.config.removeSkill(name);
|
|
1479
|
+
const successCount = Array.from(results.values()).filter((r)=>r).length;
|
|
1480
|
+
logger.success(`Uninstalled ${name} from ${successCount} agent(s)`);
|
|
1481
|
+
return results;
|
|
1482
|
+
}
|
|
1483
|
+
}
|
|
1484
|
+
class SkillValidationError extends Error {
|
|
1485
|
+
field;
|
|
1486
|
+
constructor(message, field){
|
|
1487
|
+
super(message), this.field = field;
|
|
1488
|
+
this.name = 'SkillValidationError';
|
|
1489
|
+
}
|
|
1490
|
+
}
|
|
1491
|
+
function parseFrontmatter(content) {
|
|
1492
|
+
const frontmatterRegex = /^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/;
|
|
1493
|
+
const match = content.match(frontmatterRegex);
|
|
1494
|
+
if (!match) return {
|
|
1495
|
+
data: {},
|
|
1496
|
+
content
|
|
1497
|
+
};
|
|
1498
|
+
const yamlContent = match[1];
|
|
1499
|
+
const markdownContent = match[2];
|
|
1500
|
+
const data = {};
|
|
1501
|
+
const lines = yamlContent.split('\n');
|
|
1502
|
+
let currentKey = '';
|
|
1503
|
+
let currentValue = '';
|
|
1504
|
+
let inMultiline = false;
|
|
1505
|
+
for (const line of lines){
|
|
1506
|
+
const trimmedLine = line.trim();
|
|
1507
|
+
if (!trimmedLine || trimmedLine.startsWith('#')) continue;
|
|
1508
|
+
const keyValueMatch = line.match(/^([a-zA-Z_-]+):\s*(.*)$/);
|
|
1509
|
+
if (keyValueMatch && !inMultiline) {
|
|
1510
|
+
if (currentKey) data[currentKey] = parseYamlValue(currentValue.trim());
|
|
1511
|
+
currentKey = keyValueMatch[1];
|
|
1512
|
+
currentValue = keyValueMatch[2];
|
|
1513
|
+
if ('|' === currentValue || '>' === currentValue) {
|
|
1514
|
+
inMultiline = true;
|
|
1515
|
+
currentValue = '';
|
|
1516
|
+
}
|
|
1517
|
+
} else if (inMultiline && line.startsWith(' ')) currentValue += (currentValue ? '\n' : '') + line.slice(2);
|
|
1518
|
+
else if (inMultiline && !line.startsWith(' ')) {
|
|
1519
|
+
inMultiline = false;
|
|
1520
|
+
data[currentKey] = currentValue.trim();
|
|
1521
|
+
const newKeyMatch = line.match(/^([a-zA-Z_-]+):\s*(.*)$/);
|
|
1522
|
+
if (newKeyMatch) {
|
|
1523
|
+
currentKey = newKeyMatch[1];
|
|
1524
|
+
currentValue = newKeyMatch[2];
|
|
1525
|
+
}
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
if (currentKey) data[currentKey] = parseYamlValue(currentValue.trim());
|
|
1529
|
+
return {
|
|
1530
|
+
data,
|
|
1531
|
+
content: markdownContent
|
|
1532
|
+
};
|
|
1533
|
+
}
|
|
1534
|
+
function parseYamlValue(value) {
|
|
1535
|
+
if (!value) return '';
|
|
1536
|
+
if ('true' === value) return true;
|
|
1537
|
+
if ('false' === value) return false;
|
|
1538
|
+
if (/^-?\d+$/.test(value)) return parseInt(value, 10);
|
|
1539
|
+
if (/^-?\d+\.\d+$/.test(value)) return parseFloat(value);
|
|
1540
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) return value.slice(1, -1);
|
|
1541
|
+
return value;
|
|
1542
|
+
}
|
|
1543
|
+
function validateSkillName(name) {
|
|
1544
|
+
if (!name) throw new SkillValidationError('Skill name is required', 'name');
|
|
1545
|
+
if (name.length > 64) throw new SkillValidationError('Skill name must be at most 64 characters', 'name');
|
|
1546
|
+
if (!/^[a-z0-9]/.test(name)) throw new SkillValidationError('Skill name must start with a lowercase letter or number', 'name');
|
|
1547
|
+
if (!/[a-z0-9]$/.test(name)) throw new SkillValidationError('Skill name must end with a lowercase letter or number', 'name');
|
|
1548
|
+
if (/--/.test(name)) throw new SkillValidationError('Skill name cannot contain consecutive hyphens', 'name');
|
|
1549
|
+
if (!/^[a-z0-9][a-z0-9-]*[a-z0-9]$/.test(name) && name.length > 1) throw new SkillValidationError('Skill name can only contain lowercase letters, numbers, and hyphens', 'name');
|
|
1550
|
+
if (1 === name.length && !/^[a-z0-9]$/.test(name)) throw new SkillValidationError('Single character skill name must be a lowercase letter or number', 'name');
|
|
1551
|
+
}
|
|
1552
|
+
function validateSkillDescription(description) {
|
|
1553
|
+
if (!description) throw new SkillValidationError('Skill description is required', 'description');
|
|
1554
|
+
if (description.length > 1024) throw new SkillValidationError('Skill description must be at most 1024 characters', 'description');
|
|
1555
|
+
if (/<|>/.test(description)) throw new SkillValidationError('Skill description cannot contain angle brackets', 'description');
|
|
1556
|
+
}
|
|
1557
|
+
function parseSkillMd(content, options = {}) {
|
|
1558
|
+
const { strict = false } = options;
|
|
1559
|
+
try {
|
|
1560
|
+
const { data, content: body } = parseFrontmatter(content);
|
|
1561
|
+
if (!data.name || !data.description) {
|
|
1562
|
+
if (strict) throw new SkillValidationError('SKILL.md must have name and description in frontmatter');
|
|
1563
|
+
return null;
|
|
1564
|
+
}
|
|
1565
|
+
const name = String(data.name);
|
|
1566
|
+
const description = String(data.description);
|
|
1567
|
+
if (strict) {
|
|
1568
|
+
validateSkillName(name);
|
|
1569
|
+
validateSkillDescription(description);
|
|
1570
|
+
}
|
|
1571
|
+
let allowedTools;
|
|
1572
|
+
if (data['allowed-tools']) {
|
|
1573
|
+
const toolsStr = String(data['allowed-tools']);
|
|
1574
|
+
allowedTools = toolsStr.split(/\s+/).filter(Boolean);
|
|
1575
|
+
}
|
|
1576
|
+
return {
|
|
1577
|
+
name,
|
|
1578
|
+
description,
|
|
1579
|
+
license: data.license ? String(data.license) : void 0,
|
|
1580
|
+
compatibility: data.compatibility ? String(data.compatibility) : void 0,
|
|
1581
|
+
metadata: data.metadata,
|
|
1582
|
+
allowedTools,
|
|
1583
|
+
content: body,
|
|
1584
|
+
rawContent: content
|
|
1585
|
+
};
|
|
1586
|
+
} catch (error) {
|
|
1587
|
+
if (error instanceof SkillValidationError) throw error;
|
|
1588
|
+
if (strict) throw new SkillValidationError(`Failed to parse SKILL.md: ${error}`);
|
|
1589
|
+
return null;
|
|
1590
|
+
}
|
|
1591
|
+
}
|
|
1592
|
+
function parseSkillMdFile(filePath, options = {}) {
|
|
1593
|
+
if (!external_node_fs_.existsSync(filePath)) {
|
|
1594
|
+
if (options.strict) throw new SkillValidationError(`SKILL.md not found: ${filePath}`);
|
|
1595
|
+
return null;
|
|
1596
|
+
}
|
|
1597
|
+
const content = external_node_fs_.readFileSync(filePath, 'utf-8');
|
|
1598
|
+
return parseSkillMd(content, options);
|
|
1599
|
+
}
|
|
1600
|
+
function parseSkillFromDir(dirPath, options = {}) {
|
|
1601
|
+
const skillMdPath = __WEBPACK_EXTERNAL_MODULE_node_path__.join(dirPath, 'SKILL.md');
|
|
1602
|
+
return parseSkillMdFile(skillMdPath, options);
|
|
1603
|
+
}
|
|
1604
|
+
function hasValidSkillMd(dirPath) {
|
|
1605
|
+
const skillMdPath = __WEBPACK_EXTERNAL_MODULE_node_path__.join(dirPath, 'SKILL.md');
|
|
1606
|
+
if (!external_node_fs_.existsSync(skillMdPath)) return false;
|
|
1607
|
+
try {
|
|
1608
|
+
const skill = parseSkillMdFile(skillMdPath);
|
|
1609
|
+
return null !== skill;
|
|
1610
|
+
} catch {
|
|
1611
|
+
return false;
|
|
1612
|
+
}
|
|
1613
|
+
}
|
|
1614
|
+
function generateSkillMd(skill) {
|
|
1615
|
+
const frontmatter = [
|
|
1616
|
+
'---'
|
|
1617
|
+
];
|
|
1618
|
+
frontmatter.push(`name: ${skill.name}`);
|
|
1619
|
+
frontmatter.push(`description: ${skill.description}`);
|
|
1620
|
+
if (skill.license) frontmatter.push(`license: ${skill.license}`);
|
|
1621
|
+
if (skill.compatibility) frontmatter.push(`compatibility: ${skill.compatibility}`);
|
|
1622
|
+
if (skill.allowedTools && skill.allowedTools.length > 0) frontmatter.push(`allowed-tools: ${skill.allowedTools.join(' ')}`);
|
|
1623
|
+
frontmatter.push('---');
|
|
1624
|
+
frontmatter.push('');
|
|
1625
|
+
return frontmatter.join('\n') + skill.content;
|
|
1032
1626
|
}
|
|
1033
|
-
export { CacheManager, ConfigLoader, DEFAULT_REGISTRIES, GitResolver, LockManager, SkillManager, logger };
|
|
1627
|
+
export { CacheManager, ConfigLoader, DEFAULT_REGISTRIES, GitResolver, Installer, LockManager, SkillManager, SkillValidationError, agents, detectInstalledAgents, generateSkillMd, getAgentConfig, getAgentSkillsDir, getAllAgentTypes, getCanonicalSkillPath, getCanonicalSkillsDir, hasValidSkillMd, isPathSafe, isValidAgentType, logger, parseSkillFromDir, parseSkillMd, parseSkillMdFile, sanitizeName, shortenPath, validateSkillDescription, validateSkillName };
|
package/dist/types/index.d.ts
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
* Skills Package Manager Type Definitions
|
|
3
3
|
* Based on: docs/skills-management-design.md
|
|
4
4
|
*/
|
|
5
|
+
/**
|
|
6
|
+
* 支持的 Agent 类型
|
|
7
|
+
*/
|
|
8
|
+
export type { AgentType, AgentConfig, } from '../core/agent-registry.js';
|
|
9
|
+
/**
|
|
10
|
+
* 安装模式
|
|
11
|
+
*/
|
|
12
|
+
export type { InstallMode, InstallResult } from '../core/installer.js';
|
|
13
|
+
/**
|
|
14
|
+
* SKILL.md 解析相关类型 (遵循 agentskills.io 规范)
|
|
15
|
+
*/
|
|
16
|
+
export type { SkillMdFrontmatter, ParsedSkill, } from '../core/skill-parser.js';
|
|
5
17
|
/**
|
|
6
18
|
* 版本规范格式
|
|
7
19
|
* - 精确版本: @v1.0.0
|
|
@@ -32,6 +44,10 @@ export interface SkillsDefaults {
|
|
|
32
44
|
registry?: string;
|
|
33
45
|
/** 安装目录,默认 .skills */
|
|
34
46
|
installDir?: string;
|
|
47
|
+
/** 目标 agents 列表 */
|
|
48
|
+
targetAgents?: string[];
|
|
49
|
+
/** 安装模式: symlink | copy */
|
|
50
|
+
installMode?: 'symlink' | 'copy';
|
|
35
51
|
}
|
|
36
52
|
/**
|
|
37
53
|
* Skill 覆盖配置
|
|
@@ -193,8 +209,14 @@ export interface InstallOptions {
|
|
|
193
209
|
force?: boolean;
|
|
194
210
|
/** 保存到 skills.json */
|
|
195
211
|
save?: boolean;
|
|
196
|
-
/**
|
|
212
|
+
/** 全局安装 */
|
|
197
213
|
global?: boolean;
|
|
214
|
+
/** 目标 agents 列表 */
|
|
215
|
+
agents?: string[];
|
|
216
|
+
/** 安装模式: symlink | copy */
|
|
217
|
+
mode?: 'symlink' | 'copy';
|
|
218
|
+
/** 跳过确认 */
|
|
219
|
+
yes?: boolean;
|
|
198
220
|
}
|
|
199
221
|
/**
|
|
200
222
|
* 更新选项
|