Skip to Content

Architecture

The parts of Glint and how a frame becomes speech.

Glint is an Electron app in plain TypeScript. Everything runs on the user's computer.

cameraSDKrenderer receivesdecidesoutputWebcamSmartSpectraSDKframes tometricsLandmarksbrow ratioBreathing traceTalkingPulse rateValidationOK, or a hintbrowDetectorscannerexhaleDetectortalking blocks itSpeakand copyphrasesOn screen onlynever used for decisionsNot OK: the board pausesno scanning, select or speech
From a frame to speech. Only the brow ratio, the breathing trace and talking make decisions. Pulse is only shown, and failing validation only pauses the board.

The three parts

PartPathJob
Mainsrc/main/Runs the SDK's native side. Owns camera permission, the settings file, the clipboard and the espeak-ng fallback.
Preloadsrc/preload/The bridge: the SDK's own preload, plus a small window.glint API.
Renderersrc/renderer/The app itself: screens, gestures, board and signal sources. Sandboxed, with no file access.

Main and the renderer are separate operating-system processes. The preload runs inside the renderer's process, in its own isolated JavaScript world.

Renderer processsandbox: truePage: screens, detectors, scannerno Node, no file accessSDK renderer modulecamera stream; API key in memorycontextIsolation: truewindow.glintcontextBridge: named functions only__smartspectraBridgeholds the SDK's MessagePortProcess boundary: IPCapiKey, settings, copy,speak, replayrecord, frame: unused dev tooleach one a fixed channelto main: frames, start, stopto page: metrics, validation,errorsMain processfull Node accessipcMain handlerssettings sanitized in and outreplay reads one fixed pathespeak-ng with an args array, no shellpermissions: camera, own page onlybindSmartSpectraIpcclamps every payloadkoffi FFINative runtimelibsmartspectra_capi: frames to metricsThis computersettings.json, clipboard, espeak-ngPresage serverskey check, models; telemetry only if on
The preload shares the renderer's process but not its JavaScript world. Only named functions and one SDK message port reach the main process.

The screens

app.ts is a state machine with three phases:

Try a recorded sessionvalidation fails:pausedconsentcamera offsetupcamera onboardcamera or replayStart cameraAPI key foundface OK for 1.5 sover 30 brow samplesno API key,bad recording:message shownFrom setup: Stop, failed start,fatal SDK errorFrom board: Stop, Esc, fatal SDK errorcamera released on every red path
Every path back to consent goes through stop(), which releases the camera. Esc only works on the board. Failing validation pauses the board without leaving it.

Stop, Esc and any error that ends the session all return to consent and release the camera. A recoverable problem only pauses the board. The camera is opened in exactly one place, liveSource in signals/presage.ts, and that is reached only from the consent screen's button.

Pure logic, thin shell

The parts that need to be right are pure functions with no knowledge of Electron or the camera: the detectors, the scanner and the settings sanitizer. That is why they can be tested on a recording in milliseconds.

On this page