@@ -32,7 +32,8 @@ export enum CONFIG_KEYS {
3232
3333export enum CONFIG_MODES {
3434 get = 'get' ,
35- set = 'set'
35+ set = 'set' ,
36+ describe = 'describe'
3637}
3738
3839export const MODEL_LIST = {
@@ -622,28 +623,208 @@ export const setConfig = (
622623 outro ( `${ chalk . green ( '✔' ) } config successfully set` ) ;
623624} ;
624625
626+ // --- HELP MESSAGE GENERATION ---
627+ function getConfigKeyDetails ( key ) {
628+ switch ( key ) {
629+ case CONFIG_KEYS . OCO_MODEL :
630+ return {
631+ description : 'The AI model to use for generating commit messages' ,
632+ values : MODEL_LIST
633+ } ;
634+ case CONFIG_KEYS . OCO_AI_PROVIDER :
635+ return {
636+ description : 'The AI provider to use' ,
637+ values : Object . values ( OCO_AI_PROVIDER_ENUM )
638+ } ;
639+ case CONFIG_KEYS . OCO_PROMPT_MODULE :
640+ return {
641+ description : 'The prompt module to use for commit message generation' ,
642+ values : Object . values ( OCO_PROMPT_MODULE_ENUM )
643+ } ;
644+ case CONFIG_KEYS . OCO_LANGUAGE :
645+ return {
646+ description : 'The locale to use for commit messages' ,
647+ values : Object . keys ( i18n )
648+ } ;
649+ case CONFIG_KEYS . OCO_TEST_MOCK_TYPE :
650+ return {
651+ description : 'The type of test mock to use' ,
652+ values : [ 'commit-message' , 'prompt-module-commitlint-config' ]
653+ } ;
654+ case CONFIG_KEYS . OCO_ONE_LINE_COMMIT :
655+ return {
656+ description : 'One line commit message' ,
657+ values : [ 'true' , 'false' ]
658+ } ;
659+ case CONFIG_KEYS . OCO_DESCRIPTION :
660+ return {
661+ description : 'Postface a message with ~3 sentences description of the changes' ,
662+ values : [ 'true' , 'false' ]
663+ } ;
664+ case CONFIG_KEYS . OCO_EMOJI :
665+ return {
666+ description : 'Preface a message with GitMoji' ,
667+ values : [ 'true' , 'false' ]
668+ } ;
669+ case CONFIG_KEYS . OCO_WHY :
670+ return {
671+ description : 'Output a short description of why the changes were done after the commit message (default: false)' ,
672+ values : [ 'true' , 'false' ]
673+ }
674+ case CONFIG_KEYS . OCO_OMIT_SCOPE :
675+ return {
676+ description : 'Do not include a scope in the commit message' ,
677+ values : [ 'true' , 'false' ]
678+ } ;
679+ case CONFIG_KEYS . OCO_GITPUSH :
680+ return {
681+ description : 'Push to git after commit (deprecated). If false, oco will exit after committing' ,
682+ values : [ 'true' , 'false' ]
683+ } ;
684+ case CONFIG_KEYS . OCO_TOKENS_MAX_INPUT :
685+ return {
686+ description : 'Max model token limit' ,
687+ values : [ 'Any positive integer' ]
688+ } ;
689+ case CONFIG_KEYS . OCO_TOKENS_MAX_OUTPUT :
690+ return {
691+ description : 'Max response tokens' ,
692+ values : [ 'Any positive integer' ]
693+ } ;
694+ case CONFIG_KEYS . OCO_API_KEY :
695+ return {
696+ description : 'API key for the selected provider' ,
697+ values : [ 'String (required for most providers)' ]
698+ } ;
699+ case CONFIG_KEYS . OCO_API_URL :
700+ return {
701+ description : 'Custom API URL - may be used to set proxy path to OpenAI API' ,
702+ values : [ "URL string (must start with 'http://' or 'https://')" ]
703+ } ;
704+ case CONFIG_KEYS . OCO_MESSAGE_TEMPLATE_PLACEHOLDER :
705+ return {
706+ description : 'Message template placeholder' ,
707+ values : [ "String (must start with $)" ]
708+ } ;
709+ default :
710+ return {
711+ description : 'String value' ,
712+ values : [ 'Any string' ]
713+ } ;
714+ }
715+ }
716+
717+ function printConfigKeyHelp ( param ) {
718+ if ( ! Object . values ( CONFIG_KEYS ) . includes ( param ) ) {
719+ console . log ( chalk . red ( `Unknown config parameter: ${ param } ` ) ) ;
720+ return ;
721+ }
722+
723+ const details = getConfigKeyDetails ( param as CONFIG_KEYS ) ;
724+
725+ let desc = details . description ;
726+ let defaultValue = undefined ;
727+ if ( param in DEFAULT_CONFIG ) {
728+ defaultValue = DEFAULT_CONFIG [ param ] ;
729+ }
730+
731+
732+ console . log ( chalk . bold ( `\n${ param } :` ) ) ;
733+ console . log ( chalk . gray ( ` Description: ${ desc } ` ) ) ;
734+ if ( defaultValue !== undefined ) {
735+ // Print booleans and numbers as-is, strings without quotes
736+ if ( typeof defaultValue === 'string' ) {
737+ console . log ( chalk . gray ( ` Default: ${ defaultValue } ` ) ) ;
738+ } else {
739+ console . log ( chalk . gray ( ` Default: ${ defaultValue } ` ) ) ;
740+ }
741+ }
742+
743+ if ( Array . isArray ( details . values ) ) {
744+ console . log ( chalk . gray ( ' Accepted values:' ) ) ;
745+ details . values . forEach ( value => {
746+ console . log ( chalk . gray ( ` - ${ value } ` ) ) ;
747+ } ) ;
748+ } else {
749+ console . log ( chalk . gray ( ' Accepted values by provider:' ) ) ;
750+ Object . entries ( details . values ) . forEach ( ( [ provider , values ] ) => {
751+ console . log ( chalk . gray ( ` ${ provider } :` ) ) ;
752+ ( values as string [ ] ) . forEach ( value => {
753+ console . log ( chalk . gray ( ` - ${ value } ` ) ) ;
754+ } ) ;
755+ } ) ;
756+ }
757+ }
758+
759+ function printAllConfigHelp ( ) {
760+ console . log ( chalk . bold ( 'Available config parameters:' ) ) ;
761+ for ( const key of Object . values ( CONFIG_KEYS ) . sort ( ) ) {
762+ const details = getConfigKeyDetails ( key ) ;
763+ // Try to get the default value from DEFAULT_CONFIG
764+ let defaultValue = undefined ;
765+ if ( key in DEFAULT_CONFIG ) {
766+ defaultValue = DEFAULT_CONFIG [ key ] ;
767+ }
768+
769+ console . log ( chalk . bold ( `\n${ key } :` ) ) ;
770+ console . log ( chalk . gray ( ` Description: ${ details . description } ` ) ) ;
771+ if ( defaultValue !== undefined ) {
772+ if ( typeof defaultValue === 'string' ) {
773+ console . log ( chalk . gray ( ` Default: ${ defaultValue } ` ) ) ;
774+ } else {
775+ console . log ( chalk . gray ( ` Default: ${ defaultValue } ` ) ) ;
776+ }
777+ }
778+ }
779+ console . log ( chalk . yellow ( '\nUse "oco config describe [PARAMETER]" to see accepted values and more details for a specific config parameter.' ) ) ;
780+ }
781+
625782export const configCommand = command (
626783 {
627784 name : COMMANDS . config ,
628- parameters : [ '<mode>' , '<key=values...>' ]
785+ parameters : [ '<mode>' , '[key=values...]' ] ,
786+ help : {
787+ description : 'Configure opencommit settings' ,
788+ examples : [
789+ 'Describe all config parameters: oco config describe' ,
790+ 'Describe a specific parameter: oco config describe OCO_MODEL' ,
791+ 'Get a config value: oco config get OCO_MODEL' ,
792+ 'Set a config value: oco config set OCO_MODEL=gpt-4'
793+ ]
794+ }
629795 } ,
630796 async ( argv ) => {
631797 try {
632798 const { mode, keyValues } = argv . _ ;
633799 intro ( `COMMAND: config ${ mode } ${ keyValues } ` ) ;
634800
635- if ( mode === CONFIG_MODES . get ) {
801+ if ( mode === CONFIG_MODES . describe ) {
802+ if ( ! keyValues || keyValues . length === 0 ) {
803+ printAllConfigHelp ( ) ;
804+ } else {
805+ for ( const key of keyValues ) {
806+ printConfigKeyHelp ( key ) ;
807+ }
808+ }
809+ process . exit ( 0 ) ;
810+ } else if ( mode === CONFIG_MODES . get ) {
811+ if ( ! keyValues || keyValues . length === 0 ) {
812+ throw new Error ( 'No config keys specified for get mode' ) ;
813+ }
636814 const config = getConfig ( ) || { } ;
637815 for ( const key of keyValues ) {
638816 outro ( `${ key } =${ config [ key as keyof typeof config ] } ` ) ;
639817 }
640818 } else if ( mode === CONFIG_MODES . set ) {
819+ if ( ! keyValues || keyValues . length === 0 ) {
820+ throw new Error ( 'No config keys specified for set mode' ) ;
821+ }
641822 await setConfig (
642823 keyValues . map ( ( keyValue ) => keyValue . split ( '=' ) as [ string , string ] )
643824 ) ;
644825 } else {
645826 throw new Error (
646- `Unsupported mode: ${ mode } . Valid modes are: "set" and "get "`
827+ `Unsupported mode: ${ mode } . Valid modes are: "set", "get", and "describe "`
647828 ) ;
648829 }
649830 } catch ( error ) {
0 commit comments