()
| 1032 | }; |
| 1033 | |
| 1034 | const loadAggregatedConfig = () => { |
| 1035 | const roots = getSearchRoots(); |
| 1036 | const activeConfigPath = getConfigPath(); |
| 1037 | const activeDir = activeConfigPath ? path.dirname(activeConfigPath) : null; |
| 1038 | |
| 1039 | const aggregated = { |
| 1040 | mcp: {}, |
| 1041 | command: {}, |
| 1042 | env: {}, |
| 1043 | plugins: [] |
| 1044 | }; |
| 1045 | |
| 1046 | const configs = []; |
| 1047 | for (const root of roots) { |
| 1048 | const configPath = path.join(root, 'opencode.json'); |
| 1049 | if (fs.existsSync(configPath)) { |
| 1050 | try { |
| 1051 | const content = JSON.parse(fs.readFileSync(configPath, 'utf8')); |
| 1052 | configs.push({ |
| 1053 | root, |
| 1054 | isHighestPriority: activeDir ? path.resolve(root) === path.resolve(activeDir) : false, |
| 1055 | config: content |
| 1056 | }); |
| 1057 | } catch (err) { |
| 1058 | console.error(`Failed to read config from ${configPath}:`, err.message); |
| 1059 | } |
| 1060 | } |
| 1061 | } |
| 1062 | |
| 1063 | configs.sort((a, b) => { |
| 1064 | if (a.isHighestPriority) return -1; |
| 1065 | if (b.isHighestPriority) return 1; |
| 1066 | return 0; |
| 1067 | }); |
| 1068 | |
| 1069 | [...configs].reverse().forEach(({ config }) => { |
| 1070 | if (config.mcp && typeof config.mcp === 'object') { |
| 1071 | for (const [key, value] of Object.entries(config.mcp)) { |
| 1072 | aggregated.mcp[key] = value; |
| 1073 | } |
| 1074 | } |
| 1075 | |
| 1076 | if (config.command && typeof config.command === 'object') { |
| 1077 | Object.assign(aggregated.command, config.command); |
| 1078 | } |
| 1079 | |
| 1080 | if (config.env && typeof config.env === 'object') { |
| 1081 | Object.assign(aggregated.env, config.env); |
| 1082 | } |
| 1083 | |
| 1084 | if (config.plugins && Array.isArray(config.plugins)) { |
| 1085 | for (const plugin of config.plugins) { |
| 1086 | const name = typeof plugin === 'string' ? plugin : plugin.name || plugin.npm; |
| 1087 | if (name && !aggregated.plugins.find((p) => p.name === name)) { |
| 1088 | aggregated.plugins.push({ |
| 1089 | name, |
| 1090 | source: 'json-config', |
| 1091 | type: typeof plugin === 'object' && plugin.npm ? 'npm' : 'file' |
no test coverage detected