get method
Resolves one dotted key (memory.projectPath, tools.web_search,
provider, mcp.servers.fs.url, ...) to its effective value. Project
scope wins for the project-capable sections; everything else comes
from the user file. Unknown top-level keys throw — get must catch
typos, not report them as "not set".
Implementation
Future<ConfigGetResult> get(String key) async {
final segments = _parseKey(key);
final top = segments.first;
if (!configTopLevelKeys.contains(top)) {
throw ConfigException(
'unknown config key: "$top" (known top-level keys: '
'${configTopLevelKeys.join(', ')})',
);
}
final memberRefusal = _stdioServerRefusal(segments);
if (memberRefusal != null) {
return ConfigGetResult(
key: key,
found: false,
notApplicable: _mcpStdioNote(memberRefusal),
);
}
if (_projectSections.contains(top)) {
final projectDoc = await _readTextOrNull(projectConfigPath) ?? '';
final projectValue = _walk(_tryParse(projectDoc), segments);
if (projectValue != null) {
final stdio = _stdioServerRefusal(segments, projectValue);
if (stdio != null) {
return ConfigGetResult(
key: key,
found: false,
notApplicable: _mcpStdioNote(stdio),
);
}
return ConfigGetResult(
key: key,
found: true,
display: _display(projectValue),
scope: 'project',
file: projectConfigPath,
);
}
}
final globalText = globalConfigPath == null
? ''
: await _readTextOrNull(globalConfigPath!) ?? '';
final globalValue = _walk(_tryParse(globalText), segments);
if (globalValue != null) {
final stdio = _stdioServerRefusal(segments, globalValue);
if (stdio != null) {
return ConfigGetResult(
key: key,
found: false,
notApplicable: _mcpStdioNote(stdio),
);
}
return ConfigGetResult(
key: key,
found: true,
display: _display(globalValue),
scope: 'global',
file: globalConfigPath,
);
}
return ConfigGetResult(key: key, found: false);
}