mergeSettings function
Merge multiple settings (first takes priority).
Implementation
SettingsJson mergeSettings(List<SettingsJson> sources) {
if (sources.isEmpty) return const SettingsJson();
if (sources.length == 1) return sources.first;
// Model: first non-null wins
String? model;
for (final s in sources) {
if (s.model != null) {
model = s.model;
break;
}
}
// Permissions: concatenate all rules
final allAllow = <String>[];
final allDeny = <String>[];
final allAsk = <String>[];
final allAdditionalDirs = <String>[];
String? defaultMode;
bool? disableBypass;
for (final s in sources) {
allAllow.addAll(s.permissions.allow);
allDeny.addAll(s.permissions.deny);
allAsk.addAll(s.permissions.ask);
allAdditionalDirs.addAll(s.permissions.additionalDirectories);
defaultMode ??= s.permissions.defaultMode;
disableBypass ??= s.permissions.disableBypassPermissionsMode;
}
// Sandbox: first non-default wins
SandboxSettings sandbox = const SandboxSettings();
for (final s in sources) {
if (s.sandbox.enabled) {
sandbox = s.sandbox;
break;
}
}
// Environment variables: merge (earlier takes priority)
final envVars = <String, String>{};
for (final s in sources.reversed) {
envVars.addAll(s.environmentVariables);
}
// Model overrides: merge
final modelOverrides = <String, String>{};
for (final s in sources.reversed) {
modelOverrides.addAll(s.modelOverrides);
}
// Available models: first non-empty wins
List<String> availableModels = [];
for (final s in sources) {
if (s.availableModels.isNotEmpty) {
availableModels = s.availableModels;
break;
}
}
// Managed-only: any source can enable
final managedOnly = sources.any((s) => s.allowManagedPermissionRulesOnly);
return SettingsJson(
model: model,
permissions: PermissionSettings(
allow: allAllow,
deny: allDeny,
ask: allAsk,
defaultMode: defaultMode,
disableBypassPermissionsMode: disableBypass,
additionalDirectories: allAdditionalDirs,
),
sandbox: sandbox,
hooks: sources
.firstWhere((s) => s.hooks != null, orElse: () => const SettingsJson())
.hooks,
installedPlugins: sources
.expand((s) => s.installedPlugins)
.toSet()
.toList(),
environmentVariables: envVars,
modelOverrides: modelOverrides,
availableModels: availableModels,
allowManagedPermissionRulesOnly: managedOnly,
syntaxHighlightingEnabled: sources.first.syntaxHighlightingEnabled,
theme: sources
.map((s) => s.theme)
.firstWhere((t) => t != null, orElse: () => null),
outputStyle: sources
.map((s) => s.outputStyle)
.firstWhere((o) => o != null, orElse: () => null),
);
}