Local dictation had never produced a transcript on an installed build. The engine itself was healthy; every connection to it was broken. Installed builds shipped no speech engine at all: the packaging config had no entry for the faster-whisper sidecar and no pipeline step built one, so the app always fell back to a system Python without the runtime. Development was broken too, because the sidecar and SoX paths were resolved against the Vite output directory instead of the app root, which also meant recording failed with a SoX ENOENT. On hosts where localhost resolves only to IPv6, every local request was refused outright, which silently disabled both local transcription and the local LLM. The sidecar is now built and bundled (including the Silero VAD data it needs), gated by a packaging check that fails when the engine or its data is missing. Paths are discovered from the app root and fail loudly when the engine is absent. Local engine URLs are normalized to the IPv4 loopback, decoding is tuned so repeated hallucinations cannot compound (the same transcript now takes about a fifth of the time), the engine is warmed up at startup, and holding the hotkey now shows the text forming live in the recording tip.
20 KiB
20 KiB
Changelog
All notable changes to D3RO Voice will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[Unreleased]
Planned
- macOS / Linux support
- Additional Whisper model management UI
- Cloud-optional backup (encrypted, opt-in)
- Plugin system for custom pipelines
[1.3.0] - 2026-09-18
Published from an annotated tag through CI. Installer and update metadata are served by the canonical Forgejo feed; no binaries are committed to this repository.
Added
- Live partial transcript while dictating: while the hotkey is held, the app now transcribes the recent window of audio every 1.5 seconds and shows it in the recording tip, so the text can be seen forming before the key is released. Partials never reach the clipboard or the result popup; only the final transcription is inserted.
- Instant first dictation: the local speech engine (sidecar process + Whisper model) is warmed up in the background at app start, so the first press does not wait for the model to load.
- Packaged local speech engine: desktop installers now ship the faster-whisper
sidecar (
sidecar.exeplus runtime data, including the Silero VAD model) and ffmpeg, so local transcription works on a fresh install without Python on the machine. - Sidecar build tooling:
npm --prefix apps/desktop run sidecar:setupandsidecar:build, plus a packaging-time bundle verifier that fails the build when the engine or its VAD data is missing.
Changed
- Local engine connections now target the IPv4 loopback (
127.0.0.1) instead oflocalhost. On machines wherelocalhostresolves only to IPv6, every local request (Ollama and the speech sidecar) was refused and local AI silently did nothing. - Whisper decoding is tuned for dictation: previous-text conditioning is disabled so repeated hallucinations cannot compound, silence is trimmed more aggressively, and low-confidence fallbacks are bounded. Same transcript quality, roughly five times faster on the same machine.
- The sidecar reuses an already-loaded model instead of reloading it, and reports the load time it measured.
- Local engine logs stream to the app log as complete UTF-8 lines instead of mangled fragments, so failures are diagnosable.
- Failed local-engine startup now fails immediately with an actionable message (missing bundled engine, damaged virtualenv, or missing SoX) instead of waiting for a 30 second health check and reporting a generic error.
Fixed
- Local transcription never worked in packaged builds: the sidecar was not part of the packaged resources and no pipeline step built it, so the app always fell back to a system Python that had no faster-whisper installed.
- Local transcription and local LLM never worked in development: the sidecar and SoX
paths were resolved against the Vite output directory (
out/main) instead of the app root, so recording failed with a SoXENOENTand the sidecar fell back to a Python without the runtime dependencies. - Silero VAD data was missing from the bundled engine, which would have made silence-trimmed transcription fail at runtime even with the engine bundled.
- Audio capture and the speech sidecar no longer flash a console window on Windows, and
SoX/spawn failures name the fix (
npm --prefix apps/desktop run setup:sox).
[1.2.0] - 2026-09-16
Published from an annotated tag through CI. Installer and update metadata are served by the canonical Forgejo feed; no binaries are committed to this repository.
Added
- Canonical desktop release channel: desktop auto-update now reads one Forgejo Generic Package Registry feed, published by a version-agnostic publisher (
scripts/ci/publish-forgejo-release.mjs) from tag-triggered Forgejo Actions, GitLab, and GitHub pipelines. The GitLab registry stays a legacy mirror for pre-Forgejo installs. - Update policy SSOT (
release/update-policy.json): channels (latest/beta/alpha), minimum supported version, forced install, full-installer thresholds, staged rollout percentage, and a remote kill switch, enforced at runtime byapps/desktop/src/main/update-policy.ts. - Dictionary import/export on desktop and web: round-trip import with per-entry conflict reporting, a web dictionary client, and an expanded knowledge add form.
- Multi-transport push delivery: Web Push (VAPID) and token-based Apple Push (APNs) transports join Firebase Cloud Messaging, with a Cloudflare Worker cron drain over an outbox table.
- Team activity feed: team activity events, migration, and the web feed component.
- Shared entitlement gating in
@d3ro/corefor free/paid feature boundaries. - Infrastructure map (
docs/map/) documenting the infrastructure and feature status per platform, with an update protocol so feature work and the map stay in step. - 21 unit tests for update policy decisions and feed helpers, plus tests for dictionary I/O, entitlements, push drain, Web Push, and APNs payloads.
Changed
- Desktop runtime updater feed moved from GitLab project 1172 to the canonical Forgejo registry;
electron-builder.yml, the metadata verifier, and both CI publishers now enforce the canonical/mirror split. - Release metadata verifier self-test expanded to negative cases covering the feed contract, policy schema, and Forgejo publisher invariants.
- The canonical publisher refuses to re-publish a version whose registry assets already hold different bytes, so a same-version re-release fails closed instead of overwriting a shipped installer.
- Landing site and web console download centers now link the canonical Forgejo feed instead of repository-local installer paths, which are not part of any deploy artifact.
- Admin console data views (models, pipelines, users, subscriptions, audit log) read live back-office data, with a unified sidebar and console theme.
- Desktop settings, ad surfaces, license, and meeting-export UI aligned on the shared theme tokens; meeting export filenames now go through one sanitizer.
- Developer-only automation, scratch captures, .NET build output, and Playwright run output left the release checkout.
- Product version moved to
1.2.0with Android version code and iOS build number1020001.
Fixed
- Desktop configuration writes fail explicitly when the config store is unavailable instead of falling back to a throwaway in-memory store.
- Speech provider and model failures reach the UI as errors instead of surfacing as empty transcriptions.
- Removed the Forgejo release-publishing prohibition; the legacy hardcoded-version script is replaced by a version-gated publisher.
- Dropped a stale admin bundle from the API server web root.
- Mobile team, meeting, memo, template, command, and dictionary screens follow the server contract, and report submission no longer hangs without confirming to the user.
[1.1.0] - 2026-08-29
Added
- Android/iOS product mobile app: implemented account bootstrap and lifecycle, onboarding, recording and audio import, transcription, history, meetings, templates, memos, teams and invitations, notifications, knowledge, AI Talk, generated documents, data portability, and role-aware administration flows.
- Mobile-native recording and intake: added Android foreground recording with persistent controls and recovery, external
ACTION_SENDaudio/video intake, durable upload processing, and supported-device on-device Whisper transcription. - Server-verified mobile monetization: added Google Play purchase and restore verification, entitlement reconciliation, AdMob rewarded SSV validation, and replay-safe reward receipts.
- Generated-content safety controls: added generation receipts, shared generative-AI safety instructions, and an authenticated report flow for owned AI-generated meeting documents.
- Release verification tooling: added Android artifact, App Links, production Firebase/AdMob configuration, Play asset, secret scanning, signed provenance, and publication-boundary checks.
- Complete mobile icon set: added canonical Android legacy/adaptive/monochrome launchers, the 512px Play icon, and all required iPhone, iPad, and App Store marketing icon slots.
Changed
- Unified mobile authentication and invitation links on the canonical
d3ro-voiceapp scheme and added fail-closed verification for the HTTPS App Links contract. - Hardened Supabase and mobile production configuration to fail closed when required public configuration is absent or does not match the release identity.
- Expanded CI coverage across Node.js 24, .NET 10, Deno Edge Functions, React Native tests, Android emulator gates, 16 KB page-size compatibility, and reproducible release evidence.
- Aligned account deletion guidance with external subscription cancellation requirements and centralized local sensitive-data purge on logout, account deletion, and session loss.
- Centralized product version
1.1.0, Android version code1010001, release notes, updater metadata, and app-store changelogs under release SSOT checks. - Finalized benchmarked
ko-KR/en-USPlay listing copy and a Console-previewed 1024×500 canonical feature graphic with preserved generation prompt, source, output, and hashes.
Security
- Added atomic authorization and replay protection for teams, invitations, push delivery, transcription quotas, billing, ad rewards, administrative actions, data portability, and content reports.
- Removed synthetic success fallbacks from protected STT and AI paths; provider and configuration failures now return explicit failures without creating fabricated user data.
- Strengthened generated-document reporting so only the owner can report an existing document backed by immutable generation audit evidence.
- Removed the repository-exposed desktop license private key and prefix-only paid-tier activation; production now accepts only Ed25519 licenses signed by the rotated external key.
- Made Windows stable packaging fail closed unless an external public-trust code-signing PFX is provided and both the NSIS installer and unpacked app pass exact-version, updater SHA-512, Authenticode
Valid, and expected signer-subject verification; local self-signed development certificates are rejected.
Fixed
- Corrected realtime Edge Function model routing and type checks for team and enterprise tiers.
- Removed the legacy
d3ro://deep-link surface to prevent divergent authentication callback identities.
[0.2.1-alpha] - 2026-07-22
Fixed
- v0.2.0-alpha 치명적 버그 (앱 실행 불가): refactor-wave WS2(AppConfig SSOT)에서 7개 키(
customInstructions,llmChains,voiceCommandRules,voiceCommandsEnabled,activeInstructionId,activeChainId,captionAudioSource)를 AppConfig 인터페이스에 추가하고as never16건을 제거했으나CONFIG_DEFAULTS(ConfigService.ts) 기본값을 누락 → 기존 사용자 config(0.1.x) 마이그레이션 시configGet()이undefined반환 → main 프로세스.map()크래시.CONFIG_DEFAULTS에 기본값([],[],[],false,'',null,'mic') 추가. - 교훈: typecheck/lint/unit test가 GREEN이어도 런타임을 보장하지 않음. 배포 전
npm run dev실행 + 산물 설치 e2e 필수 — 이번에 e2e를 건너뛰어 사용자가 발견.
[0.2.0-alpha] - 2026-07-22
다운로드: Windows
D3RO-Voice-Setup-0.2.0-alpha-x64.exe· macOSD3RO-Voice-0.2.0-alpha-arm64.dmg(Release assets 첨부) — 기존 Windows 사용자는 자동 업데이트(4시간 주기)로 수신됩니다. macOS는 ad-hoc 서명 — Gatekeeper 차단 시 우클릭→열기.
Midnight Glass v2 전면 재설계 + refactor-wave 대규모 코드 품질 정리. 기능 추가보다 시각·구조 개선 중심.
Added
- Midnight Glass v2 전면 리디자인: 미드나이트 네이비 + 글래스모피즘 카드(헤어라인 그라디언트 + 앰비언트 글로우) + 시안→블루→퍼플→마젠타 그라디언트. 6종 테마(dark/light/nord/solarized/catppuccin/dracula) 전환. 보더리스 UI + 커스텀 TitleBar. Pretendard Variable 폰트 오프라인 번들.
- TiltCard DS: 커서 추종 3D 틸트 + 스페큘러 빛 반사 (reduced-motion 완전 존중)
- GradientWave / StatRing DS 신규 (기존 CrtDisplay WebGL 오실로스코프를 그라디언트 스펙트럼 웨이브로 교체)
- 실시간 부분 전사: 받아쓰기 홀드 중 RecordingTip에 interim 전사 표시
- Windows 자동 업데이트: electron-updater + GitLab Generic Registry feed (4시간 주기, 재시작 다이얼로그)
- 멀티플랫폼 배포: macOS arm64(ad-hoc 서명) + Windows 동시 릴리스. GitLab Package Registry(버전별+latest) + Release 자동 생성
- 번들 Ollama v0.32.1: 온보딩 gemma4:e4b pull 412 실패 해소, GPU 런타임 가지치기로 ~1GB→119MB 슬림화
- gpt-realtime-2.1 라이브 음성 대화 (Premium 백엔드, OpenAI Realtime) — 로컬 파이프라인 자동 fallback
- Whisper large-v3-turbo 기본 STT: 6배 빠름, 사이드카 백그라운드 다운로드 API
Fixed
- 한국어 날짜 "TODAY"/"YESTERDAY" 표시 버그 —
date.today/yesterday중복 정의(JSON last-wins) 해소 - 팝업/렌더러 색상 충돌 — 팝업이 v1 주황(
#f25b29)으로 렌더되던 것을 파랑(#3b82f6)으로 SSOT 정합 - 받아쓰기 파이프라인 4버그: press 액션이 STT 초기화를 await하며 큐 점유→release 지연/유령 세션; 사이드카 crash 루프; RecordingTip hide 타이머 leak; 빈 STT 가드
- 온보딩 무진행 구간 UX: verifying(모델 검증) 단계 피드백 + 중복 실행 가드
- 마이크 테스트 조기 종료: 초기
level:0을 종료 신호로 오인하던 버그 - 트레이 아이콘 빈 이미지 버그
Changed
accent.amber→accent.main전면 통일 (162건, deprecated 별칭 2곳 제거) — desktop/web/admin/mobile/ui-native 전역. 6 테마 일관.- IPC 채널 SSOT 일원화:
ipc-channels.ts에 9 그룹/키 추가(INSTRUCTION, POPUP_*, CLIPBOARD, APP 등), 하드코딩 채널 문자열 제거,ipcSuccess/ipcError헬퍼 통일,catch(error)패턴 32건 - AppConfig 타입 강화: 7개 누락 키 추가,
as never16건 제거, dynamicrequire→ static import - 팝업 i18n: 4종 팝업(command/history/result/recording-tip) 한국어/영어 하드코딩 →
t()키 주입 (popup.*17키) - 매직 리터럴 토큰화: 인라인 fontSize/fontWeight/borderRadius →
d3roTypo/d3roRadius토큰 (렌더러 전역)
Removed
- DS 미사용 3종: MetalDial, ButtonGroup, CrtDisplay (barrel export 포함)
- 미사용 의존성 8종:
@mui/icons-material,@d3ro/api-client,fluent-ffmpeg(+@types),pdf-parse,node-record-lpcm16(+.d.ts),electron-audio-loopback,@electron-toolkit/preload - i18n 고아 키 967건 (12 locale) — camelCase license.feature 15키 등 동적 참조는 P1 재검증으로 보존
services/index.ts데드 레지스트리,electron-builder.ymlLinux 섹션
Internal
- refactor-wave Wave 1+2: 정책(
docs/REFACTOR_POLICY.md) 수립 → 공격적 감사(106건) → 9 워크스트림 병렬 → 분리 커밋 9개 + 메타 2. 공유 패키지 토큰 SSOT, IPC/타입 정합, 데드코드 대량 제거. 보고서docs/REFACTOR_WAVE1_REPORT.md·WAVE2_REPORT.md.
[1.0.0] - 2026-08-20
Added
Core Pipeline (Phase 1-3)
- Electron 33 + React 19 + MUI 7 + TypeScript strict mode
- AudioCaptureService: SoX-based PCM16 16kHz mono microphone capture
- LocalSTTService: faster-whisper Python sidecar (dual-condition flush pattern)
- VoiceModeService: 9-state RecognitionState + 4-state AudioState dual state machine
- HotkeyService: uiohook-napi global keyboard hooking (hold/toggle/double-press)
- TextInsertService: clipboard save/set/Ctrl+V/restore via @nut-tree-fork/nut-js
- RecordingTip popup: 9 wave bars with cosine distribution, thinking progress bar
- ResultPopup: auto-close with mouse hover pause, copy button
- Settings modal: General/Audio/STT/LLM tabs
- System tray with close-to-tray support
Cursor History Popup (Phase 3.5)
- Ctrl+Shift+V global shortcut opens recent transcription history at cursor position
- Arrow key navigation, Enter to paste, 1-9 direct select, ESC dismiss
- focusable: false maintains active app focus
LLM Integration (Phase 4)
- LocalLLMService: Ollama REST API with NDJSON streaming
- 6 system prompts: refine/translate/summarize/grammar/expand/custom
- VoiceModeService LLM integration with original text fallback
Database & History (Phase 5)
- better-sqlite3 + drizzle-orm (WAL mode)
- HistoryService: CRUD + search + stats + 30-day retention policy
- DictionaryService: custom words + STT initialPrompt injection
- Dashboard with real statistics
Custom Instructions & i18n (Phase 6)
- CustomInstructionService: 5 presets + user-defined CRUD
- i18n system: ko/en with t() function and React context
Build & Test (Phase 7)
- vitest: 41 unit tests (HistoryService, DictionaryService, VoiceModeService, etc.)
- electron-builder: NSIS installer for Windows x64
- GitLab CI/CD: lint, typecheck, test, build, release pipeline
- SoX download script, PyInstaller sidecar build script
Speakly Pattern Enhancement (Phase 7.5)
- SoundEffectService: WAV preload, fire-and-forget playback
- AutoLaunchService: app.setLoginItemSettings
- TextInsertService: basic insertion verification
- VoiceModeService: sound effect integration on session events
UI Redesign (Phase 8)
- Industrial instrument aesthetic (dark theme, amber #f25b29 accent)
- Design system: 9 DS components (CrtDisplay, InstrumentPanel, Led, PhysicalButton, MetalCard, PhosphorText, MetalDial, ScreenPanel, ButtonGroup)
- d3roPalette SSOT: all colors via CSS custom properties
- HotkeyRecordModal: key combination recording UI
- DashboardPage: feature-focused layout with stats + history + system status
Quality & UX (Phase 9)
- 4-step onboarding wizard (welcome, mic, hotkey, Ollama)
- Microphone test UI with level meter
- Audio recording WAV file saving
- MetalDial component with drag rotation
- Ctrl+Shift+C command popup at cursor position
- Dictionary inline editing
- Ollama installation guide with nudging bubble
- Real-time UI refresh on data changes
Killer Features (Phase 10)
- CaptionService: 3-second chunk continuous transcription with overlay popup
- VoiceCommandService: keyword-to-command matching engine (4 preset keywords)
- ScreenContextService: active window detection + selected text capture
- ChainService: sequential LLM command pipeline with step-by-step events
- MemoService: memo tags DB table + tag CRUD + markdown export
- Shared components: EmptyStateCard, SearchInput, PageHeader, HistoryEntryCard
- Shared utilities: formatters.ts (formatDuration, getDateKey, formatNumber)
Monetization (Phase 11)
- LicenseService: Free/Pro/Pro+ 3-tier system
- Feature gating with 16 feature enums and tier-based access mapping
- Daily usage quota tracking (Free: 20 dictation/day, 10 LLM/day)
- LemonSqueezy API integration for license key activation
- UpgradePromptModal, ProBadge, useProFeature hook
- Settings License tab with tier comparison table
Pro Features (Phase 12)
- FileTranscriptionService: ffmpeg PCM conversion, 30s chunk sequential STT
- MeetingSummaryService: caption session LLM summarization
- DictationTemplateService: CRUD + session state machine, 3 presets
Pro+ Premium (Phase 13)
- VoiceConversationService: STT-LLM-TTS loop for voice conversations
- TTSPlaybackService: Windows SAPI via PowerShell
- RAGService: Ollama nomic-embed-text embeddings, SQLite vector storage, cosine similarity
- KnowledgeBasePage: document management, indexing progress, Q&A UI
- VoiceActionService: LLM JSON action plans, 6 presets, dangerous command blocking
Landing Page
- Promotional website at
site/directory - Vite + React 19 + Tailwind CSS
- 4 design references integrated into D3RO brand identity
- CRT screen effects, crosshair decorations, noise textures (CSS only)
- 10-language i18n: en/ko/ja/zh/es/fr/de/pt/ru/vi
- GitHub Pages auto-deployment workflow
Technical Details
- Total IPC channels: ~200+
- Total services: 20+
- Total error codes: 0-878
- Design system components: 9
- Supported languages (app): ko, en
- Supported languages (landing): 10
- Test count: 41 unit tests
- Build target: Windows x64 NSIS installer