Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions packages/opencode/src/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ export namespace Config {
// Project config overrides global and remote config.
if (!Flag.KILO_DISABLE_PROJECT_CONFIG) {
// kilocode_change start
for (const file of ["kilo.jsonc", "kilo.json", "opencode.jsonc", "opencode.json"]) {
for (const file of ["opencode.jsonc", "opencode.json", "kilo.jsonc", "kilo.json"]) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: This reorder still gives kilo.* higher precedence

mergeConfigConcatArrays(result, await loadFile(file)) treats the newly loaded file as the overriding source, so the last filename in this array wins. With opencode.* first and kilo.* last, a repo that has both files will still apply the legacy kilo values over the opencode ones. The same ordering issue also affects the directory and managed-directory loops below.

Suggested change
for (const file of ["opencode.jsonc", "opencode.json", "kilo.jsonc", "kilo.json"]) {
for (const file of ["kilo.jsonc", "kilo.json", "opencode.jsonc", "opencode.json"]) {

try {
result = mergeConfigConcatArrays(result, await loadFile(file))
} catch (err) {
Expand Down Expand Up @@ -311,7 +311,7 @@ export namespace Config {
dir.endsWith(".opencode") ||
dir === Flag.KILO_CONFIG_DIR
) {
for (const file of ["kilo.jsonc", "kilo.json", "opencode.jsonc", "opencode.json"]) {
for (const file of ["opencode.jsonc", "opencode.json", "kilo.jsonc", "kilo.json"]) {
log.debug(`loading config from ${path.join(dir, file)}`)
try {
result = mergeConfigConcatArrays(result, await loadFile(path.join(dir, file)))
Expand Down Expand Up @@ -369,7 +369,7 @@ export namespace Config {
// This way it only loads config file and not skills/plugins/commands
if (existsSync(managedDir)) {
// kilocode_change start
for (const file of ["kilo.jsonc", "kilo.json", "opencode.jsonc", "opencode.json"]) {
for (const file of ["opencode.jsonc", "opencode.json", "kilo.jsonc", "kilo.json"]) {
result = mergeConfigConcatArrays(result, await loadFile(path.join(managedDir, file)))
}
// kilocode_change end
Expand Down Expand Up @@ -1545,12 +1545,12 @@ export namespace Config {
let result: Info = pipe(
{},
mergeDeep(await loadFile(path.join(Global.Path.config, "config.json"))),
// kilocode_change start
mergeDeep(await loadFile(path.join(Global.Path.config, "kilo.json"))),
mergeDeep(await loadFile(path.join(Global.Path.config, "opencode.jsonc"))),
mergeDeep(await loadFile(path.join(Global.Path.config, "opencode.json"))),
// kilocode_change start — kilo files loaded last so they take priority
mergeDeep(await loadFile(path.join(Global.Path.config, "kilo.jsonc"))),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: Global precedence is reversed here too

In this pipe() chain, later mergeDeep(...) calls override earlier ones. Loading kilo.jsonc and kilo.json after the opencode.* files means the legacy global configs still win whenever both exist, which conflicts with the migration goal in this PR.

mergeDeep(await loadFile(path.join(Global.Path.config, "kilo.json"))),
// kilocode_change end
mergeDeep(await loadFile(path.join(Global.Path.config, "opencode.json"))),
mergeDeep(await loadFile(path.join(Global.Path.config, "opencode.jsonc"))),
)

const legacy = path.join(Global.Path.config, "config")
Expand Down
Loading