revert(desktop): remove the BETA gate — ship Hermes Cloud selector by default

Reverts the beta gating from 34d7d3f. The Hermes Cloud ModeCard in
Settings → Gateway now renders unconditionally alongside Local and Remote;
no BETA env var is consulted.

Not a clean `git revert`: commit 1b54d38 (the org-persist / stale-closure
fix) landed after the beta commit and edited the same useState block in
gateway-settings.tsx, so the revert conflicted there. Resolved by keeping
1b54d38's cloudOrgRef/setCloudOrg wrapper and dropping only the
cloudBetaEnabled state + its betaEnabled() useEffect. Everything else
(the sm:grid-cols-3 grid, the unconditional ModeCard, main.cjs/preload.cjs/
global.d.ts beta IPC) reverted automatically.

- main.cjs: drop betaFeaturesEnabled() + hermes☁️beta-enabled IPC
- preload.cjs / global.d.ts: drop the cloud.betaEnabled() bridge + type
- gateway-settings.tsx: drop the beta fetch/state; ModeCard renders
  unconditionally; grid back to sm:grid-cols-3

No test referenced the flag, so no test fallout. tsc clean; eslint clean on
all touched files.
This commit is contained in:
Ben 2026-07-08 10:07:14 +10:00
parent 1b54d38e75
commit c83f85abe6
4 changed files with 9 additions and 53 deletions

View file

@ -6628,17 +6628,6 @@ ipcMain.handle('hermes:cloud:status', async () => ({
portalBaseUrl: resolvePortalBaseUrl(),
signedIn: await hasLivePortalSession()
}))
// Whether the Hermes Cloud gateway selector is enabled — gated behind a BETA
// env flag while the feature is in beta. Truthy values: '1', 'true', 'yes',
// 'on' (case-insensitive). Absent, empty, 'false', '0', etc. → disabled, so the
// renderer hides the Cloud ModeCard entirely.
function betaFeaturesEnabled() {
const raw = String(process.env.BETA ?? '').trim().toLowerCase()
return raw === '1' || raw === 'true' || raw === 'yes' || raw === 'on'
}
ipcMain.handle('hermes:cloud:beta-enabled', async () => betaFeaturesEnabled())
ipcMain.handle('hermes:cloud:login', async () => {
await openPortalLoginWindow()
return { ok: true, signedIn: await hasLivePortalSession() }

View file

@ -45,7 +45,6 @@ contextBridge.exposeInMainWorld('hermesDesktop', {
// (cloud-auto-discovery Phase 3).
cloud: {
status: () => ipcRenderer.invoke('hermes:cloud:status'),
betaEnabled: () => ipcRenderer.invoke('hermes:cloud:beta-enabled'),
login: () => ipcRenderer.invoke('hermes:cloud:login'),
logout: () => ipcRenderer.invoke('hermes:cloud:logout'),
discover: org => ipcRenderer.invoke('hermes:cloud:discover', org),

View file

@ -141,34 +141,6 @@ export function GatewaySettings() {
setCloudOrgState(value)
}
// Hermes Cloud is beta-gated: the selector ModeCard only appears when the main
// process reports the BETA env flag is enabled. Default hidden until the async
// check resolves, so it never flashes in for non-beta users.
const [cloudBetaEnabled, setCloudBetaEnabled] = useState(false)
useEffect(() => {
const desktop = window.hermesDesktop
if (!desktop?.cloud?.betaEnabled) {
return
}
let cancelled = false
desktop.cloud
.betaEnabled()
.then(enabled => {
if (!cancelled) {
setCloudBetaEnabled(Boolean(enabled))
}
})
.catch(() => {
if (!cancelled) {
setCloudBetaEnabled(false)
}
})
return () => void (cancelled = true)
}, [])
// Connection scope: null = the global/default connection (the original
// behavior); a profile name = that profile's per-profile remote override, so
// each profile can point at its own backend.
@ -773,7 +745,7 @@ export function GatewaySettings() {
</div>
) : null}
<div className={cn('grid gap-3', cloudBetaEnabled ? 'sm:grid-cols-3' : 'sm:grid-cols-2')}>
<div className="grid gap-3 sm:grid-cols-3">
<ModeCard
active={state.mode === 'local'}
description={g.localDesc}
@ -782,16 +754,14 @@ export function GatewaySettings() {
onSelect={() => setState(current => ({ ...current, mode: 'local' }))}
title={g.localTitle}
/>
{cloudBetaEnabled ? (
<ModeCard
active={state.mode === 'cloud'}
description={g.cloudDesc}
disabled={state.envOverride}
icon={Cloud}
onSelect={() => setState(current => ({ ...current, mode: 'cloud' }))}
title={g.cloudTitle}
/>
) : null}
<ModeCard
active={state.mode === 'cloud'}
description={g.cloudDesc}
disabled={state.envOverride}
icon={Cloud}
onSelect={() => setState(current => ({ ...current, mode: 'cloud' }))}
title={g.cloudTitle}
/>
<ModeCard
active={state.mode === 'remote'}
description={g.remoteDesc}

View file

@ -59,8 +59,6 @@ declare global {
// sign-in (cloud-auto-discovery Phase 3).
cloud: {
status: () => Promise<DesktopCloudStatus>
// Whether the BETA env flag enables the Hermes Cloud gateway selector.
betaEnabled: () => Promise<boolean>
login: () => Promise<DesktopCloudStatus & { ok: boolean }>
logout: () => Promise<DesktopCloudStatus & { ok: boolean }>
discover: (org?: string) => Promise<DesktopCloudDiscoverResult>