@@ -51,6 +51,11 @@ export interface TurnProtection {
5151 turns : number
5252}
5353
54+ export interface TuiConfig {
55+ sidebar : boolean
56+ debug : boolean
57+ }
58+
5459export interface ExperimentalConfig {
5560 allowSubAgents : boolean
5661 customPrompts : boolean
@@ -64,6 +69,7 @@ export interface PluginConfig {
6469 commands : Commands
6570 manualMode : ManualModeConfig
6671 turnProtection : TurnProtection
72+ tui : TuiConfig
6773 experimental : ExperimentalConfig
6874 protectedFilePatterns : string [ ]
6975 compress : CompressTool
@@ -101,6 +107,9 @@ export const VALID_CONFIG_KEYS = new Set([
101107 "turnProtection" ,
102108 "turnProtection.enabled" ,
103109 "turnProtection.turns" ,
110+ "tui" ,
111+ "tui.sidebar" ,
112+ "tui.debug" ,
104113 "experimental" ,
105114 "experimental.allowSubAgents" ,
106115 "experimental.customPrompts" ,
@@ -165,6 +174,13 @@ interface ValidationError {
165174 actual : string
166175}
167176
177+ type ConfigWarningNotifier = ( title : string , message : string ) => void
178+
179+ interface ConfigWarningCallbacks {
180+ onParseWarning ?: ( title : string , message : string ) => void
181+ onConfigWarning ?: ( configPath : string , data : Record < string , any > , isProject : boolean ) => void
182+ }
183+
168184export function validateConfigTypes ( config : Record < string , any > ) : ValidationError [ ] {
169185 const errors : ValidationError [ ] = [ ]
170186
@@ -282,6 +298,32 @@ export function validateConfigTypes(config: Record<string, any>): ValidationErro
282298 }
283299 }
284300
301+ const tui = config . tui
302+ if ( tui !== undefined ) {
303+ if ( typeof tui !== "object" || tui === null || Array . isArray ( tui ) ) {
304+ errors . push ( {
305+ key : "tui" ,
306+ expected : "object" ,
307+ actual : typeof tui ,
308+ } )
309+ } else {
310+ if ( tui . sidebar !== undefined && typeof tui . sidebar !== "boolean" ) {
311+ errors . push ( {
312+ key : "tui.sidebar" ,
313+ expected : "boolean" ,
314+ actual : typeof tui . sidebar ,
315+ } )
316+ }
317+ if ( tui . debug !== undefined && typeof tui . debug !== "boolean" ) {
318+ errors . push ( {
319+ key : "tui.debug" ,
320+ expected : "boolean" ,
321+ actual : typeof tui . debug ,
322+ } )
323+ }
324+ }
325+ }
326+
285327 const commands = config . commands
286328 if ( commands !== undefined ) {
287329 if ( typeof commands !== "object" || commands === null || Array . isArray ( commands ) ) {
@@ -594,8 +636,21 @@ export function validateConfigTypes(config: Record<string, any>): ValidationErro
594636 return errors
595637}
596638
639+ function scheduleConfigWarning (
640+ notify : ConfigWarningNotifier | undefined ,
641+ title : string ,
642+ message : string ,
643+ ) : void {
644+ setTimeout ( ( ) => {
645+ if ( ! notify ) return
646+ try {
647+ notify ( title , message )
648+ } catch { }
649+ } , 7000 )
650+ }
651+
597652function showConfigWarnings (
598- ctx : PluginInput ,
653+ notify : ConfigWarningNotifier | undefined ,
599654 configPath : string ,
600655 configData : Record < string , any > ,
601656 isProject : boolean ,
@@ -625,18 +680,11 @@ function showConfigWarnings(
625680 }
626681 }
627682
628- setTimeout ( ( ) => {
629- try {
630- ctx . client . tui . showToast ( {
631- body : {
632- title : `DCP: ${ configType } warning` ,
633- message : `${ configPath } \n${ messages . join ( "\n" ) } ` ,
634- variant : "warning" ,
635- duration : 7000 ,
636- } ,
637- } )
638- } catch { }
639- } , 7000 )
683+ scheduleConfigWarning (
684+ notify ,
685+ `DCP: ${ configType } warning` ,
686+ `${ configPath } \n${ messages . join ( "\n" ) } ` ,
687+ )
640688}
641689
642690const defaultConfig : PluginConfig = {
@@ -652,6 +700,10 @@ const defaultConfig: PluginConfig = {
652700 enabled : false ,
653701 automaticStrategies : true ,
654702 } ,
703+ tui : {
704+ sidebar : true ,
705+ debug : false ,
706+ } ,
655707 turnProtection : {
656708 enabled : false ,
657709 turns : 4 ,
@@ -711,7 +763,7 @@ function findOpencodeDir(startDir: string): string | null {
711763 return null
712764}
713765
714- function getConfigPaths ( ctx ?: PluginInput ) : {
766+ function getConfigPaths ( directory ?: string ) : {
715767 global : string | null
716768 configDir : string | null
717769 project : string | null
@@ -735,8 +787,8 @@ function getConfigPaths(ctx?: PluginInput): {
735787 }
736788
737789 let project : string | null = null
738- if ( ctx ?. directory ) {
739- const opencodeDir = findOpencodeDir ( ctx . directory )
790+ if ( directory ) {
791+ const opencodeDir = findOpencodeDir ( directory )
740792 if ( opencodeDir ) {
741793 const projectJsonc = join ( opencodeDir , "dcp.jsonc" )
742794 const projectJson = join ( opencodeDir , "dcp.json" )
@@ -871,6 +923,18 @@ function mergeManualMode(
871923 }
872924}
873925
926+ function mergeTui (
927+ base : PluginConfig [ "tui" ] ,
928+ override ?: Partial < PluginConfig [ "tui" ] > ,
929+ ) : PluginConfig [ "tui" ] {
930+ if ( override === undefined ) return base
931+
932+ return {
933+ sidebar : override . sidebar ?? base . sidebar ,
934+ debug : override . debug ?? base . debug ,
935+ }
936+ }
937+
874938function mergeExperimental (
875939 base : PluginConfig [ "experimental" ] ,
876940 override ?: Partial < PluginConfig [ "experimental" ] > ,
@@ -894,6 +958,7 @@ function deepCloneConfig(config: PluginConfig): PluginConfig {
894958 enabled : config . manualMode . enabled ,
895959 automaticStrategies : config . manualMode . automaticStrategies ,
896960 } ,
961+ tui : { ...config . tui } ,
897962 turnProtection : { ...config . turnProtection } ,
898963 experimental : { ...config . experimental } ,
899964 protectedFilePatterns : [ ...config . protectedFilePatterns ] ,
@@ -923,6 +988,7 @@ function mergeLayer(config: PluginConfig, data: Record<string, any>): PluginConf
923988 debug : data . debug ?? config . debug ,
924989 pruneNotification : data . pruneNotification ?? config . pruneNotification ,
925990 pruneNotificationType : data . pruneNotificationType ?? config . pruneNotificationType ,
991+ tui : mergeTui ( config . tui , data . tui as any ) ,
926992 commands : mergeCommands ( config . commands , data . commands as any ) ,
927993 manualMode : mergeManualMode ( config . manualMode , data . manualMode as any ) ,
928994 turnProtection : {
@@ -938,24 +1004,21 @@ function mergeLayer(config: PluginConfig, data: Record<string, any>): PluginConf
9381004 }
9391005}
9401006
941- function scheduleParseWarning ( ctx : PluginInput , title : string , message : string ) : void {
942- setTimeout ( ( ) => {
943- try {
944- ctx . client . tui . showToast ( {
945- body : {
946- title,
947- message,
948- variant : "warning" ,
949- duration : 7000 ,
950- } ,
951- } )
952- } catch { }
953- } , 7000 )
1007+ function createConfigWarningCallbacks (
1008+ notify ?: ConfigWarningNotifier ,
1009+ ) : ConfigWarningCallbacks | undefined {
1010+ if ( ! notify ) return undefined
1011+
1012+ return {
1013+ onParseWarning : ( title , message ) => scheduleConfigWarning ( notify , title , message ) ,
1014+ onConfigWarning : ( configPath , data , isProject ) =>
1015+ showConfigWarnings ( notify , configPath , data , isProject ) ,
1016+ }
9541017}
9551018
956- export function getConfig ( ctx : PluginInput ) : PluginConfig {
1019+ function loadMergedConfig ( directory ?: string , callbacks ?: ConfigWarningCallbacks ) : PluginConfig {
9571020 let config = deepCloneConfig ( defaultConfig )
958- const configPaths = getConfigPaths ( ctx )
1021+ const configPaths = getConfigPaths ( directory )
9591022
9601023 if ( ! configPaths . global ) {
9611024 createDefaultConfig ( )
@@ -974,8 +1037,7 @@ export function getConfig(ctx: PluginInput): PluginConfig {
9741037
9751038 const result = loadConfigFile ( layer . path )
9761039 if ( result . parseError ) {
977- scheduleParseWarning (
978- ctx ,
1040+ callbacks ?. onParseWarning ?.(
9791041 `DCP: Invalid ${ layer . name } ` ,
9801042 `${ layer . path } \n${ result . parseError } \nUsing previous/default values` ,
9811043 )
@@ -986,9 +1048,32 @@ export function getConfig(ctx: PluginInput): PluginConfig {
9861048 continue
9871049 }
9881050
989- showConfigWarnings ( ctx , layer . path , result . data , layer . isProject )
1051+ callbacks ?. onConfigWarning ?. ( layer . path , result . data , layer . isProject )
9901052 config = mergeLayer ( config , result . data )
9911053 }
9921054
9931055 return config
9941056}
1057+
1058+ export function getConfigForDirectory (
1059+ directory ?: string ,
1060+ notify ?: ConfigWarningNotifier ,
1061+ ) : PluginConfig {
1062+ return loadMergedConfig ( directory , createConfigWarningCallbacks ( notify ) )
1063+ }
1064+
1065+ export function getConfig ( ctx : PluginInput ) : PluginConfig {
1066+ return loadMergedConfig (
1067+ ctx . directory ,
1068+ createConfigWarningCallbacks ( ( title , message ) => {
1069+ ctx . client . tui . showToast ( {
1070+ body : {
1071+ title,
1072+ message,
1073+ variant : "warning" ,
1074+ duration : 7000 ,
1075+ } ,
1076+ } )
1077+ } ) ,
1078+ )
1079+ }
0 commit comments