feat(desktop): ts-ify everything

This commit is contained in:
ethernet 2026-06-29 16:31:36 -04:00
parent fac85518fc
commit 39d09453f9
116 changed files with 2500 additions and 1756 deletions

View file

@ -847,7 +847,7 @@ export function DesktopController() {
// window's gateway (the overlay has none) so it survives restart.
setPetOverlayScaleHandler(scale => setPetScale(requestGatewayRef.current, scale))
// Mail icon: $sessions is ordered most-recent-first; the pet is global (not
// per session) so "most recent" is the right target. main.cjs already raised
// per session) so "most recent" is the right target. main.ts already raised
// the window before forwarding this.
setPetOverlayOpenAppHandler(() => {
const recent = $sessions.get()[0]

View file

@ -1422,7 +1422,7 @@ describe('uploadComposerAttachment remote read failures', () => {
})
it('turns the raw 16MB IPC cap error into a friendly remote-gateway message', async () => {
// electron/hardening.cjs rejects the readFileDataUrl IPC with this exact
// electron/hardening.ts rejects the readFileDataUrl IPC with this exact
// shape when a file exceeds DATA_URL_READ_MAX_BYTES.
Object.defineProperty(window, 'hermesDesktop', {
configurable: true,

View file

@ -21,9 +21,9 @@ import {
_submitInFlight,
type GatewayRequest,
inlineErrorMessage,
isGatewayTimeoutError,
isProviderSetupError,
isSessionBusyError,
isGatewayTimeoutError,
isSessionNotFoundError,
type SubmitTextOptions,
withSessionBusyRetry

View file

@ -142,7 +142,7 @@ export async function readFileDataUrlForAttach(filePath: string): Promise<string
}
// The readFileDataUrl IPC base64-loads the whole file into memory and is
// hard-capped (DATA_URL_READ_MAX_BYTES, 16 MB) in electron/hardening.cjs, which
// hard-capped (DATA_URL_READ_MAX_BYTES, 16 MB) in electron/hardening.ts, which
// rejects with a raw "file is too large (N bytes; limit M bytes)" string. In
// remote mode every attachment's bytes go through that read, so a big file
// surfaces that internal message verbatim in the failure toast. Translate it

View file

@ -22,7 +22,7 @@ import { cn } from '@/lib/utils'
* DesktopInstallOverlay
*
* Renders the first-launch install progress for Hermes Agent. Mounted always;
* shows itself only when main.cjs reports an in-flight bootstrap (state.active)
* shows itself only when main.ts reports an in-flight bootstrap (state.active)
* OR an error from a completed-failed bootstrap (state.error). When the
* bootstrap finishes successfully the overlay fades out and the rest of the
* app (existing onboarding overlay -> main UI) takes over.
@ -32,7 +32,7 @@ import { cn } from '@/lib/utils'
* - onBootstrapEvent(callback) -- live event stream
*
* The reducer is intentionally simple: every event mutates an in-component
* snapshot the same way main.cjs mutates its server-side snapshot. We don't
* snapshot the same way main.ts mutates its server-side snapshot. We don't
* try to reconcile -- if we miss an event (shouldn't happen) the initial
* getBootstrapState() call will resync the picture on the next render.
*
@ -559,7 +559,7 @@ export function DesktopInstallOverlay({ enabled = true }: DesktopInstallOverlayP
</Button>
<Button
onClick={async () => {
// Tell main.cjs to clear its latched failure BEFORE we
// Tell main.ts to clear its latched failure BEFORE we
// reload. Otherwise the renderer reload calls getConnection
// and main short-circuits to the latched error without
// re-running install.ps1.

View file

@ -220,7 +220,7 @@ export function FloatingPet() {
})
// Wire the overlay control channel once, only in the primary window — the
// pop-out overlay belongs to it (main.cjs positions it against the main
// pop-out overlay belongs to it (main.ts positions it against the main
// window and routes control messages back to it).
useEffect(() => {
if (isSecondaryWindow()) {

View file

@ -459,7 +459,7 @@ export interface DesktopBootProgress {
}
// First-launch install ("bootstrap") event types -- emitted by
// electron/bootstrap-runner.cjs and observed by the renderer install overlay.
// electron/bootstrap-runner.ts and observed by the renderer install overlay.
// Mirrors the event shapes emitted by runBootstrap()'s onEvent callback.
export interface DesktopBootstrapStageDescriptor {

View file

@ -61,7 +61,7 @@ import type {
// model info/options, cron) the moment the backend passes readiness. On a
// profile-heavy or remote install these can each take tens of seconds — e.g.
// /api/profiles runs list_profiles(), which does a recursive skill-tree walk
// per profile — so the 15s default (DEFAULT_FETCH_TIMEOUT_MS in hardening.cjs)
// per profile — so the 15s default (DEFAULT_FETCH_TIMEOUT_MS in hardening.ts)
// times out a backend that is alive-but-busy, surfacing as a spurious
// "Timed out connecting to Hermes backend" that hangs the UI (#48504).
//

View file

@ -79,7 +79,7 @@ export function mediaExternalUrl(path: string): string {
return /^file:/i.test(path) ? path : `file://${path}`
}
// Custom Electron scheme (registered in electron/main.cjs) that streams a local
// Custom Electron scheme (registered in electron/main.ts) that streams a local
// file with Range support. Used for audio/video so playback bypasses the data
// URL size cap and supports seeking. `path` may be a plain path or `file://…`.
export function mediaStreamUrl(path: string): string {

View file

@ -8,7 +8,7 @@ import { $awaitingResponse, $busy } from '@/store/session'
* Controller for the pop-out pet overlay (main-renderer side).
*
* Shift-clicking the in-window pet "pops it out" into a transparent,
* always-on-top OS window (created in electron/main.cjs) that can leave the
* always-on-top OS window (created in electron/main.ts) that can leave the
* app's bounds and stays visible while Hermes is minimized. That window carries
* NO gateway connection this renderer remains the single source of truth and
* pushes the live pet state to it over IPC. Control flows back (pop the pet back
@ -30,7 +30,7 @@ export interface PetOverlayBounds {
/**
* Request to open the overlay window. `screen` says whether `bounds` are already
* in absolute screen coordinates (a remembered/dragged spot) or in the main
* window's viewport space (a fresh shift-click pop-out, which main.cjs converts
* window's viewport space (a fresh shift-click pop-out, which main.ts converts
* by adding the content origin).
*/
export interface PetOverlayOpenRequest {
@ -172,7 +172,7 @@ function openOverlay(request: PetOverlayOpenRequest): void {
/**
* Pop the pet out of the window. `petRect` is the in-window sprite's viewport
* rect; we grow it to the padded overlay size and center the window on the
* pet's old spot (main.cjs adds the window's screen origin). If the user has
* pet's old spot (main.ts adds the window's screen origin). If the user has
* popped out before, reopen at that remembered desktop spot instead.
*/
export function popOutPet(petRect: PetOverlayBounds): void {
@ -273,7 +273,7 @@ export function initPetOverlayBridge(): () => void {
// overlay on the next push, keeping both surfaces in sync.
scaleHandler?.(payload.scale)
} else if (payload?.type === 'open-app') {
// Mail icon: surface the app on the most recent thread (main.cjs already
// Mail icon: surface the app on the most recent thread (main.ts already
// focused the window before forwarding this) and mark it read.
clearPetUnread()
openAppHandler?.()

View file

@ -1,7 +1,7 @@
import { notifyError } from './notifications'
// Window flag set by the Electron main process when it opens a standalone
// session window (see electron/main.cjs buildSessionWindowUrl). It rides in the
// session window (see electron/main.ts buildSessionWindowUrl). It rides in the
// query string BEFORE the HashRouter '#', so we read it from location.search,
// never from the router. A "secondary" window renders a single chat without the
// global session sidebar or the install / onboarding overlays.

View file

@ -1,7 +1,7 @@
/**
* Window text size (zoom).
*
* The main process owns the zoom level and persists it (see electron/zoom.cjs
* The main process owns the zoom level and persists it (see electron/zoom.ts
* for the scale). The renderer only mirrors the current percent for the
* settings UI: preset clicks go to the main process over IPC, and every
* change comes back through onChanged, including ones made with the

View file

@ -2,7 +2,7 @@
* Install desktop themes from external sources.
*
* The heavy lifting (network + .vsix unzip) lives in the Electron main process
* (`electron/vscode-marketplace.cjs`), reached via `window.hermesDesktop.themes`.
* (`electron/vscode-marketplace.ts`), reached via `window.hermesDesktop.themes`.
* Main hands back the raw theme JSON; we parse + convert + persist here so the
* conversion stays in one unit-testable place.
*/