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/cli/index.js
CHANGED
|
@@ -3,10 +3,14 @@ import * as __WEBPACK_EXTERNAL_MODULE_node_fs__ from "node:fs";
|
|
|
3
3
|
import * as __WEBPACK_EXTERNAL_MODULE_commander__ from "commander";
|
|
4
4
|
import * as __WEBPACK_EXTERNAL_MODULE_node_path__ from "node:path";
|
|
5
5
|
import * as __WEBPACK_EXTERNAL_MODULE_chalk__ from "chalk";
|
|
6
|
-
import * as
|
|
6
|
+
import * as __WEBPACK_EXTERNAL_MODULE__clack_prompts__ from "@clack/prompts";
|
|
7
7
|
import * as __WEBPACK_EXTERNAL_MODULE_semver__ from "semver";
|
|
8
8
|
import * as __WEBPACK_EXTERNAL_MODULE_node_child_process__ from "node:child_process";
|
|
9
9
|
import * as __WEBPACK_EXTERNAL_MODULE_node_util__ from "node:util";
|
|
10
|
+
import * as __WEBPACK_EXTERNAL_MODULE_os__ from "os";
|
|
11
|
+
import * as __WEBPACK_EXTERNAL_MODULE_path__ from "path";
|
|
12
|
+
import * as __WEBPACK_EXTERNAL_MODULE_fs__ from "fs";
|
|
13
|
+
import * as __WEBPACK_EXTERNAL_MODULE_ora__ from "ora";
|
|
10
14
|
var __webpack_modules__ = {
|
|
11
15
|
"node:fs": function(module) {
|
|
12
16
|
module.exports = __WEBPACK_EXTERNAL_MODULE_node_fs__;
|
|
@@ -102,6 +106,13 @@ function getGlobalSkillsDir() {
|
|
|
102
106
|
const home = getHomeDir();
|
|
103
107
|
return __WEBPACK_EXTERNAL_MODULE_node_path__.join(home, '.claude', 'skills');
|
|
104
108
|
}
|
|
109
|
+
function shortenPath(fullPath, cwd) {
|
|
110
|
+
const home = getHomeDir();
|
|
111
|
+
const currentDir = cwd || process.cwd();
|
|
112
|
+
if (fullPath.startsWith(home)) return fullPath.replace(home, '~');
|
|
113
|
+
if (fullPath.startsWith(currentDir)) return '.' + fullPath.slice(currentDir.length);
|
|
114
|
+
return fullPath;
|
|
115
|
+
}
|
|
105
116
|
const DEFAULT_SKILLS_JSON = {
|
|
106
117
|
skills: {},
|
|
107
118
|
defaults: {
|
|
@@ -167,7 +178,9 @@ class ConfigLoader {
|
|
|
167
178
|
const config = this.config || (this.exists() ? this.load() : DEFAULT_SKILLS_JSON);
|
|
168
179
|
return {
|
|
169
180
|
registry: config.defaults?.registry || DEFAULT_SKILLS_JSON.defaults.registry,
|
|
170
|
-
installDir: config.defaults?.installDir || DEFAULT_SKILLS_JSON.defaults.installDir
|
|
181
|
+
installDir: config.defaults?.installDir || DEFAULT_SKILLS_JSON.defaults.installDir,
|
|
182
|
+
targetAgents: config.defaults?.targetAgents || [],
|
|
183
|
+
installMode: config.defaults?.installMode || 'symlink'
|
|
171
184
|
};
|
|
172
185
|
}
|
|
173
186
|
getRegistryUrl(registryName) {
|
|
@@ -630,6 +643,9 @@ class CacheManager {
|
|
|
630
643
|
getSkillCachePath(parsed, version) {
|
|
631
644
|
return __WEBPACK_EXTERNAL_MODULE_node_path__.join(this.cacheDir, parsed.registry, parsed.owner, parsed.repo, version);
|
|
632
645
|
}
|
|
646
|
+
getCachePath(parsed, version) {
|
|
647
|
+
return this.getSkillCachePath(parsed, version);
|
|
648
|
+
}
|
|
633
649
|
isCached(parsed, version) {
|
|
634
650
|
const cachePath = this.getSkillCachePath(parsed, version);
|
|
635
651
|
return exists(cachePath) && isDirectory(cachePath);
|
|
@@ -827,6 +843,332 @@ class LockManager {
|
|
|
827
843
|
this.lockData = null;
|
|
828
844
|
}
|
|
829
845
|
}
|
|
846
|
+
const agent_registry_home = (0, __WEBPACK_EXTERNAL_MODULE_os__.homedir)();
|
|
847
|
+
const agents = {
|
|
848
|
+
amp: {
|
|
849
|
+
name: 'amp',
|
|
850
|
+
displayName: 'Amp',
|
|
851
|
+
skillsDir: '.agents/skills',
|
|
852
|
+
globalSkillsDir: (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.config/agents/skills'),
|
|
853
|
+
detectInstalled: async ()=>(0, __WEBPACK_EXTERNAL_MODULE_fs__.existsSync)((0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.config/amp'))
|
|
854
|
+
},
|
|
855
|
+
antigravity: {
|
|
856
|
+
name: 'antigravity',
|
|
857
|
+
displayName: 'Antigravity',
|
|
858
|
+
skillsDir: '.agent/skills',
|
|
859
|
+
globalSkillsDir: (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.gemini/antigravity/skills'),
|
|
860
|
+
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'))
|
|
861
|
+
},
|
|
862
|
+
'claude-code': {
|
|
863
|
+
name: 'claude-code',
|
|
864
|
+
displayName: 'Claude Code',
|
|
865
|
+
skillsDir: '.claude/skills',
|
|
866
|
+
globalSkillsDir: (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.claude/skills'),
|
|
867
|
+
detectInstalled: async ()=>(0, __WEBPACK_EXTERNAL_MODULE_fs__.existsSync)((0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.claude'))
|
|
868
|
+
},
|
|
869
|
+
clawdbot: {
|
|
870
|
+
name: 'clawdbot',
|
|
871
|
+
displayName: 'Clawdbot',
|
|
872
|
+
skillsDir: 'skills',
|
|
873
|
+
globalSkillsDir: (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.clawdbot/skills'),
|
|
874
|
+
detectInstalled: async ()=>(0, __WEBPACK_EXTERNAL_MODULE_fs__.existsSync)((0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.clawdbot'))
|
|
875
|
+
},
|
|
876
|
+
codex: {
|
|
877
|
+
name: 'codex',
|
|
878
|
+
displayName: 'Codex',
|
|
879
|
+
skillsDir: '.codex/skills',
|
|
880
|
+
globalSkillsDir: (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.codex/skills'),
|
|
881
|
+
detectInstalled: async ()=>(0, __WEBPACK_EXTERNAL_MODULE_fs__.existsSync)((0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.codex'))
|
|
882
|
+
},
|
|
883
|
+
cursor: {
|
|
884
|
+
name: 'cursor',
|
|
885
|
+
displayName: 'Cursor',
|
|
886
|
+
skillsDir: '.cursor/skills',
|
|
887
|
+
globalSkillsDir: (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.cursor/skills'),
|
|
888
|
+
detectInstalled: async ()=>(0, __WEBPACK_EXTERNAL_MODULE_fs__.existsSync)((0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.cursor'))
|
|
889
|
+
},
|
|
890
|
+
droid: {
|
|
891
|
+
name: 'droid',
|
|
892
|
+
displayName: 'Droid',
|
|
893
|
+
skillsDir: '.factory/skills',
|
|
894
|
+
globalSkillsDir: (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.factory/skills'),
|
|
895
|
+
detectInstalled: async ()=>(0, __WEBPACK_EXTERNAL_MODULE_fs__.existsSync)((0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.factory/skills'))
|
|
896
|
+
},
|
|
897
|
+
'gemini-cli': {
|
|
898
|
+
name: 'gemini-cli',
|
|
899
|
+
displayName: 'Gemini CLI',
|
|
900
|
+
skillsDir: '.gemini/skills',
|
|
901
|
+
globalSkillsDir: (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.gemini/skills'),
|
|
902
|
+
detectInstalled: async ()=>(0, __WEBPACK_EXTERNAL_MODULE_fs__.existsSync)((0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.gemini'))
|
|
903
|
+
},
|
|
904
|
+
'github-copilot': {
|
|
905
|
+
name: 'github-copilot',
|
|
906
|
+
displayName: 'GitHub Copilot',
|
|
907
|
+
skillsDir: '.github/skills',
|
|
908
|
+
globalSkillsDir: (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.copilot/skills'),
|
|
909
|
+
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'))
|
|
910
|
+
},
|
|
911
|
+
goose: {
|
|
912
|
+
name: 'goose',
|
|
913
|
+
displayName: 'Goose',
|
|
914
|
+
skillsDir: '.goose/skills',
|
|
915
|
+
globalSkillsDir: (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.config/goose/skills'),
|
|
916
|
+
detectInstalled: async ()=>(0, __WEBPACK_EXTERNAL_MODULE_fs__.existsSync)((0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.config/goose'))
|
|
917
|
+
},
|
|
918
|
+
kilo: {
|
|
919
|
+
name: 'kilo',
|
|
920
|
+
displayName: 'Kilo Code',
|
|
921
|
+
skillsDir: '.kilocode/skills',
|
|
922
|
+
globalSkillsDir: (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.kilocode/skills'),
|
|
923
|
+
detectInstalled: async ()=>(0, __WEBPACK_EXTERNAL_MODULE_fs__.existsSync)((0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.kilocode'))
|
|
924
|
+
},
|
|
925
|
+
'kiro-cli': {
|
|
926
|
+
name: 'kiro-cli',
|
|
927
|
+
displayName: 'Kiro CLI',
|
|
928
|
+
skillsDir: '.kiro/skills',
|
|
929
|
+
globalSkillsDir: (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.kiro/skills'),
|
|
930
|
+
detectInstalled: async ()=>(0, __WEBPACK_EXTERNAL_MODULE_fs__.existsSync)((0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.kiro'))
|
|
931
|
+
},
|
|
932
|
+
opencode: {
|
|
933
|
+
name: 'opencode',
|
|
934
|
+
displayName: 'OpenCode',
|
|
935
|
+
skillsDir: '.opencode/skills',
|
|
936
|
+
globalSkillsDir: (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.config/opencode/skills'),
|
|
937
|
+
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'))
|
|
938
|
+
},
|
|
939
|
+
roo: {
|
|
940
|
+
name: 'roo',
|
|
941
|
+
displayName: 'Roo Code',
|
|
942
|
+
skillsDir: '.roo/skills',
|
|
943
|
+
globalSkillsDir: (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.roo/skills'),
|
|
944
|
+
detectInstalled: async ()=>(0, __WEBPACK_EXTERNAL_MODULE_fs__.existsSync)((0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.roo'))
|
|
945
|
+
},
|
|
946
|
+
trae: {
|
|
947
|
+
name: 'trae',
|
|
948
|
+
displayName: 'Trae',
|
|
949
|
+
skillsDir: '.trae/skills',
|
|
950
|
+
globalSkillsDir: (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.trae/skills'),
|
|
951
|
+
detectInstalled: async ()=>(0, __WEBPACK_EXTERNAL_MODULE_fs__.existsSync)((0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.trae'))
|
|
952
|
+
},
|
|
953
|
+
windsurf: {
|
|
954
|
+
name: 'windsurf',
|
|
955
|
+
displayName: 'Windsurf',
|
|
956
|
+
skillsDir: '.windsurf/skills',
|
|
957
|
+
globalSkillsDir: (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.codeium/windsurf/skills'),
|
|
958
|
+
detectInstalled: async ()=>(0, __WEBPACK_EXTERNAL_MODULE_fs__.existsSync)((0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.codeium/windsurf'))
|
|
959
|
+
},
|
|
960
|
+
neovate: {
|
|
961
|
+
name: 'neovate',
|
|
962
|
+
displayName: 'Neovate',
|
|
963
|
+
skillsDir: '.neovate/skills',
|
|
964
|
+
globalSkillsDir: (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.neovate/skills'),
|
|
965
|
+
detectInstalled: async ()=>(0, __WEBPACK_EXTERNAL_MODULE_fs__.existsSync)((0, __WEBPACK_EXTERNAL_MODULE_path__.join)(agent_registry_home, '.neovate'))
|
|
966
|
+
}
|
|
967
|
+
};
|
|
968
|
+
async function detectInstalledAgents() {
|
|
969
|
+
const installed = [];
|
|
970
|
+
for (const [type, config] of Object.entries(agents))if (await config.detectInstalled()) installed.push(type);
|
|
971
|
+
return installed;
|
|
972
|
+
}
|
|
973
|
+
function getAgentConfig(type) {
|
|
974
|
+
return agents[type];
|
|
975
|
+
}
|
|
976
|
+
function isValidAgentType(type) {
|
|
977
|
+
return type in agents;
|
|
978
|
+
}
|
|
979
|
+
const installer_AGENTS_DIR = '.agents';
|
|
980
|
+
const installer_SKILLS_SUBDIR = 'skills';
|
|
981
|
+
function installer_sanitizeName(name) {
|
|
982
|
+
let sanitized = name.replace(/[/\\:\0]/g, '');
|
|
983
|
+
sanitized = sanitized.replace(/^[.\s]+|[.\s]+$/g, '');
|
|
984
|
+
sanitized = sanitized.replace(/^\.+/, '');
|
|
985
|
+
if (!sanitized || 0 === sanitized.length) sanitized = 'unnamed-skill';
|
|
986
|
+
if (sanitized.length > 255) sanitized = sanitized.substring(0, 255);
|
|
987
|
+
return sanitized;
|
|
988
|
+
}
|
|
989
|
+
function installer_isPathSafe(basePath, targetPath) {
|
|
990
|
+
const normalizedBase = __WEBPACK_EXTERNAL_MODULE_node_path__.normalize(__WEBPACK_EXTERNAL_MODULE_node_path__.resolve(basePath));
|
|
991
|
+
const normalizedTarget = __WEBPACK_EXTERNAL_MODULE_node_path__.normalize(__WEBPACK_EXTERNAL_MODULE_node_path__.resolve(targetPath));
|
|
992
|
+
return normalizedTarget.startsWith(normalizedBase + __WEBPACK_EXTERNAL_MODULE_node_path__.sep) || normalizedTarget === normalizedBase;
|
|
993
|
+
}
|
|
994
|
+
function installer_getCanonicalSkillsDir(isGlobal, cwd) {
|
|
995
|
+
const baseDir = isGlobal ? (0, __WEBPACK_EXTERNAL_MODULE_os__.homedir)() : cwd || process.cwd();
|
|
996
|
+
return __WEBPACK_EXTERNAL_MODULE_node_path__.join(baseDir, installer_AGENTS_DIR, installer_SKILLS_SUBDIR);
|
|
997
|
+
}
|
|
998
|
+
function installer_ensureDir(dirPath) {
|
|
999
|
+
if (!external_node_fs_.existsSync(dirPath)) external_node_fs_.mkdirSync(dirPath, {
|
|
1000
|
+
recursive: true
|
|
1001
|
+
});
|
|
1002
|
+
}
|
|
1003
|
+
function installer_remove(targetPath) {
|
|
1004
|
+
if (external_node_fs_.existsSync(targetPath)) external_node_fs_.rmSync(targetPath, {
|
|
1005
|
+
recursive: true,
|
|
1006
|
+
force: true
|
|
1007
|
+
});
|
|
1008
|
+
}
|
|
1009
|
+
function copyDirectory(src, dest, options) {
|
|
1010
|
+
const exclude = new Set(options?.exclude || [
|
|
1011
|
+
'README.md',
|
|
1012
|
+
'metadata.json'
|
|
1013
|
+
]);
|
|
1014
|
+
installer_ensureDir(dest);
|
|
1015
|
+
const entries = external_node_fs_.readdirSync(src, {
|
|
1016
|
+
withFileTypes: true
|
|
1017
|
+
});
|
|
1018
|
+
for (const entry of entries){
|
|
1019
|
+
if (exclude.has(entry.name) || entry.name.startsWith('_')) continue;
|
|
1020
|
+
const srcPath = __WEBPACK_EXTERNAL_MODULE_node_path__.join(src, entry.name);
|
|
1021
|
+
const destPath = __WEBPACK_EXTERNAL_MODULE_node_path__.join(dest, entry.name);
|
|
1022
|
+
if (entry.isDirectory()) copyDirectory(srcPath, destPath, options);
|
|
1023
|
+
else external_node_fs_.copyFileSync(srcPath, destPath);
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
async function installer_createSymlink(target, linkPath) {
|
|
1027
|
+
try {
|
|
1028
|
+
try {
|
|
1029
|
+
const stats = external_node_fs_.lstatSync(linkPath);
|
|
1030
|
+
if (stats.isSymbolicLink()) {
|
|
1031
|
+
const existingTarget = external_node_fs_.readlinkSync(linkPath);
|
|
1032
|
+
if (__WEBPACK_EXTERNAL_MODULE_node_path__.resolve(existingTarget) === __WEBPACK_EXTERNAL_MODULE_node_path__.resolve(target)) return true;
|
|
1033
|
+
external_node_fs_.rmSync(linkPath);
|
|
1034
|
+
} else external_node_fs_.rmSync(linkPath, {
|
|
1035
|
+
recursive: true
|
|
1036
|
+
});
|
|
1037
|
+
} catch (err) {
|
|
1038
|
+
if (err && 'object' == typeof err && 'code' in err) {
|
|
1039
|
+
if ('ELOOP' === err.code) try {
|
|
1040
|
+
external_node_fs_.rmSync(linkPath, {
|
|
1041
|
+
force: true
|
|
1042
|
+
});
|
|
1043
|
+
} catch {}
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
const linkDir = __WEBPACK_EXTERNAL_MODULE_node_path__.dirname(linkPath);
|
|
1047
|
+
installer_ensureDir(linkDir);
|
|
1048
|
+
const relativePath = __WEBPACK_EXTERNAL_MODULE_node_path__.relative(linkDir, target);
|
|
1049
|
+
const symlinkType = 'win32' === (0, __WEBPACK_EXTERNAL_MODULE_os__.platform)() ? 'junction' : void 0;
|
|
1050
|
+
external_node_fs_.symlinkSync(relativePath, linkPath, symlinkType);
|
|
1051
|
+
return true;
|
|
1052
|
+
} catch {
|
|
1053
|
+
return false;
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
class Installer {
|
|
1057
|
+
cwd;
|
|
1058
|
+
isGlobal;
|
|
1059
|
+
constructor(options = {}){
|
|
1060
|
+
this.cwd = options.cwd || process.cwd();
|
|
1061
|
+
this.isGlobal = options.global || false;
|
|
1062
|
+
}
|
|
1063
|
+
getCanonicalPath(skillName) {
|
|
1064
|
+
const sanitized = installer_sanitizeName(skillName);
|
|
1065
|
+
const canonicalBase = installer_getCanonicalSkillsDir(this.isGlobal, this.cwd);
|
|
1066
|
+
return __WEBPACK_EXTERNAL_MODULE_node_path__.join(canonicalBase, sanitized);
|
|
1067
|
+
}
|
|
1068
|
+
getAgentSkillPath(skillName, agentType) {
|
|
1069
|
+
const agent = getAgentConfig(agentType);
|
|
1070
|
+
const sanitized = installer_sanitizeName(skillName);
|
|
1071
|
+
const agentBase = this.isGlobal ? agent.globalSkillsDir : __WEBPACK_EXTERNAL_MODULE_node_path__.join(this.cwd, agent.skillsDir);
|
|
1072
|
+
return __WEBPACK_EXTERNAL_MODULE_node_path__.join(agentBase, sanitized);
|
|
1073
|
+
}
|
|
1074
|
+
async installForAgent(sourcePath, skillName, agentType, options = {}) {
|
|
1075
|
+
const agent = getAgentConfig(agentType);
|
|
1076
|
+
const installMode = options.mode || 'symlink';
|
|
1077
|
+
const sanitized = installer_sanitizeName(skillName);
|
|
1078
|
+
const canonicalBase = installer_getCanonicalSkillsDir(this.isGlobal, this.cwd);
|
|
1079
|
+
const canonicalDir = __WEBPACK_EXTERNAL_MODULE_node_path__.join(canonicalBase, sanitized);
|
|
1080
|
+
const agentBase = this.isGlobal ? agent.globalSkillsDir : __WEBPACK_EXTERNAL_MODULE_node_path__.join(this.cwd, agent.skillsDir);
|
|
1081
|
+
const agentDir = __WEBPACK_EXTERNAL_MODULE_node_path__.join(agentBase, sanitized);
|
|
1082
|
+
if (!installer_isPathSafe(canonicalBase, canonicalDir)) return {
|
|
1083
|
+
success: false,
|
|
1084
|
+
path: agentDir,
|
|
1085
|
+
mode: installMode,
|
|
1086
|
+
error: 'Invalid skill name: potential path traversal detected'
|
|
1087
|
+
};
|
|
1088
|
+
if (!installer_isPathSafe(agentBase, agentDir)) return {
|
|
1089
|
+
success: false,
|
|
1090
|
+
path: agentDir,
|
|
1091
|
+
mode: installMode,
|
|
1092
|
+
error: 'Invalid skill name: potential path traversal detected'
|
|
1093
|
+
};
|
|
1094
|
+
try {
|
|
1095
|
+
if ('copy' === installMode) {
|
|
1096
|
+
installer_ensureDir(agentDir);
|
|
1097
|
+
installer_remove(agentDir);
|
|
1098
|
+
copyDirectory(sourcePath, agentDir);
|
|
1099
|
+
return {
|
|
1100
|
+
success: true,
|
|
1101
|
+
path: agentDir,
|
|
1102
|
+
mode: 'copy'
|
|
1103
|
+
};
|
|
1104
|
+
}
|
|
1105
|
+
installer_ensureDir(canonicalDir);
|
|
1106
|
+
installer_remove(canonicalDir);
|
|
1107
|
+
copyDirectory(sourcePath, canonicalDir);
|
|
1108
|
+
const symlinkCreated = await installer_createSymlink(canonicalDir, agentDir);
|
|
1109
|
+
if (!symlinkCreated) {
|
|
1110
|
+
try {
|
|
1111
|
+
installer_remove(agentDir);
|
|
1112
|
+
} catch {}
|
|
1113
|
+
installer_ensureDir(agentDir);
|
|
1114
|
+
copyDirectory(sourcePath, agentDir);
|
|
1115
|
+
return {
|
|
1116
|
+
success: true,
|
|
1117
|
+
path: agentDir,
|
|
1118
|
+
canonicalPath: canonicalDir,
|
|
1119
|
+
mode: 'symlink',
|
|
1120
|
+
symlinkFailed: true
|
|
1121
|
+
};
|
|
1122
|
+
}
|
|
1123
|
+
return {
|
|
1124
|
+
success: true,
|
|
1125
|
+
path: agentDir,
|
|
1126
|
+
canonicalPath: canonicalDir,
|
|
1127
|
+
mode: 'symlink'
|
|
1128
|
+
};
|
|
1129
|
+
} catch (error) {
|
|
1130
|
+
return {
|
|
1131
|
+
success: false,
|
|
1132
|
+
path: agentDir,
|
|
1133
|
+
mode: installMode,
|
|
1134
|
+
error: error instanceof Error ? error.message : 'Unknown error'
|
|
1135
|
+
};
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
async installToAgents(sourcePath, skillName, targetAgents, options = {}) {
|
|
1139
|
+
const results = new Map();
|
|
1140
|
+
for (const agent of targetAgents){
|
|
1141
|
+
const result = await this.installForAgent(sourcePath, skillName, agent, options);
|
|
1142
|
+
results.set(agent, result);
|
|
1143
|
+
}
|
|
1144
|
+
return results;
|
|
1145
|
+
}
|
|
1146
|
+
isInstalled(skillName, agentType) {
|
|
1147
|
+
const skillPath = this.getAgentSkillPath(skillName, agentType);
|
|
1148
|
+
return external_node_fs_.existsSync(skillPath);
|
|
1149
|
+
}
|
|
1150
|
+
uninstallFromAgent(skillName, agentType) {
|
|
1151
|
+
const skillPath = this.getAgentSkillPath(skillName, agentType);
|
|
1152
|
+
if (!external_node_fs_.existsSync(skillPath)) return false;
|
|
1153
|
+
installer_remove(skillPath);
|
|
1154
|
+
return true;
|
|
1155
|
+
}
|
|
1156
|
+
uninstallFromAgents(skillName, targetAgents) {
|
|
1157
|
+
const results = new Map();
|
|
1158
|
+
for (const agent of targetAgents)results.set(agent, this.uninstallFromAgent(skillName, agent));
|
|
1159
|
+
const canonicalPath = this.getCanonicalPath(skillName);
|
|
1160
|
+
if (external_node_fs_.existsSync(canonicalPath)) installer_remove(canonicalPath);
|
|
1161
|
+
return results;
|
|
1162
|
+
}
|
|
1163
|
+
listInstalledSkills(agentType) {
|
|
1164
|
+
const agent = getAgentConfig(agentType);
|
|
1165
|
+
const skillsDir = this.isGlobal ? agent.globalSkillsDir : __WEBPACK_EXTERNAL_MODULE_node_path__.join(this.cwd, agent.skillsDir);
|
|
1166
|
+
if (!external_node_fs_.existsSync(skillsDir)) return [];
|
|
1167
|
+
return external_node_fs_.readdirSync(skillsDir, {
|
|
1168
|
+
withFileTypes: true
|
|
1169
|
+
}).filter((entry)=>entry.isDirectory() || entry.isSymbolicLink()).map((entry)=>entry.name);
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
830
1172
|
class SkillManager {
|
|
831
1173
|
projectRoot;
|
|
832
1174
|
resolver;
|
|
@@ -1056,57 +1398,327 @@ class SkillManager {
|
|
|
1056
1398
|
}
|
|
1057
1399
|
return results;
|
|
1058
1400
|
}
|
|
1401
|
+
async installToAgents(ref, targetAgents, options = {}) {
|
|
1402
|
+
const { save = true, mode = 'symlink' } = options;
|
|
1403
|
+
const resolved = await this.resolver.resolve(ref);
|
|
1404
|
+
const { parsed, repoUrl } = resolved;
|
|
1405
|
+
const version = resolved.ref;
|
|
1406
|
+
const skillName = parsed.subPath ? __WEBPACK_EXTERNAL_MODULE_node_path__.basename(parsed.subPath) : parsed.repo;
|
|
1407
|
+
logger["package"](`Installing ${skillName}@${version} to ${targetAgents.length} agent(s)...`);
|
|
1408
|
+
let cacheResult = await this.cache.get(parsed, version);
|
|
1409
|
+
if (cacheResult) logger.debug(`Using cached ${skillName}@${version}`);
|
|
1410
|
+
else {
|
|
1411
|
+
logger.debug(`Caching ${skillName}@${version} from ${repoUrl}`);
|
|
1412
|
+
cacheResult = await this.cache.cache(repoUrl, parsed, version, version);
|
|
1413
|
+
}
|
|
1414
|
+
const sourcePath = this.cache.getCachePath(parsed, version);
|
|
1415
|
+
const installer = new Installer({
|
|
1416
|
+
cwd: this.projectRoot,
|
|
1417
|
+
global: this.isGlobal
|
|
1418
|
+
});
|
|
1419
|
+
const results = await installer.installToAgents(sourcePath, skillName, targetAgents, {
|
|
1420
|
+
mode: mode
|
|
1421
|
+
});
|
|
1422
|
+
if (!this.isGlobal) this.lockManager.lockSkill(skillName, {
|
|
1423
|
+
source: `${parsed.registry}:${parsed.owner}/${parsed.repo}${parsed.subPath ? '/' + parsed.subPath : ''}`,
|
|
1424
|
+
version,
|
|
1425
|
+
resolved: repoUrl,
|
|
1426
|
+
commit: cacheResult.commit
|
|
1427
|
+
});
|
|
1428
|
+
if (!this.isGlobal && save && this.config.exists()) this.config.addSkill(skillName, ref);
|
|
1429
|
+
const successCount = Array.from(results.values()).filter((r)=>r.success).length;
|
|
1430
|
+
const failCount = results.size - successCount;
|
|
1431
|
+
if (0 === failCount) logger.success(`Installed ${skillName}@${version} to ${successCount} agent(s)`);
|
|
1432
|
+
else logger.warn(`Installed ${skillName}@${version} to ${successCount} agent(s), ${failCount} failed`);
|
|
1433
|
+
const skill = {
|
|
1434
|
+
name: skillName,
|
|
1435
|
+
path: sourcePath,
|
|
1436
|
+
version,
|
|
1437
|
+
source: `${parsed.registry}:${parsed.owner}/${parsed.repo}${parsed.subPath ? '/' + parsed.subPath : ''}`
|
|
1438
|
+
};
|
|
1439
|
+
return {
|
|
1440
|
+
skill,
|
|
1441
|
+
results
|
|
1442
|
+
};
|
|
1443
|
+
}
|
|
1444
|
+
async getDefaultTargetAgents() {
|
|
1445
|
+
const defaults = this.config.getDefaults();
|
|
1446
|
+
if (defaults.targetAgents && defaults.targetAgents.length > 0) return defaults.targetAgents.filter(isValidAgentType);
|
|
1447
|
+
return detectInstalledAgents();
|
|
1448
|
+
}
|
|
1449
|
+
getDefaultInstallMode() {
|
|
1450
|
+
const defaults = this.config.getDefaults();
|
|
1451
|
+
if ('copy' === defaults.installMode || 'symlink' === defaults.installMode) return defaults.installMode;
|
|
1452
|
+
return 'symlink';
|
|
1453
|
+
}
|
|
1454
|
+
validateAgentTypes(agentNames) {
|
|
1455
|
+
const valid = [];
|
|
1456
|
+
const invalid = [];
|
|
1457
|
+
for (const name of agentNames)if (isValidAgentType(name)) valid.push(name);
|
|
1458
|
+
else invalid.push(name);
|
|
1459
|
+
return {
|
|
1460
|
+
valid,
|
|
1461
|
+
invalid
|
|
1462
|
+
};
|
|
1463
|
+
}
|
|
1464
|
+
getAllAgentTypes() {
|
|
1465
|
+
return Object.keys(agents);
|
|
1466
|
+
}
|
|
1467
|
+
uninstallFromAgents(name, targetAgents) {
|
|
1468
|
+
const installer = new Installer({
|
|
1469
|
+
cwd: this.projectRoot,
|
|
1470
|
+
global: this.isGlobal
|
|
1471
|
+
});
|
|
1472
|
+
const results = installer.uninstallFromAgents(name, targetAgents);
|
|
1473
|
+
if (!this.isGlobal) this.lockManager.remove(name);
|
|
1474
|
+
if (!this.isGlobal && this.config.exists()) this.config.removeSkill(name);
|
|
1475
|
+
const successCount = Array.from(results.values()).filter((r)=>r).length;
|
|
1476
|
+
logger.success(`Uninstalled ${name} from ${successCount} agent(s)`);
|
|
1477
|
+
return results;
|
|
1478
|
+
}
|
|
1059
1479
|
}
|
|
1060
|
-
|
|
1061
|
-
const
|
|
1480
|
+
function formatAgentNames(agentTypes, maxShow = 5) {
|
|
1481
|
+
const names = agentTypes.map((a)=>agents[a].displayName);
|
|
1482
|
+
if (names.length <= maxShow) return names.join(', ');
|
|
1483
|
+
const shown = names.slice(0, maxShow);
|
|
1484
|
+
const remaining = names.length - maxShow;
|
|
1485
|
+
return `${shown.join(', ')} +${remaining} more`;
|
|
1486
|
+
}
|
|
1487
|
+
const installCommand = new __WEBPACK_EXTERNAL_MODULE_commander__.Command('install').alias('i').description('Install a skill or all skills from skills.json').argument('[skill]', 'Skill reference (e.g., github:user/skill@v1.0.0 or git@github.com:user/repo.git)').option('-f, --force', 'Force reinstall even if already installed').option('-g, --global', 'Install globally to user home directory').option('--no-save', 'Do not save to skills.json').option('-a, --agent <agents...>', 'Specify target agents (e.g., cursor, claude-code)').option('--mode <mode>', 'Installation mode: symlink or copy').option('-y, --yes', 'Skip confirmation prompts').option('--all', 'Install to all agents (implies -y -g)').action(async (skill, options)=>{
|
|
1488
|
+
if (options.all) {
|
|
1489
|
+
options.yes = true;
|
|
1490
|
+
options.global = true;
|
|
1491
|
+
}
|
|
1492
|
+
const skipConfirm = options.yes || false;
|
|
1062
1493
|
const configLoader = new ConfigLoader();
|
|
1063
|
-
const
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1494
|
+
const allAgentTypes = Object.keys(agents);
|
|
1495
|
+
console.log();
|
|
1496
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.intro(__WEBPACK_EXTERNAL_MODULE_chalk__["default"].bgCyan.black(' reskill '));
|
|
1497
|
+
try {
|
|
1498
|
+
const spinner = __WEBPACK_EXTERNAL_MODULE__clack_prompts__.spinner();
|
|
1499
|
+
let targetAgents;
|
|
1500
|
+
if (options.all) {
|
|
1501
|
+
targetAgents = allAgentTypes;
|
|
1502
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.info(`Installing to all ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].cyan(targetAgents.length)} agents`);
|
|
1503
|
+
} else if (options.agent && options.agent.length > 0) {
|
|
1504
|
+
const validAgents = Object.keys(agents);
|
|
1505
|
+
const invalidAgents = options.agent.filter((a)=>!validAgents.includes(a));
|
|
1506
|
+
if (invalidAgents.length > 0) {
|
|
1507
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.error(`Invalid agents: ${invalidAgents.join(', ')}`);
|
|
1508
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.info(`Valid agents: ${validAgents.join(', ')}`);
|
|
1509
|
+
process.exit(1);
|
|
1510
|
+
}
|
|
1511
|
+
targetAgents = options.agent;
|
|
1512
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.info(`Installing to: ${formatAgentNames(targetAgents)}`);
|
|
1513
|
+
} else {
|
|
1514
|
+
spinner.start('Detecting installed agents...');
|
|
1515
|
+
const installedAgents = await detectInstalledAgents();
|
|
1516
|
+
spinner.stop(`Detected ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].green(installedAgents.length)} agent${1 !== installedAgents.length ? 's' : ''}`);
|
|
1517
|
+
if (0 === installedAgents.length) {
|
|
1518
|
+
if (skipConfirm) {
|
|
1519
|
+
targetAgents = allAgentTypes;
|
|
1520
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.info('Installing to all agents (none detected)');
|
|
1521
|
+
} else {
|
|
1522
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.warn('No coding agents detected. You can still install skills.');
|
|
1523
|
+
const allAgentChoices = Object.entries(agents).map(([key, config])=>({
|
|
1524
|
+
value: key,
|
|
1525
|
+
label: config.displayName
|
|
1526
|
+
}));
|
|
1527
|
+
const selected = await __WEBPACK_EXTERNAL_MODULE__clack_prompts__.multiselect({
|
|
1528
|
+
message: 'Select agents to install skills to',
|
|
1529
|
+
options: allAgentChoices,
|
|
1530
|
+
required: true,
|
|
1531
|
+
initialValues: allAgentTypes
|
|
1532
|
+
});
|
|
1533
|
+
if (__WEBPACK_EXTERNAL_MODULE__clack_prompts__.isCancel(selected)) {
|
|
1534
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.cancel('Installation cancelled');
|
|
1535
|
+
process.exit(0);
|
|
1536
|
+
}
|
|
1537
|
+
targetAgents = selected;
|
|
1538
|
+
}
|
|
1539
|
+
} else if (1 === installedAgents.length || skipConfirm) {
|
|
1540
|
+
targetAgents = installedAgents;
|
|
1541
|
+
if (1 === installedAgents.length) __WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.info(`Installing to: ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].cyan(agents[installedAgents[0]].displayName)}`);
|
|
1542
|
+
else __WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.info(`Installing to: ${installedAgents.map((a)=>__WEBPACK_EXTERNAL_MODULE_chalk__["default"].cyan(agents[a].displayName)).join(', ')}`);
|
|
1543
|
+
} else {
|
|
1544
|
+
const agentChoices = installedAgents.map((a)=>({
|
|
1545
|
+
value: a,
|
|
1546
|
+
label: agents[a].displayName,
|
|
1547
|
+
hint: agents[a].skillsDir
|
|
1548
|
+
}));
|
|
1549
|
+
const selected = await __WEBPACK_EXTERNAL_MODULE__clack_prompts__.multiselect({
|
|
1550
|
+
message: 'Select agents to install skills to',
|
|
1551
|
+
options: agentChoices,
|
|
1552
|
+
required: true,
|
|
1553
|
+
initialValues: installedAgents
|
|
1554
|
+
});
|
|
1555
|
+
if (__WEBPACK_EXTERNAL_MODULE__clack_prompts__.isCancel(selected)) {
|
|
1556
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.cancel('Installation cancelled');
|
|
1557
|
+
process.exit(0);
|
|
1558
|
+
}
|
|
1559
|
+
targetAgents = selected;
|
|
1560
|
+
}
|
|
1086
1561
|
}
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1562
|
+
let installGlobally = options.global ?? false;
|
|
1563
|
+
if (void 0 === options.global && !skipConfirm) {
|
|
1564
|
+
const scope = await __WEBPACK_EXTERNAL_MODULE__clack_prompts__.select({
|
|
1565
|
+
message: 'Installation scope',
|
|
1566
|
+
options: [
|
|
1567
|
+
{
|
|
1568
|
+
value: false,
|
|
1569
|
+
label: 'Project',
|
|
1570
|
+
hint: 'Install in current directory (committed with your project)'
|
|
1571
|
+
},
|
|
1572
|
+
{
|
|
1573
|
+
value: true,
|
|
1574
|
+
label: 'Global',
|
|
1575
|
+
hint: 'Install in home directory (available across all projects)'
|
|
1576
|
+
}
|
|
1577
|
+
]
|
|
1578
|
+
});
|
|
1579
|
+
if (__WEBPACK_EXTERNAL_MODULE__clack_prompts__.isCancel(scope)) {
|
|
1580
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.cancel('Installation cancelled');
|
|
1581
|
+
process.exit(0);
|
|
1582
|
+
}
|
|
1583
|
+
installGlobally = scope;
|
|
1090
1584
|
}
|
|
1091
|
-
|
|
1092
|
-
if (
|
|
1093
|
-
|
|
1094
|
-
|
|
1585
|
+
let installMode = options.mode || 'symlink';
|
|
1586
|
+
if (!options.mode && !skipConfirm) {
|
|
1587
|
+
const modeChoice = await __WEBPACK_EXTERNAL_MODULE__clack_prompts__.select({
|
|
1588
|
+
message: 'Installation method',
|
|
1589
|
+
options: [
|
|
1590
|
+
{
|
|
1591
|
+
value: 'symlink',
|
|
1592
|
+
label: 'Symlink (Recommended)',
|
|
1593
|
+
hint: 'Single source of truth, easy updates'
|
|
1594
|
+
},
|
|
1595
|
+
{
|
|
1596
|
+
value: 'copy',
|
|
1597
|
+
label: 'Copy to all agents',
|
|
1598
|
+
hint: 'Independent copies for each agent'
|
|
1599
|
+
}
|
|
1600
|
+
]
|
|
1601
|
+
});
|
|
1602
|
+
if (__WEBPACK_EXTERNAL_MODULE__clack_prompts__.isCancel(modeChoice)) {
|
|
1603
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.cancel('Installation cancelled');
|
|
1604
|
+
process.exit(0);
|
|
1605
|
+
}
|
|
1606
|
+
installMode = modeChoice;
|
|
1095
1607
|
}
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1608
|
+
const skillManager = new SkillManager(void 0, {
|
|
1609
|
+
global: installGlobally
|
|
1610
|
+
});
|
|
1611
|
+
const cwd = process.cwd();
|
|
1612
|
+
if (skill) {
|
|
1613
|
+
const summaryLines = [];
|
|
1614
|
+
summaryLines.push(`${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].cyan(skill)}`);
|
|
1615
|
+
summaryLines.push(` ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].dim('→')} ${formatAgentNames(targetAgents)}`);
|
|
1616
|
+
summaryLines.push(` ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].dim('Scope:')} ${installGlobally ? 'Global' : 'Project'}${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].dim(', Mode:')} ${installMode}`);
|
|
1617
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.note(summaryLines.join('\n'), 'Installation Summary');
|
|
1618
|
+
if (!skipConfirm) {
|
|
1619
|
+
const confirmed = await __WEBPACK_EXTERNAL_MODULE__clack_prompts__.confirm({
|
|
1620
|
+
message: 'Proceed with installation?'
|
|
1621
|
+
});
|
|
1622
|
+
if (__WEBPACK_EXTERNAL_MODULE__clack_prompts__.isCancel(confirmed) || !confirmed) {
|
|
1623
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.cancel('Installation cancelled');
|
|
1624
|
+
process.exit(0);
|
|
1625
|
+
}
|
|
1626
|
+
}
|
|
1627
|
+
spinner.start(`Installing ${skill}...`);
|
|
1628
|
+
const { skill: installed, results } = await skillManager.installToAgents(skill, targetAgents, {
|
|
1629
|
+
force: options.force,
|
|
1630
|
+
save: options.save && !installGlobally,
|
|
1631
|
+
mode: installMode
|
|
1101
1632
|
});
|
|
1102
|
-
spinner.stop();
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1633
|
+
spinner.stop('Installation complete');
|
|
1634
|
+
const successful = Array.from(results.entries()).filter(([, r])=>r.success);
|
|
1635
|
+
const failed = Array.from(results.entries()).filter(([, r])=>!r.success);
|
|
1636
|
+
const symlinkFailed = successful.filter(([, r])=>'symlink' === r.mode && r.symlinkFailed);
|
|
1637
|
+
if (successful.length > 0) {
|
|
1638
|
+
const resultLines = [];
|
|
1639
|
+
const firstResult = successful[0][1];
|
|
1640
|
+
if ('copy' === firstResult.mode) {
|
|
1641
|
+
resultLines.push(`${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].green('✓')} ${installed.name}@${installed.version} ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].dim('(copied)')}`);
|
|
1642
|
+
for (const [, result] of successful){
|
|
1643
|
+
const shortPath = shortenPath(result.path, cwd);
|
|
1644
|
+
resultLines.push(` ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].dim('→')} ${shortPath}`);
|
|
1645
|
+
}
|
|
1646
|
+
} else {
|
|
1647
|
+
if (firstResult.canonicalPath) {
|
|
1648
|
+
const shortPath = shortenPath(firstResult.canonicalPath, cwd);
|
|
1649
|
+
resultLines.push(`${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].green('✓')} ${shortPath}`);
|
|
1650
|
+
} else resultLines.push(`${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].green('✓')} ${installed.name}@${installed.version}`);
|
|
1651
|
+
const symlinked = successful.filter(([, r])=>!r.symlinkFailed).map(([a])=>agents[a].displayName);
|
|
1652
|
+
const copied = successful.filter(([, r])=>r.symlinkFailed).map(([a])=>agents[a].displayName);
|
|
1653
|
+
if (symlinked.length > 0) resultLines.push(` ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].dim('symlink →')} ${symlinked.join(', ')}`);
|
|
1654
|
+
if (copied.length > 0) resultLines.push(` ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].yellow('copied →')} ${copied.join(', ')}`);
|
|
1655
|
+
}
|
|
1656
|
+
const title = __WEBPACK_EXTERNAL_MODULE_chalk__["default"].green(`Installed 1 skill to ${successful.length} agent${1 !== successful.length ? 's' : ''}`);
|
|
1657
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.note(resultLines.join('\n'), title);
|
|
1658
|
+
if (symlinkFailed.length > 0) {
|
|
1659
|
+
const copiedAgentNames = symlinkFailed.map(([a])=>agents[a].displayName);
|
|
1660
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.warn(__WEBPACK_EXTERNAL_MODULE_chalk__["default"].yellow(`Symlinks failed for: ${copiedAgentNames.join(', ')}`));
|
|
1661
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.message(__WEBPACK_EXTERNAL_MODULE_chalk__["default"].dim(' Files were copied instead. On Windows, enable Developer Mode for symlink support.'));
|
|
1662
|
+
}
|
|
1663
|
+
}
|
|
1664
|
+
if (failed.length > 0) {
|
|
1665
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.error(__WEBPACK_EXTERNAL_MODULE_chalk__["default"].red(`Failed to install to ${failed.length} agent(s)`));
|
|
1666
|
+
for (const [agent, result] of failed)__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.message(` ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].red('✗')} ${agents[agent].displayName}: ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].dim(result.error)}`);
|
|
1667
|
+
}
|
|
1668
|
+
} else {
|
|
1669
|
+
if (installGlobally) {
|
|
1670
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.error('Cannot install all skills globally. Please specify a skill to install.');
|
|
1671
|
+
process.exit(1);
|
|
1672
|
+
}
|
|
1673
|
+
if (!configLoader.exists()) {
|
|
1674
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.error("skills.json not found. Run 'reskill init' first.");
|
|
1675
|
+
process.exit(1);
|
|
1676
|
+
}
|
|
1677
|
+
const skills = configLoader.getSkills();
|
|
1678
|
+
if (0 === Object.keys(skills).length) {
|
|
1679
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.info('No skills defined in skills.json');
|
|
1680
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.outro('Done');
|
|
1681
|
+
return;
|
|
1682
|
+
}
|
|
1683
|
+
const summaryLines = [];
|
|
1684
|
+
summaryLines.push(`${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].cyan(Object.keys(skills).length)} skill(s) → ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].cyan(targetAgents.length)} agent(s)`);
|
|
1685
|
+
summaryLines.push(`${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].dim('Scope:')} ${installGlobally ? 'Global (~/)' : 'Project (./)'}${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].dim(', Mode:')} ${installMode}`);
|
|
1686
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.note(summaryLines.join('\n'), 'Installation Summary');
|
|
1687
|
+
if (!skipConfirm) {
|
|
1688
|
+
const confirmed = await __WEBPACK_EXTERNAL_MODULE__clack_prompts__.confirm({
|
|
1689
|
+
message: 'Proceed with installation?'
|
|
1690
|
+
});
|
|
1691
|
+
if (__WEBPACK_EXTERNAL_MODULE__clack_prompts__.isCancel(confirmed) || !confirmed) {
|
|
1692
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.cancel('Installation cancelled');
|
|
1693
|
+
process.exit(0);
|
|
1694
|
+
}
|
|
1695
|
+
}
|
|
1696
|
+
spinner.start('Installing skills...');
|
|
1697
|
+
let totalInstalled = 0;
|
|
1698
|
+
let totalFailed = 0;
|
|
1699
|
+
for (const [name, ref] of Object.entries(skills))try {
|
|
1700
|
+
const { results } = await skillManager.installToAgents(ref, targetAgents, {
|
|
1701
|
+
force: options.force,
|
|
1702
|
+
save: false,
|
|
1703
|
+
mode: installMode
|
|
1704
|
+
});
|
|
1705
|
+
const successCount = Array.from(results.values()).filter((r)=>r.success).length;
|
|
1706
|
+
totalInstalled += successCount;
|
|
1707
|
+
totalFailed += results.size - successCount;
|
|
1708
|
+
} catch (error) {
|
|
1709
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.error(`Failed to install ${name}: ${error.message}`);
|
|
1710
|
+
totalFailed += targetAgents.length;
|
|
1711
|
+
}
|
|
1712
|
+
spinner.stop('Installation complete');
|
|
1713
|
+
if (0 === totalFailed) __WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.success(`Installed ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].green(Object.keys(skills).length)} skill(s) to ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].green(targetAgents.length)} agent(s)`);
|
|
1714
|
+
else __WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.warn(`Installed ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].green(totalInstalled)} successfully, ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].red(totalFailed)} failed`);
|
|
1109
1715
|
}
|
|
1716
|
+
console.log();
|
|
1717
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.outro(__WEBPACK_EXTERNAL_MODULE_chalk__["default"].green('Done!'));
|
|
1718
|
+
} catch (error) {
|
|
1719
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.error(error.message);
|
|
1720
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.outro(__WEBPACK_EXTERNAL_MODULE_chalk__["default"].red('Installation failed'));
|
|
1721
|
+
process.exit(1);
|
|
1110
1722
|
}
|
|
1111
1723
|
});
|
|
1112
1724
|
const listCommand = new __WEBPACK_EXTERNAL_MODULE_commander__.Command('list').alias('ls').description('List installed skills').option('-j, --json', 'Output as JSON').option('-g, --global', 'List globally installed skills').action((options)=>{
|