@@ -2,6 +2,7 @@ import fs from 'node:fs'
2
2
import os from 'node:os'
3
3
import path from 'node:path'
4
4
import process from 'node:process'
5
+ import yaml from 'js-yaml'
5
6
6
7
import { verbose } from './logger'
7
8
// import { execFileSync } from "node:child_process"
@@ -16,6 +17,7 @@ interface ClientFileTarget {
16
17
path : string
17
18
localPath ?: string
18
19
configKey : string
20
+ format ?: 'json' | 'yaml' // Add format property for different file types
19
21
}
20
22
type ClientInstallTarget = ClientFileTarget
21
23
@@ -117,6 +119,12 @@ function getClientPaths(): { [key: string]: ClientInstallTarget } {
117
119
localPath : path . join ( process . cwd ( ) , '.mcp.json' ) ,
118
120
configKey : 'mcpServers' ,
119
121
} ,
122
+ goose : {
123
+ type : 'file' ,
124
+ path : path . join ( baseDir , 'goose' , 'config.yaml' ) ,
125
+ configKey : 'extensions' ,
126
+ format : 'yaml' ,
127
+ } ,
120
128
}
121
129
}
122
130
@@ -132,6 +140,7 @@ export const clientNames = [
132
140
'gemini-cli' ,
133
141
'vscode' ,
134
142
'claude-code' ,
143
+ 'goose' ,
135
144
]
136
145
137
146
// Helper function to get nested value from an object using dot notation
@@ -197,7 +206,15 @@ export function readConfig(client: string, local?: boolean): ClientConfig {
197
206
}
198
207
199
208
verbose ( 'Reading config file content' )
200
- const rawConfig = JSON . parse ( fs . readFileSync ( configPath . path , 'utf8' ) )
209
+ const fileContent = fs . readFileSync ( configPath . path , 'utf8' )
210
+
211
+ let rawConfig : ClientConfig
212
+ if ( configPath . format === 'yaml' ) {
213
+ rawConfig = yaml . load ( fileContent ) as ClientConfig || { }
214
+ } else {
215
+ rawConfig = JSON . parse ( fileContent )
216
+ }
217
+
201
218
verbose ( `Config loaded successfully: ${ JSON . stringify ( rawConfig , null , 2 ) } ` )
202
219
203
220
// Ensure the nested structure exists
@@ -261,7 +278,14 @@ function writeConfigFile(config: ClientConfig, target: ClientFileTarget): void {
261
278
try {
262
279
if ( fs . existsSync ( target . path ) ) {
263
280
verbose ( 'Reading existing config file for merging' )
264
- existingConfig = JSON . parse ( fs . readFileSync ( target . path , 'utf8' ) )
281
+ const fileContent = fs . readFileSync ( target . path , 'utf8' )
282
+
283
+ if ( target . format === 'yaml' ) {
284
+ existingConfig = yaml . load ( fileContent ) as ClientConfig || { }
285
+ } else {
286
+ existingConfig = JSON . parse ( fileContent )
287
+ }
288
+
265
289
verbose ( `Existing config loaded: ${ JSON . stringify ( existingConfig , null , 2 ) } ` )
266
290
}
267
291
} catch ( error ) {
@@ -274,6 +298,18 @@ function writeConfigFile(config: ClientConfig, target: ClientFileTarget): void {
274
298
verbose ( `Merged config: ${ JSON . stringify ( mergedConfig , null , 2 ) } ` )
275
299
276
300
verbose ( `Writing config to file: ${ target . path } ` )
277
- fs . writeFileSync ( target . path , JSON . stringify ( mergedConfig , null , 2 ) )
301
+
302
+ let configContent : string
303
+ if ( target . format === 'yaml' ) {
304
+ configContent = yaml . dump ( mergedConfig , {
305
+ indent : 2 ,
306
+ lineWidth : - 1 ,
307
+ noRefs : true
308
+ } )
309
+ } else {
310
+ configContent = JSON . stringify ( mergedConfig , null , 2 )
311
+ }
312
+
313
+ fs . writeFileSync ( target . path , configContent )
278
314
verbose ( 'Config successfully written' )
279
315
}
0 commit comments