fix(i18n): re-export I18nReplacer with the ClideSettings facade (T-462)

ClideSettings.i18n.interpolated takes I18nReplacer, but the type didn't travel
with the facade — every templated-lookup call site had to separately import it
from the kernel. Re-export it from clide_settings so it ships via the widgets
barrel alongside ClideSettings; the interpolated API is now self-contained.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-18 21:14:20 +02:00
co-authored by Claude Opus 4.8
parent e1d57e7964
commit 93aa9bc332
3 changed files with 35 additions and 0 deletions
@@ -5935,3 +5935,7 @@ INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, chang
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FDA0VPB99NGS4J6Z5B2RJM2M', 'status', 'backlog', 'in_progress', NULL, '2026-06-18 07:46:07', '2026-06-18 07:46:07.636', '2026-06-18 07:46:07.636', NULL, 'e9e9c6719b8a49a39309bf8268eeee55', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FDA0VPB99NGS4J6Z5B2RJM2M', 'status', 'in_progress', 'done', NULL, '2026-06-18 07:56:10', '2026-06-18 07:56:10.133', '2026-06-18 07:56:10.133', NULL, '666602e799384337b8631789be144e53', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FDA0X5WFME83GS0DKYG3WVJ8', 'status', 'backlog', 'done', NULL, '2026-06-18 13:41:29', '2026-06-18 13:41:29.322', '2026-06-18 13:41:29.322', NULL, 'debbcd81ff12cb112671ba428f1a826b', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FDA0WCPG458GF5FXTXM9VY98', 'status', 'backlog', 'in_progress', NULL, '2026-06-18 13:52:52', '2026-06-18 13:52:52.920', '2026-06-18 13:52:52.920', NULL, 'c6f7f43d0c2d88dabcc176783b1e7006', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FDA0YCY2WGSG8W46RHQ5Z9MW', 'status', 'backlog', 'in_progress', NULL, '2026-06-18 13:52:52', '2026-06-18 13:52:52.931', '2026-06-18 13:52:52.931', NULL, '4d4b842c99b6ff11a2820f9bccd0e73c', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FDA0XMA9BQV4RHJ55BFN4JR4', 'status', 'backlog', 'in_progress', NULL, '2026-06-18 13:52:52', '2026-06-18 13:52:52.931', '2026-06-18 13:52:52.931', NULL, '8a7fef08c302d2119d32ceb18a58346e', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FDA0YYCJ0NK8C4HMDYKJHRDG', 'status', 'backlog', 'in_progress', NULL, '2026-06-18 13:52:52', '2026-06-18 13:52:52.932', '2026-06-18 13:52:52.932', NULL, 'f0b77fdf0ef68d872155912ef3882cb1', 2) ON CONFLICT(hash) DO NOTHING;
+27
View File
@@ -7301,3 +7301,30 @@ INSERT INTO tickets (record_id, type, parent_record_id, title, description, stat
Hotspots from the audit: lib/builtin/welcome/src/welcome_view.dart e.g. :108 ''TIPS'', :173 ''START'', :258 ''RECENT'', plus the title/subtitle/open-project block the catalog already has translations for.
Acceptance: no hardcoded user-facing string literals remain in lib/builtin/welcome/; the pre-existing builtin.welcome catalog keys are actually consumed (no orphans); section headers added as keys.', 'done', 'medium', NULL, NULL, 'D-21', '2026-06-17 09:57:26.627', '2026-06-18 13:41:29.322', NULL, '9ce7dc6dd92151c29617d26088c3c85c', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FDA0WCPG458GF5FXTXM9VY98', 'task', '06FDA0TPYSWEM10RP0Q76XAP58', 'i18n: migrate builtin.claude UI labels to the catalog (~35 strings)', 'Largest single offender in the audit: ~35 hardcoded user-facing strings in builtin.claude bypass i18n, despite builtin.claude_en_us.json already existing (currently tab.title + 4 orphaned status.* keys).
Route the hardcoded ClideText/Text/tooltip literals through ctx.i18n.string(key, namespace: ''builtin.claude'', placeholder: <current literal>), and add the keys to the catalog. Hotspots from the audit include lib/builtin/claude/src/prompt_card.dart (e.g. :314 ''Review your answers'', :372 ''Review'') and the permission/AskUserQuestion interaction widgets sweep the whole extension, not just those lines.
Watch the interaction-zone widgets (D-78): keep them display-only; the i18n change is label-only, no behavioural change.
Acceptance: no hardcoded user-facing string literals remain in lib/builtin/claude/ (single-char glyphs like ''<'' / ''+'' used as icons are exempt note any left); all new keys present in the catalog; existing orphaned status.* keys either wired up or removed.', 'in_progress', 'high', NULL, NULL, 'D-21', '2026-06-17 09:57:20.180', '2026-06-18 13:52:52.920', NULL, '056dfb04194ffe61a7e2eb3102b88aa5', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FDA0XMA9BQV4RHJ55BFN4JR4', 'task', '06FDA0TPYSWEM10RP0Q76XAP58', 'i18n: migrate git + diff panel labels to the catalog (~16 strings)', 'builtin.git (~9 hardcoded) and builtin.diff (~7 hardcoded) panel/view labels bypass i18n. builtin.git has a tab.title-only catalog; builtin.diff''s catalog is created by the gaps task (T-463) — extend both.
Hotspots from the audit:
- lib/builtin/git/src/git_status_item.dart:167 ''Switch branch'', :179 ''Loading''
- lib/builtin/git/src/git_panel_view.dart:94 ''Nothing to commit, working tree clean.''
- lib/builtin/diff/src/diff_view.dart:105 ''No staged changes.''/''No unstaged changes.'', :153 ''Unstaged'', :163 ''Staged''
Acceptance: no hardcoded user-facing literals in lib/builtin/git/ or lib/builtin/diff/; keys added to builtin.git and builtin.diff catalogs. Depends on T-463 for the builtin.diff catalog file.', 'in_progress', 'medium', NULL, NULL, 'D-21', '2026-06-17 09:57:30.322', '2026-06-18 13:52:52.931', NULL, '0c8b2df9caa133215ac9c0b1b1a46296', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FDA0YCY2WGSG8W46RHQ5Z9MW', 'task', '06FDA0TPYSWEM10RP0Q76XAP58', 'i18n: migrate planning-pane labels — tickets, pql, decisions, problems (~21 strings)', 'The four pql/planning-surface extensions each have a tab.title-only catalog and hardcode the rest: tickets ~6, pql ~6, decisions ~6, problems ~3. Sweep all four, extend each catalog.
For each: route hardcoded ClideText/Text/tooltip literals through ctx.i18n.string(..., namespace: ''builtin.<ext>'', placeholder: <current literal>) and add keys.
Acceptance: no hardcoded user-facing literals remain in lib/builtin/{tickets,pql,decisions,problems}/; keys present in each respective catalog.', 'in_progress', 'medium', NULL, NULL, 'D-21', '2026-06-17 09:57:36.624', '2026-06-18 13:52:52.931', NULL, '6a60e0b3b5cc6a4b09b0b65a1bf05e79', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FDA0YYCJ0NK8C4HMDYKJHRDG', 'task', '06FDA0TPYSWEM10RP0Q76XAP58', 'i18n: migrate remaining extension labels — menubar, output, search, deeplink, editor, files, terminal, markdown, vim (~24 strings)', 'Tail of the audit: the remaining extensions with hardcoded labels. menubar ~6 (no catalog), output ~4 (no catalog), search ~3 (no catalog), deeplink ~3 (no catalog), editor ~1, files ~1, terminal ~1, markdown ~1 (no catalog), vim ~1 (no catalog).
Several have no catalog file yet create lib/kernel/src/i18n/catalog/builtin.<ext>_en_us.json for menubar, output, search, deeplink, markdown, vim. editor/files/terminal already have catalogs (with orphaned keys) wire their hardcoded literals up and consume the orphans where they match.
Can be split into smaller tasks if a single PR is too large; grouped here to keep the long tail in one tracked place.
Acceptance: no hardcoded user-facing literals remain in any of these extensions; each has a catalog file with the keys it uses; no orphaned keys left in editor/files/terminal.', 'in_progress', 'medium', NULL, NULL, 'D-21', '2026-06-17 09:57:41.092', '2026-06-18 13:52:52.932', NULL, '3313d03f3d8428d61aa3528c2f4371db', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
+4
View File
@@ -1,5 +1,9 @@
import 'package:clide/kernel/src/facade.dart' show ClideKernel;
import 'package:clide/kernel/src/i18n/i18n.dart' show I18n, I18nReplacer;
// Re-export so ClideSettings.i18n.interpolated callers get I18nReplacer with
// the facade (via the widgets barrel) — the templated-lookup API is then
// self-contained (T-462).
export 'package:clide/kernel/src/i18n/i18n.dart' show I18nReplacer;
import 'package:clide/kernel/src/theme/controller.dart' show ClideTheme, ClideThemeData;
import 'package:clide/widgets/src/typography.dart';
import 'package:flutter/widgets.dart';