reskill 0.16.0 → 0.17.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 +0 -3
- package/README.zh-CN.md +0 -3
- package/dist/cli/commands/completion.d.ts.map +1 -1
- package/dist/cli/commands/index.d.ts +0 -1
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/install.d.ts +10 -11
- package/dist/cli/commands/install.d.ts.map +1 -1
- package/dist/cli/index.js +331 -333
- package/dist/core/config-loader.d.ts +63 -15
- package/dist/core/config-loader.d.ts.map +1 -1
- package/dist/core/skill-manager.d.ts +0 -8
- package/dist/core/skill-manager.d.ts.map +1 -1
- package/dist/index.js +44 -58
- package/package.json +1 -1
- package/dist/cli/commands/link.d.ts +0 -5
- package/dist/cli/commands/link.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -42,7 +42,6 @@ reskill offers **fine-grained skill management and synchronization**:
|
|
|
42
42
|
|
|
43
43
|
- **Declarative config** — `skills.json` clearly expresses project dependencies
|
|
44
44
|
- **Global cache** — Avoid redundant downloads, speed up installation
|
|
45
|
-
- **Local development** — Use `link` to develop and debug skills locally
|
|
46
45
|
|
|
47
46
|
### Engineering-Grade Management
|
|
48
47
|
|
|
@@ -151,8 +150,6 @@ npx reskill@latest list
|
|
|
151
150
|
| `npx reskill@latest update [skill]` | Update all or specific skill |
|
|
152
151
|
| `npx reskill@latest outdated` | Check for outdated skills |
|
|
153
152
|
| `npx reskill@latest uninstall <skill>` | Remove a skill |
|
|
154
|
-
| `npx reskill@latest link <path>` | Link local skill for development |
|
|
155
|
-
| `npx reskill@latest unlink <skill>` | Unlink a local skill |
|
|
156
153
|
| `npx reskill@latest completion install` | Install shell tab completion |
|
|
157
154
|
|
|
158
155
|
Run `npx reskill@latest <command> --help` for detailed options.
|
package/README.zh-CN.md
CHANGED
|
@@ -42,7 +42,6 @@ reskill 提供**精细化的 skill 管理和同步方案**:
|
|
|
42
42
|
|
|
43
43
|
- **声明式配置** — `skills.json` 清晰表达项目依赖
|
|
44
44
|
- **全局缓存** — 避免重复下载,加速安装
|
|
45
|
-
- **本地开发** — 使用 `link` 链接本地 skill 进行开发调试
|
|
46
45
|
|
|
47
46
|
### 工程化项目管理
|
|
48
47
|
|
|
@@ -152,8 +151,6 @@ npx reskill@latest list
|
|
|
152
151
|
| `npx reskill@latest update [skill]` | 更新所有或指定 skill |
|
|
153
152
|
| `npx reskill@latest outdated` | 检查过期的 skills |
|
|
154
153
|
| `npx reskill@latest uninstall <skill>` | 卸载 skill |
|
|
155
|
-
| `npx reskill@latest link <path>` | 链接本地 skill(开发用) |
|
|
156
|
-
| `npx reskill@latest unlink <skill>` | 取消链接本地 skill |
|
|
157
154
|
| `npx reskill@latest completion install` | 安装 Shell Tab 补全 |
|
|
158
155
|
|
|
159
156
|
运行 `npx reskill@latest <command> --help` 查看详细选项。
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"completion.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/completion.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"completion.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/completion.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA2IpC;;GAEG;AACH,eAAO,MAAM,iBAAiB,SA2D1B,CAAC;AAEL;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,CAO/C;AAED,eAAe,iBAAiB,CAAC"}
|
|
@@ -2,7 +2,6 @@ export { completionCommand, maybeHandleCompletion } from './completion.js';
|
|
|
2
2
|
export { infoCommand } from './info.js';
|
|
3
3
|
export { initCommand } from './init.js';
|
|
4
4
|
export { installCommand } from './install.js';
|
|
5
|
-
export { linkCommand, unlinkCommand } from './link.js';
|
|
6
5
|
export { listCommand } from './list.js';
|
|
7
6
|
export { outdatedCommand } from './outdated.js';
|
|
8
7
|
export { uninstallCommand } from './uninstall.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
/**
|
|
3
|
-
* install command - Install a skill
|
|
3
|
+
* install command - Install a skill or all skills from skills.json
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* Installation Flow:
|
|
6
|
+
* 1. Resolve target agents (CLI > stored > detected > prompt)
|
|
7
|
+
* 2. Resolve installation scope (global vs project)
|
|
8
|
+
* 3. Resolve installation mode (symlink vs copy)
|
|
9
|
+
* 4. Execute installation
|
|
10
|
+
* 5. Save defaults for future installs
|
|
9
11
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* 3. Select installation scope (project/global)
|
|
14
|
-
* 4. Select installation method (symlink/copy)
|
|
15
|
-
* 5. Confirm and execute
|
|
12
|
+
* Behavior:
|
|
13
|
+
* - Single skill install: Prompts for agents/mode (stored config as defaults)
|
|
14
|
+
* - Reinstall all (no args): Uses stored config directly, no confirmation
|
|
16
15
|
*/
|
|
17
16
|
export declare const installCommand: Command;
|
|
18
17
|
export default installCommand;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/install.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/install.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkjBpC;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,cAAc,SA6DvB,CAAC;AAEL,eAAe,cAAc,CAAC"}
|
package/dist/cli/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import * as __WEBPACK_EXTERNAL_MODULE_node_fs__ from "node:fs";
|
|
3
|
+
import * as __WEBPACK_EXTERNAL_MODULE_commander__ from "commander";
|
|
3
4
|
import * as __WEBPACK_EXTERNAL_MODULE_node_path__ from "node:path";
|
|
4
5
|
import * as __WEBPACK_EXTERNAL_MODULE_node_url__ from "node:url";
|
|
5
|
-
import * as __WEBPACK_EXTERNAL_MODULE_commander__ from "commander";
|
|
6
6
|
import * as __WEBPACK_EXTERNAL_MODULE_chalk__ from "chalk";
|
|
7
7
|
import * as __WEBPACK_EXTERNAL_MODULE_semver__ from "semver";
|
|
8
8
|
import * as __WEBPACK_EXTERNAL_MODULE_tabtab__ from "tabtab";
|
|
@@ -287,12 +287,6 @@ function isSymlink(targetPath) {
|
|
|
287
287
|
if (!exists(targetPath)) return false;
|
|
288
288
|
return external_node_fs_.lstatSync(targetPath).isSymbolicLink();
|
|
289
289
|
}
|
|
290
|
-
function createSymlink(target, linkPath) {
|
|
291
|
-
const linkDir = __WEBPACK_EXTERNAL_MODULE_node_path__.dirname(linkPath);
|
|
292
|
-
ensureDir(linkDir);
|
|
293
|
-
if (exists(linkPath)) remove(linkPath);
|
|
294
|
-
external_node_fs_.symlinkSync(target, linkPath, 'dir');
|
|
295
|
-
}
|
|
296
290
|
function getRealPath(linkPath) {
|
|
297
291
|
return external_node_fs_.realpathSync(linkPath);
|
|
298
292
|
}
|
|
@@ -841,6 +835,12 @@ const DEFAULT_SKILLS_JSON = {
|
|
|
841
835
|
installDir: '.skills'
|
|
842
836
|
}
|
|
843
837
|
};
|
|
838
|
+
const DEFAULT_VALUES = {
|
|
839
|
+
registry: 'github',
|
|
840
|
+
installDir: '.skills',
|
|
841
|
+
targetAgents: [],
|
|
842
|
+
installMode: 'symlink'
|
|
843
|
+
};
|
|
844
844
|
const DEFAULT_REGISTRIES = {
|
|
845
845
|
github: 'https://github.com',
|
|
846
846
|
gitlab: 'https://gitlab.com'
|
|
@@ -850,7 +850,7 @@ class ConfigLoader {
|
|
|
850
850
|
configPath;
|
|
851
851
|
config = null;
|
|
852
852
|
constructor(projectRoot){
|
|
853
|
-
this.projectRoot = projectRoot
|
|
853
|
+
this.projectRoot = projectRoot ?? process.cwd();
|
|
854
854
|
this.configPath = getSkillsJsonPath(this.projectRoot);
|
|
855
855
|
}
|
|
856
856
|
getProjectRoot() {
|
|
@@ -859,6 +859,10 @@ class ConfigLoader {
|
|
|
859
859
|
getConfigPath() {
|
|
860
860
|
return this.configPath;
|
|
861
861
|
}
|
|
862
|
+
getInstallDir() {
|
|
863
|
+
const { installDir } = this.getDefaults();
|
|
864
|
+
return __WEBPACK_EXTERNAL_MODULE_node_path__.join(this.projectRoot, installDir);
|
|
865
|
+
}
|
|
862
866
|
exists() {
|
|
863
867
|
return exists(this.configPath);
|
|
864
868
|
}
|
|
@@ -877,7 +881,7 @@ class ConfigLoader {
|
|
|
877
881
|
return this.load();
|
|
878
882
|
}
|
|
879
883
|
save(config) {
|
|
880
|
-
const toSave = config
|
|
884
|
+
const toSave = config ?? this.config;
|
|
881
885
|
if (!toSave) throw new Error('No config to save');
|
|
882
886
|
writeJson(this.configPath, toSave);
|
|
883
887
|
this.config = toSave;
|
|
@@ -891,7 +895,7 @@ class ConfigLoader {
|
|
|
891
895
|
const config = {
|
|
892
896
|
...DEFAULT_SKILLS_JSON,
|
|
893
897
|
...options,
|
|
894
|
-
skills: options?.skills
|
|
898
|
+
skills: options?.skills ?? {},
|
|
895
899
|
defaults: {
|
|
896
900
|
...DEFAULT_SKILLS_JSON.defaults,
|
|
897
901
|
...options?.defaults
|
|
@@ -901,31 +905,40 @@ class ConfigLoader {
|
|
|
901
905
|
return config;
|
|
902
906
|
}
|
|
903
907
|
getDefaults() {
|
|
904
|
-
const config = this.
|
|
908
|
+
const config = this.getConfigOrDefault();
|
|
909
|
+
const storedDefaults = config.defaults ?? {};
|
|
905
910
|
return {
|
|
906
|
-
registry:
|
|
907
|
-
installDir:
|
|
908
|
-
targetAgents:
|
|
909
|
-
installMode:
|
|
911
|
+
registry: storedDefaults.registry ?? DEFAULT_VALUES.registry,
|
|
912
|
+
installDir: storedDefaults.installDir ?? DEFAULT_VALUES.installDir,
|
|
913
|
+
targetAgents: storedDefaults.targetAgents ?? DEFAULT_VALUES.targetAgents,
|
|
914
|
+
installMode: storedDefaults.installMode ?? DEFAULT_VALUES.installMode
|
|
910
915
|
};
|
|
911
916
|
}
|
|
917
|
+
updateDefaults(updates) {
|
|
918
|
+
this.ensureConfigLoaded();
|
|
919
|
+
if (this.config) {
|
|
920
|
+
this.config.defaults = {
|
|
921
|
+
...this.config.defaults,
|
|
922
|
+
...updates
|
|
923
|
+
};
|
|
924
|
+
this.save();
|
|
925
|
+
}
|
|
926
|
+
}
|
|
912
927
|
getRegistryUrl(registryName) {
|
|
913
|
-
const config = this.
|
|
928
|
+
const config = this.getConfigOrDefault();
|
|
914
929
|
if (config.registries?.[registryName]) return config.registries[registryName];
|
|
915
930
|
if (DEFAULT_REGISTRIES[registryName]) return DEFAULT_REGISTRIES[registryName];
|
|
916
931
|
return `https://${registryName}`;
|
|
917
932
|
}
|
|
918
|
-
getInstallDir() {
|
|
919
|
-
const defaults = this.getDefaults();
|
|
920
|
-
return __WEBPACK_EXTERNAL_MODULE_node_path__.join(this.projectRoot, defaults.installDir);
|
|
921
|
-
}
|
|
922
933
|
addSkill(name, ref) {
|
|
923
|
-
|
|
924
|
-
if (this.config)
|
|
925
|
-
|
|
934
|
+
this.ensureConfigLoaded();
|
|
935
|
+
if (this.config) {
|
|
936
|
+
this.config.skills[name] = ref;
|
|
937
|
+
this.save();
|
|
938
|
+
}
|
|
926
939
|
}
|
|
927
940
|
removeSkill(name) {
|
|
928
|
-
|
|
941
|
+
this.ensureConfigLoaded();
|
|
929
942
|
if (this.config?.skills[name]) {
|
|
930
943
|
delete this.config.skills[name];
|
|
931
944
|
this.save();
|
|
@@ -950,6 +963,14 @@ class ConfigLoader {
|
|
|
950
963
|
const skills = this.getSkills();
|
|
951
964
|
return skills[name];
|
|
952
965
|
}
|
|
966
|
+
getConfigOrDefault() {
|
|
967
|
+
if (this.config) return this.config;
|
|
968
|
+
if (this.exists()) return this.load();
|
|
969
|
+
return DEFAULT_SKILLS_JSON;
|
|
970
|
+
}
|
|
971
|
+
ensureConfigLoaded() {
|
|
972
|
+
if (!this.config) this.load();
|
|
973
|
+
}
|
|
953
974
|
}
|
|
954
975
|
class GitResolver {
|
|
955
976
|
defaultRegistry;
|
|
@@ -1405,41 +1426,6 @@ class SkillManager {
|
|
|
1405
1426
|
}
|
|
1406
1427
|
return updated;
|
|
1407
1428
|
}
|
|
1408
|
-
link(localPath, name) {
|
|
1409
|
-
const absolutePath = __WEBPACK_EXTERNAL_MODULE_node_path__.resolve(localPath);
|
|
1410
|
-
if (!exists(absolutePath)) throw new Error(`Path ${localPath} does not exist`);
|
|
1411
|
-
const skillJsonPath = __WEBPACK_EXTERNAL_MODULE_node_path__.join(absolutePath, 'skill.json');
|
|
1412
|
-
let skillName = name || __WEBPACK_EXTERNAL_MODULE_node_path__.basename(absolutePath);
|
|
1413
|
-
if (exists(skillJsonPath)) try {
|
|
1414
|
-
const skillJson = readJson(skillJsonPath);
|
|
1415
|
-
skillName = name || skillJson.name || skillName;
|
|
1416
|
-
} catch {}
|
|
1417
|
-
const linkPath = this.getSkillPath(skillName);
|
|
1418
|
-
ensureDir(__WEBPACK_EXTERNAL_MODULE_node_path__.dirname(linkPath));
|
|
1419
|
-
createSymlink(absolutePath, linkPath);
|
|
1420
|
-
logger_logger.success(`Linked ${skillName} → ${absolutePath}`);
|
|
1421
|
-
return {
|
|
1422
|
-
name: skillName,
|
|
1423
|
-
path: linkPath,
|
|
1424
|
-
version: 'local',
|
|
1425
|
-
source: absolutePath,
|
|
1426
|
-
isLinked: true
|
|
1427
|
-
};
|
|
1428
|
-
}
|
|
1429
|
-
unlink(name) {
|
|
1430
|
-
const skillPath = this.getSkillPath(name);
|
|
1431
|
-
if (!exists(skillPath)) {
|
|
1432
|
-
logger_logger.warn(`Skill ${name} is not installed`);
|
|
1433
|
-
return false;
|
|
1434
|
-
}
|
|
1435
|
-
if (!isSymlink(skillPath)) {
|
|
1436
|
-
logger_logger.warn(`Skill ${name} is not a linked skill`);
|
|
1437
|
-
return false;
|
|
1438
|
-
}
|
|
1439
|
-
remove(skillPath);
|
|
1440
|
-
logger_logger.success(`Unlinked ${name}`);
|
|
1441
|
-
return true;
|
|
1442
|
-
}
|
|
1443
1429
|
list() {
|
|
1444
1430
|
const skills = [];
|
|
1445
1431
|
const seenNames = new Set();
|
|
@@ -1646,14 +1632,6 @@ const SUBCOMMANDS = [
|
|
|
1646
1632
|
name: 'list',
|
|
1647
1633
|
description: 'List installed skills'
|
|
1648
1634
|
},
|
|
1649
|
-
{
|
|
1650
|
-
name: 'link',
|
|
1651
|
-
description: 'Link a local skill for development'
|
|
1652
|
-
},
|
|
1653
|
-
{
|
|
1654
|
-
name: 'unlink',
|
|
1655
|
-
description: 'Unlink a linked skill'
|
|
1656
|
-
},
|
|
1657
1635
|
{
|
|
1658
1636
|
name: 'init',
|
|
1659
1637
|
description: 'Initialize skills.json'
|
|
@@ -1672,9 +1650,6 @@ const SKILL_COMPLETION_COMMANDS = [
|
|
|
1672
1650
|
'uninstall',
|
|
1673
1651
|
'update'
|
|
1674
1652
|
];
|
|
1675
|
-
const LINKED_SKILL_COMMANDS = [
|
|
1676
|
-
'unlink'
|
|
1677
|
-
];
|
|
1678
1653
|
function getAgentNames() {
|
|
1679
1654
|
return Object.keys(agents);
|
|
1680
1655
|
}
|
|
@@ -1687,15 +1662,6 @@ function getInstalledSkillNames() {
|
|
|
1687
1662
|
return [];
|
|
1688
1663
|
}
|
|
1689
1664
|
}
|
|
1690
|
-
function getLinkedSkillNames() {
|
|
1691
|
-
try {
|
|
1692
|
-
const skillManager = new SkillManager();
|
|
1693
|
-
const skills = skillManager.list();
|
|
1694
|
-
return skills.filter((s)=>s.isLinked).map((s)=>s.name);
|
|
1695
|
-
} catch {
|
|
1696
|
-
return [];
|
|
1697
|
-
}
|
|
1698
|
-
}
|
|
1699
1665
|
function handleCompletion() {
|
|
1700
1666
|
const env = __WEBPACK_EXTERNAL_MODULE_tabtab__["default"].parseEnv(process.env);
|
|
1701
1667
|
if (!env.complete) return;
|
|
@@ -1723,19 +1689,6 @@ function handleCompletion() {
|
|
|
1723
1689
|
__WEBPACK_EXTERNAL_MODULE_tabtab__["default"].log(skills);
|
|
1724
1690
|
return;
|
|
1725
1691
|
}
|
|
1726
|
-
if (LINKED_SKILL_COMMANDS.includes(command)) {
|
|
1727
|
-
if (parts.length > 2 && line.endsWith(' ')) {
|
|
1728
|
-
__WEBPACK_EXTERNAL_MODULE_tabtab__["default"].log([]);
|
|
1729
|
-
return;
|
|
1730
|
-
}
|
|
1731
|
-
if (parts.length > 3) {
|
|
1732
|
-
__WEBPACK_EXTERNAL_MODULE_tabtab__["default"].log([]);
|
|
1733
|
-
return;
|
|
1734
|
-
}
|
|
1735
|
-
const skills = getLinkedSkillNames();
|
|
1736
|
-
__WEBPACK_EXTERNAL_MODULE_tabtab__["default"].log(skills);
|
|
1737
|
-
return;
|
|
1738
|
-
}
|
|
1739
1692
|
if ('install' === command && ('-a' === prev || '--agent' === prev)) {
|
|
1740
1693
|
const agentNames = getAgentNames();
|
|
1741
1694
|
__WEBPACK_EXTERNAL_MODULE_tabtab__["default"].log(agentNames);
|
|
@@ -1918,238 +1871,302 @@ function formatAgentNames(agentTypes, maxShow = 5) {
|
|
|
1918
1871
|
const remaining = names.length - maxShow;
|
|
1919
1872
|
return `${shown.join(', ')} +${remaining} more`;
|
|
1920
1873
|
}
|
|
1874
|
+
function formatColoredAgentNames(agentTypes) {
|
|
1875
|
+
return agentTypes.map((a)=>__WEBPACK_EXTERNAL_MODULE_chalk__["default"].cyan(agents[a].displayName)).join(', ');
|
|
1876
|
+
}
|
|
1877
|
+
function filterValidAgents(storedAgents, validAgents) {
|
|
1878
|
+
if (!storedAgents || 0 === storedAgents.length) return;
|
|
1879
|
+
const filtered = storedAgents.filter((a)=>validAgents.includes(a));
|
|
1880
|
+
return filtered.length > 0 ? filtered : void 0;
|
|
1881
|
+
}
|
|
1882
|
+
function createInstallContext(skill, options) {
|
|
1883
|
+
const configLoader = new ConfigLoader();
|
|
1884
|
+
const allAgentTypes = Object.keys(agents);
|
|
1885
|
+
const hasSkillsJson = configLoader.exists();
|
|
1886
|
+
const storedDefaults = hasSkillsJson ? configLoader.getDefaults() : null;
|
|
1887
|
+
const storedAgents = filterValidAgents(storedDefaults?.targetAgents, allAgentTypes);
|
|
1888
|
+
const storedMode = storedDefaults?.installMode;
|
|
1889
|
+
return {
|
|
1890
|
+
skill,
|
|
1891
|
+
options,
|
|
1892
|
+
configLoader,
|
|
1893
|
+
allAgentTypes,
|
|
1894
|
+
hasSkillsJson,
|
|
1895
|
+
storedAgents,
|
|
1896
|
+
hasStoredAgents: !!storedAgents && storedAgents.length > 0,
|
|
1897
|
+
storedMode,
|
|
1898
|
+
isReinstallAll: !skill,
|
|
1899
|
+
skipConfirm: options.yes ?? false
|
|
1900
|
+
};
|
|
1901
|
+
}
|
|
1902
|
+
async function resolveTargetAgents(ctx, spinner) {
|
|
1903
|
+
const { options, allAgentTypes, storedAgents, hasStoredAgents, isReinstallAll } = ctx;
|
|
1904
|
+
if (options.all) {
|
|
1905
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.info(`Installing to all ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].cyan(allAgentTypes.length)} agents`);
|
|
1906
|
+
return allAgentTypes;
|
|
1907
|
+
}
|
|
1908
|
+
if (options.agent && options.agent.length > 0) return resolveAgentsFromCLI(options.agent, allAgentTypes);
|
|
1909
|
+
if (isReinstallAll && hasStoredAgents && storedAgents) {
|
|
1910
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.info(`Using saved agents: ${formatColoredAgentNames(storedAgents)}`);
|
|
1911
|
+
return storedAgents;
|
|
1912
|
+
}
|
|
1913
|
+
return await detectAndPromptAgents(ctx, spinner);
|
|
1914
|
+
}
|
|
1915
|
+
function resolveAgentsFromCLI(agentArgs, validAgents) {
|
|
1916
|
+
const invalidAgents = agentArgs.filter((a)=>!validAgents.includes(a));
|
|
1917
|
+
if (invalidAgents.length > 0) {
|
|
1918
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.error(`Invalid agents: ${invalidAgents.join(', ')}`);
|
|
1919
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.info(`Valid agents: ${validAgents.join(', ')}`);
|
|
1920
|
+
process.exit(1);
|
|
1921
|
+
}
|
|
1922
|
+
const targetAgents = agentArgs;
|
|
1923
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.info(`Installing to: ${formatAgentNames(targetAgents)}`);
|
|
1924
|
+
return targetAgents;
|
|
1925
|
+
}
|
|
1926
|
+
async function detectAndPromptAgents(ctx, spinner) {
|
|
1927
|
+
const { allAgentTypes, storedAgents, hasStoredAgents, skipConfirm } = ctx;
|
|
1928
|
+
spinner.start('Detecting installed agents...');
|
|
1929
|
+
const installedAgents = await detectInstalledAgents();
|
|
1930
|
+
spinner.stop(`Detected ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].green(installedAgents.length)} agent${1 !== installedAgents.length ? 's' : ''}`);
|
|
1931
|
+
if (0 === installedAgents.length) {
|
|
1932
|
+
if (skipConfirm) {
|
|
1933
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.info('Installing to all agents (none detected)');
|
|
1934
|
+
return allAgentTypes;
|
|
1935
|
+
}
|
|
1936
|
+
return await promptAgentSelection(allAgentTypes, hasStoredAgents ? storedAgents : allAgentTypes);
|
|
1937
|
+
}
|
|
1938
|
+
if (1 === installedAgents.length || skipConfirm) {
|
|
1939
|
+
const displayNames = formatColoredAgentNames(installedAgents);
|
|
1940
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.info(`Installing to: ${displayNames}`);
|
|
1941
|
+
return installedAgents;
|
|
1942
|
+
}
|
|
1943
|
+
const initialAgents = hasStoredAgents ? storedAgents : installedAgents;
|
|
1944
|
+
return await promptAgentSelection(installedAgents, initialAgents, true);
|
|
1945
|
+
}
|
|
1946
|
+
async function promptAgentSelection(availableAgents, initialValues, showHint = false) {
|
|
1947
|
+
if (0 === availableAgents.length) __WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.warn('No coding agents detected. You can still install skills.');
|
|
1948
|
+
const agentChoices = availableAgents.map((a)=>({
|
|
1949
|
+
value: a,
|
|
1950
|
+
label: agents[a].displayName,
|
|
1951
|
+
...showHint && {
|
|
1952
|
+
hint: agents[a].skillsDir
|
|
1953
|
+
}
|
|
1954
|
+
}));
|
|
1955
|
+
const selected = await __WEBPACK_EXTERNAL_MODULE__clack_prompts__.multiselect({
|
|
1956
|
+
message: `Select agents to install skills to ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].dim('(Space to toggle, Enter to confirm)')}`,
|
|
1957
|
+
options: agentChoices.length > 0 ? agentChoices : Object.entries(agents).map(([key, config])=>({
|
|
1958
|
+
value: key,
|
|
1959
|
+
label: config.displayName
|
|
1960
|
+
})),
|
|
1961
|
+
required: true,
|
|
1962
|
+
initialValues: initialValues ?? availableAgents
|
|
1963
|
+
});
|
|
1964
|
+
if (__WEBPACK_EXTERNAL_MODULE__clack_prompts__.isCancel(selected)) {
|
|
1965
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.cancel('Installation cancelled');
|
|
1966
|
+
process.exit(0);
|
|
1967
|
+
}
|
|
1968
|
+
return selected;
|
|
1969
|
+
}
|
|
1970
|
+
async function resolveInstallScope(ctx) {
|
|
1971
|
+
const { options, hasSkillsJson, skipConfirm } = ctx;
|
|
1972
|
+
if (void 0 !== options.global) return options.global;
|
|
1973
|
+
if (hasSkillsJson) {
|
|
1974
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.info(`Found ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].cyan('skills.json')}, installing to project`);
|
|
1975
|
+
return false;
|
|
1976
|
+
}
|
|
1977
|
+
if (skipConfirm) return false;
|
|
1978
|
+
const scope = await __WEBPACK_EXTERNAL_MODULE__clack_prompts__.select({
|
|
1979
|
+
message: 'Installation scope',
|
|
1980
|
+
options: [
|
|
1981
|
+
{
|
|
1982
|
+
value: false,
|
|
1983
|
+
label: 'Project',
|
|
1984
|
+
hint: 'Install in current directory (committed with your project)'
|
|
1985
|
+
},
|
|
1986
|
+
{
|
|
1987
|
+
value: true,
|
|
1988
|
+
label: 'Global',
|
|
1989
|
+
hint: 'Install in home directory (available across all projects)'
|
|
1990
|
+
}
|
|
1991
|
+
]
|
|
1992
|
+
});
|
|
1993
|
+
if (__WEBPACK_EXTERNAL_MODULE__clack_prompts__.isCancel(scope)) {
|
|
1994
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.cancel('Installation cancelled');
|
|
1995
|
+
process.exit(0);
|
|
1996
|
+
}
|
|
1997
|
+
return scope;
|
|
1998
|
+
}
|
|
1999
|
+
async function resolveInstallMode(ctx) {
|
|
2000
|
+
const { options, storedMode, isReinstallAll, skipConfirm } = ctx;
|
|
2001
|
+
if (options.mode) return options.mode;
|
|
2002
|
+
if (isReinstallAll && storedMode) {
|
|
2003
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.info(`Using saved install mode: ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].cyan(storedMode)}`);
|
|
2004
|
+
return storedMode;
|
|
2005
|
+
}
|
|
2006
|
+
if (skipConfirm) return storedMode ?? 'symlink';
|
|
2007
|
+
const modeChoice = await __WEBPACK_EXTERNAL_MODULE__clack_prompts__.select({
|
|
2008
|
+
message: 'Installation method',
|
|
2009
|
+
initialValue: storedMode ?? 'symlink',
|
|
2010
|
+
options: [
|
|
2011
|
+
{
|
|
2012
|
+
value: 'symlink',
|
|
2013
|
+
label: 'Symlink (Recommended)',
|
|
2014
|
+
hint: 'Single source of truth, easy updates'
|
|
2015
|
+
},
|
|
2016
|
+
{
|
|
2017
|
+
value: 'copy',
|
|
2018
|
+
label: 'Copy to all agents',
|
|
2019
|
+
hint: 'Independent copies for each agent'
|
|
2020
|
+
}
|
|
2021
|
+
]
|
|
2022
|
+
});
|
|
2023
|
+
if (__WEBPACK_EXTERNAL_MODULE__clack_prompts__.isCancel(modeChoice)) {
|
|
2024
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.cancel('Installation cancelled');
|
|
2025
|
+
process.exit(0);
|
|
2026
|
+
}
|
|
2027
|
+
return modeChoice;
|
|
2028
|
+
}
|
|
2029
|
+
async function installAllSkills(ctx, targetAgents, installMode, spinner) {
|
|
2030
|
+
const { configLoader, options } = ctx;
|
|
2031
|
+
if (!configLoader.exists()) {
|
|
2032
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.error("skills.json not found. Run 'reskill init' first.");
|
|
2033
|
+
process.exit(1);
|
|
2034
|
+
}
|
|
2035
|
+
const skills = configLoader.getSkills();
|
|
2036
|
+
if (0 === Object.keys(skills).length) {
|
|
2037
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.info('No skills defined in skills.json');
|
|
2038
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.outro('Done');
|
|
2039
|
+
return;
|
|
2040
|
+
}
|
|
2041
|
+
displayInstallSummary({
|
|
2042
|
+
skillCount: Object.keys(skills).length,
|
|
2043
|
+
agentCount: targetAgents.length,
|
|
2044
|
+
scope: 'Project (./) ',
|
|
2045
|
+
mode: installMode
|
|
2046
|
+
});
|
|
2047
|
+
spinner.start('Installing skills...');
|
|
2048
|
+
const skillManager = new SkillManager(void 0, {
|
|
2049
|
+
global: false
|
|
2050
|
+
});
|
|
2051
|
+
let totalInstalled = 0;
|
|
2052
|
+
let totalFailed = 0;
|
|
2053
|
+
for (const [name, ref] of Object.entries(skills))try {
|
|
2054
|
+
const { results } = await skillManager.installToAgents(ref, targetAgents, {
|
|
2055
|
+
force: options.force,
|
|
2056
|
+
save: false,
|
|
2057
|
+
mode: installMode
|
|
2058
|
+
});
|
|
2059
|
+
const successCount = Array.from(results.values()).filter((r)=>r.success).length;
|
|
2060
|
+
totalInstalled += successCount;
|
|
2061
|
+
totalFailed += results.size - successCount;
|
|
2062
|
+
} catch (error) {
|
|
2063
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.error(`Failed to install ${name}: ${error.message}`);
|
|
2064
|
+
totalFailed += targetAgents.length;
|
|
2065
|
+
}
|
|
2066
|
+
spinner.stop('Installation complete');
|
|
2067
|
+
displayInstallResults(Object.keys(skills).length, targetAgents.length, totalInstalled, totalFailed);
|
|
2068
|
+
if (totalInstalled > 0) configLoader.updateDefaults({
|
|
2069
|
+
targetAgents,
|
|
2070
|
+
installMode
|
|
2071
|
+
});
|
|
2072
|
+
}
|
|
2073
|
+
async function installSingleSkill(ctx, targetAgents, installGlobally, installMode, spinner) {
|
|
2074
|
+
const { skill, options, configLoader, skipConfirm } = ctx;
|
|
2075
|
+
const cwd = process.cwd();
|
|
2076
|
+
const summaryLines = [
|
|
2077
|
+
__WEBPACK_EXTERNAL_MODULE_chalk__["default"].cyan(skill),
|
|
2078
|
+
` ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].dim('→')} ${formatAgentNames(targetAgents)}`,
|
|
2079
|
+
` ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].dim('Scope:')} ${installGlobally ? 'Global' : 'Project'}${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].dim(', Mode:')} ${installMode}`
|
|
2080
|
+
];
|
|
2081
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.note(summaryLines.join('\n'), 'Installation Summary');
|
|
2082
|
+
if (!skipConfirm) {
|
|
2083
|
+
const confirmed = await __WEBPACK_EXTERNAL_MODULE__clack_prompts__.confirm({
|
|
2084
|
+
message: 'Proceed with installation?'
|
|
2085
|
+
});
|
|
2086
|
+
if (__WEBPACK_EXTERNAL_MODULE__clack_prompts__.isCancel(confirmed) || !confirmed) {
|
|
2087
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.cancel('Installation cancelled');
|
|
2088
|
+
process.exit(0);
|
|
2089
|
+
}
|
|
2090
|
+
}
|
|
2091
|
+
spinner.start(`Installing ${skill}...`);
|
|
2092
|
+
const skillManager = new SkillManager(void 0, {
|
|
2093
|
+
global: installGlobally
|
|
2094
|
+
});
|
|
2095
|
+
const { skill: installed, results } = await skillManager.installToAgents(skill, targetAgents, {
|
|
2096
|
+
force: options.force,
|
|
2097
|
+
save: false !== options.save && !installGlobally,
|
|
2098
|
+
mode: installMode
|
|
2099
|
+
});
|
|
2100
|
+
spinner.stop('Installation complete');
|
|
2101
|
+
const successful = Array.from(results.entries()).filter(([, r])=>r.success);
|
|
2102
|
+
const failed = Array.from(results.entries()).filter(([, r])=>!r.success);
|
|
2103
|
+
displaySingleSkillResults(installed, successful, failed, cwd);
|
|
2104
|
+
if (!installGlobally && successful.length > 0 && configLoader.exists()) {
|
|
2105
|
+
configLoader.reload();
|
|
2106
|
+
configLoader.updateDefaults({
|
|
2107
|
+
targetAgents,
|
|
2108
|
+
installMode
|
|
2109
|
+
});
|
|
2110
|
+
}
|
|
2111
|
+
}
|
|
2112
|
+
function displayInstallSummary(info) {
|
|
2113
|
+
const summaryLines = [
|
|
2114
|
+
`${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].cyan(info.skillCount)} skill(s) → ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].cyan(info.agentCount)} agent(s)`,
|
|
2115
|
+
`${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].dim('Scope:')} ${info.scope}${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].dim(', Mode:')} ${info.mode}`
|
|
2116
|
+
];
|
|
2117
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.note(summaryLines.join('\n'), 'Installation Summary');
|
|
2118
|
+
}
|
|
2119
|
+
function displayInstallResults(skillCount, agentCount, totalInstalled, totalFailed) {
|
|
2120
|
+
if (0 === totalFailed) __WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.success(`Installed ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].green(skillCount)} skill(s) to ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].green(agentCount)} agent(s)`);
|
|
2121
|
+
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`);
|
|
2122
|
+
}
|
|
2123
|
+
function displaySingleSkillResults(installed, successful, failed, cwd) {
|
|
2124
|
+
if (successful.length > 0) {
|
|
2125
|
+
const resultLines = [];
|
|
2126
|
+
const firstResult = successful[0][1];
|
|
2127
|
+
if ('copy' === firstResult.mode) {
|
|
2128
|
+
resultLines.push(`${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].green('✓')} ${installed.name}@${installed.version} ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].dim('(copied)')}`);
|
|
2129
|
+
for (const [, result] of successful)resultLines.push(` ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].dim('→')} ${shortenPath(result.path, cwd)}`);
|
|
2130
|
+
} else {
|
|
2131
|
+
const displayPath = firstResult.canonicalPath ? shortenPath(firstResult.canonicalPath, cwd) : `${installed.name}@${installed.version}`;
|
|
2132
|
+
resultLines.push(`${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].green('✓')} ${displayPath}`);
|
|
2133
|
+
const symlinked = successful.filter(([, r])=>!r.symlinkFailed).map(([a])=>agents[a].displayName);
|
|
2134
|
+
const copied = successful.filter(([, r])=>r.symlinkFailed).map(([a])=>agents[a].displayName);
|
|
2135
|
+
if (symlinked.length > 0) resultLines.push(` ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].dim('symlink →')} ${symlinked.join(', ')}`);
|
|
2136
|
+
if (copied.length > 0) resultLines.push(` ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].yellow('copied →')} ${copied.join(', ')}`);
|
|
2137
|
+
}
|
|
2138
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.note(resultLines.join('\n'), __WEBPACK_EXTERNAL_MODULE_chalk__["default"].green(`Installed 1 skill to ${successful.length} agent${1 !== successful.length ? 's' : ''}`));
|
|
2139
|
+
const symlinkFailed = successful.filter(([, r])=>'symlink' === r.mode && r.symlinkFailed);
|
|
2140
|
+
if (symlinkFailed.length > 0) {
|
|
2141
|
+
const copiedAgentNames = symlinkFailed.map(([a])=>agents[a].displayName);
|
|
2142
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.warn(__WEBPACK_EXTERNAL_MODULE_chalk__["default"].yellow(`Symlinks failed for: ${copiedAgentNames.join(', ')}`));
|
|
2143
|
+
__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.'));
|
|
2144
|
+
}
|
|
2145
|
+
}
|
|
2146
|
+
if (failed.length > 0) {
|
|
2147
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.error(__WEBPACK_EXTERNAL_MODULE_chalk__["default"].red(`Failed to install to ${failed.length} agent(s)`));
|
|
2148
|
+
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)}`);
|
|
2149
|
+
}
|
|
2150
|
+
}
|
|
1921
2151
|
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)=>{
|
|
1922
2152
|
if (options.all) {
|
|
1923
2153
|
options.yes = true;
|
|
1924
2154
|
options.global = true;
|
|
1925
2155
|
}
|
|
1926
|
-
const
|
|
1927
|
-
const configLoader = new ConfigLoader();
|
|
1928
|
-
const allAgentTypes = Object.keys(agents);
|
|
2156
|
+
const ctx = createInstallContext(skill, options);
|
|
1929
2157
|
console.log();
|
|
1930
2158
|
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.intro(__WEBPACK_EXTERNAL_MODULE_chalk__["default"].bgCyan.black(' reskill '));
|
|
1931
2159
|
try {
|
|
1932
2160
|
const spinner = __WEBPACK_EXTERNAL_MODULE__clack_prompts__.spinner();
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.
|
|
1937
|
-
|
|
1938
|
-
const validAgents = Object.keys(agents);
|
|
1939
|
-
const invalidAgents = options.agent.filter((a)=>!validAgents.includes(a));
|
|
1940
|
-
if (invalidAgents.length > 0) {
|
|
1941
|
-
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.error(`Invalid agents: ${invalidAgents.join(', ')}`);
|
|
1942
|
-
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.info(`Valid agents: ${validAgents.join(', ')}`);
|
|
1943
|
-
process.exit(1);
|
|
1944
|
-
}
|
|
1945
|
-
targetAgents = options.agent;
|
|
1946
|
-
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.info(`Installing to: ${formatAgentNames(targetAgents)}`);
|
|
1947
|
-
} else {
|
|
1948
|
-
spinner.start('Detecting installed agents...');
|
|
1949
|
-
const installedAgents = await detectInstalledAgents();
|
|
1950
|
-
spinner.stop(`Detected ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].green(installedAgents.length)} agent${1 !== installedAgents.length ? 's' : ''}`);
|
|
1951
|
-
if (0 === installedAgents.length) {
|
|
1952
|
-
if (skipConfirm) {
|
|
1953
|
-
targetAgents = allAgentTypes;
|
|
1954
|
-
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.info('Installing to all agents (none detected)');
|
|
1955
|
-
} else {
|
|
1956
|
-
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.warn('No coding agents detected. You can still install skills.');
|
|
1957
|
-
const allAgentChoices = Object.entries(agents).map(([key, config])=>({
|
|
1958
|
-
value: key,
|
|
1959
|
-
label: config.displayName
|
|
1960
|
-
}));
|
|
1961
|
-
const selected = await __WEBPACK_EXTERNAL_MODULE__clack_prompts__.multiselect({
|
|
1962
|
-
message: `Select agents to install skills to ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].dim('(Space to toggle, Enter to confirm)')}`,
|
|
1963
|
-
options: allAgentChoices,
|
|
1964
|
-
required: true,
|
|
1965
|
-
initialValues: allAgentTypes
|
|
1966
|
-
});
|
|
1967
|
-
if (__WEBPACK_EXTERNAL_MODULE__clack_prompts__.isCancel(selected)) {
|
|
1968
|
-
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.cancel('Installation cancelled');
|
|
1969
|
-
process.exit(0);
|
|
1970
|
-
}
|
|
1971
|
-
targetAgents = selected;
|
|
1972
|
-
}
|
|
1973
|
-
} else if (1 === installedAgents.length || skipConfirm) {
|
|
1974
|
-
targetAgents = installedAgents;
|
|
1975
|
-
if (1 === installedAgents.length) __WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.info(`Installing to: ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].cyan(agents[installedAgents[0]].displayName)}`);
|
|
1976
|
-
else __WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.info(`Installing to: ${installedAgents.map((a)=>__WEBPACK_EXTERNAL_MODULE_chalk__["default"].cyan(agents[a].displayName)).join(', ')}`);
|
|
1977
|
-
} else {
|
|
1978
|
-
const agentChoices = installedAgents.map((a)=>({
|
|
1979
|
-
value: a,
|
|
1980
|
-
label: agents[a].displayName,
|
|
1981
|
-
hint: agents[a].skillsDir
|
|
1982
|
-
}));
|
|
1983
|
-
const selected = await __WEBPACK_EXTERNAL_MODULE__clack_prompts__.multiselect({
|
|
1984
|
-
message: `Select agents to install skills to ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].dim('(Space to toggle, Enter to confirm)')}`,
|
|
1985
|
-
options: agentChoices,
|
|
1986
|
-
required: true,
|
|
1987
|
-
initialValues: installedAgents
|
|
1988
|
-
});
|
|
1989
|
-
if (__WEBPACK_EXTERNAL_MODULE__clack_prompts__.isCancel(selected)) {
|
|
1990
|
-
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.cancel('Installation cancelled');
|
|
1991
|
-
process.exit(0);
|
|
1992
|
-
}
|
|
1993
|
-
targetAgents = selected;
|
|
1994
|
-
}
|
|
1995
|
-
}
|
|
1996
|
-
let installGlobally = options.global ?? false;
|
|
1997
|
-
const hasSkillsJson = configLoader.exists();
|
|
1998
|
-
if (void 0 !== options.global || skipConfirm || hasSkillsJson) {
|
|
1999
|
-
if (hasSkillsJson && void 0 === options.global) __WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.info(`Found ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].cyan('skills.json')}, installing to project`);
|
|
2000
|
-
} else {
|
|
2001
|
-
const scope = await __WEBPACK_EXTERNAL_MODULE__clack_prompts__.select({
|
|
2002
|
-
message: 'Installation scope',
|
|
2003
|
-
options: [
|
|
2004
|
-
{
|
|
2005
|
-
value: false,
|
|
2006
|
-
label: 'Project',
|
|
2007
|
-
hint: 'Install in current directory (committed with your project)'
|
|
2008
|
-
},
|
|
2009
|
-
{
|
|
2010
|
-
value: true,
|
|
2011
|
-
label: 'Global',
|
|
2012
|
-
hint: 'Install in home directory (available across all projects)'
|
|
2013
|
-
}
|
|
2014
|
-
]
|
|
2015
|
-
});
|
|
2016
|
-
if (__WEBPACK_EXTERNAL_MODULE__clack_prompts__.isCancel(scope)) {
|
|
2017
|
-
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.cancel('Installation cancelled');
|
|
2018
|
-
process.exit(0);
|
|
2019
|
-
}
|
|
2020
|
-
installGlobally = scope;
|
|
2021
|
-
}
|
|
2022
|
-
let installMode = options.mode || 'symlink';
|
|
2023
|
-
if (!options.mode && !skipConfirm) {
|
|
2024
|
-
const modeChoice = await __WEBPACK_EXTERNAL_MODULE__clack_prompts__.select({
|
|
2025
|
-
message: 'Installation method',
|
|
2026
|
-
options: [
|
|
2027
|
-
{
|
|
2028
|
-
value: 'symlink',
|
|
2029
|
-
label: 'Symlink (Recommended)',
|
|
2030
|
-
hint: 'Single source of truth, easy updates'
|
|
2031
|
-
},
|
|
2032
|
-
{
|
|
2033
|
-
value: 'copy',
|
|
2034
|
-
label: 'Copy to all agents',
|
|
2035
|
-
hint: 'Independent copies for each agent'
|
|
2036
|
-
}
|
|
2037
|
-
]
|
|
2038
|
-
});
|
|
2039
|
-
if (__WEBPACK_EXTERNAL_MODULE__clack_prompts__.isCancel(modeChoice)) {
|
|
2040
|
-
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.cancel('Installation cancelled');
|
|
2041
|
-
process.exit(0);
|
|
2042
|
-
}
|
|
2043
|
-
installMode = modeChoice;
|
|
2044
|
-
}
|
|
2045
|
-
const skillManager = new SkillManager(void 0, {
|
|
2046
|
-
global: installGlobally
|
|
2047
|
-
});
|
|
2048
|
-
const cwd = process.cwd();
|
|
2049
|
-
if (skill) {
|
|
2050
|
-
const summaryLines = [];
|
|
2051
|
-
summaryLines.push(`${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].cyan(skill)}`);
|
|
2052
|
-
summaryLines.push(` ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].dim('→')} ${formatAgentNames(targetAgents)}`);
|
|
2053
|
-
summaryLines.push(` ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].dim('Scope:')} ${installGlobally ? 'Global' : 'Project'}${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].dim(', Mode:')} ${installMode}`);
|
|
2054
|
-
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.note(summaryLines.join('\n'), 'Installation Summary');
|
|
2055
|
-
if (!skipConfirm) {
|
|
2056
|
-
const confirmed = await __WEBPACK_EXTERNAL_MODULE__clack_prompts__.confirm({
|
|
2057
|
-
message: 'Proceed with installation?'
|
|
2058
|
-
});
|
|
2059
|
-
if (__WEBPACK_EXTERNAL_MODULE__clack_prompts__.isCancel(confirmed) || !confirmed) {
|
|
2060
|
-
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.cancel('Installation cancelled');
|
|
2061
|
-
process.exit(0);
|
|
2062
|
-
}
|
|
2063
|
-
}
|
|
2064
|
-
spinner.start(`Installing ${skill}...`);
|
|
2065
|
-
const { skill: installed, results } = await skillManager.installToAgents(skill, targetAgents, {
|
|
2066
|
-
force: options.force,
|
|
2067
|
-
save: options.save && !installGlobally,
|
|
2068
|
-
mode: installMode
|
|
2069
|
-
});
|
|
2070
|
-
spinner.stop('Installation complete');
|
|
2071
|
-
const successful = Array.from(results.entries()).filter(([, r])=>r.success);
|
|
2072
|
-
const failed = Array.from(results.entries()).filter(([, r])=>!r.success);
|
|
2073
|
-
const symlinkFailed = successful.filter(([, r])=>'symlink' === r.mode && r.symlinkFailed);
|
|
2074
|
-
if (successful.length > 0) {
|
|
2075
|
-
const resultLines = [];
|
|
2076
|
-
const firstResult = successful[0][1];
|
|
2077
|
-
if ('copy' === firstResult.mode) {
|
|
2078
|
-
resultLines.push(`${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].green('✓')} ${installed.name}@${installed.version} ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].dim('(copied)')}`);
|
|
2079
|
-
for (const [, result] of successful){
|
|
2080
|
-
const shortPath = shortenPath(result.path, cwd);
|
|
2081
|
-
resultLines.push(` ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].dim('→')} ${shortPath}`);
|
|
2082
|
-
}
|
|
2083
|
-
} else {
|
|
2084
|
-
if (firstResult.canonicalPath) {
|
|
2085
|
-
const shortPath = shortenPath(firstResult.canonicalPath, cwd);
|
|
2086
|
-
resultLines.push(`${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].green('✓')} ${shortPath}`);
|
|
2087
|
-
} else resultLines.push(`${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].green('✓')} ${installed.name}@${installed.version}`);
|
|
2088
|
-
const symlinked = successful.filter(([, r])=>!r.symlinkFailed).map(([a])=>agents[a].displayName);
|
|
2089
|
-
const copied = successful.filter(([, r])=>r.symlinkFailed).map(([a])=>agents[a].displayName);
|
|
2090
|
-
if (symlinked.length > 0) resultLines.push(` ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].dim('symlink →')} ${symlinked.join(', ')}`);
|
|
2091
|
-
if (copied.length > 0) resultLines.push(` ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].yellow('copied →')} ${copied.join(', ')}`);
|
|
2092
|
-
}
|
|
2093
|
-
const title = __WEBPACK_EXTERNAL_MODULE_chalk__["default"].green(`Installed 1 skill to ${successful.length} agent${1 !== successful.length ? 's' : ''}`);
|
|
2094
|
-
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.note(resultLines.join('\n'), title);
|
|
2095
|
-
if (symlinkFailed.length > 0) {
|
|
2096
|
-
const copiedAgentNames = symlinkFailed.map(([a])=>agents[a].displayName);
|
|
2097
|
-
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.warn(__WEBPACK_EXTERNAL_MODULE_chalk__["default"].yellow(`Symlinks failed for: ${copiedAgentNames.join(', ')}`));
|
|
2098
|
-
__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.'));
|
|
2099
|
-
}
|
|
2100
|
-
}
|
|
2101
|
-
if (failed.length > 0) {
|
|
2102
|
-
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.error(__WEBPACK_EXTERNAL_MODULE_chalk__["default"].red(`Failed to install to ${failed.length} agent(s)`));
|
|
2103
|
-
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)}`);
|
|
2104
|
-
}
|
|
2105
|
-
} else {
|
|
2106
|
-
if (installGlobally) {
|
|
2107
|
-
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.error('Cannot install all skills globally. Please specify a skill to install.');
|
|
2108
|
-
process.exit(1);
|
|
2109
|
-
}
|
|
2110
|
-
if (!configLoader.exists()) {
|
|
2111
|
-
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.error("skills.json not found. Run 'reskill init' first.");
|
|
2112
|
-
process.exit(1);
|
|
2113
|
-
}
|
|
2114
|
-
const skills = configLoader.getSkills();
|
|
2115
|
-
if (0 === Object.keys(skills).length) {
|
|
2116
|
-
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.info('No skills defined in skills.json');
|
|
2117
|
-
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.outro('Done');
|
|
2118
|
-
return;
|
|
2119
|
-
}
|
|
2120
|
-
const summaryLines = [];
|
|
2121
|
-
summaryLines.push(`${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].cyan(Object.keys(skills).length)} skill(s) → ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].cyan(targetAgents.length)} agent(s)`);
|
|
2122
|
-
summaryLines.push(`${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].dim('Scope:')} ${installGlobally ? 'Global (~/)' : 'Project (./)'}${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].dim(', Mode:')} ${installMode}`);
|
|
2123
|
-
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.note(summaryLines.join('\n'), 'Installation Summary');
|
|
2124
|
-
if (!skipConfirm) {
|
|
2125
|
-
const confirmed = await __WEBPACK_EXTERNAL_MODULE__clack_prompts__.confirm({
|
|
2126
|
-
message: 'Proceed with installation?'
|
|
2127
|
-
});
|
|
2128
|
-
if (__WEBPACK_EXTERNAL_MODULE__clack_prompts__.isCancel(confirmed) || !confirmed) {
|
|
2129
|
-
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.cancel('Installation cancelled');
|
|
2130
|
-
process.exit(0);
|
|
2131
|
-
}
|
|
2132
|
-
}
|
|
2133
|
-
spinner.start('Installing skills...');
|
|
2134
|
-
let totalInstalled = 0;
|
|
2135
|
-
let totalFailed = 0;
|
|
2136
|
-
for (const [name, ref] of Object.entries(skills))try {
|
|
2137
|
-
const { results } = await skillManager.installToAgents(ref, targetAgents, {
|
|
2138
|
-
force: options.force,
|
|
2139
|
-
save: false,
|
|
2140
|
-
mode: installMode
|
|
2141
|
-
});
|
|
2142
|
-
const successCount = Array.from(results.values()).filter((r)=>r.success).length;
|
|
2143
|
-
totalInstalled += successCount;
|
|
2144
|
-
totalFailed += results.size - successCount;
|
|
2145
|
-
} catch (error) {
|
|
2146
|
-
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.error(`Failed to install ${name}: ${error.message}`);
|
|
2147
|
-
totalFailed += targetAgents.length;
|
|
2148
|
-
}
|
|
2149
|
-
spinner.stop('Installation complete');
|
|
2150
|
-
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)`);
|
|
2151
|
-
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`);
|
|
2161
|
+
const targetAgents = await resolveTargetAgents(ctx, spinner);
|
|
2162
|
+
const installGlobally = await resolveInstallScope(ctx);
|
|
2163
|
+
if (ctx.isReinstallAll && installGlobally) {
|
|
2164
|
+
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.error('Cannot install all skills globally. Please specify a skill to install.');
|
|
2165
|
+
process.exit(1);
|
|
2152
2166
|
}
|
|
2167
|
+
const installMode = await resolveInstallMode(ctx);
|
|
2168
|
+
if (ctx.isReinstallAll) await installAllSkills(ctx, targetAgents, installMode, spinner);
|
|
2169
|
+
else await installSingleSkill(ctx, targetAgents, installGlobally, installMode, spinner);
|
|
2153
2170
|
console.log();
|
|
2154
2171
|
__WEBPACK_EXTERNAL_MODULE__clack_prompts__.outro(__WEBPACK_EXTERNAL_MODULE_chalk__["default"].green('Done!'));
|
|
2155
2172
|
} catch (error) {
|
|
@@ -2158,23 +2175,6 @@ const installCommand = new __WEBPACK_EXTERNAL_MODULE_commander__.Command('instal
|
|
|
2158
2175
|
process.exit(1);
|
|
2159
2176
|
}
|
|
2160
2177
|
});
|
|
2161
|
-
const linkCmd = new __WEBPACK_EXTERNAL_MODULE_commander__.Command('link').description('Link a local skill for development').argument('<path>', 'Path to local skill directory').option('-n, --name <name>', 'Custom skill name').action((localPath, options)=>{
|
|
2162
|
-
const skillManager = new SkillManager();
|
|
2163
|
-
try {
|
|
2164
|
-
const linked = skillManager.link(localPath, options.name);
|
|
2165
|
-
logger_logger.log(`Linked skill available at: ${linked.path}`);
|
|
2166
|
-
} catch (error) {
|
|
2167
|
-
logger_logger.error(error.message);
|
|
2168
|
-
process.exit(1);
|
|
2169
|
-
}
|
|
2170
|
-
});
|
|
2171
|
-
const unlinkCmd = new __WEBPACK_EXTERNAL_MODULE_commander__.Command('unlink').description('Unlink a linked skill').argument('<skill>', 'Skill name to unlink').action((skillName)=>{
|
|
2172
|
-
const skillManager = new SkillManager();
|
|
2173
|
-
const result = skillManager.unlink(skillName);
|
|
2174
|
-
if (!result) process.exit(1);
|
|
2175
|
-
});
|
|
2176
|
-
const linkCommand = linkCmd;
|
|
2177
|
-
const unlinkCommand = unlinkCmd;
|
|
2178
2178
|
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)=>{
|
|
2179
2179
|
const isGlobal = options.global || false;
|
|
2180
2180
|
const skillManager = new SkillManager(void 0, {
|
|
@@ -2337,8 +2337,6 @@ program.addCommand(infoCommand);
|
|
|
2337
2337
|
program.addCommand(updateCommand);
|
|
2338
2338
|
program.addCommand(outdatedCommand);
|
|
2339
2339
|
program.addCommand(uninstallCommand);
|
|
2340
|
-
program.addCommand(linkCommand);
|
|
2341
|
-
program.addCommand(unlinkCommand);
|
|
2342
2340
|
program.addCommand(completionCommand);
|
|
2343
2341
|
const updateCheckPromise = checkForUpdate(packageJson.name, packageJson.version);
|
|
2344
2342
|
program.parseAsync().then(async ()=>{
|
|
@@ -1,14 +1,29 @@
|
|
|
1
1
|
import type { SkillsDefaults, SkillsJson } from '../types/index.js';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Well-known registry URLs
|
|
4
4
|
*/
|
|
5
5
|
export declare const DEFAULT_REGISTRIES: Record<string, string>;
|
|
6
6
|
/**
|
|
7
7
|
* ConfigLoader - Load and manage skills.json configuration
|
|
8
|
+
*
|
|
9
|
+
* Handles reading, writing, and managing the project's skills.json file.
|
|
10
|
+
* Provides methods for:
|
|
11
|
+
* - Loading/saving configuration
|
|
12
|
+
* - Managing skill dependencies
|
|
13
|
+
* - Managing default settings (registry, installDir, targetAgents, installMode)
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* const config = new ConfigLoader();
|
|
18
|
+
* if (config.exists()) {
|
|
19
|
+
* const defaults = config.getDefaults();
|
|
20
|
+
* console.log(defaults.targetAgents);
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
8
23
|
*/
|
|
9
24
|
export declare class ConfigLoader {
|
|
10
|
-
private projectRoot;
|
|
11
|
-
private configPath;
|
|
25
|
+
private readonly projectRoot;
|
|
26
|
+
private readonly configPath;
|
|
12
27
|
private config;
|
|
13
28
|
constructor(projectRoot?: string);
|
|
14
29
|
/**
|
|
@@ -19,20 +34,29 @@ export declare class ConfigLoader {
|
|
|
19
34
|
* Get configuration file path
|
|
20
35
|
*/
|
|
21
36
|
getConfigPath(): string;
|
|
37
|
+
/**
|
|
38
|
+
* Get installation directory (resolved absolute path)
|
|
39
|
+
*/
|
|
40
|
+
getInstallDir(): string;
|
|
22
41
|
/**
|
|
23
42
|
* Check if configuration file exists
|
|
24
43
|
*/
|
|
25
44
|
exists(): boolean;
|
|
26
45
|
/**
|
|
27
|
-
* Load configuration
|
|
46
|
+
* Load configuration from file
|
|
47
|
+
*
|
|
48
|
+
* @throws Error if file doesn't exist or is invalid JSON
|
|
28
49
|
*/
|
|
29
50
|
load(): SkillsJson;
|
|
30
51
|
/**
|
|
31
|
-
* Reload configuration (
|
|
52
|
+
* Reload configuration from file (ignores cache)
|
|
32
53
|
*/
|
|
33
54
|
reload(): SkillsJson;
|
|
34
55
|
/**
|
|
35
|
-
* Save configuration
|
|
56
|
+
* Save configuration to file
|
|
57
|
+
*
|
|
58
|
+
* @param config - Configuration to save (uses cached config if not provided)
|
|
59
|
+
* @throws Error if no configuration to save
|
|
36
60
|
*/
|
|
37
61
|
save(config?: SkillsJson): void;
|
|
38
62
|
/**
|
|
@@ -42,41 +66,65 @@ export declare class ConfigLoader {
|
|
|
42
66
|
*/
|
|
43
67
|
ensureExists(): boolean;
|
|
44
68
|
/**
|
|
45
|
-
* Create
|
|
69
|
+
* Create new configuration file with defaults
|
|
70
|
+
*
|
|
71
|
+
* @param options - Optional overrides for default configuration
|
|
46
72
|
*/
|
|
47
73
|
create(options?: Partial<SkillsJson>): SkillsJson;
|
|
48
74
|
/**
|
|
49
|
-
* Get default configuration
|
|
75
|
+
* Get default configuration values
|
|
76
|
+
*
|
|
77
|
+
* Returns a complete defaults object with all fields populated.
|
|
78
|
+
* Uses stored values if available, falls back to defaults.
|
|
50
79
|
*/
|
|
51
80
|
getDefaults(): Required<SkillsDefaults>;
|
|
52
81
|
/**
|
|
53
|
-
*
|
|
82
|
+
* Update default configuration values
|
|
83
|
+
*
|
|
84
|
+
* Merges the provided updates with existing defaults and saves to file.
|
|
85
|
+
*
|
|
86
|
+
* @param updates - Partial defaults to merge
|
|
54
87
|
*/
|
|
55
|
-
|
|
88
|
+
updateDefaults(updates: Partial<SkillsDefaults>): void;
|
|
56
89
|
/**
|
|
57
|
-
* Get
|
|
90
|
+
* Get registry URL by name
|
|
91
|
+
*
|
|
92
|
+
* Resolution order:
|
|
93
|
+
* 1. Custom registries defined in skills.json
|
|
94
|
+
* 2. Well-known registries (github, gitlab)
|
|
95
|
+
* 3. Assumes it's a custom domain (https://{registryName})
|
|
58
96
|
*/
|
|
59
|
-
|
|
97
|
+
getRegistryUrl(registryName: string): string;
|
|
60
98
|
/**
|
|
61
99
|
* Add skill to configuration
|
|
62
100
|
*/
|
|
63
101
|
addSkill(name: string, ref: string): void;
|
|
64
102
|
/**
|
|
65
103
|
* Remove skill from configuration
|
|
104
|
+
*
|
|
105
|
+
* @returns true if skill was removed, false if it didn't exist
|
|
66
106
|
*/
|
|
67
107
|
removeSkill(name: string): boolean;
|
|
68
108
|
/**
|
|
69
|
-
* Get all skills
|
|
109
|
+
* Get all skills as a shallow copy
|
|
70
110
|
*/
|
|
71
111
|
getSkills(): Record<string, string>;
|
|
72
112
|
/**
|
|
73
|
-
* Check if skill exists
|
|
113
|
+
* Check if skill exists in configuration
|
|
74
114
|
*/
|
|
75
115
|
hasSkill(name: string): boolean;
|
|
76
116
|
/**
|
|
77
|
-
* Get skill reference
|
|
117
|
+
* Get skill reference by name
|
|
78
118
|
*/
|
|
79
119
|
getSkillRef(name: string): string | undefined;
|
|
120
|
+
/**
|
|
121
|
+
* Get loaded config or default (does not throw)
|
|
122
|
+
*/
|
|
123
|
+
private getConfigOrDefault;
|
|
124
|
+
/**
|
|
125
|
+
* Ensure config is loaded into memory
|
|
126
|
+
*/
|
|
127
|
+
private ensureConfigLoaded;
|
|
80
128
|
}
|
|
81
129
|
export default ConfigLoader;
|
|
82
130
|
//# sourceMappingURL=config-loader.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../../src/core/config-loader.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../../src/core/config-loader.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AA4BpE;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAGrD,CAAC;AAMF;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,MAAM,CAA2B;gBAE7B,WAAW,CAAC,EAAE,MAAM;IAShC;;OAEG;IACH,cAAc,IAAI,MAAM;IAIxB;;OAEG;IACH,aAAa,IAAI,MAAM;IAIvB;;OAEG;IACH,aAAa,IAAI,MAAM;IASvB;;OAEG;IACH,MAAM,IAAI,OAAO;IAIjB;;;;OAIG;IACH,IAAI,IAAI,UAAU;IAiBlB;;OAEG;IACH,MAAM,IAAI,UAAU;IAKpB;;;;;OAKG;IACH,IAAI,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,IAAI;IAS/B;;;;OAIG;IACH,YAAY,IAAI,OAAO;IAQvB;;;;OAIG;IACH,MAAM,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,UAAU;IAmBjD;;;;;OAKG;IACH,WAAW,IAAI,QAAQ,CAAC,cAAc,CAAC;IAYvC;;;;;;OAMG;IACH,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,IAAI;IAgBtD;;;;;;;OAOG;IACH,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM;IAqB5C;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IASzC;;;;OAIG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAWlC;;OAEG;IACH,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAUnC;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAK/B;;OAEG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAS7C;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAU1B;;OAEG;IACH,OAAO,CAAC,kBAAkB;CAK3B;AAED,eAAe,YAAY,CAAC"}
|
|
@@ -80,14 +80,6 @@ export declare class SkillManager {
|
|
|
80
80
|
* Update skill
|
|
81
81
|
*/
|
|
82
82
|
update(name?: string): Promise<InstalledSkill[]>;
|
|
83
|
-
/**
|
|
84
|
-
* Link local skill for development
|
|
85
|
-
*/
|
|
86
|
-
link(localPath: string, name?: string): InstalledSkill;
|
|
87
|
-
/**
|
|
88
|
-
* Unlink a linked skill
|
|
89
|
-
*/
|
|
90
|
-
unlink(name: string): boolean;
|
|
91
83
|
/**
|
|
92
84
|
* List installed skills
|
|
93
85
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skill-manager.d.ts","sourceRoot":"","sources":["../../src/core/skill-manager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAa,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"skill-manager.d.ts","sourceRoot":"","sources":["../../src/core/skill-manager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAa,MAAM,mBAAmB,CAAC;AAanF,OAAO,EACL,KAAK,SAAS,EAIf,MAAM,qBAAqB,CAAC;AAI7B,OAAO,EAAa,KAAK,WAAW,EAAE,KAAK,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACjF,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,+CAA+C;IAC/C,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;GASG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,QAAQ,CAAc;IAC9B,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,QAAQ,CAAU;gBAEd,WAAW,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB;IAY/D;;OAEG;IACH,YAAY,IAAI,OAAO;IAIvB;;OAEG;IACH,cAAc,IAAI,MAAM;IAIxB;;;;;OAKG;IACH,aAAa,IAAI,MAAM;IAOvB;;;;;;OAMG;IACH,qBAAqB,IAAI,MAAM;IAM/B;;;;OAIG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAiBlC;;OAEG;IACG,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,cAAc,CAAC;IA4FjF;;OAEG;IACG,UAAU,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAgBzE;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IA2BhC;;;;;;OAMG;IACH,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO;IAY7D;;OAEG;IACG,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IA+CtD;;;;OAIG;IACH,IAAI,IAAI,cAAc,EAAE;IA0DxB;;OAEG;IACH,OAAO,CAAC,yBAAyB;IA6BjC;;;;OAIG;IACH,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAgBtD;;OAEG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG;QACrB,SAAS,EAAE,cAAc,GAAG,IAAI,CAAC;QACjC,MAAM,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;QACvC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;KAC5B;IAQD;;OAEG;IACG,aAAa,IAAI,OAAO,CAC5B,KAAK,CAAC;QACJ,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,eAAe,EAAE,OAAO,CAAC;KAC1B,CAAC,CACH;IAwDD;;;;;;OAMG;IACG,eAAe,CACnB,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,SAAS,EAAE,EACzB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC;QACT,KAAK,EAAE,cAAc,CAAC;QACtB,OAAO,EAAE,GAAG,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;KACxC,CAAC;IA0FF;;;;;;;OAOG;IACG,sBAAsB,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAWpD;;OAEG;IACH,qBAAqB,IAAI,WAAW;IAQpC;;OAEG;IACH,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG;QAAE,KAAK,EAAE,SAAS,EAAE,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE;IAenF;;OAEG;IACH,gBAAgB,IAAI,SAAS,EAAE;IAI/B;;OAEG;IACH,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,GAAG,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC;CAuBtF;AAED,eAAe,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -215,12 +215,6 @@ function isSymlink(targetPath) {
|
|
|
215
215
|
if (!exists(targetPath)) return false;
|
|
216
216
|
return external_node_fs_.lstatSync(targetPath).isSymbolicLink();
|
|
217
217
|
}
|
|
218
|
-
function createSymlink(target, linkPath) {
|
|
219
|
-
const linkDir = __WEBPACK_EXTERNAL_MODULE_node_path__.dirname(linkPath);
|
|
220
|
-
ensureDir(linkDir);
|
|
221
|
-
if (exists(linkPath)) remove(linkPath);
|
|
222
|
-
external_node_fs_.symlinkSync(target, linkPath, 'dir');
|
|
223
|
-
}
|
|
224
218
|
function getRealPath(linkPath) {
|
|
225
219
|
return external_node_fs_.realpathSync(linkPath);
|
|
226
220
|
}
|
|
@@ -792,6 +786,12 @@ const DEFAULT_SKILLS_JSON = {
|
|
|
792
786
|
installDir: '.skills'
|
|
793
787
|
}
|
|
794
788
|
};
|
|
789
|
+
const DEFAULT_VALUES = {
|
|
790
|
+
registry: 'github',
|
|
791
|
+
installDir: '.skills',
|
|
792
|
+
targetAgents: [],
|
|
793
|
+
installMode: 'symlink'
|
|
794
|
+
};
|
|
795
795
|
const DEFAULT_REGISTRIES = {
|
|
796
796
|
github: 'https://github.com',
|
|
797
797
|
gitlab: 'https://gitlab.com'
|
|
@@ -801,7 +801,7 @@ class ConfigLoader {
|
|
|
801
801
|
configPath;
|
|
802
802
|
config = null;
|
|
803
803
|
constructor(projectRoot){
|
|
804
|
-
this.projectRoot = projectRoot
|
|
804
|
+
this.projectRoot = projectRoot ?? process.cwd();
|
|
805
805
|
this.configPath = getSkillsJsonPath(this.projectRoot);
|
|
806
806
|
}
|
|
807
807
|
getProjectRoot() {
|
|
@@ -810,6 +810,10 @@ class ConfigLoader {
|
|
|
810
810
|
getConfigPath() {
|
|
811
811
|
return this.configPath;
|
|
812
812
|
}
|
|
813
|
+
getInstallDir() {
|
|
814
|
+
const { installDir } = this.getDefaults();
|
|
815
|
+
return __WEBPACK_EXTERNAL_MODULE_node_path__.join(this.projectRoot, installDir);
|
|
816
|
+
}
|
|
813
817
|
exists() {
|
|
814
818
|
return exists(this.configPath);
|
|
815
819
|
}
|
|
@@ -828,7 +832,7 @@ class ConfigLoader {
|
|
|
828
832
|
return this.load();
|
|
829
833
|
}
|
|
830
834
|
save(config) {
|
|
831
|
-
const toSave = config
|
|
835
|
+
const toSave = config ?? this.config;
|
|
832
836
|
if (!toSave) throw new Error('No config to save');
|
|
833
837
|
writeJson(this.configPath, toSave);
|
|
834
838
|
this.config = toSave;
|
|
@@ -842,7 +846,7 @@ class ConfigLoader {
|
|
|
842
846
|
const config = {
|
|
843
847
|
...DEFAULT_SKILLS_JSON,
|
|
844
848
|
...options,
|
|
845
|
-
skills: options?.skills
|
|
849
|
+
skills: options?.skills ?? {},
|
|
846
850
|
defaults: {
|
|
847
851
|
...DEFAULT_SKILLS_JSON.defaults,
|
|
848
852
|
...options?.defaults
|
|
@@ -852,31 +856,40 @@ class ConfigLoader {
|
|
|
852
856
|
return config;
|
|
853
857
|
}
|
|
854
858
|
getDefaults() {
|
|
855
|
-
const config = this.
|
|
859
|
+
const config = this.getConfigOrDefault();
|
|
860
|
+
const storedDefaults = config.defaults ?? {};
|
|
856
861
|
return {
|
|
857
|
-
registry:
|
|
858
|
-
installDir:
|
|
859
|
-
targetAgents:
|
|
860
|
-
installMode:
|
|
862
|
+
registry: storedDefaults.registry ?? DEFAULT_VALUES.registry,
|
|
863
|
+
installDir: storedDefaults.installDir ?? DEFAULT_VALUES.installDir,
|
|
864
|
+
targetAgents: storedDefaults.targetAgents ?? DEFAULT_VALUES.targetAgents,
|
|
865
|
+
installMode: storedDefaults.installMode ?? DEFAULT_VALUES.installMode
|
|
861
866
|
};
|
|
862
867
|
}
|
|
868
|
+
updateDefaults(updates) {
|
|
869
|
+
this.ensureConfigLoaded();
|
|
870
|
+
if (this.config) {
|
|
871
|
+
this.config.defaults = {
|
|
872
|
+
...this.config.defaults,
|
|
873
|
+
...updates
|
|
874
|
+
};
|
|
875
|
+
this.save();
|
|
876
|
+
}
|
|
877
|
+
}
|
|
863
878
|
getRegistryUrl(registryName) {
|
|
864
|
-
const config = this.
|
|
879
|
+
const config = this.getConfigOrDefault();
|
|
865
880
|
if (config.registries?.[registryName]) return config.registries[registryName];
|
|
866
881
|
if (DEFAULT_REGISTRIES[registryName]) return DEFAULT_REGISTRIES[registryName];
|
|
867
882
|
return `https://${registryName}`;
|
|
868
883
|
}
|
|
869
|
-
getInstallDir() {
|
|
870
|
-
const defaults = this.getDefaults();
|
|
871
|
-
return __WEBPACK_EXTERNAL_MODULE_node_path__.join(this.projectRoot, defaults.installDir);
|
|
872
|
-
}
|
|
873
884
|
addSkill(name, ref) {
|
|
874
|
-
|
|
875
|
-
if (this.config)
|
|
876
|
-
|
|
885
|
+
this.ensureConfigLoaded();
|
|
886
|
+
if (this.config) {
|
|
887
|
+
this.config.skills[name] = ref;
|
|
888
|
+
this.save();
|
|
889
|
+
}
|
|
877
890
|
}
|
|
878
891
|
removeSkill(name) {
|
|
879
|
-
|
|
892
|
+
this.ensureConfigLoaded();
|
|
880
893
|
if (this.config?.skills[name]) {
|
|
881
894
|
delete this.config.skills[name];
|
|
882
895
|
this.save();
|
|
@@ -901,6 +914,14 @@ class ConfigLoader {
|
|
|
901
914
|
const skills = this.getSkills();
|
|
902
915
|
return skills[name];
|
|
903
916
|
}
|
|
917
|
+
getConfigOrDefault() {
|
|
918
|
+
if (this.config) return this.config;
|
|
919
|
+
if (this.exists()) return this.load();
|
|
920
|
+
return DEFAULT_SKILLS_JSON;
|
|
921
|
+
}
|
|
922
|
+
ensureConfigLoaded() {
|
|
923
|
+
if (!this.config) this.load();
|
|
924
|
+
}
|
|
904
925
|
}
|
|
905
926
|
class GitResolver {
|
|
906
927
|
defaultRegistry;
|
|
@@ -1397,41 +1418,6 @@ class SkillManager {
|
|
|
1397
1418
|
}
|
|
1398
1419
|
return updated;
|
|
1399
1420
|
}
|
|
1400
|
-
link(localPath, name) {
|
|
1401
|
-
const absolutePath = __WEBPACK_EXTERNAL_MODULE_node_path__.resolve(localPath);
|
|
1402
|
-
if (!exists(absolutePath)) throw new Error(`Path ${localPath} does not exist`);
|
|
1403
|
-
const skillJsonPath = __WEBPACK_EXTERNAL_MODULE_node_path__.join(absolutePath, 'skill.json');
|
|
1404
|
-
let skillName = name || __WEBPACK_EXTERNAL_MODULE_node_path__.basename(absolutePath);
|
|
1405
|
-
if (exists(skillJsonPath)) try {
|
|
1406
|
-
const skillJson = readJson(skillJsonPath);
|
|
1407
|
-
skillName = name || skillJson.name || skillName;
|
|
1408
|
-
} catch {}
|
|
1409
|
-
const linkPath = this.getSkillPath(skillName);
|
|
1410
|
-
ensureDir(__WEBPACK_EXTERNAL_MODULE_node_path__.dirname(linkPath));
|
|
1411
|
-
createSymlink(absolutePath, linkPath);
|
|
1412
|
-
logger_logger.success(`Linked ${skillName} → ${absolutePath}`);
|
|
1413
|
-
return {
|
|
1414
|
-
name: skillName,
|
|
1415
|
-
path: linkPath,
|
|
1416
|
-
version: 'local',
|
|
1417
|
-
source: absolutePath,
|
|
1418
|
-
isLinked: true
|
|
1419
|
-
};
|
|
1420
|
-
}
|
|
1421
|
-
unlink(name) {
|
|
1422
|
-
const skillPath = this.getSkillPath(name);
|
|
1423
|
-
if (!exists(skillPath)) {
|
|
1424
|
-
logger_logger.warn(`Skill ${name} is not installed`);
|
|
1425
|
-
return false;
|
|
1426
|
-
}
|
|
1427
|
-
if (!isSymlink(skillPath)) {
|
|
1428
|
-
logger_logger.warn(`Skill ${name} is not a linked skill`);
|
|
1429
|
-
return false;
|
|
1430
|
-
}
|
|
1431
|
-
remove(skillPath);
|
|
1432
|
-
logger_logger.success(`Unlinked ${name}`);
|
|
1433
|
-
return true;
|
|
1434
|
-
}
|
|
1435
1421
|
list() {
|
|
1436
1422
|
const skills = [];
|
|
1437
1423
|
const seenNames = new Set();
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"link.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/link.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAsCpC,eAAO,MAAM,WAAW,SAAU,CAAC;AACnC,eAAO,MAAM,aAAa,SAAY,CAAC;AACvC,eAAe,WAAW,CAAC"}
|