From 9d19cfbb78d0439dbca2c83d8dc7353965a78a29 Mon Sep 17 00:00:00 2001 From: Brooklyn Nicholson Date: Tue, 30 Jun 2026 14:12:39 -0500 Subject: [PATCH] refactor(desktop): extract app-version IPC from main.cjs into version-ipc.cjs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ninth main.cjs cluster peel. The hermes:version handler moves verbatim into electron/version-ipc.cjs behind a registerVersionIpc({ ipcMain, resolveHermesVersion, resolveUpdateRoot }) registrar. The version + root resolvers stay in the main process (shared with the About menu) and are injected. Channel name unchanged → preload + renderer untouched. Adds electron/version-ipc.test.cjs (surface + payload behavior). --- apps/desktop/electron/main.cjs | 10 ++---- apps/desktop/electron/version-ipc.cjs | 17 +++++++++ apps/desktop/electron/version-ipc.test.cjs | 41 ++++++++++++++++++++++ 3 files changed, 61 insertions(+), 7 deletions(-) create mode 100644 apps/desktop/electron/version-ipc.cjs create mode 100644 apps/desktop/electron/version-ipc.test.cjs diff --git a/apps/desktop/electron/main.cjs b/apps/desktop/electron/main.cjs index 58eba7ef201..618726b259b 100644 --- a/apps/desktop/electron/main.cjs +++ b/apps/desktop/electron/main.cjs @@ -63,6 +63,7 @@ const { registerLogsIpc } = require('./logs-ipc.cjs') const { registerProjectDirIpc } = require('./project-dir-ipc.cjs') const { registerVscodeThemeIpc } = require('./vscode-theme-ipc.cjs') const { registerUninstallIpc } = require('./uninstall-ipc.cjs') +const { registerVersionIpc } = require('./version-ipc.cjs') const { OFFICIAL_REPO_HTTPS_URL, isOfficialSshRemote } = require('./update-remote.cjs') const { resolveBehindCount, shouldCountCommits } = require('./update-count.cjs') const { runRebuildWithRetry } = require('./update-rebuild.cjs') @@ -6929,13 +6930,8 @@ function showAboutPanelFresh() { app.showAboutPanel() } -ipcMain.handle('hermes:version', async () => ({ - appVersion: resolveHermesVersion(), - electronVersion: process.versions.electron, - nodeVersion: process.versions.node, - platform: process.platform, - hermesRoot: resolveUpdateRoot() -})) +// App-version IPC lives in version-ipc.cjs; the version + root resolvers are injected. +registerVersionIpc({ ipcMain, resolveHermesVersion, resolveUpdateRoot }) // =========================================================================== // Uninstall — remove the Chat GUI (and optionally the agent / user data). diff --git a/apps/desktop/electron/version-ipc.cjs b/apps/desktop/electron/version-ipc.cjs new file mode 100644 index 00000000000..01df9389627 --- /dev/null +++ b/apps/desktop/electron/version-ipc.cjs @@ -0,0 +1,17 @@ +'use strict' + +// App-version IPC: report the canonical Hermes version (resolved from the source +// tree, falling back to the Electron app version) alongside the Electron/Node +// runtime versions + the resolved Hermes root. The version + root resolvers live +// in the main process and are injected. +function registerVersionIpc({ ipcMain, resolveHermesVersion, resolveUpdateRoot }) { + ipcMain.handle('hermes:version', async () => ({ + appVersion: resolveHermesVersion(), + electronVersion: process.versions.electron, + nodeVersion: process.versions.node, + platform: process.platform, + hermesRoot: resolveUpdateRoot() + })) +} + +module.exports = { registerVersionIpc } diff --git a/apps/desktop/electron/version-ipc.test.cjs b/apps/desktop/electron/version-ipc.test.cjs new file mode 100644 index 00000000000..d1203900e6b --- /dev/null +++ b/apps/desktop/electron/version-ipc.test.cjs @@ -0,0 +1,41 @@ +'use strict' + +const assert = require('node:assert/strict') +const test = require('node:test') + +const { registerVersionIpc } = require('./version-ipc.cjs') + +function fakeIpcMain() { + const handlers = new Map() + + return { + handlers, + handle(channel, handler) { + assert.ok(!handlers.has(channel), `duplicate registration for ${channel}`) + handlers.set(channel, handler) + } + } +} + +test('registerVersionIpc wires hermes:version to a handler fn', () => { + const ipcMain = fakeIpcMain() + + registerVersionIpc({ ipcMain, resolveHermesVersion: () => '1.2.3', resolveUpdateRoot: () => '/root' }) + + assert.deepEqual([...ipcMain.handlers.keys()], ['hermes:version']) + assert.equal(typeof ipcMain.handlers.get('hermes:version'), 'function') +}) + +test('version reports the resolved Hermes version + root alongside runtime versions', async () => { + const ipcMain = fakeIpcMain() + + registerVersionIpc({ ipcMain, resolveHermesVersion: () => '1.2.3', resolveUpdateRoot: () => '/root' }) + + const res = await ipcMain.handlers.get('hermes:version')({}) + + assert.equal(res.appVersion, '1.2.3') + assert.equal(res.hermesRoot, '/root') + assert.equal(res.electronVersion, process.versions.electron) + assert.equal(res.nodeVersion, process.versions.node) + assert.equal(res.platform, process.platform) +})