Skip to content

Commit 0e2dcaa

Browse files
committed
fix: merge configs instead of overwriting, switch to @clack/prompts
- addPluginToOpenCodeConfig now reads existing config and merges - writeMagicContextConfig reads existing file and merges per-section - disableOmoHooks preserves all existing oh-my-opencode settings - Comments are lost on write (JSON.parse strips them) but all user settings are preserved
1 parent 999b36c commit 0e2dcaa

File tree

1 file changed

+24
-14
lines changed

1 file changed

+24
-14
lines changed

src/cli/setup.ts

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -46,25 +46,28 @@ function addPluginToOpenCodeConfig(configPath: string, format: "json" | "jsonc"
4646
plugin: [PLUGIN_NAME],
4747
compaction: { auto: false, prune: false },
4848
};
49-
writeJsonc(configPath, config);
49+
writeFileSync(configPath, `${JSON.stringify(config, null, 2)}\n`);
5050
return;
5151
}
5252

53-
const config = readJsonc(configPath);
53+
// Read existing config, merge our changes, preserve everything else
54+
const existing = readJsonc(configPath);
5455

55-
const plugins = (config.plugin as string[]) ?? [];
56+
// Add plugin if not present
57+
const plugins = (existing.plugin as string[]) ?? [];
5658
const hasPlugin = plugins.some((p) => p === PLUGIN_NAME || p.startsWith(`${PLUGIN_NAME}@`));
5759
if (!hasPlugin) {
5860
plugins.push(PLUGIN_NAME);
59-
config.plugin = plugins;
6061
}
62+
existing.plugin = plugins;
6163

62-
const compaction = (config.compaction as Record<string, unknown>) ?? {};
64+
// Set compaction fields without replacing other compaction settings
65+
const compaction = (existing.compaction as Record<string, unknown>) ?? {};
6366
compaction.auto = false;
6467
compaction.prune = false;
65-
config.compaction = compaction;
68+
existing.compaction = compaction;
6669

67-
writeJsonc(configPath, config);
70+
writeFileSync(configPath, `${JSON.stringify(existing, null, 2)}\n`);
6871
}
6972

7073
function writeMagicContextConfig(
@@ -77,31 +80,38 @@ function writeMagicContextConfig(
7780
sidekickModel: string | null;
7881
},
7982
): void {
80-
const config: Record<string, unknown> = {};
83+
// Read existing config to preserve user's other settings
84+
const config: Record<string, unknown> = existsSync(configPath) ? readJsonc(configPath) : {};
8185

8286
if (options.historianModel) {
83-
config.historian = { model: options.historianModel };
87+
const historian = (config.historian as Record<string, unknown>) ?? {};
88+
historian.model = options.historianModel;
89+
config.historian = historian;
8490
}
8591

8692
if (options.dreamerEnabled) {
87-
const dreamer: Record<string, unknown> = { enabled: true };
93+
const dreamer = (config.dreamer as Record<string, unknown>) ?? {};
94+
dreamer.enabled = true;
8895
if (options.dreamerModel) {
8996
dreamer.model = options.dreamerModel;
9097
}
9198
config.dreamer = dreamer;
9299
} else {
93-
config.dreamer = { enabled: false };
100+
const dreamer = (config.dreamer as Record<string, unknown>) ?? {};
101+
dreamer.enabled = false;
102+
config.dreamer = dreamer;
94103
}
95104

96105
if (options.sidekickEnabled) {
97-
const sidekick: Record<string, unknown> = { enabled: true };
106+
const sidekick = (config.sidekick as Record<string, unknown>) ?? {};
107+
sidekick.enabled = true;
98108
if (options.sidekickModel) {
99109
sidekick.model = options.sidekickModel;
100110
}
101111
config.sidekick = sidekick;
102112
}
103113

104-
writeJsonc(configPath, config);
114+
writeFileSync(configPath, `${JSON.stringify(config, null, 2)}\n`);
105115
}
106116

107117
function disableOmoHooks(omoConfigPath: string): void {
@@ -121,7 +131,7 @@ function disableOmoHooks(omoConfigPath: string): void {
121131
}
122132

123133
config.disabled_hooks = disabledHooks;
124-
writeJsonc(omoConfigPath, config);
134+
writeFileSync(omoConfigPath, `${JSON.stringify(config, null, 2)}\n`);
125135
}
126136

127137
// ─── Main Setup Flow ──────────────────────────────────────

0 commit comments

Comments
 (0)