@@ -14,6 +14,8 @@ import { Flag } from "../flag/flag"
1414import { Auth } from "../auth"
1515import { type ParseError as JsoncParseError , parse as parseJsonc , printParseErrorCode } from "jsonc-parser"
1616import { Instance } from "../project/instance"
17+ import { Bus } from "../bus"
18+ import { State } from "../project/state"
1719
1820export namespace Config {
1921 const log = Log . create ( { service : "config" } )
@@ -673,4 +675,59 @@ export namespace Config {
673675 export async function directories ( ) {
674676 return state ( ) . then ( ( x ) => x . directories )
675677 }
678+
679+ export type ConfigScope = "global" | "project"
680+
681+ export async function update ( scope : ConfigScope , updates : Partial < Info > ) {
682+ const validated = Info . partial ( ) . parse ( updates )
683+
684+ const targetPath =
685+ scope === "global"
686+ ? path . join ( Global . Path . config , "opencode.json" )
687+ : path . join ( Instance . directory , "opencode.json" )
688+
689+ log . info ( "updating config" , { scope, path : targetPath } )
690+
691+ let existing : Info = { }
692+ try {
693+ const content = await Bun . file ( targetPath ) . text ( )
694+ const errors : JsoncParseError [ ] = [ ]
695+ existing = parseJsonc ( content , errors , { allowTrailingComma : true } ) || { }
696+ } catch ( err ) {
697+ if ( ( err as any ) . code !== "ENOENT" ) {
698+ throw new JsonError ( { path : targetPath , message : "Failed to read existing config" } , { cause : err } )
699+ }
700+ }
701+
702+ const merged = mergeDeep ( existing , validated )
703+
704+ if ( ! merged . $schema ) {
705+ merged . $schema = "https://opencode.ai/config.json"
706+ }
707+
708+ await Bun . write ( targetPath , JSON . stringify ( merged , null , 2 ) )
709+
710+ const reloaded = await reload ( )
711+
712+ log . info ( "config updated" , { scope } )
713+ return reloaded
714+ }
715+
716+ export async function reload ( ) {
717+ log . info ( "reloading config" )
718+
719+ global . clear ( )
720+
721+ await State . dispose ( Instance . directory )
722+
723+ const reloaded = await get ( )
724+
725+ Bus . publish ( Event . Reloaded , { config : reloaded } )
726+
727+ return reloaded
728+ }
729+
730+ export const Event = {
731+ Reloaded : Bus . event ( "config.reloaded" , z . object ( { config : Info } ) ) ,
732+ }
676733}
0 commit comments