The TypeScript migration turned app.js from a classic script into an ES module, so its top-level declarations stopped being shared globals. bookmarks.ts was converted verbatim and kept reading them as window properties, which app.ts no longer publishes. Every bookmark interaction read undefined: the Add Bookmark and Select All buttons stayed hidden because the auth check saw no authEnabled or authRole, per-rig scopes were missing from the scope picker and the move target, decoder checkboxes were never built, and Tune threw on bridge.postPath before issuing a single request. Extend the typed window.trx host contract instead of restoring globals, as docs/frontend-architecture.md closes the standalone window property list. trx.state publishes authEnabled; trx.core publishes setRigFrequency, applyLocalTunedFrequency, armOptimisticFrequency, syncBandwidthInput, scheduleSpectrumDraw, and onDecoderRegistryReady. Replace the vchan setRigFrequency wrapper with an interceptFrequency service method, matching interceptMode and interceptBandwidth. The wrapper captured an undefined original and silently dropped every tune; routing interception through setRigFrequency also restores virtual channel redirection for the application's own tuning. Read registry-built elements through bmOptionalEl, since bmEl throws and the decoder checkboxes and decode toggle buttons are legitimately absent until the registry arrives. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GdyUjuXejCEfiub675z6cz Signed-off-by: Stan Grams <sjg@haxx.space>