|
@@ -21,25 +21,36 @@ import { ConfigMarkdown } from "./markdown"
|
|
|
export namespace Config {
|
|
export namespace Config {
|
|
|
const log = Log.create({ service: "config" })
|
|
const log = Log.create({ service: "config" })
|
|
|
|
|
|
|
|
|
|
+ // Custom merge function that concatenates plugin arrays instead of replacing them
|
|
|
|
|
+ function mergeConfigWithPlugins(target: Info, source: Info): Info {
|
|
|
|
|
+ const merged = mergeDeep(target, source)
|
|
|
|
|
+ // If both configs have plugin arrays, concatenate them instead of replacing
|
|
|
|
|
+ if (target.plugin && source.plugin) {
|
|
|
|
|
+ const pluginSet = new Set([...target.plugin, ...source.plugin])
|
|
|
|
|
+ merged.plugin = Array.from(pluginSet)
|
|
|
|
|
+ }
|
|
|
|
|
+ return merged
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
export const state = Instance.state(async () => {
|
|
export const state = Instance.state(async () => {
|
|
|
const auth = await Auth.all()
|
|
const auth = await Auth.all()
|
|
|
let result = await global()
|
|
let result = await global()
|
|
|
|
|
|
|
|
// Override with custom config if provided
|
|
// Override with custom config if provided
|
|
|
if (Flag.OPENCODE_CONFIG) {
|
|
if (Flag.OPENCODE_CONFIG) {
|
|
|
- result = mergeDeep(result, await loadFile(Flag.OPENCODE_CONFIG))
|
|
|
|
|
|
|
+ result = mergeConfigWithPlugins(result, await loadFile(Flag.OPENCODE_CONFIG))
|
|
|
log.debug("loaded custom config", { path: Flag.OPENCODE_CONFIG })
|
|
log.debug("loaded custom config", { path: Flag.OPENCODE_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)
|
|
|
for (const resolved of found.toReversed()) {
|
|
for (const resolved of found.toReversed()) {
|
|
|
- result = mergeDeep(result, await loadFile(resolved))
|
|
|
|
|
|
|
+ result = mergeConfigWithPlugins(result, await loadFile(resolved))
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (Flag.OPENCODE_CONFIG_CONTENT) {
|
|
if (Flag.OPENCODE_CONFIG_CONTENT) {
|
|
|
- result = mergeDeep(result, JSON.parse(Flag.OPENCODE_CONFIG_CONTENT))
|
|
|
|
|
|
|
+ result = mergeConfigWithPlugins(result, JSON.parse(Flag.OPENCODE_CONFIG_CONTENT))
|
|
|
log.debug("loaded custom config from OPENCODE_CONFIG_CONTENT")
|
|
log.debug("loaded custom config from OPENCODE_CONFIG_CONTENT")
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -47,7 +58,7 @@ export namespace Config {
|
|
|
if (value.type === "wellknown") {
|
|
if (value.type === "wellknown") {
|
|
|
process.env[value.key] = value.token
|
|
process.env[value.key] = value.token
|
|
|
const wellknown = (await fetch(`${key}/.well-known/opencode`).then((x) => x.json())) as any
|
|
const wellknown = (await fetch(`${key}/.well-known/opencode`).then((x) => x.json())) as any
|
|
|
- result = mergeDeep(result, await load(JSON.stringify(wellknown.config ?? {}), process.cwd()))
|
|
|
|
|
|
|
+ result = mergeConfigWithPlugins(result, await load(JSON.stringify(wellknown.config ?? {}), process.cwd()))
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -78,7 +89,7 @@ export namespace Config {
|
|
|
if (dir.endsWith(".opencode") || dir === Flag.OPENCODE_CONFIG_DIR) {
|
|
if (dir.endsWith(".opencode") || dir === Flag.OPENCODE_CONFIG_DIR) {
|
|
|
for (const file of ["opencode.jsonc", "opencode.json"]) {
|
|
for (const file of ["opencode.jsonc", "opencode.json"]) {
|
|
|
log.debug(`loading config from ${path.join(dir, file)}`)
|
|
log.debug(`loading config from ${path.join(dir, file)}`)
|
|
|
- result = mergeDeep(result, await loadFile(path.join(dir, file)))
|
|
|
|
|
|
|
+ result = mergeConfigWithPlugins(result, await loadFile(path.join(dir, file)))
|
|
|
// to satisy the type checker
|
|
// to satisy the type checker
|
|
|
result.agent ??= {}
|
|
result.agent ??= {}
|
|
|
result.mode ??= {}
|
|
result.mode ??= {}
|