@@ -11,6 +11,7 @@ import {
1111 resolveBoilerplateBaseDir ,
1212 scaffoldTemplate ,
1313 scanBoilerplates ,
14+ SkillInstaller ,
1415 sluggify ,
1516} from '@pgpmjs/core' ;
1617import { resolveWorkspaceByType } from '@pgpmjs/env' ;
@@ -44,6 +45,7 @@ Options:
4445 --template, -t <path> Full template path (e.g., pnpm/module) - combines dir and fromPath
4546 --boilerplate Prompt to select from available boilerplates
4647 --create-workspace, -w Create a workspace first, then create the module inside it
48+ --use-skills Use npx skills CLI for skill installation (slower, writes skills-lock.json)
4749
4850Examples:
4951 ${ binaryName } init Initialize new module (default)
@@ -79,6 +81,7 @@ async function handleInit(argv: Partial<Record<string, any>>, prompter: Inquirer
7981 const noTty = Boolean ( ( argv as any ) . noTty || argv [ 'no-tty' ] || argv . tty === false || process . env . CI === 'true' ) ;
8082 const useBoilerplatePrompt = Boolean ( argv . boilerplate ) ;
8183 const createWorkspace = Boolean ( argv . createWorkspace || argv [ 'create-workspace' ] || argv . w ) ;
84+ const useNpxSkills = Boolean ( argv . useSkills || argv [ 'use-skills' ] ) ;
8285
8386 // Get fromPath from first positional arg
8487 const positionalFromPath = argv . _ ?. [ 0 ] as string | undefined ;
@@ -110,6 +113,7 @@ async function handleInit(argv: Partial<Record<string, any>>, prompter: Inquirer
110113 dir,
111114 noTty,
112115 cwd,
116+ useNpxSkills,
113117 } ) ;
114118 }
115119
@@ -139,6 +143,7 @@ async function handleInit(argv: Partial<Record<string, any>>, prompter: Inquirer
139143 dir,
140144 noTty,
141145 cwd,
146+ useNpxSkills,
142147 } ) ;
143148 }
144149
@@ -152,6 +157,7 @@ async function handleInit(argv: Partial<Record<string, any>>, prompter: Inquirer
152157 cwd,
153158 requiresWorkspace : inspection . config ?. requiresWorkspace ,
154159 createWorkspace,
160+ useNpxSkills,
155161 } , wasExplicitModuleRequest ) ;
156162}
157163
@@ -162,6 +168,7 @@ interface BoilerplateInitContext {
162168 dir ?: string ;
163169 noTty : boolean ;
164170 cwd : string ;
171+ useNpxSkills ?: boolean ;
165172}
166173
167174async function handleBoilerplateInit (
@@ -243,6 +250,7 @@ async function handleBoilerplateInit(
243250 dir : ctx . dir ,
244251 noTty : ctx . noTty ,
245252 cwd : ctx . cwd ,
253+ useNpxSkills : ctx . useNpxSkills ,
246254 } ) ;
247255 }
248256
@@ -256,6 +264,7 @@ async function handleBoilerplateInit(
256264 noTty : ctx . noTty ,
257265 cwd : ctx . cwd ,
258266 requiresWorkspace : inspection . config ?. requiresWorkspace ,
267+ useNpxSkills : ctx . useNpxSkills ,
259268 } , true ) ;
260269}
261270
@@ -275,9 +284,46 @@ interface InitContext {
275284 * If true, create a workspace first, then create the module inside it.
276285 */
277286 createWorkspace ?: boolean ;
287+ /**
288+ * If true, use npx skills CLI instead of built-in shallow clone.
289+ */
290+ useNpxSkills ?: boolean ;
291+ }
292+
293+ function installSkills ( skills : BoilerplateSkill [ ] , cwd : string , useNpxSkills : boolean ) : void {
294+ if ( process . env . PGPM_SKIP_SKILL_INSTALL ) return ;
295+
296+ if ( useNpxSkills ) {
297+ installSkillsViaNpx ( skills , cwd ) ;
298+ } else {
299+ installSkillsBuiltin ( skills , cwd ) ;
300+ }
301+ }
302+
303+ function installSkillsBuiltin ( skills : BoilerplateSkill [ ] , cwd : string ) : void {
304+ const installer = new SkillInstaller ( { toolName : DEFAULT_TEMPLATE_TOOL_NAME } ) ;
305+ const result = installer . install ( skills , cwd ) ;
306+
307+ if ( result . installed . length > 0 ) {
308+ for ( const name of result . installed ) {
309+ process . stdout . write ( ` installed ${ name } \n` ) ;
310+ }
311+ }
312+
313+ if ( result . failed . length > 0 ) {
314+ process . stdout . write ( '\n⚠️ Some skills could not be installed automatically.\n' ) ;
315+ process . stdout . write ( 'Run the following commands manually:\n\n' ) ;
316+ for ( const f of result . failed ) {
317+ const source = f . source . includes ( '://' )
318+ ? f . source
319+ : `https://github.com/${ f . source } ` ;
320+ process . stdout . write ( ` npx skills add ${ source } --skill ${ f . skill } \n` ) ;
321+ }
322+ process . stdout . write ( '\n' ) ;
323+ }
278324}
279325
280- function installSkills ( skills : BoilerplateSkill [ ] , cwd : string ) : void {
326+ function installSkillsViaNpx ( skills : BoilerplateSkill [ ] , cwd : string ) : void {
281327 const failed : string [ ] = [ ] ;
282328
283329 for ( const entry of skills ) {
@@ -373,7 +419,7 @@ async function handleWorkspaceInit(
373419 } ) ;
374420 if ( templateInfo . config ?. skills ?. length ) {
375421 process . stdout . write ( '\n📦 Installing skills...\n\n' ) ;
376- installSkills ( templateInfo . config . skills , targetPath ) ;
422+ installSkills ( templateInfo . config . skills , targetPath , Boolean ( ctx . useNpxSkills ) ) ;
377423 }
378424
379425 const relPath = path . relative ( process . cwd ( ) , targetPath ) ;
@@ -678,7 +724,7 @@ async function handleModuleInit(
678724 if ( moduleTemplateInfo . config ?. skills ?. length ) {
679725 const skillsCwd = project . workspacePath || modulePath ;
680726 process . stdout . write ( '\n📦 Installing skills...\n\n' ) ;
681- installSkills ( moduleTemplateInfo . config . skills , skillsCwd ) ;
727+ installSkills ( moduleTemplateInfo . config . skills , skillsCwd , Boolean ( ctx . useNpxSkills ) ) ;
682728 }
683729
684730 const relPath = path . relative ( process . cwd ( ) , modulePath ) ;
0 commit comments