fix(i18n): stop warning on missing tool.name.* keys for proper-name tools (T-493)
Tool display names are open-ended (Bash, Grep, Glob, ScheduleWakeup, MCP tools, …) — they intentionally have no catalog key and fall back to the raw name, so a miss isn't a gap to fix. The conversation pane was logging an i18n "missing key" warning for each, cluttering the output dock. Adds a `warnIfMissing` flag to I18nService.string (default true, so fixed UI strings still warn on a real gap) threaded through the ClideSettings facade; _toolNameLabel passes false. Display is unchanged — the placeholder already rendered the raw name. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1162,10 +1162,11 @@ class _ActivityCard extends StatelessWidget {
|
||||
}
|
||||
|
||||
/// Localized display label for a tool name (T-462). File/web/task operations
|
||||
/// have natural translations; command/proper-name tools (Bash, Grep, Glob, LS)
|
||||
/// have no catalog key and fall back to the raw name via the placeholder.
|
||||
/// have natural translations; command/proper-name tools (Bash, Grep, Glob,
|
||||
/// ScheduleWakeup, MCP tools, …) have no catalog key by design and fall back to
|
||||
/// the raw name — so `warnIfMissing: false` keeps a miss from logging (T-493).
|
||||
String _toolNameLabel(BuildContext context, String name) =>
|
||||
ClideSettings.i18n.string(context, 'tool.name.$name', namespace: 'builtin.claude', placeholder: name);
|
||||
ClideSettings.i18n.string(context, 'tool.name.$name', namespace: 'builtin.claude', placeholder: name, warnIfMissing: false);
|
||||
|
||||
/// Localized "N steps" counter for a collapser header (T-462). Singular and
|
||||
/// plural are distinct catalog keys; the English forms double as the fallback.
|
||||
|
||||
@@ -92,10 +92,15 @@ class I18n extends ChangeNotifier {
|
||||
/// Look up a key, walking the locale fallback chain. Returns the
|
||||
/// placeholder if nothing hits; returns the key itself when placeholder
|
||||
/// is null (developer fallback — keys are more useful than blanks).
|
||||
String string(String key, {required String namespace, String? placeholder}) {
|
||||
/// [warnIfMissing] false suppresses the missing-key warning for OPEN-ENDED
|
||||
/// lookups where a miss is the normal case, not a bug — e.g. tool display
|
||||
/// names (`tool.name.Bash`, `tool.name.ScheduleWakeup`, MCP tools), which are
|
||||
/// proper-name identifiers that intentionally fall back to the raw name. Keep
|
||||
/// the warning on for fixed UI strings, where a miss is a real translation gap.
|
||||
String string(String key, {required String namespace, String? placeholder, bool warnIfMissing = true}) {
|
||||
final byLocale = _cache[namespace];
|
||||
if (byLocale == null) {
|
||||
_warnOnce('$namespace::MISSING_NAMESPACE::$key', 'i18n: namespace not registered: $namespace (key: $key)');
|
||||
if (warnIfMissing) _warnOnce('$namespace::MISSING_NAMESPACE::$key', 'i18n: namespace not registered: $namespace (key: $key)');
|
||||
return placeholder ?? key;
|
||||
}
|
||||
|
||||
@@ -108,7 +113,9 @@ class I18n extends ChangeNotifier {
|
||||
if (hit != null) return hit;
|
||||
}
|
||||
|
||||
_warnOnce('$namespace::${_current.languageCode}::$key', 'i18n: missing key "$key" in namespace "$namespace" (locale ${_current.toString()})');
|
||||
if (warnIfMissing) {
|
||||
_warnOnce('$namespace::${_current.languageCode}::$key', 'i18n: missing key "$key" in namespace "$namespace" (locale ${_current.toString()})');
|
||||
}
|
||||
return placeholder ?? key;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,9 +54,9 @@ class _I18n {
|
||||
/// uniform widget-facing lookup (T-462). [placeholder] is the inline English
|
||||
/// fallback. With no kernel in scope (isolated primitive tests) it returns
|
||||
/// the placeholder, so a widget never needs one to render.
|
||||
String string(BuildContext context, String key, {required String namespace, String? placeholder}) {
|
||||
String string(BuildContext context, String key, {required String namespace, String? placeholder, bool warnIfMissing = true}) {
|
||||
final i = ClideKernel.maybeOf(context)?.i18n;
|
||||
return i == null ? (placeholder ?? key) : i.string(key, namespace: namespace, placeholder: placeholder);
|
||||
return i == null ? (placeholder ?? key) : i.string(key, namespace: namespace, placeholder: placeholder, warnIfMissing: warnIfMissing);
|
||||
}
|
||||
|
||||
/// [string] with `replaceAll` interpolation per replacer (templated labels).
|
||||
|
||||
Reference in New Issue
Block a user