feat(ui): land the centralized shortcuts core from #2532 with review fixes

The schema/config/bindings/registry/dispatcher module, useKeybind hooks,
recording dialog, reworked shortcuts settings page, help dialog, and the
localized action labels — re-based onto current main rather than merged
(the branch predates 440+ commits including the session-tabs shortcuts).

Review fixes applied on top of the original:
- close_session_tab (alt+w) joins the schema with labels in every locale;
  it shipped on main after the PR's base and would otherwise silently die.
- switch_context_surface's special-case in conflict resolution is now a
  declared prefixStyle config property instead of a magic id string.
- Duplicate handler registration warns in dev builds.
- The risky-browser-shortcut warning inspects every chord and covers
  mod+q/d/h/j/o/u plus mod+shift+w/q.
- The dispatcher remembers which target armed a two-chord prefix so the
  window-level completion handler can distinguish a deliberate sequence
  from typing in an editable field (guard lands with the dispatch hook).
- Schema tests: unique normalized default bindings enforced, and the
  flat-file-era override format proven to keep resolving.
This commit is contained in:
Bohdan Triapitsyn
2026-08-26 10:47:44 +03:00
parent 428854fd78
commit f1c3870909
44 changed files with 2716 additions and 1045 deletions
@@ -1134,7 +1134,7 @@ export const settingsDict = {
'settings.openchamber.keyboardShortcuts.overwritePrompt': 'このキーコンボは別のショートカットで既に使用されています。上書きしてそのマッピングをクリアしますか?',
'settings.openchamber.keyboardShortcuts.field.pressKeys': 'キーを押してください...',
'settings.openchamber.keyboardShortcuts.error.captureFirst': '最初にショートカットを設定してください。',
'settings.openchamber.keyboardShortcuts.warning.riskyBrowserShortcut': 'このショートカットはブラウザのデフォルトと競合する可能性があります。それでも保存されます。',
'settings.openchamber.keyboardShortcuts.warning.riskyBrowserShortcut': 'このショートカットはブラウザのデフォルトと競合する可能性がありますが、そのまま保存できます。',
'settings.openchamber.keyboardShortcuts.action.open_go_to_line.label': '指定行に移動(ファイルエディター)',
'settings.openchamber.keyboardShortcuts.action.open_command_palette.label': 'コマンドパレットを開く',
'settings.openchamber.keyboardShortcuts.action.focus_input.label': '入力をフォーカス',
@@ -1149,6 +1149,7 @@ export const settingsDict = {
'settings.openchamber.keyboardShortcuts.action.switch_context_surface.label': 'コンテキストパネルのサーフェスを切り替え',
'settings.openchamber.keyboardShortcuts.action.switch_context_surface.suffix': ' + 1…0',
'settings.openchamber.keyboardShortcuts.action.new_chat.label': '新しい Session',
'settings.openchamber.keyboardShortcuts.action.close_session_tab.label': 'セッションタブを閉じる',
'settings.openchamber.keyboardShortcuts.action.new_chat_worktree.label': '新しい Worktree 下書き',
'settings.openchamber.keyboardShortcuts.action.new_mini_chat.label': '新しいミニチャットウィンドウ',
'settings.openchamber.keyboardShortcuts.action.open_help.label': 'キーボードショートカットを開く',
@@ -1163,6 +1164,27 @@ export const settingsDict = {
'settings.openchamber.keyboardShortcuts.action.open_model_selector.label': 'モデルセレクターを開く',
'settings.openchamber.keyboardShortcuts.action.open_timeline_dialog.label': '会話タイムラインを開く',
'settings.openchamber.keyboardShortcuts.action.toggle_prompt_navigator.label': 'プロンプトナビゲーターの表示切替',
'settings.openchamber.keyboardShortcuts.warning.contextualPrefix': 'このシーケンスは {action} とコンテキスト依存のプレフィックスを共有しています。そのコンテキストが有効な間は、この操作が優先されます。',
'settings.openchamber.keyboardShortcuts.category.session': 'セッション操作',
'settings.openchamber.keyboardShortcuts.category.models': 'モデルとエージェント',
'settings.openchamber.keyboardShortcuts.category.panels': 'パネルとツール',
'settings.openchamber.keyboardShortcuts.category.navigation': 'ナビゲーション',
'settings.openchamber.keyboardShortcuts.category.application': 'アプリケーション',
'settings.openchamber.keyboardShortcuts.actions.edit': '編集',
'settings.openchamber.keyboardShortcuts.actions.confirm': '確認',
'settings.openchamber.keyboardShortcuts.dialog.title': '{action} を編集',
'settings.openchamber.keyboardShortcuts.dialog.instructions': 'キーの組み合わせを最大2つ入力でき、各組み合わせは最大3キーです。最初の組み合わせの後、2つ目の組み合わせを最大3秒待ちます。適用するには確認、破棄するにはキャンセルを選択してください。Backspace で最後の組み合わせを削除します。',
'settings.openchamber.keyboardShortcuts.dialog.firstChord': '最初の組み合わせ',
'settings.openchamber.keyboardShortcuts.dialog.secondChord': '2番目の組み合わせ',
'settings.openchamber.keyboardShortcuts.dialog.recording': 'キーを押してください…',
'settings.openchamber.keyboardShortcuts.unassigned': '未割り当て',
'settings.openchamber.keyboardShortcuts.error.prefixConflict': '{action} のシーケンスと競合しています。別の組み合わせを選択してください。',
'settings.openchamber.keyboardShortcuts.error.exactConflict': 'この組み合わせは {action} で使用されています。',
'settings.openchamber.keyboardShortcuts.error.internalConflict': 'この組み合わせは組み込みショートカットと競合しています。組み込みショートカットは置き換えられません。',
'settings.openchamber.keyboardShortcuts.action.open_draft_project_picker.label': '下書きプロジェクト選択を開く',
'settings.openchamber.keyboardShortcuts.action.open_draft_worktree_picker.label': '下書きワークツリー選択を開く',
'settings.openchamber.keyboardShortcuts.action.open_session_list.label': '最近のセッションを開く',
'settings.openchamber.keyboardShortcuts.action.toggle_dictation.label': '音声入力',
'settings.projects.sidebar.total': '合計 {count}',
'settings.projects.sidebar.actions.addProject': 'プロジェクトを追加',
'settings.projects.page.empty.noProjects': '利用可能なプロジェクトがありません。',