11import { existsSync , mkdirSync , cpSync , rmSync , symlinkSync } from 'node:fs' ;
22import { join } from 'node:path' ;
3+ import { execFile } from 'node:child_process' ;
4+ import { promisify } from 'node:util' ;
5+
6+ const execFileAsync = promisify ( execFile ) ;
37import { Command , Option } from 'clipanion' ;
48import { detectProvider , isLocalPath , getProvider , evaluateSkillDirectory } from '@skillkit/core' ;
59import 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 = {
0 commit comments