Lucy v2 (Etappe 2): guter Chat + animierter digitaler Raum

Chat:
- react-markdown/remark-gfm: Lucys Antworten formatiert (fett/listen/inline-code)
- Code-Bloecke mit Kopier-Knopf; Links oeffnen im System-Browser (shell.openExternal via IPC)
- Kopier-Knopf pro Antwort (Hover)
- Persona erlaubt Code/Links SCHRIFTLICH auf Nachfrage; Stimme liest nur kurze Einleitung (cleanForTTS filtert)

Digitaler Raum:
- driftendes Aurora-Licht + schwebende Partikel (2 Parallax-Ebenen) + Vignette ueber dem Neon-Gitter
- reine CSS-Animation (GPU), im Overlay weiter ausgeblendet

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-06-30 19:12:12 +02:00
parent 41f46569bf
commit 16f4683859
8 changed files with 2155 additions and 3 deletions
+27
View File
@@ -0,0 +1,27 @@
import { contextBridge, ipcRenderer } from "electron"
// Schmale Bruecke Renderer -> Main: Fenster-Chrome (frameless), Modus-Umschaltung, Tray/Hotkey-Events.
contextBridge.exposeInMainWorld("lucy", {
minimize: () => ipcRenderer.invoke("win:minimize"),
close: () => ipcRenderer.invoke("win:close"),
setMode: (m: "full" | "overlay") => ipcRenderer.invoke("win:setMode", m),
getMode: () => ipcRenderer.invoke("win:getMode"),
togglePin: () => ipcRenderer.invoke("win:togglePin"),
// Bildschirm-Sicht
captureScreen: () => ipcRenderer.invoke("screen:capture"), // alle Monitore -> string[]
listWindows: () => ipcRenderer.invoke("screen:listWindows"),
captureWindow: (id: string) => ipcRenderer.invoke("screen:captureWindow", id),
captureByName: (q: string) => ipcRenderer.invoke("screen:captureByName", q),
openExternal: (url: string) => ipcRenderer.invoke("open:external", url), // Link im System-Browser
// Events aus dem Main-Prozess (Tray/Hotkey/Modus)
onMode: (cb: (m: "full" | "overlay") => void) => {
const h = (_e: unknown, m: "full" | "overlay") => cb(m)
ipcRenderer.on("lucy:mode", h)
return () => ipcRenderer.removeListener("lucy:mode", h)
},
onHotkey: (cb: () => void) => {
const h = () => cb()
ipcRenderer.on("lucy:hotkey", h)
return () => ipcRenderer.removeListener("lucy:hotkey", h)
},
})