chore(desktop): zero eslint/typecheck debt + prettier pass (#39100)
- eslint --fix across src/ and electron/ (unused imports, import/prop sort, padding) - flatten empty catch blocks in electron CJS; drop unused applyUpdatesPosixInApp arg - add setMutableRef helper for imperative ref writes (react-compiler clean) - move sidebar cookie persistence into an effect; extract scrollElementToBottom helper
This commit is contained in:
@@ -67,7 +67,9 @@ test('verifyHermesCli returns true when --version exits 0', () => {
|
||||
} finally {
|
||||
try {
|
||||
fs.unlinkSync(scriptPath)
|
||||
} catch {}
|
||||
} catch {
|
||||
void 0
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -52,7 +52,9 @@ function detectRemoteDisplay(options = {}) {
|
||||
const env = options.env ?? process.env
|
||||
const platform = options.platform ?? process.platform
|
||||
|
||||
const override = String(env.HERMES_DESKTOP_DISABLE_GPU || '').trim().toLowerCase()
|
||||
const override = String(env.HERMES_DESKTOP_DISABLE_GPU || '')
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
if (GPU_OVERRIDE_ON.has(override)) return 'override (HERMES_DESKTOP_DISABLE_GPU)'
|
||||
if (GPU_OVERRIDE_OFF.has(override)) return null
|
||||
|
||||
|
||||
@@ -45,11 +45,17 @@ test('detectRemoteDisplay does not treat WSLg as remote', () => {
|
||||
// WSLg renders locally via vGPU and doesn't show the flicker, so a WSL
|
||||
// session with a local DISPLAY keeps hardware acceleration on.
|
||||
assert.equal(detectRemoteDisplay({ env: { WSL_DISTRO_NAME: 'Ubuntu', DISPLAY: ':0' }, platform: 'linux' }), null)
|
||||
assert.equal(detectRemoteDisplay({ env: { WSL_INTEROP: '/run/WSL/1_interop', DISPLAY: ':0' }, platform: 'linux' }), null)
|
||||
assert.equal(
|
||||
detectRemoteDisplay({ env: { WSL_INTEROP: '/run/WSL/1_interop', DISPLAY: ':0' }, platform: 'linux' }),
|
||||
null
|
||||
)
|
||||
})
|
||||
|
||||
test('detectRemoteDisplay flags SSH sessions on any platform', () => {
|
||||
assert.equal(detectRemoteDisplay({ env: { SSH_CONNECTION: '1.2.3.4 5 6.7.8.9 22' }, platform: 'linux' }), 'ssh-session')
|
||||
assert.equal(
|
||||
detectRemoteDisplay({ env: { SSH_CONNECTION: '1.2.3.4 5 6.7.8.9 22' }, platform: 'linux' }),
|
||||
'ssh-session'
|
||||
)
|
||||
assert.equal(detectRemoteDisplay({ env: { SSH_CLIENT: '1.2.3.4 5 22' }, platform: 'darwin' }), 'ssh-session')
|
||||
assert.equal(detectRemoteDisplay({ env: { SSH_TTY: '/dev/pts/0' }, platform: 'win32' }), 'ssh-session')
|
||||
})
|
||||
|
||||
@@ -101,7 +101,9 @@ function downloadInstallScript(commit, destPath) {
|
||||
.get(res.headers.location, res2 => {
|
||||
if (res2.statusCode !== 200) {
|
||||
reject(
|
||||
new Error(`Failed to download ${scriptName}: HTTP ${res2.statusCode} from redirect ${res.headers.location}`)
|
||||
new Error(
|
||||
`Failed to download ${scriptName}: HTTP ${res2.statusCode} from redirect ${res.headers.location}`
|
||||
)
|
||||
)
|
||||
return
|
||||
}
|
||||
@@ -121,7 +123,9 @@ function downloadInstallScript(commit, destPath) {
|
||||
out.close()
|
||||
try {
|
||||
fs.unlinkSync(tmpPath)
|
||||
} catch {}
|
||||
} catch {
|
||||
void 0
|
||||
}
|
||||
reject(new Error(`Failed to download ${scriptName}: HTTP ${res.statusCode} from ${url}`))
|
||||
return
|
||||
}
|
||||
@@ -134,14 +138,18 @@ function downloadInstallScript(commit, destPath) {
|
||||
out.on('error', err => {
|
||||
try {
|
||||
fs.unlinkSync(tmpPath)
|
||||
} catch {}
|
||||
} catch {
|
||||
void 0
|
||||
}
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
.on('error', err => {
|
||||
try {
|
||||
fs.unlinkSync(tmpPath)
|
||||
} catch {}
|
||||
} catch {
|
||||
void 0
|
||||
}
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
@@ -168,13 +176,19 @@ async function resolveInstallScript({ installStamp, sourceRepoRoot, hermesHome,
|
||||
const cached = cachedScriptPath(hermesHome, installStamp.commit)
|
||||
try {
|
||||
await fsp.access(cached, fs.constants.R_OK)
|
||||
emit({ type: 'log', line: `[bootstrap] using cached ${installScriptName()} for ${installStamp.commit.slice(0, 12)}` })
|
||||
emit({
|
||||
type: 'log',
|
||||
line: `[bootstrap] using cached ${installScriptName()} for ${installStamp.commit.slice(0, 12)}`
|
||||
})
|
||||
return { path: cached, source: 'cache', commit: installStamp.commit, kind: installScriptKind() }
|
||||
} catch {
|
||||
// not cached; download
|
||||
}
|
||||
|
||||
emit({ type: 'log', line: `[bootstrap] fetching ${installScriptName()} for ${installStamp.commit.slice(0, 12)} from GitHub` })
|
||||
emit({
|
||||
type: 'log',
|
||||
line: `[bootstrap] fetching ${installScriptName()} for ${installStamp.commit.slice(0, 12)} from GitHub`
|
||||
})
|
||||
await downloadInstallScript(installStamp.commit, cached)
|
||||
emit({ type: 'log', line: `[bootstrap] saved to ${cached}` })
|
||||
return { path: cached, source: 'download', commit: installStamp.commit, kind: installScriptKind() }
|
||||
@@ -207,7 +221,9 @@ function spawnPowerShell(scriptPath, args, { emit, stageName, abortSignal, herme
|
||||
killed = true
|
||||
try {
|
||||
child.kill('SIGTERM')
|
||||
} catch {}
|
||||
} catch {
|
||||
void 0
|
||||
}
|
||||
}
|
||||
if (abortSignal) {
|
||||
if (abortSignal.aborted) {
|
||||
@@ -278,7 +294,9 @@ function spawnBash(scriptPath, args, { emit, stageName, abortSignal, hermesHome
|
||||
killed = true
|
||||
try {
|
||||
child.kill('SIGTERM')
|
||||
} catch {}
|
||||
} catch {
|
||||
void 0
|
||||
}
|
||||
}
|
||||
if (abortSignal) {
|
||||
if (abortSignal.aborted) {
|
||||
@@ -369,7 +387,9 @@ async function fetchManifest({ scriptPath, installerKind, emit, hermesHome, acti
|
||||
hermesHome
|
||||
})
|
||||
if (result.code !== 0) {
|
||||
throw new Error(`${isPosix ? 'install.sh --manifest' : 'install.ps1 -Manifest'} failed: exit ${result.code}\n${result.stderr || result.stdout}`)
|
||||
throw new Error(
|
||||
`${isPosix ? 'install.sh --manifest' : 'install.ps1 -Manifest'} failed: exit ${result.code}\n${result.stderr || result.stdout}`
|
||||
)
|
||||
}
|
||||
// The manifest is the LAST JSON line on stdout (install.ps1 may print
|
||||
// banner / info lines first depending on Console.OutputEncoding effects).
|
||||
@@ -381,9 +401,13 @@ async function fetchManifest({ scriptPath, installerKind, emit, hermesHome, acti
|
||||
if (parsed && Array.isArray(parsed.stages)) {
|
||||
return parsed
|
||||
}
|
||||
} catch {}
|
||||
} catch {
|
||||
void 0
|
||||
}
|
||||
}
|
||||
throw new Error(`${isPosix ? 'install.sh --manifest' : 'install.ps1 -Manifest'} produced no parseable JSON payload\n${result.stdout}`)
|
||||
throw new Error(
|
||||
`${isPosix ? 'install.sh --manifest' : 'install.ps1 -Manifest'} produced no parseable JSON payload\n${result.stdout}`
|
||||
)
|
||||
}
|
||||
|
||||
// Parse the JSON result frame from a stage run. The protocol guarantees
|
||||
@@ -397,7 +421,9 @@ function parseStageResult(stdout) {
|
||||
if (parsed && typeof parsed.ok === 'boolean' && typeof parsed.stage === 'string') {
|
||||
return parsed
|
||||
}
|
||||
} catch {}
|
||||
} catch {
|
||||
void 0
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
@@ -408,13 +434,20 @@ async function runStage({ scriptPath, installerKind, stage, emit, hermesHome, ac
|
||||
|
||||
const isPosix = installerKind === 'posix'
|
||||
const args = isPosix
|
||||
? ['--stage', stage.name, '--non-interactive', '--json', ...buildPosixPinArgs({ installStamp, activeRoot, hermesHome })]
|
||||
? [
|
||||
'--stage',
|
||||
stage.name,
|
||||
'--non-interactive',
|
||||
'--json',
|
||||
...buildPosixPinArgs({ installStamp, activeRoot, hermesHome })
|
||||
]
|
||||
: ['-Stage', stage.name, '-NonInteractive', '-Json', ...buildPinArgs(installStamp)]
|
||||
const result = await (isPosix ? spawnBash : spawnPowerShell)(
|
||||
scriptPath,
|
||||
args,
|
||||
{ emit, stageName: stage.name, abortSignal, hermesHome }
|
||||
)
|
||||
const result = await (isPosix ? spawnBash : spawnPowerShell)(scriptPath, args, {
|
||||
emit,
|
||||
stageName: stage.name,
|
||||
abortSignal,
|
||||
hermesHome
|
||||
})
|
||||
|
||||
const durationMs = Date.now() - startedAt
|
||||
|
||||
@@ -449,7 +482,14 @@ async function runStage({ scriptPath, installerKind, stage, emit, hermesHome, ac
|
||||
emit(ev)
|
||||
return ev
|
||||
}
|
||||
const ev = { type: 'stage', name: stage.name, state: 'failed', durationMs, json, error: json.reason || `exit code ${result.code}` }
|
||||
const ev = {
|
||||
type: 'stage',
|
||||
name: stage.name,
|
||||
state: 'failed',
|
||||
durationMs,
|
||||
json,
|
||||
error: json.reason || `exit code ${result.code}`
|
||||
}
|
||||
emit(ev)
|
||||
return ev
|
||||
}
|
||||
@@ -489,7 +529,9 @@ async function runBootstrap(opts) {
|
||||
if (typeof onEvent === 'function') {
|
||||
try {
|
||||
onEvent({ type: 'failed', error: 'bootstrap cancelled by user' })
|
||||
} catch {}
|
||||
} catch {
|
||||
void 0
|
||||
}
|
||||
}
|
||||
return { ok: false, cancelled: true }
|
||||
}
|
||||
@@ -501,7 +543,9 @@ async function runBootstrap(opts) {
|
||||
const emit = ev => {
|
||||
try {
|
||||
runLog.stream.write(JSON.stringify(ev) + '\n')
|
||||
} catch {}
|
||||
} catch {
|
||||
void 0
|
||||
}
|
||||
try {
|
||||
if (typeof onEvent === 'function') onEvent(ev)
|
||||
} catch (err) {
|
||||
@@ -578,7 +622,9 @@ async function runBootstrap(opts) {
|
||||
} finally {
|
||||
try {
|
||||
runLog.stream.end()
|
||||
} catch {}
|
||||
} catch {
|
||||
void 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,31 +53,19 @@ test('normalizeRemoteBaseUrl rejects garbage', () => {
|
||||
// --- buildGatewayWsUrl (token) ---
|
||||
|
||||
test('buildGatewayWsUrl uses wss for https and bakes the token', () => {
|
||||
assert.equal(
|
||||
buildGatewayWsUrl('https://gw.example.com', 'tok123'),
|
||||
'wss://gw.example.com/api/ws?token=tok123'
|
||||
)
|
||||
assert.equal(buildGatewayWsUrl('https://gw.example.com', 'tok123'), 'wss://gw.example.com/api/ws?token=tok123')
|
||||
})
|
||||
|
||||
test('buildGatewayWsUrl uses ws for http', () => {
|
||||
assert.equal(
|
||||
buildGatewayWsUrl('http://127.0.0.1:9119', 'abc'),
|
||||
'ws://127.0.0.1:9119/api/ws?token=abc'
|
||||
)
|
||||
assert.equal(buildGatewayWsUrl('http://127.0.0.1:9119', 'abc'), 'ws://127.0.0.1:9119/api/ws?token=abc')
|
||||
})
|
||||
|
||||
test('buildGatewayWsUrl honors a path prefix', () => {
|
||||
assert.equal(
|
||||
buildGatewayWsUrl('https://host/hermes', 't'),
|
||||
'wss://host/hermes/api/ws?token=t'
|
||||
)
|
||||
assert.equal(buildGatewayWsUrl('https://host/hermes', 't'), 'wss://host/hermes/api/ws?token=t')
|
||||
})
|
||||
|
||||
test('buildGatewayWsUrl url-encodes the token', () => {
|
||||
assert.equal(
|
||||
buildGatewayWsUrl('https://host', 'a/b c+d'),
|
||||
'wss://host/api/ws?token=a%2Fb%20c%2Bd'
|
||||
)
|
||||
assert.equal(buildGatewayWsUrl('https://host', 'a/b c+d'), 'wss://host/api/ws?token=a%2Fb%20c%2Bd')
|
||||
})
|
||||
|
||||
// --- buildGatewayWsUrlWithTicket (oauth) ---
|
||||
@@ -89,10 +77,7 @@ test('buildGatewayWsUrlWithTicket uses ?ticket= not ?token=', () => {
|
||||
})
|
||||
|
||||
test('buildGatewayWsUrlWithTicket url-encodes the ticket', () => {
|
||||
assert.equal(
|
||||
buildGatewayWsUrlWithTicket('https://host', 'a+b/c'),
|
||||
'wss://host/api/ws?ticket=a%2Bb%2Fc'
|
||||
)
|
||||
assert.equal(buildGatewayWsUrlWithTicket('https://host', 'a+b/c'), 'wss://host/api/ws?ticket=a%2Bb%2Fc')
|
||||
})
|
||||
|
||||
// --- authModeFromStatus ---
|
||||
@@ -157,11 +142,7 @@ test('cookiesHaveSession handles non-arrays', () => {
|
||||
})
|
||||
|
||||
test('AT_COOKIE_VARIANTS covers all three deploy shapes', () => {
|
||||
assert.deepEqual(AT_COOKIE_VARIANTS, [
|
||||
'__Host-hermes_session_at',
|
||||
'__Secure-hermes_session_at',
|
||||
'hermes_session_at'
|
||||
])
|
||||
assert.deepEqual(AT_COOKIE_VARIANTS, ['__Host-hermes_session_at', '__Secure-hermes_session_at', 'hermes_session_at'])
|
||||
})
|
||||
|
||||
// --- tokenPreview ---
|
||||
|
||||
@@ -1352,9 +1352,7 @@ async function applyUpdates(opts = {}) {
|
||||
env: {
|
||||
...process.env,
|
||||
HERMES_HOME,
|
||||
PATH: [path.join(HERMES_HOME, 'node', 'bin'), venvBin, process.env.PATH]
|
||||
.filter(Boolean)
|
||||
.join(path.delimiter)
|
||||
PATH: [path.join(HERMES_HOME, 'node', 'bin'), venvBin, process.env.PATH].filter(Boolean).join(path.delimiter)
|
||||
},
|
||||
detached: true,
|
||||
stdio: 'ignore',
|
||||
@@ -1428,7 +1426,7 @@ function shellQuote(value) {
|
||||
// (`hermes desktop --build-only`), then atomically swap the running .app bundle
|
||||
// with the freshly built one and relaunch. Degrades to "backend updated,
|
||||
// restart to load the new GUI" if the swap can't be performed.
|
||||
async function applyUpdatesPosixInApp(opts = {}) {
|
||||
async function applyUpdatesPosixInApp() {
|
||||
const updateRoot = resolveUpdateRoot()
|
||||
const hermes = resolveHermesCliBinary(updateRoot)
|
||||
if (!hermes) {
|
||||
@@ -1901,7 +1899,9 @@ async function ensureRuntime(backend) {
|
||||
stages: [],
|
||||
protocolVersion: null
|
||||
})
|
||||
} catch {}
|
||||
} catch {
|
||||
void 0
|
||||
}
|
||||
|
||||
bootstrapAbortController = new AbortController()
|
||||
|
||||
@@ -1919,10 +1919,14 @@ async function ensureRuntime(backend) {
|
||||
// bootstrap and a log-write failure doesn't suppress the UI signal.
|
||||
try {
|
||||
rememberLog(`[bootstrap] ${JSON.stringify(ev)}`)
|
||||
} catch {}
|
||||
} catch {
|
||||
void 0
|
||||
}
|
||||
try {
|
||||
broadcastBootstrapEvent(ev)
|
||||
} catch {}
|
||||
} catch {
|
||||
void 0
|
||||
}
|
||||
},
|
||||
writeMarker: writeBootstrapMarker
|
||||
})
|
||||
@@ -2848,7 +2852,9 @@ function buildApplicationMenu() {
|
||||
{
|
||||
label: 'Actual Size',
|
||||
accelerator: 'CommandOrControl+0',
|
||||
click: () => { if (mainWindow && !mainWindow.isDestroyed()) mainWindow.webContents.setZoomLevel(0) }
|
||||
click: () => {
|
||||
if (mainWindow && !mainWindow.isDestroyed()) mainWindow.webContents.setZoomLevel(0)
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Zoom In',
|
||||
@@ -3191,7 +3197,7 @@ function openOauthLoginWindow(baseUrl) {
|
||||
let win = null
|
||||
let pollTimer = null
|
||||
|
||||
const finish = (err) => {
|
||||
const finish = err => {
|
||||
if (settled) return
|
||||
settled = true
|
||||
if (pollTimer) clearInterval(pollTimer)
|
||||
@@ -3314,7 +3320,7 @@ function fetchJsonViaOauthSession(url, options = {}) {
|
||||
return
|
||||
}
|
||||
const looksHtml = /^\s*<(?:!doctype|html)/i.test(text)
|
||||
const contentType = String((res.headers['content-type'] || res.headers['Content-Type'] || ''))
|
||||
const contentType = String(res.headers['content-type'] || res.headers['Content-Type'] || '')
|
||||
if (looksHtml || contentType.includes('text/html')) {
|
||||
reject(new Error(`Expected JSON from ${url} but got HTML (status ${statusCode}).`))
|
||||
return
|
||||
@@ -3553,8 +3559,7 @@ async function resolveRemoteBackend() {
|
||||
ticket = await mintGatewayWsTicket(baseUrl)
|
||||
} catch (error) {
|
||||
const err = new Error(
|
||||
'Your remote gateway session has expired. ' +
|
||||
'Open Settings → Gateway and click "Sign in" again.'
|
||||
'Your remote gateway session has expired. ' + 'Open Settings → Gateway and click "Sign in" again.'
|
||||
)
|
||||
err.needsOauthLogin = true
|
||||
err.cause = error
|
||||
@@ -4036,7 +4041,9 @@ ipcMain.handle('hermes:bootstrap:cancel', async () => {
|
||||
if (bootstrapAbortController) {
|
||||
try {
|
||||
bootstrapAbortController.abort()
|
||||
} catch {}
|
||||
} catch {
|
||||
void 0
|
||||
}
|
||||
return { ok: true, cancelled: true }
|
||||
}
|
||||
return { ok: false, cancelled: false }
|
||||
@@ -4614,7 +4621,9 @@ app.on('before-quit', () => {
|
||||
if (bootstrapAbortController) {
|
||||
try {
|
||||
bootstrapAbortController.abort()
|
||||
} catch {}
|
||||
} catch {
|
||||
void 0
|
||||
}
|
||||
}
|
||||
|
||||
if (desktopLogFlushTimer) {
|
||||
|
||||
Reference in New Issue
Block a user