Rudder is the first plugin that isn't a map: it shows that one plugin-designs/ folder, developed live in the Plugin Studio, can ship as a desktop app with its own local backend. - plugin-designs/rudder-voice: <rudder-voice> element. Words stream into the end of a text area while you type/paste anywhere (typing holds the stream; nothing duplicated or lost). Mic picker with hot-plug, 3-second mic test, plain-language errors, info panel, privacy-safe debug report. meta.json declares "targets": ["desktop"]. - backend/rudder-engine (Go): supervises NVIDIA NeMo-Speech.cpp (ggml, CPU) with the Nemotron 3.5 ASR Streaming GGUF over a loopback WebSocket; records with parec/pw-record only while recording; recovers dead Bluetooth mic links (reopen -> CVSD voice profile -> optional RUDDER_BT_RESET) and starts headsets on CVSD. No telemetry: traced with strace, zero sockets/DNS while transcribing. - Privacy: log lines redact MAC addresses and the home folder, transcripts are never logged, Host check against DNS rebinding, CORS only for the desktop webview, random API key for the speech server. - internal/backend-dev-plugin.mjs + vite.config.js: `bun run dev` starts built plugin backends and proxies /api/<name> same-origin, so a plugin calls the same API in the studio and on desktop. - backend/rudder-engine/setup-runtime.sh: fetches the runtime and model pinned by SHA-256. Not yet: the Tauri desktop build (sidecar) and the PocketBase word-correction table.
23 lines
1 KiB
JavaScript
23 lines
1 KiB
JavaScript
/**
|
|
* rudder-voice / index.js — Bundle entry (Capability-1 single element, DESKTOP target).
|
|
*
|
|
* <rudder-voice> — private, offline, streaming voice-to-text. The UI is this bundle; the speech model
|
|
* runs in the local backend (backend/rudder-engine), started by `bun run dev` in the Plugin Studio and
|
|
* by Tauri as a sidecar in the desktop app. See rudder-voice.vue for the contract.
|
|
*
|
|
* Desktop-only: rudder-voice.meta.json declares "targets": ["desktop"]. On a plain website there is no
|
|
* local engine, so the element shows "Engine offline" instead of pretending to work.
|
|
*
|
|
* Usage (desktop shell / Plugin Studio):
|
|
* <rudder-voice profile-config='{"apiBase":"http://127.0.0.1:5193/api/rudder"}'></rudder-voice>
|
|
*/
|
|
import { defineCustomElement } from 'vue'
|
|
import RudderVoice from './rudder-voice.vue'
|
|
|
|
const RudderVoiceElement = defineCustomElement(RudderVoice)
|
|
|
|
if (typeof customElements !== 'undefined') {
|
|
if (!customElements.get('rudder-voice')) customElements.define('rudder-voice', RudderVoiceElement)
|
|
}
|
|
|
|
export default RudderVoiceElement
|