fix(opencode): give OPENCODE_CONFIG_CONTENT proper priority for setting config based on docs (#11670)
This commit is contained in:
@@ -62,8 +62,14 @@ export namespace Config {
|
|||||||
export const state = Instance.state(async () => {
|
export const state = Instance.state(async () => {
|
||||||
const auth = await Auth.all()
|
const auth = await Auth.all()
|
||||||
|
|
||||||
// Load remote/well-known config first as the base layer (lowest precedence)
|
// Config loading order (low -> high precedence): https://opencode.ai/docs/config#precedence-order
|
||||||
// This allows organizations to provide default configs that users can override
|
// 1) Remote .well-known/opencode (org defaults)
|
||||||
|
// 2) Global config (~/.config/opencode/opencode.json{,c})
|
||||||
|
// 3) Custom config (OPENCODE_CONFIG)
|
||||||
|
// 4) Project config (opencode.json{,c})
|
||||||
|
// 5) .opencode directories (.opencode/agents/, .opencode/commands/, .opencode/plugins/, .opencode/opencode.json{,c})
|
||||||
|
// 6) Inline config (OPENCODE_CONFIG_CONTENT)
|
||||||
|
// Managed config directory is enterprise-only and always overrides everything above.
|
||||||
let result: Info = {}
|
let result: Info = {}
|
||||||
for (const [key, value] of Object.entries(auth)) {
|
for (const [key, value] of Object.entries(auth)) {
|
||||||
if (value.type === "wellknown") {
|
if (value.type === "wellknown") {
|
||||||
@@ -85,16 +91,16 @@ export namespace Config {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Global user config overrides remote config
|
// Global user config overrides remote config.
|
||||||
result = mergeConfigConcatArrays(result, await global())
|
result = mergeConfigConcatArrays(result, await global())
|
||||||
|
|
||||||
// Custom config path overrides global
|
// Custom config path overrides global config.
|
||||||
if (Flag.OPENCODE_CONFIG) {
|
if (Flag.OPENCODE_CONFIG) {
|
||||||
result = mergeConfigConcatArrays(result, await loadFile(Flag.OPENCODE_CONFIG))
|
result = mergeConfigConcatArrays(result, await loadFile(Flag.OPENCODE_CONFIG))
|
||||||
log.debug("loaded custom config", { path: Flag.OPENCODE_CONFIG })
|
log.debug("loaded custom config", { path: Flag.OPENCODE_CONFIG })
|
||||||
}
|
}
|
||||||
|
|
||||||
// Project config has highest precedence (overrides global and remote)
|
// Project config overrides global and remote config.
|
||||||
if (!Flag.OPENCODE_DISABLE_PROJECT_CONFIG) {
|
if (!Flag.OPENCODE_DISABLE_PROJECT_CONFIG) {
|
||||||
for (const file of ["opencode.jsonc", "opencode.json"]) {
|
for (const file of ["opencode.jsonc", "opencode.json"]) {
|
||||||
const found = await Filesystem.findUp(file, Instance.directory, Instance.worktree)
|
const found = await Filesystem.findUp(file, Instance.directory, Instance.worktree)
|
||||||
@@ -104,12 +110,6 @@ export namespace Config {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inline config content has highest precedence
|
|
||||||
if (Flag.OPENCODE_CONFIG_CONTENT) {
|
|
||||||
result = mergeConfigConcatArrays(result, JSON.parse(Flag.OPENCODE_CONFIG_CONTENT))
|
|
||||||
log.debug("loaded custom config from OPENCODE_CONFIG_CONTENT")
|
|
||||||
}
|
|
||||||
|
|
||||||
result.agent = result.agent || {}
|
result.agent = result.agent || {}
|
||||||
result.mode = result.mode || {}
|
result.mode = result.mode || {}
|
||||||
result.plugin = result.plugin || []
|
result.plugin = result.plugin || []
|
||||||
@@ -136,6 +136,7 @@ export namespace Config {
|
|||||||
)),
|
)),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
// .opencode directory config overrides (project and global) config sources.
|
||||||
if (Flag.OPENCODE_CONFIG_DIR) {
|
if (Flag.OPENCODE_CONFIG_DIR) {
|
||||||
directories.push(Flag.OPENCODE_CONFIG_DIR)
|
directories.push(Flag.OPENCODE_CONFIG_DIR)
|
||||||
log.debug("loading config from OPENCODE_CONFIG_DIR", { path: Flag.OPENCODE_CONFIG_DIR })
|
log.debug("loading config from OPENCODE_CONFIG_DIR", { path: Flag.OPENCODE_CONFIG_DIR })
|
||||||
@@ -163,6 +164,12 @@ export namespace Config {
|
|||||||
result.plugin.push(...(await loadPlugin(dir)))
|
result.plugin.push(...(await loadPlugin(dir)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Inline config content overrides all non-managed config sources.
|
||||||
|
if (Flag.OPENCODE_CONFIG_CONTENT) {
|
||||||
|
result = mergeConfigConcatArrays(result, JSON.parse(Flag.OPENCODE_CONFIG_CONTENT))
|
||||||
|
log.debug("loaded custom config from OPENCODE_CONFIG_CONTENT")
|
||||||
|
}
|
||||||
|
|
||||||
// Load managed config files last (highest priority) - enterprise admin-controlled
|
// Load managed config files last (highest priority) - enterprise admin-controlled
|
||||||
// Kept separate from directories array to avoid write operations when installing plugins
|
// Kept separate from directories array to avoid write operations when installing plugins
|
||||||
// which would fail on system directories requiring elevated permissions
|
// which would fail on system directories requiring elevated permissions
|
||||||
|
|||||||
Reference in New Issue
Block a user