diff --git a/backlog/tasks/task-303 - Update-tray-menu-help-action.md b/backlog/tasks/task-303 - Update-tray-menu-help-action.md new file mode 100644 index 00000000..6b8148a6 --- /dev/null +++ b/backlog/tasks/task-303 - Update-tray-menu-help-action.md @@ -0,0 +1,57 @@ +--- +id: TASK-303 +title: Update tray menu help action +status: Done +assignee: + - Codex +created_date: '2026-04-26 03:54' +updated_date: '2026-04-26 04:12' +labels: + - tray + - overlay +dependencies: [] +priority: medium +--- + +## Description + + +Replace the tray menu's direct visible-overlay open action with an action that opens the existing in-session help modal. The tray should no longer expose an "Open Overlay" menu item; users should be able to open help from the tray instead. + + +## Acceptance Criteria + +- [x] #1 Tray menu no longer includes an "Open Overlay" option. +- [x] #2 Tray menu includes an option to open the session help modal. +- [x] #3 Selecting the new tray help option initializes overlay runtime if needed and invokes the existing session help modal path. +- [x] #4 Focused regression tests cover the menu label and action wiring. + + +## Implementation Plan + + +1. Add focused regression coverage for tray menu template labels and main-process action wiring: assert Open Overlay is absent, Open Help is present, and clicking help initializes overlay runtime if needed before opening the existing session help modal path. +2. Update tray runtime action types/template to replace openOverlay with openSessionHelp. +3. Update tray main action builder dependencies to call the existing openSessionHelpModal function after overlay runtime initialization. +4. Run targeted tray tests, then broader relevant fast tests if needed. +5. Check acceptance criteria and finalize backlog notes. + + +## Implementation Notes + + +Implemented tray menu replacement via existing session help overlay path. Verification passed: targeted tray tests (`bun test src/main/runtime/tray-runtime.test.ts src/main/runtime/tray-main-actions.test.ts src/main/runtime/tray-main-deps.test.ts src/main/runtime/tray-runtime-handlers.test.ts`), SubMiner verifier lanes `runtime-compat` and `docs`, and `bun run changelog:lint`. + + +## Final Summary + + +Replaced the tray menu's `Open Overlay` item with `Open Help`, wired it to initialize overlay runtime when needed, and then open the existing session help modal path. Updated tray runtime/main-deps/action tests to assert the old label is absent, the new label is present, and the new action calls the help modal. Added changelog fragment `changes/303-tray-help-menu.md`. + +Verification: +- `bun test src/main/runtime/tray-runtime.test.ts src/main/runtime/tray-main-actions.test.ts src/main/runtime/tray-main-deps.test.ts src/main/runtime/tray-runtime-handlers.test.ts` +- `bash plugins/subminer-workflow/skills/subminer-change-verification/scripts/verify_subminer_change.sh --lane runtime-compat --lane docs src/main/runtime/tray-runtime.ts src/main/runtime/tray-main-actions.ts src/main/runtime/tray-main-deps.ts src/main.ts changes/303-tray-help-menu.md` +- `bun run changelog:lint` + +Verifier artifacts: `.tmp/skill-verification/subminer-verify-20260425-211156-9fkdDf/`. + diff --git a/changes/303-tray-help-menu.md b/changes/303-tray-help-menu.md new file mode 100644 index 00000000..11a2a32c --- /dev/null +++ b/changes/303-tray-help-menu.md @@ -0,0 +1,4 @@ +type: changed +area: tray + +- Tray: Replaced the Open Overlay tray menu item with Open Help, which opens the session help modal. diff --git a/src/main.ts b/src/main.ts index 29089c19..85dd19da 100644 --- a/src/main.ts +++ b/src/main.ts @@ -5139,7 +5139,7 @@ const { ensureTray: ensureTrayHandler, destroyTray: destroyTrayHandler } = buildTrayMenuTemplateRuntime, initializeOverlayRuntime: () => initializeOverlayRuntime(), isOverlayRuntimeInitialized: () => appState.overlayRuntimeInitialized, - setVisibleOverlayVisible: (visible) => setVisibleOverlayVisible(visible), + openSessionHelpModal: () => openSessionHelpOverlay(), showFirstRunSetup: () => !firstRunSetupService.isSetupCompleted(), openFirstRunSetupWindow: () => openFirstRunSetupWindow(), showWindowsMpvLauncherSetup: () => process.platform === 'win32', diff --git a/src/main/runtime/tray-main-actions.test.ts b/src/main/runtime/tray-main-actions.test.ts index bffc375b..45bd1139 100644 --- a/src/main/runtime/tray-main-actions.test.ts +++ b/src/main/runtime/tray-main-actions.test.ts @@ -41,7 +41,7 @@ test('build tray template handler wires actions and init guards', () => { let initialized = false; const buildTemplate = createBuildTrayMenuTemplateHandler({ buildTrayMenuTemplateRuntime: (handlers) => { - handlers.openOverlay(); + handlers.openSessionHelp(); handlers.openFirstRunSetup(); handlers.openWindowsMpvLauncherSetup(); handlers.openYomitanSettings(); @@ -56,7 +56,7 @@ test('build tray template handler wires actions and init guards', () => { calls.push('init'); }, isOverlayRuntimeInitialized: () => initialized, - setVisibleOverlayVisible: (visible) => calls.push(`visible:${visible}`), + openSessionHelpModal: () => calls.push('help'), showFirstRunSetup: () => true, openFirstRunSetupWindow: () => calls.push('setup'), showWindowsMpvLauncherSetup: () => true, @@ -71,7 +71,7 @@ test('build tray template handler wires actions and init guards', () => { assert.deepEqual(template, [{ label: 'ok' }]); assert.deepEqual(calls, [ 'init', - 'visible:true', + 'help', 'setup', 'setup', 'yomitan', diff --git a/src/main/runtime/tray-main-actions.ts b/src/main/runtime/tray-main-actions.ts index c38bf23e..4aa2e543 100644 --- a/src/main/runtime/tray-main-actions.ts +++ b/src/main/runtime/tray-main-actions.ts @@ -28,7 +28,7 @@ export function createResolveTrayIconPathHandler(deps: { export function createBuildTrayMenuTemplateHandler(deps: { buildTrayMenuTemplateRuntime: (handlers: { - openOverlay: () => void; + openSessionHelp: () => void; openFirstRunSetup: () => void; showFirstRunSetup: boolean; openWindowsMpvLauncherSetup: () => void; @@ -41,7 +41,7 @@ export function createBuildTrayMenuTemplateHandler(deps: { }) => TMenuItem[]; initializeOverlayRuntime: () => void; isOverlayRuntimeInitialized: () => boolean; - setVisibleOverlayVisible: (visible: boolean) => void; + openSessionHelpModal: () => void; showFirstRunSetup: () => boolean; openFirstRunSetupWindow: () => void; showWindowsMpvLauncherSetup: () => boolean; @@ -53,11 +53,11 @@ export function createBuildTrayMenuTemplateHandler(deps: { }) { return (): TMenuItem[] => { return deps.buildTrayMenuTemplateRuntime({ - openOverlay: () => { + openSessionHelp: () => { if (!deps.isOverlayRuntimeInitialized()) { deps.initializeOverlayRuntime(); } - deps.setVisibleOverlayVisible(true); + deps.openSessionHelpModal(); }, openFirstRunSetup: () => { deps.openFirstRunSetupWindow(); diff --git a/src/main/runtime/tray-main-deps.test.ts b/src/main/runtime/tray-main-deps.test.ts index d33ab8cc..6baea9f6 100644 --- a/src/main/runtime/tray-main-deps.test.ts +++ b/src/main/runtime/tray-main-deps.test.ts @@ -24,7 +24,7 @@ test('tray main deps builders return mapped handlers', () => { buildTrayMenuTemplateRuntime: () => [{ label: 'tray' }] as never, initializeOverlayRuntime: () => calls.push('init'), isOverlayRuntimeInitialized: () => false, - setVisibleOverlayVisible: (visible) => calls.push(`visible:${visible}`), + openSessionHelpModal: () => calls.push('help'), showFirstRunSetup: () => true, openFirstRunSetupWindow: () => calls.push('setup'), showWindowsMpvLauncherSetup: () => true, @@ -36,7 +36,7 @@ test('tray main deps builders return mapped handlers', () => { })(); const template = menuDeps.buildTrayMenuTemplateRuntime({ - openOverlay: () => calls.push('open-overlay'), + openSessionHelp: () => calls.push('open-help'), openFirstRunSetup: () => calls.push('open-setup'), showFirstRunSetup: true, openWindowsMpvLauncherSetup: () => calls.push('open-windows-mpv'), diff --git a/src/main/runtime/tray-main-deps.ts b/src/main/runtime/tray-main-deps.ts index 57e601b0..9ad9408b 100644 --- a/src/main/runtime/tray-main-deps.ts +++ b/src/main/runtime/tray-main-deps.ts @@ -27,7 +27,7 @@ export function createBuildResolveTrayIconPathMainDepsHandler(deps: { export function createBuildTrayMenuTemplateMainDepsHandler(deps: { buildTrayMenuTemplateRuntime: (handlers: { - openOverlay: () => void; + openSessionHelp: () => void; openFirstRunSetup: () => void; showFirstRunSetup: boolean; openWindowsMpvLauncherSetup: () => void; @@ -40,7 +40,7 @@ export function createBuildTrayMenuTemplateMainDepsHandler(deps: { }) => TMenuItem[]; initializeOverlayRuntime: () => void; isOverlayRuntimeInitialized: () => boolean; - setVisibleOverlayVisible: (visible: boolean) => void; + openSessionHelpModal: () => void; showFirstRunSetup: () => boolean; openFirstRunSetupWindow: () => void; showWindowsMpvLauncherSetup: () => boolean; @@ -54,7 +54,7 @@ export function createBuildTrayMenuTemplateMainDepsHandler(deps: { buildTrayMenuTemplateRuntime: deps.buildTrayMenuTemplateRuntime, initializeOverlayRuntime: deps.initializeOverlayRuntime, isOverlayRuntimeInitialized: deps.isOverlayRuntimeInitialized, - setVisibleOverlayVisible: deps.setVisibleOverlayVisible, + openSessionHelpModal: deps.openSessionHelpModal, showFirstRunSetup: deps.showFirstRunSetup, openFirstRunSetupWindow: deps.openFirstRunSetupWindow, showWindowsMpvLauncherSetup: deps.showWindowsMpvLauncherSetup, diff --git a/src/main/runtime/tray-runtime-handlers.test.ts b/src/main/runtime/tray-runtime-handlers.test.ts index 16c1cc3b..407b6178 100644 --- a/src/main/runtime/tray-runtime-handlers.test.ts +++ b/src/main/runtime/tray-runtime-handlers.test.ts @@ -19,14 +19,12 @@ test('tray runtime handlers compose resolve/menu/ensure/destroy handlers', () => fileExists: () => true, }, buildTrayMenuTemplateDeps: { - buildTrayMenuTemplateRuntime: () => [{ label: 'Open Overlay' }], + buildTrayMenuTemplateRuntime: () => [{ label: 'Open Help' }], initializeOverlayRuntime: () => { overlayInitialized = true; }, isOverlayRuntimeInitialized: () => overlayInitialized, - setVisibleOverlayVisible: (visible) => { - visibleOverlay = visible; - }, + openSessionHelpModal: () => {}, showFirstRunSetup: () => true, openFirstRunSetupWindow: () => {}, showWindowsMpvLauncherSetup: () => true, @@ -88,7 +86,7 @@ test('tray runtime handlers compose resolve/menu/ensure/destroy handlers', () => }); assert.equal(runtime.resolveTrayIconPath(), '/tmp/SubMiner.png'); - assert.deepEqual(runtime.buildTrayMenu(), { template: [{ label: 'Open Overlay' }] }); + assert.deepEqual(runtime.buildTrayMenu(), { template: [{ label: 'Open Help' }] }); runtime.ensureTray(); assert.equal(overlayInitialized, true); assert.equal(visibleOverlay, true); diff --git a/src/main/runtime/tray-runtime.test.ts b/src/main/runtime/tray-runtime.test.ts index f25ab59a..5b972264 100644 --- a/src/main/runtime/tray-runtime.test.ts +++ b/src/main/runtime/tray-runtime.test.ts @@ -29,7 +29,7 @@ test('resolve tray icon returns null when no asset exists', () => { test('tray menu template contains expected entries and handlers', () => { const calls: string[] = []; const template = buildTrayMenuTemplateRuntime({ - openOverlay: () => calls.push('overlay'), + openSessionHelp: () => calls.push('help'), openFirstRunSetup: () => calls.push('setup'), showFirstRunSetup: true, openWindowsMpvLauncherSetup: () => calls.push('windows-mpv'), @@ -42,15 +42,17 @@ test('tray menu template contains expected entries and handlers', () => { }); assert.equal(template.length, 9); + assert.equal(template.some((entry) => entry.label === 'Open Overlay'), false); + assert.equal(template[0]!.label, 'Open Help'); template[0]!.click?.(); template[7]!.type === 'separator' ? calls.push('separator') : calls.push('bad'); template[8]!.click?.(); - assert.deepEqual(calls, ['overlay', 'separator', 'quit']); + assert.deepEqual(calls, ['help', 'separator', 'quit']); }); test('tray menu template omits first-run setup entry when setup is complete', () => { const labels = buildTrayMenuTemplateRuntime({ - openOverlay: () => undefined, + openSessionHelp: () => undefined, openFirstRunSetup: () => undefined, showFirstRunSetup: false, openWindowsMpvLauncherSetup: () => undefined, diff --git a/src/main/runtime/tray-runtime.ts b/src/main/runtime/tray-runtime.ts index f6b3ec89..083f3035 100644 --- a/src/main/runtime/tray-runtime.ts +++ b/src/main/runtime/tray-runtime.ts @@ -30,7 +30,7 @@ export function resolveTrayIconPathRuntime(deps: { } export type TrayMenuActionHandlers = { - openOverlay: () => void; + openSessionHelp: () => void; openFirstRunSetup: () => void; showFirstRunSetup: boolean; openWindowsMpvLauncherSetup: () => void; @@ -49,8 +49,8 @@ export function buildTrayMenuTemplateRuntime(handlers: TrayMenuActionHandlers): }> { return [ { - label: 'Open Overlay', - click: handlers.openOverlay, + label: 'Open Help', + click: handlers.openSessionHelp, }, ...(handlers.showFirstRunSetup ? [