@@ -425,7 +425,7 @@ describe('ConfigManager', () => {
425425 } ) ;
426426
427427 describe ( 'addSkill' , ( ) => {
428- it ( 'adds a new skill entry to config when skills is an array ' , async ( ) => {
428+ it ( 'adds a new skill entry to config' , async ( ) => {
429429 const config : DevKitConfig = {
430430 version : '1.0.0' ,
431431 environments : [ 'cursor' ] ,
@@ -444,46 +444,10 @@ describe('ConfigManager', () => {
444444 name : 'memory'
445445 } ) ;
446446
447- expect ( result . skills ) . toEqual ( {
448- installed : [
449- { registry : 'codeaholicguy/ai-devkit' , name : 'debug' } ,
450- { registry : 'codeaholicguy/ai-devkit' , name : 'memory' }
451- ]
452- } ) ;
453- expect ( mockFs . writeJson ) . toHaveBeenCalled ( ) ;
454- } ) ;
455-
456- it ( 'adds a new skill entry when skills is an object with registries' , async ( ) => {
457- const config = {
458- version : '1.0.0' ,
459- environments : [ 'cursor' ] ,
460- phases : [ ] ,
461- skills : {
462- registries : {
463- 'custom/repo' : 'https://github.com/custom/repo.git'
464- }
465- } ,
466- createdAt : '2024-01-01T00:00:00.000Z' ,
467- updatedAt : '2024-01-01T00:00:00.000Z'
468- } ;
469-
470- ( mockFs . pathExists as any ) . mockResolvedValue ( true ) ;
471- ( mockFs . readJson as any ) . mockResolvedValue ( config ) ;
472- ( mockFs . writeJson as any ) . mockResolvedValue ( undefined ) ;
473-
474- const result = await configManager . addSkill ( {
475- registry : 'custom/repo' ,
476- name : 'my-skill'
477- } ) ;
478-
479- expect ( result . skills ) . toEqual ( {
480- registries : {
481- 'custom/repo' : 'https://github.com/custom/repo.git'
482- } ,
483- installed : [
484- { registry : 'custom/repo' , name : 'my-skill' }
485- ]
486- } ) ;
447+ expect ( result . skills ) . toEqual ( [
448+ { registry : 'codeaholicguy/ai-devkit' , name : 'debug' } ,
449+ { registry : 'codeaholicguy/ai-devkit' , name : 'memory' }
450+ ] ) ;
487451 expect ( mockFs . writeJson ) . toHaveBeenCalled ( ) ;
488452 } ) ;
489453
@@ -527,46 +491,15 @@ describe('ConfigManager', () => {
527491 name : 'memory'
528492 } ) ;
529493
530- expect ( result . skills ) . toEqual ( {
531- installed : [
532- { registry : 'codeaholicguy/ai-devkit' , name : 'memory' }
533- ]
534- } ) ;
494+ expect ( result . skills ) . toEqual ( [
495+ { registry : 'codeaholicguy/ai-devkit' , name : 'memory' }
496+ ] ) ;
535497 expect ( mockFs . writeJson ) . toHaveBeenCalled ( ) ;
536498 } ) ;
537499 } ) ;
538500
539501 describe ( 'removeSkill' , ( ) => {
540- it ( 'removes the skill entry from the installed array' , async ( ) => {
541- const config : DevKitConfig = {
542- version : '1.0.0' ,
543- environments : [ 'claude' ] ,
544- phases : [ ] ,
545- skills : {
546- installed : [
547- { registry : 'codeaholicguy/ai-devkit' , name : 'dev-lifecycle' } ,
548- { registry : 'codeaholicguy/ai-devkit' , name : 'memory' }
549- ]
550- } ,
551- createdAt : '2024-01-01T00:00:00.000Z' ,
552- updatedAt : '2024-01-01T00:00:00.000Z'
553- } ;
554-
555- ( mockFs . pathExists as any ) . mockResolvedValue ( true ) ;
556- ( mockFs . readJson as any ) . mockResolvedValue ( config ) ;
557- ( mockFs . writeJson as any ) . mockResolvedValue ( undefined ) ;
558-
559- const result = await configManager . removeSkill ( 'dev-lifecycle' ) ;
560-
561- expect ( result . skills ) . toEqual ( {
562- installed : [
563- { registry : 'codeaholicguy/ai-devkit' , name : 'memory' }
564- ]
565- } ) ;
566- expect ( mockFs . writeJson ) . toHaveBeenCalled ( ) ;
567- } ) ;
568-
569- it ( 'removes skill when skills is an array' , async ( ) => {
502+ it ( 'removes the skill entry from the skills array' , async ( ) => {
570503 const config : DevKitConfig = {
571504 version : '1.0.0' ,
572505 environments : [ 'claude' ] ,
@@ -585,24 +518,20 @@ describe('ConfigManager', () => {
585518
586519 const result = await configManager . removeSkill ( 'dev-lifecycle' ) ;
587520
588- expect ( result . skills ) . toEqual ( {
589- installed : [
590- { registry : 'codeaholicguy/ai-devkit' , name : 'memory' }
591- ]
592- } ) ;
521+ expect ( result . skills ) . toEqual ( [
522+ { registry : 'codeaholicguy/ai-devkit' , name : 'memory' }
523+ ] ) ;
593524 expect ( mockFs . writeJson ) . toHaveBeenCalled ( ) ;
594525 } ) ;
595526
596- it ( 'results in an empty installed array when last skill is removed' , async ( ) => {
527+ it ( 'results in an empty array when last skill is removed' , async ( ) => {
597528 const config : DevKitConfig = {
598529 version : '1.0.0' ,
599530 environments : [ 'claude' ] ,
600531 phases : [ ] ,
601- skills : {
602- installed : [
603- { registry : 'codeaholicguy/ai-devkit' , name : 'dev-lifecycle' }
604- ]
605- } ,
532+ skills : [
533+ { registry : 'codeaholicguy/ai-devkit' , name : 'dev-lifecycle' }
534+ ] ,
606535 createdAt : '2024-01-01T00:00:00.000Z' ,
607536 updatedAt : '2024-01-01T00:00:00.000Z'
608537 } ;
@@ -613,20 +542,18 @@ describe('ConfigManager', () => {
613542
614543 const result = await configManager . removeSkill ( 'dev-lifecycle' ) ;
615544
616- expect ( result . skills ) . toEqual ( { installed : [ ] } ) ;
545+ expect ( result . skills ) . toEqual ( [ ] ) ;
617546 expect ( mockFs . writeJson ) . toHaveBeenCalled ( ) ;
618547 } ) ;
619548
620- it ( 'is a no-op when skill name does not exist in installed ' , async ( ) => {
549+ it ( 'is a no-op when skill name does not exist' , async ( ) => {
621550 const config : DevKitConfig = {
622551 version : '1.0.0' ,
623552 environments : [ 'claude' ] ,
624553 phases : [ ] ,
625- skills : {
626- installed : [
627- { registry : 'codeaholicguy/ai-devkit' , name : 'memory' }
628- ]
629- } ,
554+ skills : [
555+ { registry : 'codeaholicguy/ai-devkit' , name : 'memory' }
556+ ] ,
630557 createdAt : '2024-01-01T00:00:00.000Z' ,
631558 updatedAt : '2024-01-01T00:00:00.000Z'
632559 } ;
@@ -637,9 +564,9 @@ describe('ConfigManager', () => {
637564
638565 const result = await configManager . removeSkill ( 'nonexistent' ) ;
639566
640- expect ( result . skills ) . toEqual ( {
641- installed : [ { registry : 'codeaholicguy/ai-devkit' , name : 'memory' } ]
642- } ) ;
567+ expect ( result . skills ) . toEqual ( [
568+ { registry : 'codeaholicguy/ai-devkit' , name : 'memory' }
569+ ] ) ;
643570 } ) ;
644571
645572 it ( 'throws when config file is not found' , async ( ) => {
@@ -651,100 +578,16 @@ describe('ConfigManager', () => {
651578 } ) ;
652579 } ) ;
653580
654- describe ( 'normalizeSkillsConfig' , ( ) => {
655- it ( 'normalizes an array to SkillsConfig' , ( ) => {
656- const result = configManager . normalizeSkillsConfig ( [
657- { registry : 'r' , name : 's' }
658- ] ) ;
659- expect ( result ) . toEqual ( {
660- installed : [ { registry : 'r' , name : 's' } ]
661- } ) ;
662- } ) ;
663-
664- it ( 'normalizes an object with registries and installed' , ( ) => {
665- const result = configManager . normalizeSkillsConfig ( {
666- registries : { 'r' : 'https://example.com' } ,
667- installed : [ { registry : 'r' , name : 's' } ]
668- } ) ;
669- expect ( result ) . toEqual ( {
670- registries : { 'r' : 'https://example.com' } ,
671- installed : [ { registry : 'r' , name : 's' } ]
672- } ) ;
673- } ) ;
674-
675- it ( 'normalizes an object with only registries' , ( ) => {
676- const result = configManager . normalizeSkillsConfig ( {
677- registries : { 'r' : 'https://example.com' }
678- } ) ;
679- expect ( result ) . toEqual ( {
680- registries : { 'r' : 'https://example.com' } ,
681- installed : [ ]
682- } ) ;
683- } ) ;
684-
685- it ( 'normalizes undefined to empty SkillsConfig' , ( ) => {
686- const result = configManager . normalizeSkillsConfig ( undefined ) ;
687- expect ( result ) . toEqual ( { installed : [ ] } ) ;
688- } ) ;
689-
690- it ( 'normalizes null to empty SkillsConfig' , ( ) => {
691- const result = configManager . normalizeSkillsConfig ( null ) ;
692- expect ( result ) . toEqual ( { installed : [ ] } ) ;
693- } ) ;
694- } ) ;
695-
696- describe ( 'getInstalledSkills' , ( ) => {
697- it ( 'returns skills from array format' , ( ) => {
698- const config : DevKitConfig = {
699- version : '1.0.0' ,
700- environments : [ ] ,
701- phases : [ ] ,
702- skills : [ { registry : 'r' , name : 's' } ] ,
703- createdAt : '' ,
704- updatedAt : ''
705- } ;
706- expect ( configManager . getInstalledSkills ( config ) ) . toEqual ( [ { registry : 'r' , name : 's' } ] ) ;
707- } ) ;
708-
709- it ( 'returns skills from object format' , ( ) => {
710- const config = {
711- version : '1.0.0' ,
712- environments : [ ] ,
713- phases : [ ] ,
714- skills : {
715- registries : { 'r' : 'https://example.com' } ,
716- installed : [ { registry : 'r' , name : 's' } ]
717- } ,
718- createdAt : '' ,
719- updatedAt : ''
720- } as DevKitConfig ;
721- expect ( configManager . getInstalledSkills ( config ) ) . toEqual ( [ { registry : 'r' , name : 's' } ] ) ;
722- } ) ;
723-
724- it ( 'returns empty array when skills is undefined' , ( ) => {
725- const config : DevKitConfig = {
726- version : '1.0.0' ,
727- environments : [ ] ,
728- phases : [ ] ,
729- createdAt : '' ,
730- updatedAt : ''
731- } ;
732- expect ( configManager . getInstalledSkills ( config ) ) . toEqual ( [ ] ) ;
733- } ) ;
734- } ) ;
735-
736581 describe ( 'getSkillRegistries' , ( ) => {
737- it ( 'returns registries from skills. registries' , async ( ) => {
582+ it ( 'returns registries from top-level registries field ' , async ( ) => {
738583 ( mockFs . pathExists as any ) . mockResolvedValue ( true ) ;
739584 ( mockFs . readJson as any ) . mockResolvedValue ( {
740585 version : '1.0.0' ,
741586 environments : [ 'cursor' ] ,
742587 phases : [ ] ,
743- skills : {
744- registries : {
745- 'nested/skills' : 'https://github.com/nested/skills.git' ,
746- 'invalid/value' : false
747- }
588+ registries : {
589+ 'my-org/skills' : 'https://github.com/my-org/skills.git' ,
590+ 'invalid/value' : false
748591 } ,
749592 createdAt : '2024-01-01T00:00:00.000Z' ,
750593 updatedAt : '2024-01-01T00:00:00.000Z'
@@ -753,11 +596,11 @@ describe('ConfigManager', () => {
753596 const registries = await configManager . getSkillRegistries ( ) ;
754597
755598 expect ( registries ) . toEqual ( {
756- 'nested /skills' : 'https://github.com/nested /skills.git'
599+ 'my-org /skills' : 'https://github.com/my-org /skills.git'
757600 } ) ;
758601 } ) ;
759602
760- it ( 'returns empty object when no registry map exists' , async ( ) => {
603+ it ( 'returns empty object when no registries field exists' , async ( ) => {
761604 ( mockFs . pathExists as any ) . mockResolvedValue ( true ) ;
762605 ( mockFs . readJson as any ) . mockResolvedValue ( {
763606 version : '1.0.0' ,
0 commit comments