Two related defects were breaking the 'open file' flow:
1. The BrowserWindow webPreferences had no preload path AND
contextIsolation: false, so contextBridge.exposeInMainWorld
threw on load and window.electronAPI was never set. Result:
every renderer-side ipc.* call returned CHANNEL_MISSING and
silently no-op'd. Toolbar Open/Save, the file menu, every
dialog — all broken.
2. The 'file.opened' IPC bridge in register-menu-commands.ts
dispatched to a 'file.opened' command that was never registered
as a handler. Even if the preload had worked, the main menu's
File -> Open would have been a no-op once it reached the
command store.
Fixes:
- window/index.js: add preload path; set contextIsolation: true
(required for contextBridge) and nodeIntegration: false
(renderer no longer needs direct Node access; everything goes
through the whitelisted preload bridge).
- file-store.ts: add openFileFromMain(path, content) that opens
a tab + editor buffer from content the main process already read
(skips the renderer's ipc.file.read since main has the bytes).
Preserves existing buffer content if the file is already open.
- register-menu-commands.ts: register 'file.opened' to call
openFileFromMain. Drop the dead 'command.palette' bridge
(no consumer, no UI, no handler).
- tests: two new cases for openFileFromMain — verifies it does
not call ipc.file.read and does not clobber user edits on
re-open.
Verified end-to-end via the run-desktop driver: triggering
file-opened from the main process with a test .md now shows the
content in BOTH the CodeMirror editor and the rendered preview
pane (plus the Outline panel picks up the H1). 497 tests pass.
Adds the actual right-alignment heuristic to toAsciiTable (was missing
from initial implementation). When any column header starts with a digit,
all columns are right-padded instead of left-padded. Matches the test
added in 53870d5 which exercises the right-alignment path with header
['Item', '7'].
All 6 ascii-table tests pass.
- useRegisterMenuCommands: registers file.open, file.save, file.closeTab,
tab.next, tab.prev, view.toggleSidebar, view.togglePreview in command store
- useBridgeNativeMenu: useMenuAction for 13 native-menu channels
(file-save, toggle-preview, load-template-menu, etc.)
- AppShell calls both on mount
- integration test mock extended to include ipc.menu.on
- 145/145 tests pass (was 105)
- bridge between main-process menu events and the command dispatcher
- optional transform: convert raw IPC payload to command args
- extends ipc.ts with ipc.menu.on() helper
- TDD: 5 unit tests covering subscription, payload transform, no-op, unmount