From 6ab3d823a42532730c5af1487ed243394e66fae7 Mon Sep 17 00:00:00 2001 From: sudacode Date: Sat, 11 Jul 2026 23:36:44 -0700 Subject: [PATCH] feat(shortcuts): make clipboard-video-append shortcut configurable (#158) --- .../configurable-clipboard-video-shortcut.md | 4 ++ config.example.jsonc | 3 +- docs-site/configuration.md | 4 +- docs-site/public/config.example.jsonc | 3 +- docs-site/shortcuts.md | 4 +- src/config/definitions/defaults-core.ts | 1 + src/config/definitions/options-core.ts | 6 +++ src/config/resolve/core-domains.ts | 5 +++ src/config/settings/registry.ts | 2 +- .../services/overlay-shortcut-handler.test.ts | 1 + src/core/services/overlay-shortcut.test.ts | 1 + src/core/services/session-actions.test.ts | 1 + src/core/services/session-actions.ts | 4 ++ src/core/services/session-bindings.test.ts | 39 +++++++++++++++++++ src/core/services/session-bindings.ts | 1 + src/core/utils/shortcut-config.ts | 2 + src/main.ts | 3 ++ .../global-shortcuts-runtime-handlers.test.ts | 1 + src/main/runtime/global-shortcuts.test.ts | 1 + src/renderer/handlers/keyboard.test.ts | 2 +- src/renderer/handlers/keyboard.ts | 7 ---- src/renderer/modals/session-help-sections.ts | 4 +- src/renderer/renderer.ts | 3 -- src/shared/ipc/validators.ts | 1 + src/types/config.ts | 1 + src/types/session-bindings.ts | 1 + 26 files changed, 87 insertions(+), 18 deletions(-) create mode 100644 changes/configurable-clipboard-video-shortcut.md diff --git a/changes/configurable-clipboard-video-shortcut.md b/changes/configurable-clipboard-video-shortcut.md new file mode 100644 index 00000000..e1654cf4 --- /dev/null +++ b/changes/configurable-clipboard-video-shortcut.md @@ -0,0 +1,4 @@ +type: changed +area: shortcuts + +- Made the clipboard-video playlist shortcut configurable through `shortcuts.appendClipboardVideoToQueue`. diff --git a/config.example.jsonc b/config.example.jsonc index e739e85f..387c8f1a 100644 --- a/config.example.jsonc +++ b/config.example.jsonc @@ -209,7 +209,8 @@ "openControllerSelect": "Alt+C", // Accelerator that opens the controller selection and learn-mode modal. "openControllerDebug": "Alt+Shift+C", // Accelerator that opens the controller debug modal with live axis/button readouts. "toggleSubtitleSidebar": "Backslash", // Accelerator that toggles the subtitle sidebar visibility. - "toggleNotificationHistory": "CommandOrControl+N" // Accelerator that toggles the overlay notification history panel. + "toggleNotificationHistory": "CommandOrControl+N", // Accelerator that toggles the overlay notification history panel. + "appendClipboardVideoToQueue": "CommandOrControl+A" // Accelerator that appends a video path from the clipboard to the mpv playlist. }, // Overlay keyboard shortcuts. Set a shortcut to null to disable. // ========================================== diff --git a/docs-site/configuration.md b/docs-site/configuration.md index e70c90cb..115c0f0d 100644 --- a/docs-site/configuration.md +++ b/docs-site/configuration.md @@ -655,6 +655,7 @@ See `config.example.jsonc` for detailed configuration options. "openJimaku": "Ctrl+Shift+J", "toggleSubtitleSidebar": "Backslash", "toggleNotificationHistory": "CommandOrControl+N", + "appendClipboardVideoToQueue": "CommandOrControl+A", "multiCopyTimeoutMs": 3000 } } @@ -681,6 +682,7 @@ See `config.example.jsonc` for detailed configuration options. | `openJimaku` | string \| `null` | Opens the Jimaku search modal (default: `"Ctrl+Shift+J"`) | | `toggleSubtitleSidebar` | string \| `null` | Dispatches the subtitle sidebar toggle action (default: `"Backslash"`). `subtitleSidebar.toggleKey` remains the primary bare-key setting. | | `toggleNotificationHistory` | string \| `null` | Toggles the overlay notification history panel (default: `"CommandOrControl+N"`). The panel slides in from the same edge as notifications (right when notifications are centered). | +| `appendClipboardVideoToQueue` | string \| `null` | Appends a video file path from the clipboard to the mpv playlist (default: `"CommandOrControl+A"`). Works whether the overlay or mpv has focus. | **See `config.example.jsonc`** for the complete list of shortcut configuration options. @@ -820,7 +822,7 @@ When automatic card updates are disabled, new cards are detected but not automat | `Ctrl+Shift+A` | Mark the last added Anki card as an audio card (sets IsAudioCard, SentenceAudio, Sentence, Picture) | | `Ctrl+D` | Open loaded character dictionary manager | | `Ctrl+Shift+O` | Open runtime options palette (session-only live toggles) | -| `Ctrl/Cmd+A` | Append clipboard video path to MPV playlist (fixed, not currently configurable) | +| `Ctrl/Cmd+A` | Append clipboard video path to MPV playlist (configurable via `shortcuts.appendClipboardVideoToQueue`) | **Multi-line copy workflow:** diff --git a/docs-site/public/config.example.jsonc b/docs-site/public/config.example.jsonc index e739e85f..387c8f1a 100644 --- a/docs-site/public/config.example.jsonc +++ b/docs-site/public/config.example.jsonc @@ -209,7 +209,8 @@ "openControllerSelect": "Alt+C", // Accelerator that opens the controller selection and learn-mode modal. "openControllerDebug": "Alt+Shift+C", // Accelerator that opens the controller debug modal with live axis/button readouts. "toggleSubtitleSidebar": "Backslash", // Accelerator that toggles the subtitle sidebar visibility. - "toggleNotificationHistory": "CommandOrControl+N" // Accelerator that toggles the overlay notification history panel. + "toggleNotificationHistory": "CommandOrControl+N", // Accelerator that toggles the overlay notification history panel. + "appendClipboardVideoToQueue": "CommandOrControl+A" // Accelerator that appends a video path from the clipboard to the mpv playlist. }, // Overlay keyboard shortcuts. Set a shortcut to null to disable. // ========================================== diff --git a/docs-site/shortcuts.md b/docs-site/shortcuts.md index d8e481f1..97c97542 100644 --- a/docs-site/shortcuts.md +++ b/docs-site/shortcuts.md @@ -66,9 +66,8 @@ These control playback and subtitle display. They require overlay window focus. | `Ctrl+W` | Quit mpv | | `Right-click` | Toggle pause (outside subtitle area) | | `Right-click + drag` | Reposition subtitles (on subtitle area) | -| `Ctrl/Cmd+A` | Append clipboard video path to mpv playlist | -The mpv-command rows above (`Space`, `F`, `J`, `Shift+J`, the seek/sub-seek/sub-step/sub-delay keys, replay/play-next, and quit) are merged from the `keybindings` config array and can be remapped or disabled there. `V`, `Ctrl/Cmd+A`, and the mouse actions are built-in overlay behaviors and are not part of the `keybindings` array. The playlist browser opens a split overlay modal with sibling video files on the left and the live mpv playlist on the right. +The mpv-command rows above (`Space`, `F`, `J`, `Shift+J`, the seek/sub-seek/sub-step/sub-delay keys, replay/play-next, and quit) are merged from the `keybindings` config array and can be remapped or disabled there. `V` and the mouse actions are built-in overlay behaviors and are not part of the `keybindings` array. The playlist browser opens a split overlay modal with sibling video files on the left and the live mpv playlist on the right. On macOS managed playback, SubMiner disables mpv's menu-bar shortcuts so configured SubMiner shortcuts like `Cmd+Shift+O` reach the mpv plugin instead of opening native mpv menu actions. @@ -86,6 +85,7 @@ Mouse-hover playback behavior is configured separately from shortcuts: `subtitle | `Ctrl/Cmd+N` | Toggle overlay notification history panel | `shortcuts.toggleNotificationHistory` | | `Ctrl+Alt+C` | Open the manual YouTube subtitle picker | `keybindings` | | `Ctrl+Alt+S` | Open subtitle sync (subsync) modal | `shortcuts.triggerSubsync` | +| `Ctrl/Cmd+A` | Append clipboard video path to mpv playlist | `shortcuts.appendClipboardVideoToQueue` | | `\` | Toggle subtitle sidebar | `subtitleSidebar.toggleKey` (overlay) / `shortcuts.toggleSubtitleSidebar` (mpv session binding) | | `` ` `` | Toggle stats overlay | `stats.toggleKey` | | `W` | Mark current video watched and advance to next in queue | `stats.markWatchedKey` | diff --git a/src/config/definitions/defaults-core.ts b/src/config/definitions/defaults-core.ts index a0adc8fc..ff884b52 100644 --- a/src/config/definitions/defaults-core.ts +++ b/src/config/definitions/defaults-core.ts @@ -103,6 +103,7 @@ export const CORE_DEFAULT_CONFIG: Pick< openControllerDebug: 'Alt+Shift+C', toggleSubtitleSidebar: 'Backslash', toggleNotificationHistory: 'CommandOrControl+N', + appendClipboardVideoToQueue: 'CommandOrControl+A', }, secondarySub: { secondarySubLanguages: [], diff --git a/src/config/definitions/options-core.ts b/src/config/definitions/options-core.ts index 70957d9e..5a243453 100644 --- a/src/config/definitions/options-core.ts +++ b/src/config/definitions/options-core.ts @@ -646,5 +646,11 @@ export function buildCoreConfigOptionRegistry( defaultValue: defaultConfig.shortcuts.toggleNotificationHistory, description: 'Accelerator that toggles the overlay notification history panel.', }, + { + path: 'shortcuts.appendClipboardVideoToQueue', + kind: 'string', + defaultValue: defaultConfig.shortcuts.appendClipboardVideoToQueue, + description: 'Accelerator that appends a video path from the clipboard to the mpv playlist.', + }, ]; } diff --git a/src/config/resolve/core-domains.ts b/src/config/resolve/core-domains.ts index cc1e167b..94361596 100644 --- a/src/config/resolve/core-domains.ts +++ b/src/config/resolve/core-domains.ts @@ -236,7 +236,12 @@ export function applyCoreDomainConfig(context: ResolveContext): void { 'openCharacterDictionaryManager', 'openRuntimeOptions', 'openJimaku', + 'openSessionHelp', + 'openControllerSelect', + 'openControllerDebug', + 'toggleSubtitleSidebar', 'toggleNotificationHistory', + 'appendClipboardVideoToQueue', ] as const; for (const key of shortcutKeys) { diff --git a/src/config/settings/registry.ts b/src/config/settings/registry.ts index 2b821523..35309160 100644 --- a/src/config/settings/registry.ts +++ b/src/config/settings/registry.ts @@ -600,7 +600,7 @@ function subsectionForPath(path: string): string | undefined { ) { return 'Open Panels'; } - if (leaf === 'triggerSubsync') return 'Playback'; + if (leaf === 'triggerSubsync' || leaf === 'appendClipboardVideoToQueue') return 'Playback'; return undefined; } return undefined; diff --git a/src/core/services/overlay-shortcut-handler.test.ts b/src/core/services/overlay-shortcut-handler.test.ts index 1798e3e9..870fffb3 100644 --- a/src/core/services/overlay-shortcut-handler.test.ts +++ b/src/core/services/overlay-shortcut-handler.test.ts @@ -33,6 +33,7 @@ function makeShortcuts(overrides: Partial = {}): Configured openControllerDebug: null, toggleSubtitleSidebar: null, toggleNotificationHistory: null, + appendClipboardVideoToQueue: null, ...overrides, }; } diff --git a/src/core/services/overlay-shortcut.test.ts b/src/core/services/overlay-shortcut.test.ts index b41e6029..aef4ba53 100644 --- a/src/core/services/overlay-shortcut.test.ts +++ b/src/core/services/overlay-shortcut.test.ts @@ -28,6 +28,7 @@ function createShortcuts(overrides: Partial = {}): Configur openControllerDebug: null, toggleSubtitleSidebar: null, toggleNotificationHistory: null, + appendClipboardVideoToQueue: null, ...overrides, }; } diff --git a/src/core/services/session-actions.test.ts b/src/core/services/session-actions.test.ts index 3e9daa4f..e76f6e4e 100644 --- a/src/core/services/session-actions.test.ts +++ b/src/core/services/session-actions.test.ts @@ -26,6 +26,7 @@ function createDeps(overrides: Partial = {}) { toggleSecondarySub: () => calls.push('secondary'), toggleSubtitleSidebar: () => calls.push('sidebar'), toggleNotificationHistory: () => calls.push('notification-history'), + appendClipboardVideoToQueue: () => calls.push('append-clipboard-video'), markLastCardAsAudioCard: async () => { calls.push('audio'); }, diff --git a/src/core/services/session-actions.ts b/src/core/services/session-actions.ts index d32bce81..b5f33447 100644 --- a/src/core/services/session-actions.ts +++ b/src/core/services/session-actions.ts @@ -15,6 +15,7 @@ export interface SessionActionExecutorDeps { toggleSecondarySub: () => void; toggleSubtitleSidebar: () => void; toggleNotificationHistory: () => void; + appendClipboardVideoToQueue: () => void; markLastCardAsAudioCard: () => Promise; markActiveVideoWatched: () => Promise; openRuntimeOptionsPalette: () => void; @@ -82,6 +83,9 @@ export async function dispatchSessionAction( case 'toggleNotificationHistory': deps.toggleNotificationHistory(); return; + case 'appendClipboardVideoToQueue': + deps.appendClipboardVideoToQueue(); + return; case 'markAudioCard': await deps.markLastCardAsAudioCard(); return; diff --git a/src/core/services/session-bindings.test.ts b/src/core/services/session-bindings.test.ts index 7dacbbcc..7e119d44 100644 --- a/src/core/services/session-bindings.test.ts +++ b/src/core/services/session-bindings.test.ts @@ -27,6 +27,7 @@ function createShortcuts(overrides: Partial = {}): Configur openControllerDebug: null, toggleSubtitleSidebar: null, toggleNotificationHistory: null, + appendClipboardVideoToQueue: null, ...overrides, }; } @@ -515,6 +516,8 @@ test('compileSessionBindings wires every configured shortcut key into the shared 'openControllerSelect', 'openControllerDebug', 'toggleSubtitleSidebar', + 'toggleNotificationHistory', + 'appendClipboardVideoToQueue', ]; const shortcuts = createShortcuts(); shortcutKeys.forEach((key, index) => { @@ -582,6 +585,42 @@ test('buildPluginSessionBindingsArtifact emits CLI args for plugin-bound session }); }); +test('appendClipboardVideoToQueue shortcut compiles to a session action with plugin CLI args', () => { + const result = compileSessionBindings({ + shortcuts: createShortcuts({ + appendClipboardVideoToQueue: 'CommandOrControl+A', + }), + keybindings: [], + platform: 'linux', + }); + + assert.deepEqual(result.warnings, []); + const binding = result.bindings.find( + (candidate) => + candidate.actionType === 'session-action' && + candidate.actionId === 'appendClipboardVideoToQueue', + ); + assert.ok(binding); + assert.deepEqual(binding.key, { code: 'KeyA', modifiers: ['ctrl'] }); + + const artifact = buildPluginSessionBindingsArtifact({ + bindings: result.bindings, + warnings: result.warnings, + numericSelectionTimeoutMs: 2500, + now: new Date('2026-05-26T00:00:00.000Z'), + }); + const pluginBinding = artifact.bindings.find( + (candidate) => + candidate.actionType === 'session-action' && + candidate.actionId === 'appendClipboardVideoToQueue', + ); + assert.ok(pluginBinding && 'cliArgs' in pluginBinding); + assert.equal(pluginBinding.cliArgs?.[0], '--session-action'); + assert.deepEqual(JSON.parse(pluginBinding.cliArgs?.[1] ?? ''), { + actionId: 'appendClipboardVideoToQueue', + }); +}); + test('buildPluginSessionBindingsArtifact preserves plugin selector CLI for no-count multi-line actions', () => { const result = compileSessionBindings({ shortcuts: createShortcuts({ diff --git a/src/core/services/session-bindings.ts b/src/core/services/session-bindings.ts index b04a847a..13f16ee6 100644 --- a/src/core/services/session-bindings.ts +++ b/src/core/services/session-bindings.ts @@ -60,6 +60,7 @@ const SESSION_SHORTCUT_ACTIONS: Array<{ { key: 'openControllerDebug', actionId: 'openControllerDebug' }, { key: 'toggleSubtitleSidebar', actionId: 'toggleSubtitleSidebar' }, { key: 'toggleNotificationHistory', actionId: 'toggleNotificationHistory' }, + { key: 'appendClipboardVideoToQueue', actionId: 'appendClipboardVideoToQueue' }, ]; function normalizeModifiers(modifiers: SessionKeyModifier[]): SessionKeyModifier[] { diff --git a/src/core/utils/shortcut-config.ts b/src/core/utils/shortcut-config.ts index 4b55f58e..e113f82e 100644 --- a/src/core/utils/shortcut-config.ts +++ b/src/core/utils/shortcut-config.ts @@ -20,6 +20,7 @@ export interface ConfiguredShortcuts { openControllerDebug: string | null | undefined; toggleSubtitleSidebar: string | null | undefined; toggleNotificationHistory: string | null | undefined; + appendClipboardVideoToQueue: string | null | undefined; } export function resolveConfiguredShortcuts( @@ -69,5 +70,6 @@ export function resolveConfiguredShortcuts( openControllerDebug: normalizeShortcut(shortcutValue('openControllerDebug')), toggleSubtitleSidebar: normalizeShortcut(shortcutValue('toggleSubtitleSidebar')), toggleNotificationHistory: normalizeShortcut(shortcutValue('toggleNotificationHistory')), + appendClipboardVideoToQueue: normalizeShortcut(shortcutValue('appendClipboardVideoToQueue')), }; } diff --git a/src/main.ts b/src/main.ts index f32e0db0..87cc77f6 100644 --- a/src/main.ts +++ b/src/main.ts @@ -5416,6 +5416,9 @@ async function dispatchSessionAction(request: SessionActionDispatchRequest): Pro toggleSecondarySub: () => handleCycleSecondarySubMode(), toggleSubtitleSidebar: () => toggleSubtitleSidebar(), toggleNotificationHistory: () => toggleNotificationHistoryPanel(), + appendClipboardVideoToQueue: () => { + appendClipboardVideoToQueue(); + }, markLastCardAsAudioCard: () => markLastCardAsAudioCard(), markActiveVideoWatched: async () => { ensureImmersionTrackerStarted(); diff --git a/src/main/runtime/global-shortcuts-runtime-handlers.test.ts b/src/main/runtime/global-shortcuts-runtime-handlers.test.ts index 92ae205f..0bd8c5f9 100644 --- a/src/main/runtime/global-shortcuts-runtime-handlers.test.ts +++ b/src/main/runtime/global-shortcuts-runtime-handlers.test.ts @@ -24,6 +24,7 @@ function createShortcuts(): ConfiguredShortcuts { openControllerDebug: null, toggleSubtitleSidebar: null, toggleNotificationHistory: null, + appendClipboardVideoToQueue: null, }; } diff --git a/src/main/runtime/global-shortcuts.test.ts b/src/main/runtime/global-shortcuts.test.ts index a1ec5995..12d29cac 100644 --- a/src/main/runtime/global-shortcuts.test.ts +++ b/src/main/runtime/global-shortcuts.test.ts @@ -28,6 +28,7 @@ function createShortcuts(): ConfiguredShortcuts { openControllerDebug: null, toggleSubtitleSidebar: null, toggleNotificationHistory: null, + appendClipboardVideoToQueue: null, }; } diff --git a/src/renderer/handlers/keyboard.test.ts b/src/renderer/handlers/keyboard.test.ts index 25b5011b..b60af257 100644 --- a/src/renderer/handlers/keyboard.test.ts +++ b/src/renderer/handlers/keyboard.test.ts @@ -95,6 +95,7 @@ function createEmptyShortcuts(): ConfiguredShortcuts { openControllerDebug: null, toggleSubtitleSidebar: null, toggleNotificationHistory: null, + appendClipboardVideoToQueue: null, }; } @@ -508,7 +509,6 @@ function createKeyboardHandlerHarness() { openControllerDebugModal: () => { openControllerDebugCount += 1; }, - appendClipboardVideoToQueue: () => {}, getPlaybackPaused: () => testGlobals.getPlaybackPaused(), }); diff --git a/src/renderer/handlers/keyboard.ts b/src/renderer/handlers/keyboard.ts index fba6269a..09b48a1e 100644 --- a/src/renderer/handlers/keyboard.ts +++ b/src/renderer/handlers/keyboard.ts @@ -28,7 +28,6 @@ export function createKeyboardHandlers( }) => void; openControllerSelectModal?: () => void; openControllerDebugModal?: () => void; - appendClipboardVideoToQueue: () => void; getPlaybackPaused: () => Promise; toggleSubtitleSidebarModal?: () => void; }, @@ -1221,12 +1220,6 @@ export function createKeyboardHandlers( return; } - if ((e.ctrlKey || e.metaKey) && !e.altKey && !e.shiftKey && e.code === 'KeyA' && !e.repeat) { - e.preventDefault(); - options.appendClipboardVideoToQueue(); - return; - } - const keyString = keyEventToString(e); const binding = ctx.state.sessionBindingMap.get(keyString); if (binding) { diff --git a/src/renderer/modals/session-help-sections.ts b/src/renderer/modals/session-help-sections.ts index 5c34a848..1d0d5a5f 100644 --- a/src/renderer/modals/session-help-sections.ts +++ b/src/renderer/modals/session-help-sections.ts @@ -203,6 +203,8 @@ function describeSessionAction( return 'Toggle subtitle sidebar'; case 'toggleNotificationHistory': return 'Toggle notification history'; + case 'appendClipboardVideoToQueue': + return 'Append clipboard video path to playlist'; case 'markAudioCard': return 'Mark audio card'; case 'markWatched': @@ -267,6 +269,7 @@ function sectionForSessionBinding(binding: CompiledSessionBinding): string { return 'Modals and tools'; case 'replayCurrentSubtitle': case 'playNextSubtitle': + case 'appendClipboardVideoToQueue': return 'Playback and navigation'; case 'cycleRuntimeOption': return 'Runtime settings'; @@ -346,7 +349,6 @@ function buildFixedOverlaySections(): SessionHelpSection[] { title: 'Fixed overlay controls', rows: [ { shortcut: 'V', action: 'Toggle primary subtitle bar visibility' }, - { shortcut: 'Ctrl/Cmd + A', action: 'Append clipboard video path to playlist' }, { shortcut: 'Right-click', action: 'Toggle playback outside subtitle area' }, { shortcut: 'Right-click + drag', action: 'Reposition subtitles on subtitle area' }, ], diff --git a/src/renderer/renderer.ts b/src/renderer/renderer.ts index 1e07598d..e2b5f9c2 100644 --- a/src/renderer/renderer.ts +++ b/src/renderer/renderer.ts @@ -215,9 +215,6 @@ const keyboardHandlers = createKeyboardHandlers(ctx, { window.electronAPI.notifyOverlayModalOpened('controller-debug'); } }, - appendClipboardVideoToQueue: () => { - void window.electronAPI.appendClipboardVideoToQueue(); - }, getPlaybackPaused: () => window.electronAPI.getPlaybackPaused(), toggleSubtitleSidebarModal: () => { void subtitleSidebarModal.toggleSubtitleSidebarModal(); diff --git a/src/shared/ipc/validators.ts b/src/shared/ipc/validators.ts index b741082a..aadb41ec 100644 --- a/src/shared/ipc/validators.ts +++ b/src/shared/ipc/validators.ts @@ -33,6 +33,7 @@ const SESSION_ACTION_IDS: SessionActionId[] = [ 'markAudioCard', 'toggleSubtitleSidebar', 'toggleNotificationHistory', + 'appendClipboardVideoToQueue', 'openRuntimeOptions', 'openSessionHelp', 'openCharacterDictionaryManager', diff --git a/src/types/config.ts b/src/types/config.ts index 1866fd33..a256e863 100644 --- a/src/types/config.ts +++ b/src/types/config.ts @@ -127,6 +127,7 @@ export interface ShortcutsConfig { openControllerDebug?: string | null; toggleSubtitleSidebar?: string | null; toggleNotificationHistory?: string | null; + appendClipboardVideoToQueue?: string | null; } export interface Config { diff --git a/src/types/session-bindings.ts b/src/types/session-bindings.ts index 2c0a10e1..b1a12fac 100644 --- a/src/types/session-bindings.ts +++ b/src/types/session-bindings.ts @@ -14,6 +14,7 @@ export type SessionActionId = | 'toggleSecondarySub' | 'toggleSubtitleSidebar' | 'toggleNotificationHistory' + | 'appendClipboardVideoToQueue' | 'markAudioCard' | 'openRuntimeOptions' | 'openSessionHelp'