Files
BizGaze_Remote/CLIENTS.md
T
Sravan 21ae3e1aa5 feat(desktop): Phase D — inline-reply notifications (Windows toast reply box)
Reply to a chat straight from the OS notification, no app switch:
- node-notifier (bundles SnoreToast) renders a native Windows toast with a reply box —
  Electron's own Notification can't do Windows inline reply.
- main.js reply-notification handler resolves {text}|{open}|null; preload exposes replyNotify.
- home.html notify() routes chat toasts through it on desktop: a typed reply -> sendReplyTo()
  POSTs to /api/messages without opening the app; a click opens the chat. Web/PWA path unchanged.
- Works only in the installed app (needs the installer's AppUserModelID). desktop 0.1.2, build batch21.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 22:36:02 +05:30

6.6 KiB

Biz Connect — Mobile & Desktop clients

Native clients for Biz Connect. The web app is the single source of truth for the UI; each native client is a thin shell that loads that UI and adds the capabilities a browser can't provide (background push, native screen capture, OS input injection, store presence).

Decisions (set by the user 2026-06-30):

  • Build mobile and desktop in parallel.
  • Desktop = both pieces: the remote-control host (existing agent/) and a technician desktop client (desktop/ — Connect in a window).
  • Mobile = Capacitor wrap of the existing web UI (one codebase), not a native rewrite.

Backend is already client-ready (see ARCHITECTURE.md Phase 2): /api/v1, Authorization: Bearer + refresh tokens, API keys, per-tenant webhooks. The one remaining backend gap is APNs/FCM push for native mobile (needs Apple/Google credentials).


Components

Dir Client Tech What it adds over the browser
mobile/ iOS + Android app Capacitor loading the Connect UI Native push (FCM/APNs), camera/mic perms, store distribution, screen capture (ReplayKit / MediaProjection)
desktop/ Technician client Electron loading the Connect UI Native full-screen capture for screen-share; windowed app; later: tray, auto-update
agent/ Remote-control host (customer) Electron + nut-js (exists, v0.2.0) Screen capture + OS input injection so a technician can control the machine

All three authenticate through the same /api/v1 access layer (Bearer token for mobile/desktop, the existing consent/enroll flow for the agent).


Why "wrap the web UI" (not rewrite)

The Connect UI is already an installable PWA built from server-rendered single-file HTML. Pointing a native webview at the server origin means every relative /api and /ws URL keeps working unchanged — zero web-code changes — while native plugins augment it through the JS bridge. One codebase, three shells.

Trade-off: a server-URL shell needs network at launch (fine for a remote-support tool) and some stores scrutinise "just a website". We mitigate by shipping real native capabilities (push, screen capture, deep links), and can later switch to bundled web assets + an absolute API base if offline-launch or store policy requires it.


Phased plan

Phase A — Shells that load the live app ← start here

  • desktop/ Electron client: loadURL(server), setDisplayMediaRequestHandler so screen-share works natively, external links → browser, persisted session.
  • mobile/ Capacitor project: server.url → Connect, app icons/splash, status bar.
  • Inject window.__NATIVE__ = 'desktop' | 'ios' | 'android' so the web UI can adapt (e.g. hide the PWA "install" prompt, enable native push instead of Web Push).

Phase B — Native capabilities

  • Push backend: device-token registration (POST /api/v1/devices, /api/v1/devices/remove) + native senders folded into the single push.sendToUser path — FCM v1 (Android) and APNs token-based over HTTP/2 (iOS), each config-gated and a no-op until creds are set. Web Push (VAPID) unchanged. Dead tokens are pruned on 404/410/UNREGISTERED. (db device_tokens, repo deviceTokens, push.js.) Mobile app still needs the Capacitor push plugin wired + FCM/APNs creds to deliver end-to-end.
  • Capacitor push plugin wired in the web UI (setupNativePush in home.html): inside the app it requests permission, registers, and POSTs the FCM/APNs token to /api/v1/devices; notification taps deep-link via selectChat; logout unregisters the token. Web Push is skipped when running natively. Inert in a normal browser. Activates once the Capacitor Android/iOS app is built and FCM/APNs creds are set.
  • Mobile screen capture for "Share Screen" from a phone (ReplayKit / MediaProjection plugin).
  • Deep links / universal links so a session/meeting link opens the app.

Phase C — Packaging & distribution (needs external accounts)

  • Desktop installers via electron-builder (Win NSIS + Mac dmg); code-signing (Win EV cert, Apple Developer ID + notarization).
  • Mobile store builds: Apple Developer ($99/yr) + Google Play ($25 once); signing keys; store listings & privacy disclosures.
  • Agent host installer (signed) for customers.
  • Auto-update channels.

Phase D — Inline-reply notifications (Teams-style) (right AFTER packaging)

Reply to a chat directly from the OS notification, without opening the app. Cross-platform:

  • Desktop (Windows): native Windows toast with a reply box via node-notifier (bundles SnoreToast). main.js reply-notification handler → preload replyNotify → home.html notify() routes chat toasts through it: a typed reply calls sendReplyTo (POST /api/messages) without opening the app; clicking opens the chat. Uses the installer's AppUserModelID, so it only works in the installed app. Needs a live test in the installed app (can't drive a real Windows toast from CI).
  • Android: notification action with RemoteInput (direct reply) on the FCM message.
  • iOS: UNTextInputNotificationAction on the APNs notification category. All three hand the typed text to the same send path. Depends on Phase B push + Phase C packaging.

Build & run

Desktop (technician client)

cd desktop
npm install
SERVER_URL=https://remote.bizgaze.com npm start     # or http://localhost:8090 in dev
npm run dist                                         # build installers (needs electron-builder + certs)

Mobile (Capacitor)

cd mobile
npm install
npx cap add android        # needs Android Studio + SDK
npx cap add ios            # needs macOS + Xcode
npx cap sync
npx cap open android       # build/run from Android Studio
npx cap open ios           # build/run from Xcode

Set the server origin in capacitor.config.json (server.url).

Agent host (existing)

cd agent
npm install
SERVER_URL=https://remote.bizgaze.com AGENT_ENROLL_TOKEN=<token> npm start

What's gated on you (external, can't be done from code alone)

  • Apple Developer + Google Play accounts (mobile store builds & push).
  • Code-signing certificates (Windows EV, Apple Developer ID) for trusted installers.
  • FCM/APNs credentials for native push. Everything else — the shells, the device/push backend, native plugin wiring — is built here.