@maccesar/aiskills 1.21.0 → 1.21.1

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.
@@ -9,8 +9,10 @@ import { join } from 'path';
9
9
  import os from 'os';
10
10
  import {
11
11
  SKILLS,
12
+ COMMANDS,
12
13
  PACKAGE_VERSION,
13
14
  getAgentsSkillsDir,
15
+ getClaudeCommandsDir,
14
16
  getConfigDir,
15
17
  getPlatforms,
16
18
  } from '../config.js';
@@ -20,6 +22,7 @@ import {
20
22
  isClaudePluginEnabled,
21
23
  hasClaudePluginCache,
22
24
  pluginProvidesSkill,
25
+ pluginProvidesCommand,
23
26
  } from '../claude-plugin.js';
24
27
 
25
28
  const CHECK = chalk.green('✓');
@@ -30,6 +33,7 @@ export async function doctorCommand() {
30
33
  const homeDir = os.homedir();
31
34
  const skillsDir = getAgentsSkillsDir(homeDir);
32
35
  const claudeDir = join(homeDir, '.claude');
36
+ const commandsDir = getClaudeCommandsDir(homeDir);
33
37
  const cacheDir = getConfigDir();
34
38
 
35
39
  let issues = 0;
@@ -59,6 +63,27 @@ export async function doctorCommand() {
59
63
  issues += missingSkills.length;
60
64
  }
61
65
 
66
+ // Slash commands the enabled marketplace plugin serves are intentionally
67
+ // absent from ~/.claude/commands/ to avoid duplicate autocomplete entries.
68
+ const missingCommands = [];
69
+ const pluginCommands = [];
70
+ for (const command of COMMANDS) {
71
+ if (pluginProvidesCommand(command, homeDir)) {
72
+ pluginCommands.push(command);
73
+ } else if (!existsSync(join(commandsDir, `${command}.md`))) {
74
+ missingCommands.push(command);
75
+ }
76
+ }
77
+ const expectedCommands = COMMANDS.length - pluginCommands.length;
78
+ if (pluginCommands.length === COMMANDS.length) {
79
+ console.log(` ${CHECK} Slash commands: all ${COMMANDS.length} served by the marketplace plugin`);
80
+ } else if (missingCommands.length === 0) {
81
+ console.log(` ${CHECK} Slash commands: ${expectedCommands}/${expectedCommands} installed in ~/.claude/commands/`);
82
+ } else {
83
+ console.log(` ${CROSS} Slash commands: ${expectedCommands - missingCommands.length}/${expectedCommands} installed (missing: ${missingCommands.join(', ')})`);
84
+ issues += missingCommands.length;
85
+ }
86
+
62
87
  // Hook check
63
88
  if (hasHook(claudeDir)) {
64
89
  console.log(` ${CHECK} Hook: SessionStart configured`);
@@ -304,11 +304,21 @@ export async function skillsCommand(options) {
304
304
  skillsToInstall,
305
305
  baseDir
306
306
  );
307
- if (symlinkResult.linked.length === skillsToInstall.length) {
308
- spinner.succeed(`${platform.displayName}: Skills linked`);
307
+ const expected = skillsToInstall.length - symlinkResult.skipped.length;
308
+ const pluginNote =
309
+ symlinkResult.skipped.length > 0
310
+ ? ` (${symlinkResult.skipped.length} served by the marketplace plugin)`
311
+ : '';
312
+
313
+ if (expected === 0) {
314
+ spinner.info(
315
+ `${platform.displayName}: All ${symlinkResult.skipped.length} skills served by the marketplace plugin`
316
+ );
317
+ } else if (symlinkResult.linked.length === expected) {
318
+ spinner.succeed(`${platform.displayName}: Skills linked${pluginNote}`);
309
319
  } else {
310
320
  spinner.warn(
311
- `${platform.displayName}: ${symlinkResult.linked.length}/${skillsToInstall.length} skills linked`
321
+ `${platform.displayName}: ${symlinkResult.linked.length}/${expected} skills linked${pluginNote}`
312
322
  );
313
323
  }
314
324
  }
package/lib/config.js CHANGED
@@ -52,7 +52,8 @@ export const LEGACY_COMMANDS = [];
52
52
  export const getConfigDir = () => path.join(os.homedir(), '.aiskills');
53
53
 
54
54
  // Directory paths
55
- export const getAgentsSkillsDir = (baseDir = os.homedir()) => path.join(baseDir, '.agents', 'skills');
55
+ export const getAgentsDir = (baseDir = os.homedir()) => path.join(baseDir, '.agents');
56
+ export const getAgentsSkillsDir = (baseDir = os.homedir()) => path.join(getAgentsDir(baseDir), 'skills');
56
57
  export const getClaudeSkillsDir = (baseDir = os.homedir()) => path.join(baseDir, '.claude', 'skills');
57
58
  export const getClaudeCommandsDir = (baseDir = os.homedir()) => path.join(baseDir, '.claude', 'commands');
58
59
  export const getGeminiSkillsDir = (baseDir = os.homedir()) => path.join(baseDir, '.gemini', 'skills');
@@ -111,11 +112,17 @@ export default {
111
112
  COMMANDS,
112
113
  LEGACY_COMMANDS,
113
114
  getConfigDir,
115
+ getAgentsDir,
114
116
  getAgentsSkillsDir,
115
117
  getClaudeSkillsDir,
116
118
  getClaudeCommandsDir,
117
119
  getGeminiSkillsDir,
118
120
  getCodexSkillsDir,
121
+ CLAUDE_PLUGIN_MARKETPLACE,
122
+ CLAUDE_PLUGIN_NAME,
123
+ CLAUDE_PLUGIN_KEY,
124
+ getClaudePluginSkillsPath,
125
+ getClaudeSettingsPaths,
119
126
  getPlatforms,
120
127
  GITHUB_API_HEADERS,
121
128
  };
package/lib/installer.js CHANGED
@@ -18,6 +18,7 @@ import {
18
18
  getClaudeCommandsDir,
19
19
  } from './config.js';
20
20
  import { removeSkills, removeCommands } from './cleanup.js';
21
+ import { createSymlinkOrCopy } from './symlink.js';
21
22
 
22
23
  /**
23
24
  * Recursively copy a directory
@@ -37,6 +38,8 @@ export async function copyDirectory(src, dest) {
37
38
  * @param {string} repoDir - Repository directory
38
39
  * @param {string} skillName - Name of the skill
39
40
  * @param {string} baseDir - Base directory for installation
41
+ * Development checkouts are linked so `npm link` users see edits immediately.
42
+ * Published npm packages are copied so installed skills remain independent.
40
43
  * @returns {Promise<boolean>} True if installed successfully
41
44
  */
42
45
  export async function installSkill(repoDir, skillName, baseDir = os.homedir()) {
@@ -52,6 +55,10 @@ export async function installSkill(repoDir, skillName, baseDir = os.homedir()) {
52
55
  return false;
53
56
  }
54
57
 
58
+ if (existsSync(join(repoDir, '.git'))) {
59
+ return createSymlinkOrCopy(skillSrc, skillDest, true);
60
+ }
61
+
55
62
  if (existsSync(skillDest)) {
56
63
  await remove(skillDest);
57
64
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maccesar/aiskills",
3
- "version": "1.21.0",
3
+ "version": "1.21.1",
4
4
  "description": "AI coding assistant skills for Claude Code, Gemini CLI, and Codex CLI",
5
5
  "type": "module",
6
6
  "bin": {
@@ -56,6 +56,8 @@
56
56
  "bin/",
57
57
  "lib/",
58
58
  "skills/",
59
+ "!skills/**/__pycache__/",
60
+ "!skills/**/*.py[cod]",
59
61
  "commands/"
60
62
  ],
61
63
  "publishConfig": {