Skip to content

Commit 3565daa

Browse files
committed
fix(cli): add --skill alias and fix agent detection
- Add --skill as alias for --skills option (install command) - Fix sync command to always detect agent instead of using default 'universal' - Auto-install npm dependencies for skills with package.json
1 parent 8496e3c commit 3565daa

File tree

2 files changed

+28
-9
lines changed

2 files changed

+28
-9
lines changed

packages/cli/src/commands/install.ts

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import { existsSync, mkdirSync, cpSync, rmSync, symlinkSync } from 'node:fs';
22
import { join } from 'node:path';
3+
import { execFile } from 'node:child_process';
4+
import { promisify } from 'node:util';
5+
6+
const execFileAsync = promisify(execFile);
37
import { Command, Option } from 'clipanion';
48
import { detectProvider, isLocalPath, getProvider, evaluateSkillDirectory } from '@skillkit/core';
59
import type { SkillMetadata, GitProvider, AgentType } from '@skillkit/core';
@@ -42,7 +46,8 @@ export class InstallCommand extends Command {
4246
['Install from GitHub', '$0 install owner/repo'],
4347
['Install from GitLab', '$0 install gitlab:owner/repo'],
4448
['Install from Bitbucket', '$0 install bitbucket:owner/repo'],
45-
['Install specific skills (CI/CD)', '$0 install owner/repo --skills=pdf,xlsx'],
49+
['Install specific skill', '$0 install owner/repo --skill=pdf'],
50+
['Install multiple skills (CI/CD)', '$0 install owner/repo --skills=pdf,xlsx'],
4651
['Install all skills non-interactively', '$0 install owner/repo --all'],
4752
['Install from local path', '$0 install ./my-skills'],
4853
['Install globally', '$0 install owner/repo --global'],
@@ -53,7 +58,7 @@ export class InstallCommand extends Command {
5358

5459
source = Option.String({ required: true });
5560

56-
skills = Option.String('--skills,-s', {
61+
skills = Option.String('--skills,--skill,-s', {
5762
description: 'Comma-separated list of skills to install (non-interactive)',
5863
});
5964

@@ -143,7 +148,7 @@ export class InstallCommand extends Command {
143148
}
144149
console.log('');
145150
console.log(colors.muted(`Total: ${discoveredSkills.length} skill(s)`));
146-
console.log(colors.muted('To install: skillkit install <source> --skills=skill1,skill2'));
151+
console.log(colors.muted('To install: skillkit install <source> --skill=name'));
147152
}
148153

149154
const cleanupPath = result.tempRoot || result.path;
@@ -334,6 +339,21 @@ export class InstallCommand extends Command {
334339
if (isSymlinkMode && primaryPath === null) {
335340
primaryPath = targetPath;
336341
}
342+
343+
// Auto-install npm dependencies if package.json exists
344+
const packageJsonPath = join(targetPath, 'package.json');
345+
if (existsSync(packageJsonPath)) {
346+
s.stop(`Installed ${skillName} to ${adapter.name}`);
347+
s.start(`Installing npm dependencies for ${skillName}...`);
348+
try {
349+
await execFileAsync('npm', ['install', '--production'], { cwd: targetPath });
350+
s.stop(`Installed dependencies for ${skillName}`);
351+
} catch (npmErr) {
352+
s.stop(colors.warning(`Dependencies failed for ${skillName}`));
353+
console.log(colors.muted('Run manually: npm install in ' + targetPath));
354+
}
355+
s.start(`Finishing ${skillName} installation...`);
356+
}
337357
}
338358

339359
const metadata: SkillMetadata = {

packages/cli/src/commands/sync.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
22
import { dirname } from 'node:path';
33
import { Command, Option } from 'clipanion';
4-
import { loadConfig, findAllSkills } from '@skillkit/core';
4+
import { findAllSkills } from '@skillkit/core';
55
import type { AgentType } from '@skillkit/core';
66
import { getAdapter, detectAgent, getAllAdapters } from '@skillkit/agents';
77
import { getSearchDirs, getAgentConfigPath } from '../helpers.js';
@@ -67,10 +67,9 @@ export class SyncCommand extends Command {
6767
if (this.agent) {
6868
agentType = this.agent as AgentType;
6969
} else if (isInteractive) {
70-
// Let user select agent
70+
// Let user select agent - always detect, don't rely on default config
7171
s.start('Detecting agent...');
72-
const config = loadConfig();
73-
const detected = config.agent || (await detectAgent());
72+
const detected = await detectAgent();
7473
s.stop(`Detected: ${formatAgent(detected)}`);
7574

7675
const allAgents = getAllAdapters().map(a => a.type);
@@ -92,8 +91,8 @@ export class SyncCommand extends Command {
9291

9392
agentType = agentResult as AgentType;
9493
} else {
95-
const config = loadConfig();
96-
agentType = config.agent || (await detectAgent());
94+
// Non-interactive: always detect, don't rely on default config
95+
agentType = await detectAgent();
9796
}
9897

9998
const adapter = getAdapter(agentType);

0 commit comments

Comments
 (0)