feat(config): add cross-platform user-level config support (#20)
This commit is contained in:
82
src/index.ts
82
src/index.ts
@@ -43,6 +43,20 @@ import * as fs from "fs";
|
|||||||
import * as path from "path";
|
import * as path from "path";
|
||||||
import * as os from "os";
|
import * as os from "os";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the user-level config directory based on the OS.
|
||||||
|
* - Linux/macOS: XDG_CONFIG_HOME or ~/.config
|
||||||
|
* - Windows: %APPDATA%
|
||||||
|
*/
|
||||||
|
function getUserConfigDir(): string {
|
||||||
|
if (process.platform === "win32") {
|
||||||
|
return process.env.APPDATA || path.join(os.homedir(), "AppData", "Roaming");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Linux, macOS, and other Unix-like systems: respect XDG_CONFIG_HOME
|
||||||
|
return process.env.XDG_CONFIG_HOME || path.join(os.homedir(), ".config");
|
||||||
|
}
|
||||||
|
|
||||||
function loadConfigFromPath(configPath: string): OhMyOpenCodeConfig | null {
|
function loadConfigFromPath(configPath: string): OhMyOpenCodeConfig | null {
|
||||||
try {
|
try {
|
||||||
if (fs.existsSync(configPath)) {
|
if (fs.existsSync(configPath)) {
|
||||||
@@ -64,53 +78,61 @@ function loadConfigFromPath(configPath: string): OhMyOpenCodeConfig | null {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function mergeConfigs(base: OhMyOpenCodeConfig, override: OhMyOpenCodeConfig): OhMyOpenCodeConfig {
|
function mergeConfigs(
|
||||||
|
base: OhMyOpenCodeConfig,
|
||||||
|
override: OhMyOpenCodeConfig
|
||||||
|
): OhMyOpenCodeConfig {
|
||||||
return {
|
return {
|
||||||
...base,
|
...base,
|
||||||
...override,
|
...override,
|
||||||
agents: override.agents !== undefined
|
agents:
|
||||||
? { ...(base.agents ?? {}), ...override.agents }
|
override.agents !== undefined
|
||||||
: base.agents,
|
? { ...(base.agents ?? {}), ...override.agents }
|
||||||
|
: base.agents,
|
||||||
disabled_agents: [
|
disabled_agents: [
|
||||||
...new Set([...(base.disabled_agents ?? []), ...(override.disabled_agents ?? [])])
|
...new Set([
|
||||||
|
...(base.disabled_agents ?? []),
|
||||||
|
...(override.disabled_agents ?? []),
|
||||||
|
]),
|
||||||
],
|
],
|
||||||
disabled_mcps: [
|
disabled_mcps: [
|
||||||
...new Set([...(base.disabled_mcps ?? []), ...(override.disabled_mcps ?? [])])
|
...new Set([
|
||||||
|
...(base.disabled_mcps ?? []),
|
||||||
|
...(override.disabled_mcps ?? []),
|
||||||
|
]),
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadPluginConfig(directory: string): OhMyOpenCodeConfig {
|
function loadPluginConfig(directory: string): OhMyOpenCodeConfig {
|
||||||
// User-level config paths
|
// User-level config path (OS-specific)
|
||||||
const userConfigPaths = [
|
const userConfigPath = path.join(
|
||||||
path.join(os.homedir(), ".config", "opencode", "oh-my-opencode.json"),
|
getUserConfigDir(),
|
||||||
];
|
"opencode",
|
||||||
|
"oh-my-opencode.json"
|
||||||
|
);
|
||||||
|
|
||||||
// Project-level config paths (higher precedence)
|
// Project-level config path
|
||||||
const projectConfigPaths = [
|
const projectConfigPath = path.join(
|
||||||
path.join(directory, ".opencode", "oh-my-opencode.json"),
|
directory,
|
||||||
];
|
".opencode",
|
||||||
|
"oh-my-opencode.json"
|
||||||
|
);
|
||||||
|
|
||||||
// Load user config first
|
// Load user config first (base)
|
||||||
let config: OhMyOpenCodeConfig = {};
|
let config: OhMyOpenCodeConfig = loadConfigFromPath(userConfigPath) ?? {};
|
||||||
for (const configPath of userConfigPaths) {
|
|
||||||
const userConfig = loadConfigFromPath(configPath);
|
|
||||||
if (userConfig) {
|
|
||||||
config = userConfig;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Override with project config
|
// Override with project config
|
||||||
for (const configPath of projectConfigPaths) {
|
const projectConfig = loadConfigFromPath(projectConfigPath);
|
||||||
const projectConfig = loadConfigFromPath(configPath);
|
if (projectConfig) {
|
||||||
if (projectConfig) {
|
config = mergeConfigs(config, projectConfig);
|
||||||
config = mergeConfigs(config, projectConfig);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log("Final merged config", { agents: config.agents, disabled_agents: config.disabled_agents, disabled_mcps: config.disabled_mcps });
|
log("Final merged config", {
|
||||||
|
agents: config.agents,
|
||||||
|
disabled_agents: config.disabled_agents,
|
||||||
|
disabled_mcps: config.disabled_mcps,
|
||||||
|
});
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user