diff --git a/.github/workflows/desktop-release.yml b/.github/workflows/desktop-release.yml index 2e92703..cee7c68 100644 --- a/.github/workflows/desktop-release.yml +++ b/.github/workflows/desktop-release.yml @@ -89,6 +89,12 @@ jobs: run: npm --prefix packages/desktop run prepare:python - name: Build desktop artifact + env: + CSC_LINK: ${{ matrix.target_os == 'darwin' && secrets.MAC_CSC_LINK || '' }} + CSC_KEY_PASSWORD: ${{ matrix.target_os == 'darwin' && secrets.MAC_CSC_KEY_PASSWORD || '' }} + APPLE_ID: ${{ matrix.target_os == 'darwin' && secrets.APPLE_ID || '' }} + APPLE_APP_SPECIFIC_PASSWORD: ${{ matrix.target_os == 'darwin' && secrets.APPLE_APP_SPECIFIC_PASSWORD || '' }} + APPLE_TEAM_ID: ${{ matrix.target_os == 'darwin' && secrets.APPLE_TEAM_ID || '' }} run: npm --prefix packages/desktop run dist -- ${{ matrix.electron_target }} --publish never - name: Upload artifacts to release diff --git a/packages/client/src/api/client.ts b/packages/client/src/api/client.ts index 752e66a..029a447 100644 --- a/packages/client/src/api/client.ts +++ b/packages/client/src/api/client.ts @@ -2,8 +2,14 @@ import router from '@/router' const DEFAULT_BASE_URL = '' +function isDesktopShell(): boolean { + return typeof window !== 'undefined' && + (window as typeof window & { hermesDesktop?: { isDesktop?: boolean } }).hermesDesktop?.isDesktop === true +} + function getBaseUrl(): string { if (import.meta.env.VITE_HERMES_PREVIEW === '1') return DEFAULT_BASE_URL + if (isDesktopShell()) return DEFAULT_BASE_URL return localStorage.getItem('hermes_server_url') || DEFAULT_BASE_URL } diff --git a/packages/desktop/README.md b/packages/desktop/README.md index 6e64313..3490b05 100644 --- a/packages/desktop/README.md +++ b/packages/desktop/README.md @@ -1,6 +1,6 @@ -# Hermes Desktop +# Hermes Studio -Electron desktop distribution for Hermes Web UI. +Electron desktop distribution for Hermes Studio. ## Data directories diff --git a/packages/desktop/build/icon.icns b/packages/desktop/build/icon.icns index 99cbf26..9419e36 100644 Binary files a/packages/desktop/build/icon.icns and b/packages/desktop/build/icon.icns differ diff --git a/packages/desktop/build/icon.ico b/packages/desktop/build/icon.ico index fa879c3..89f8c3b 100644 Binary files a/packages/desktop/build/icon.ico and b/packages/desktop/build/icon.ico differ diff --git a/packages/desktop/build/icon.png b/packages/desktop/build/icon.png index 12bc95a..14c2d55 100644 Binary files a/packages/desktop/build/icon.png and b/packages/desktop/build/icon.png differ diff --git a/packages/desktop/electron-builder.yml b/packages/desktop/electron-builder.yml index 67608ed..2b3db1e 100644 --- a/packages/desktop/electron-builder.yml +++ b/packages/desktop/electron-builder.yml @@ -1,5 +1,5 @@ -appId: com.hermesagent.desktop -productName: Hermes Desktop +appId: com.hermeswebui.studio +productName: Hermes Studio copyright: Copyright © 2026 directories: @@ -45,9 +45,9 @@ mac: - target: dmg arch: [arm64, x64] category: public.app-category.developer-tools - hardenedRuntime: false + hardenedRuntime: true gatekeeperAssess: false - identity: null + notarize: true artifactName: "${productName}-${version}-${arch}.${ext}" win: diff --git a/packages/desktop/package-lock.json b/packages/desktop/package-lock.json index 282859e..c7a696f 100644 --- a/packages/desktop/package-lock.json +++ b/packages/desktop/package-lock.json @@ -1,11 +1,11 @@ { - "name": "hermes-desktop", + "name": "hermes-studio", "version": "0.6.5", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "hermes-desktop", + "name": "hermes-studio", "version": "0.6.5", "license": "MIT", "dependencies": { diff --git a/packages/desktop/package.json b/packages/desktop/package.json index 05719d2..09b6d8f 100644 --- a/packages/desktop/package.json +++ b/packages/desktop/package.json @@ -1,11 +1,11 @@ { - "name": "hermes-desktop", + "name": "hermes-studio", "version": "0.6.5", - "description": "Desktop distribution for Hermes Web UI with bundled Python runtime and hermes-agent", + "description": "Hermes Studio desktop distribution with bundled Python runtime and hermes-agent", "homepage": "https://ekkolearnai.com", "author": { - "name": "Hermes Desktop Contributors", - "email": "noreply@hermes-desktop.local" + "name": "Hermes Studio Contributors", + "email": "noreply@hermes-studio.local" }, "license": "MIT", "private": true, diff --git a/packages/desktop/scripts/install-hermes.mjs b/packages/desktop/scripts/install-hermes.mjs index 1a3d2f7..905a10f 100644 --- a/packages/desktop/scripts/install-hermes.mjs +++ b/packages/desktop/scripts/install-hermes.mjs @@ -13,6 +13,7 @@ const ROOT = resolve(__dirname, '..') const TARGET_OS = process.env.TARGET_OS || osPlatform() const TARGET_ARCH = process.env.TARGET_ARCH || osArch() const HERMES_VERSION = process.env.HERMES_VERSION || '0.15.2' +const HERMES_PACKAGE = process.env.HERMES_PACKAGE || `hermes-agent[mcp]==${HERMES_VERSION}` const OS_LABEL = TARGET_OS === 'win32' ? 'win' : TARGET_OS === 'darwin' ? 'mac' : TARGET_OS const PY_DIR = resolve(ROOT, 'resources', 'python', `${OS_LABEL}-${TARGET_ARCH}`) @@ -33,23 +34,32 @@ function hasUv() { let r if (hasUv()) { - console.log(`→ Installing hermes-agent==${HERMES_VERSION} via uv`) + console.log(`→ Installing ${HERMES_PACKAGE} via uv`) r = spawnSync('uv', [ 'pip', 'install', '--python', pyBin, - `hermes-agent==${HERMES_VERSION}`, + HERMES_PACKAGE, ], { stdio: 'inherit' }) } else { - console.log(`→ Installing hermes-agent==${HERMES_VERSION} via pip`) + console.log(`→ Installing ${HERMES_PACKAGE} via pip`) r = spawnSync(pyBin, [ '-m', 'pip', 'install', - `hermes-agent==${HERMES_VERSION}`, + HERMES_PACKAGE, '--no-warn-script-location', '--disable-pip-version-check', ], { stdio: 'inherit' }) } if (r.status !== 0) process.exit(r.status ?? 1) +r = spawnSync(pyBin, [ + '-c', + 'import mcp; import tools.mcp_tool as t; assert t._MCP_AVAILABLE', +], { stdio: 'inherit' }) +if (r.status !== 0) { + console.error('MCP Python SDK sanity check failed') + process.exit(r.status ?? 1) +} + const hermesBin = TARGET_OS === 'win32' ? resolve(PY_DIR, 'Scripts', 'hermes.exe') : resolve(PY_DIR, 'bin', 'hermes') diff --git a/packages/desktop/src/main/index.ts b/packages/desktop/src/main/index.ts index 66c6a35..03a2087 100644 --- a/packages/desktop/src/main/index.ts +++ b/packages/desktop/src/main/index.ts @@ -4,7 +4,7 @@ import { startWebUiServer, stopWebUiServer, getToken } from './webui-server' import { hermesBinExists, hermesBin } from './paths' import { initAutoUpdater } from './updater' -const PORT = Number(process.env.HERMES_DESKTOP_PORT) || 8648 +const PORT = Number(process.env.HERMES_DESKTOP_PORT) || 8748 let mainWindow: BrowserWindow | null = null let serverUrl: string | null = null @@ -15,7 +15,7 @@ function createWindow() { height: 820, minWidth: 960, minHeight: 600, - title: 'Hermes Desktop', + title: 'Hermes Studio', backgroundColor: '#1a1a1a', autoHideMenuBar: true, webPreferences: { @@ -46,7 +46,7 @@ function createWindow() { } function splashHtml(): string { - const html = `