File tree Expand file tree Collapse file tree 3 files changed +60
-1
lines changed
Expand file tree Collapse file tree 3 files changed +60
-1
lines changed Original file line number Diff line number Diff line change @@ -301,6 +301,24 @@ describe('install command', () => {
301301 const result = run ( 'install -c nonexistent.json' , { cwd : projectDir } ) ;
302302 expect ( result . exitCode ) . not . toBe ( 0 ) ;
303303 } ) ;
304+
305+ it ( 'should install when skills is an object with installed array (issue #62)' , ( ) => {
306+ writeConfigFile ( projectDir , {
307+ version : '1.0.0' ,
308+ environments : [ 'claude' ] ,
309+ phases : [ 'requirements' ] ,
310+ skills : {
311+ installed : [
312+ { registry : 'codeaholicguy/ai-devkit' , name : 'dev-lifecycle' }
313+ ]
314+ } ,
315+ createdAt : new Date ( ) . toISOString ( ) ,
316+ updatedAt : new Date ( ) . toISOString ( )
317+ } ) ;
318+
319+ const result = run ( 'install' , { cwd : projectDir } ) ;
320+ expect ( result . exitCode ) . toBe ( 0 ) ;
321+ } ) ;
304322} ) ;
305323
306324describe ( 'skill command' , ( ) => {
Original file line number Diff line number Diff line change @@ -31,4 +31,34 @@ describe('config util', () => {
3131 it ( 'fails when skills entry is invalid' , ( ) => {
3232 expect ( ( ) => validateInstallConfig ( { skills : [ { registry : '' , name : 'debug' } ] } , '/tmp/.ai-devkit.json' ) ) . toThrow ( 'skills[0].registry' ) ;
3333 } ) ;
34+
35+ it ( 'accepts skills as an object with installed array (issue #62)' , ( ) => {
36+ const result = validateInstallConfig ( {
37+ environments : [ 'claude' ] ,
38+ skills : {
39+ installed : [
40+ { registry : 'codeaholicguy/ai-devkit' , name : 'dev-lifecycle' }
41+ ]
42+ }
43+ } , '/tmp/.ai-devkit.json' ) ;
44+
45+ expect ( result . skills ) . toEqual ( [
46+ { registry : 'codeaholicguy/ai-devkit' , name : 'dev-lifecycle' }
47+ ] ) ;
48+ } ) ;
49+
50+ it ( 'accepts skills as an object with registries and installed array' , ( ) => {
51+ const result = validateInstallConfig ( {
52+ skills : {
53+ registries : { myorg : 'myorg/skills' } ,
54+ installed : [
55+ { registry : 'codeaholicguy/ai-devkit' , name : 'memory' }
56+ ]
57+ }
58+ } , '/tmp/.ai-devkit.json' ) ;
59+
60+ expect ( result . skills ) . toEqual ( [
61+ { registry : 'codeaholicguy/ai-devkit' , name : 'memory' }
62+ ] ) ;
63+ } ) ;
3464} ) ;
Original file line number Diff line number Diff line change @@ -46,7 +46,18 @@ const installConfigSchema = z.object({
4646 } ) ;
4747 } ) . transform ( values => dedupe ( values ) as EnvironmentCode [ ] ) ,
4848 phases : z . array ( z . string ( ) ) . optional ( ) ,
49- skills : z . array ( skillEntrySchema ) . optional ( ) . default ( [ ] ) ,
49+ skills : z . preprocess (
50+ ( val ) => {
51+ if ( val == null ) return [ ] ;
52+ if ( Array . isArray ( val ) ) return val ;
53+ if ( typeof val === 'object' && ! Array . isArray ( val ) ) {
54+ const obj = val as Record < string , unknown > ;
55+ return Array . isArray ( obj . installed ) ? obj . installed : [ ] ;
56+ }
57+ return val ;
58+ } ,
59+ z . array ( skillEntrySchema ) . default ( [ ] )
60+ ) ,
5061 mcpServers : z . record ( z . string ( ) , z . object ( {
5162 transport : z . enum ( [ 'stdio' , 'http' , 'sse' ] ) ,
5263 command : z . string ( ) . optional ( ) ,
You can’t perform that action at this time.
0 commit comments