fb13457f6f
CI / Supply-chain scan (push) Has been cancelled
Docker Build, Test, and Publish / Detect affected areas (push) Has been cancelled
auto-fix lint issues & formatting / Generate eslint --fix patch (push) Has been cancelled
Nix flake check / Detect affected areas (push) Has been cancelled
Deploy Site / deploy-vercel (push) Has been cancelled
Deploy Site / deploy-docs (push) Has been cancelled
CI / Detect affected areas (push) Has been cancelled
Docker Build, Test, and Publish / build (amd64, type=gha,scope=docker-amd64, type=gha,mode=max,scope=docker-amd64, linux/amd64, ubuntu-latest-32-core) (push) Has been cancelled
CI / Desktop E2E (push) Has been cancelled
CI / Docs Site (push) Has been cancelled
CI / Deny unrelated histories (push) Has been cancelled
CI / Check contributors (push) Has been cancelled
Docker Build, Test, and Publish / build (arm64, type=gha,scope=docker-arm64, type=gha,mode=max,scope=docker-arm64, linux/arm64, ubuntu-latest-32-arm-core) (push) Has been cancelled
CI / Check uv.lock (push) Has been cancelled
CI / Check no committed infographics (push) Has been cancelled
CI / Profile artifact check (push) Has been cancelled
Docker Build, Test, and Publish / publish (amd64, type=gha,scope=docker-amd64, type=gha,mode=max,scope=docker-amd64, linux/amd64, ubuntu-latest-32-core) (push) Has been cancelled
Docker Build, Test, and Publish / publish (arm64, type=gha,scope=docker-arm64, type=gha,mode=max,scope=docker-arm64, linux/arm64, ubuntu-latest-32-arm-core) (push) Has been cancelled
Docker Build, Test, and Publish / merge (push) Has been cancelled
auto-fix lint issues & formatting / Apply patch (push) Has been cancelled
CI / Check no case-colliding filenames (push) Has been cancelled
CI / package-lock.json diff (push) Has been cancelled
CI / Lint Docker scripts (push) Has been cancelled
CI / Review label gate (push) Has been cancelled
CI / All required checks pass (push) Has been cancelled
CI / CI timing report (push) Has been cancelled
CI / Python tests (push) Has been cancelled
CI / OS-specific tests (push) Has been cancelled
CI / Python lints (push) Has been cancelled
CI / JS & TS checks (push) Has been cancelled
CI / Installer tests (push) Has been cancelled
CI / Rust tests (push) Has been cancelled
Nix flake check / nix flake check (push) Has been cancelled
65 lines
2.5 KiB
JavaScript
65 lines
2.5 KiB
JavaScript
// macOS reads the Dock label from the launched .app bundle. Patching the stock
|
|
// Electron.app plist alone still leaves the running tile named "Electron", so
|
|
// launch a branded copy while keeping node_modules/electron's original intact.
|
|
import { execFileSync } from 'node:child_process'
|
|
import { constants, cpSync, existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from 'node:fs'
|
|
import path from 'node:path'
|
|
import { fileURLToPath } from 'node:url'
|
|
|
|
const DISPLAY_NAME = 'DeepWork'
|
|
const BUNDLE_ID = 'com.nousresearch.hermes.dev'
|
|
const CACHE_FORMAT = '3'
|
|
const BUDDY = '/usr/libexec/PlistBuddy'
|
|
const DESKTOP_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')
|
|
|
|
function plistValue(plist, key) {
|
|
return execFileSync(BUDDY, ['-c', `Print :${key}`, plist], { encoding: 'utf8' }).trim()
|
|
}
|
|
|
|
function setPlistValue(plist, key, value) {
|
|
execFileSync(BUDDY, ['-c', `Set :${key} ${value}`, plist], { stdio: 'ignore' })
|
|
}
|
|
|
|
export function prepareBrandedElectron({
|
|
electronDist = path.join(DESKTOP_ROOT, 'node_modules/electron/dist'),
|
|
cacheRoot = path.join(DESKTOP_ROOT, 'node_modules/.cache/hermes-desktop')
|
|
} = {}) {
|
|
const source = path.join(electronDist, 'Electron.app')
|
|
const sourcePlist = path.join(source, 'Contents/Info.plist')
|
|
const version = plistValue(sourcePlist, 'CFBundleShortVersionString')
|
|
const versionRoot = path.join(cacheRoot, version)
|
|
const branded = path.join(versionRoot, `${DISPLAY_NAME}.app`)
|
|
const binary = path.join(branded, 'Contents/MacOS/Electron')
|
|
const marker = path.join(branded, '.hermes-electron-version')
|
|
const cacheKey = `${version}:${CACHE_FORMAT}`
|
|
|
|
if (existsSync(binary) && existsSync(marker) && readFileSync(marker, 'utf8') === cacheKey) {
|
|
return binary
|
|
}
|
|
|
|
mkdirSync(versionRoot, { recursive: true })
|
|
|
|
const temporary = path.join(versionRoot, `${DISPLAY_NAME}.app.tmp-${process.pid}`)
|
|
|
|
rmSync(temporary, { recursive: true, force: true })
|
|
|
|
try {
|
|
cpSync(source, temporary, { recursive: true, mode: constants.COPYFILE_FICLONE, verbatimSymlinks: true })
|
|
|
|
const plist = path.join(temporary, 'Contents/Info.plist')
|
|
|
|
setPlistValue(plist, 'CFBundleName', DISPLAY_NAME)
|
|
setPlistValue(plist, 'CFBundleDisplayName', DISPLAY_NAME)
|
|
setPlistValue(plist, 'CFBundleIdentifier', BUNDLE_ID)
|
|
writeFileSync(path.join(temporary, '.hermes-electron-version'), cacheKey)
|
|
|
|
rmSync(branded, { recursive: true, force: true })
|
|
renameSync(temporary, branded)
|
|
} catch (error) {
|
|
rmSync(temporary, { recursive: true, force: true })
|
|
throw error
|
|
}
|
|
|
|
return binary
|
|
}
|