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 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;AA6KpC;;GAEG;AACH,eAAO,MAAM,iBAAiB,SA2D1B,CAAC;AAEL;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,CAO/C;AAED,eAAe,iBAAiB,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,aAAa,EAAE,MAAM,WAAW,CAAC;AACvD,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
+ {"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
- * Supports multiple installation modes:
6
- * - Project install (default): Install to project directory
7
- * - Global install (-g): Install to user home directory
8
- * - Multi-Agent install (-a): Install to specified agents
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
- * Interactive flow:
11
- * 1. Detect installed agents
12
- * 2. Select target agents (multi-select)
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;AAoBpC;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,cAAc,SAkYvB,CAAC;AAEL,eAAe,cAAc,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 || process.cwd();
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 || this.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.config || (this.exists() ? this.load() : DEFAULT_SKILLS_JSON);
908
+ const config = this.getConfigOrDefault();
909
+ const storedDefaults = config.defaults ?? {};
905
910
  return {
906
- registry: config.defaults?.registry || 'github',
907
- installDir: config.defaults?.installDir || '.skills',
908
- targetAgents: config.defaults?.targetAgents || [],
909
- installMode: config.defaults?.installMode || 'symlink'
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.config || (this.exists() ? this.load() : DEFAULT_SKILLS_JSON);
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
- if (!this.config) this.load();
924
- if (this.config) this.config.skills[name] = ref;
925
- this.save();
934
+ this.ensureConfigLoaded();
935
+ if (this.config) {
936
+ this.config.skills[name] = ref;
937
+ this.save();
938
+ }
926
939
  }
927
940
  removeSkill(name) {
928
- if (!this.config) this.load();
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 skipConfirm = options.yes || false;
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
- let targetAgents;
1934
- if (options.all) {
1935
- targetAgents = allAgentTypes;
1936
- __WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.info(`Installing to all ${__WEBPACK_EXTERNAL_MODULE_chalk__["default"].cyan(targetAgents.length)} agents`);
1937
- } else if (options.agent && options.agent.length > 0) {
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
- * Default registry URLs
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 (ignore cache)
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 default configuration
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
- * Get registry URL
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
- getRegistryUrl(registryName: string): string;
88
+ updateDefaults(updates: Partial<SkillsDefaults>): void;
56
89
  /**
57
- * Get installation directory
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
- getInstallDir(): string;
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;AAcpE;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAGrD,CAAC;AAEF;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,MAAM,CAA2B;gBAE7B,WAAW,CAAC,EAAE,MAAM;IAKhC;;OAEG;IACH,cAAc,IAAI,MAAM;IAIxB;;OAEG;IACH,aAAa,IAAI,MAAM;IAIvB;;OAEG;IACH,MAAM,IAAI,OAAO;IAIjB;;OAEG;IACH,IAAI,IAAI,UAAU;IAiBlB;;OAEG;IACH,MAAM,IAAI,UAAU;IAKpB;;OAEG;IACH,IAAI,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,IAAI;IAS/B;;;;OAIG;IACH,YAAY,IAAI,OAAO;IAQvB;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,UAAU;IAejD;;OAEG;IACH,WAAW,IAAI,QAAQ,CAAC,cAAc,CAAC;IAUvC;;OAEG;IACH,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM;IAiB5C;;OAEG;IACH,aAAa,IAAI,MAAM;IAKvB;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAUzC;;OAEG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAYlC;;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;CAI9C;AAED,eAAe,YAAY,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":"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"}
1
+ {"version":3,"file":"skill-manager.d.ts","sourceRoot":"","sources":["../../src/core/skill-manager.ts"],"names":[],"mappings":"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"}
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 || process.cwd();
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 || this.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.config || (this.exists() ? this.load() : DEFAULT_SKILLS_JSON);
859
+ const config = this.getConfigOrDefault();
860
+ const storedDefaults = config.defaults ?? {};
856
861
  return {
857
- registry: config.defaults?.registry || 'github',
858
- installDir: config.defaults?.installDir || '.skills',
859
- targetAgents: config.defaults?.targetAgents || [],
860
- installMode: config.defaults?.installMode || 'symlink'
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.config || (this.exists() ? this.load() : DEFAULT_SKILLS_JSON);
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
- if (!this.config) this.load();
875
- if (this.config) this.config.skills[name] = ref;
876
- this.save();
885
+ this.ensureConfigLoaded();
886
+ if (this.config) {
887
+ this.config.skills[name] = ref;
888
+ this.save();
889
+ }
877
890
  }
878
891
  removeSkill(name) {
879
- if (!this.config) this.load();
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,6 +1,6 @@
1
1
  {
2
2
  "name": "reskill",
3
- "version": "0.16.0",
3
+ "version": "0.17.0",
4
4
  "description": "AI Skills Package Manager - Git-based skills management for AI agents",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,5 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare const linkCommand: Command;
3
- export declare const unlinkCommand: Command;
4
- export default linkCommand;
5
- //# sourceMappingURL=link.d.ts.map
@@ -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"}