2026-10-03 22:17:20 +01:00
2026-10-03 22:17:20 +01:00

felt-tray

The Windows desktop shell for Felt. Lives in the system tray, owns the global push-to-talk hotkey, and is the relay between felt-core (the brain), Mario, and felt-overlay (the VRM desktop companion): mic in, felt-core's reply out as a toast + spoken audio, and any resolved animation tag forwarded on to felt-overlay to act on.

Originally planned as a Rust/Tauri port of the Linux prototype (felt-dashboard's src-tauri/); rebuilt in Python instead after the desktop's Linux→Windows migration (Mario, 2026-09-20: "if you think another language would be better, feel free to swap, i'm not a die hard rust fan"). felt-dashboard now builds a plain static frontend with no native shell of its own; this project hosts it.

What it does

  • Tray icon (pystray): Show Felt, keybind rebinding, a Celsius/Fahrenheit toggle mirrored to felt-core's /v1/settings/temperature-unit, Quit.
  • Global hotkeys (keyboard): one toggles voice push-to-talk, one shows the chat window ready to type. Rebindable from the tray menu, persisted back to .env.
  • Push-to-talk flow (the primary path, no window involved): native mic capture (sounddevice) → felt-core's POST /v1/voice-chat → the reply plays back as audio (winsound) and shows as a native toast (winotify) — Mario, 2026-09-20: "replace output instead of opening the thing, just toast". Any resolved animation_tag in the response is relayed on to felt-overlay.
  • Chat window (pywebview, WebView2): the hosted Felt app (felt-dashboard at felt.clockmost.com/app/, behind SSO; WP-42.2), the same app as on the phone. Lines typed there go through the tray (bridge.py's text_chat → felt-core /v1/text-chat), so she speaks the reply like a spoken turn. Cookies persist (%LOCALAPPDATA%\Felt\webview), so SSO doesn't ask again after every restart. Closing it hides it; only the tray's Quit actually exits.
  • felt-overlay handoff: felt-tray does not launch or talk to felt-overlay directly — that ownership moved to felt-animation in WP-08 (there's no src/felt_tray/overlay.py in this repo any more). felt-tray's own reply flow (mic capture, screen-reaction) posts the resolved text/tag/audio to felt-animation's POST {FELT_ANIMATION_URL} /reply_ready (app.py, timing.py); felt-animation runs lipsync, picks a reaction, and relays it to felt-overlay over its own TCP protocol. LaunchFelt.ps1 is what actually starts FeltOverlay.exe (via felt-animation's overlay.py) — see the umbrella's docs/architecture/umbrella-scripts.md and felt-animation's own ARCHITECTURE.md for that wire format.

Setup

uv sync
cp .env.example .env   # fill in VITE_FELT_CORE_URL at minimum

The chat window needs the desktop to reach felt.clockmost.com (LAN or VPN); the first open asks for the SSO login once.

uv run felt-tray

Not yet built

  • felt-core's fuller tag→clip resolution (fallback broadening, specific/generic weighting, repeat-avoidance) — felt-tray just forwards whatever tag felt-core already resolved; see my private design notes for that.
S
Description
Felt's original Windows tray shell: push-to-talk, toasts and the relay to the avatar overlay (Python)
Readme
523 KiB
0 Stars 1 Watchers 0 Forks
Languages
Python 100%