# D3RO-VOICE — 로컬 AI 음성 어시스턴트 Genspark Speakly를 리버스엔지니어링하여 얻은 노하우를 기반으로 만드는 **완전 로컬** 음성 어시스턴트. 클라우드 의존성 없이 Ollama + Whisper + TTS를 사용한다. ## 기술 스택 (고정) - **Framework**: Electron 33+ (contextIsolation: true, nodeIntegration: false) - **Frontend**: React 19 + MUI 7 + Vite - **Language**: TypeScript 5.7+ (strict mode) - **DB**: better-sqlite3 + drizzle-orm - **STT**: faster-whisper (Python sidecar) 또는 whisper.cpp - **TTS**: piper-tts 또는 kokoro - **LLM**: Ollama REST API (localhost:11434) - **Audio**: Web Audio API (renderer) + node-record-lpcm16 (main) - **Hotkey**: uiohook-napi (글로벌 키보드 후킹) - **Text Insert**: @nut-tree/nut-js (클립보드 + Ctrl+V) - **Config**: electron-store ## 프로젝트 구조 ``` D3ROVoice/ ├── src/ │ ├── main/ # Electron 메인 프로세스 │ │ ├── services/ # STT, TTS, LLM, Audio, Hotkey, TextInsert │ │ ├── windows/ # 윈도우 매니저 (팁, 팝업, 메인) │ │ ├── ipc/ # IPC 핸들러 등록 │ │ ├── db/ # SQLite (history, dictionary) │ │ └── index.ts # 앱 진입점 │ ├── renderer/ # React 앱 │ │ ├── components/ # React 컴포넌트 │ │ ├── popups/ # Vanilla JS 팝업 (recording-tip, result-popup) │ │ └── main.tsx # 렌더러 진입점 │ ├── preload/ # contextBridge IPC 브릿지 │ │ └── index.ts │ └── shared/ # 공유 타입, IPC 채널 정의, 에러 코드 │ ├── ipc-channels.ts │ ├── types.ts │ └── errors.ts ├── docs/ # 설계 문서 │ ├── phases/ # 페이즈별 요구사항 │ └── re-findings/ # Speakly 리버스엔지니어링 결과 ├── scripts/ # 빌드/유틸 스크립트 └── tests/ ``` ## 빌드 & 실행 ```bash npm run dev # Electron + Vite dev server npm run build # 프로덕션 빌드 npm run test # vitest 테스트 npm run lint # eslint + prettier npm run typecheck # tsc --noEmit ``` ## 코딩 규칙 - TypeScript strict mode 필수 (noImplicitAny, strictNullChecks) - 함수형 React 컴포넌트 + hooks만 사용 - 메인 앱 = React + MUI, 팝업 윈도우 = Vanilla JS (Speakly 패턴) - IPC 채널명: `${feature}:${action}` (예: `voice:startRecording`, `config:getLanguage`) - 에러 처리: NXError 패턴 (에러 코드 + 메시지) - 로거: electron-log 사용, console.log 금지 ## 절대 하지 말 것 - any 타입 사용 금지 - renderer에서 Node.js API 직접 import 금지 - electron의 remote 모듈 사용 금지 - console.log 남기지 말 것 (logger 사용) - 하드코딩된 시크릿/비밀번호 금지 - Co-Authored-By, Claude 관련 문구 커밋 메시지에 추가 금지 ## Speakly에서 채택한 핵심 패턴 1. **상태 머신**: RecognitionState + AudioState 분리 추적 2. **이중 조건 플러시**: 모델 로딩 + 오디오 버퍼링 동시 진행, 둘 다 준비 시 플러시 3. **텍스트 삽입**: 클립보드 save → set → Ctrl+V → restore 4. **윈도우 관리**: 프리로딩 + 2-phase 리사이즈 (측정→resize→show) 5. **팝업**: 메인 앱=React, 경량 팝업=Vanilla JS 6. **녹음 UI**: 9개 웨이브 바, cos 분포 가중치, 100ms 애니메이션 ## 현재 상태 Phase: 0 (하네스 설정 완료, 구현 시작 전) 마지막 완료: 하네스 시스템 구축 다음 작업: Phase 1 — 프로젝트 초기화 + Electron 뼈대 차단 이슈: 없음 ## 페이즈 로드맵 - Phase 1: 프로젝트 초기화 + Electron 뼈대 + 마이크 캡처 - Phase 2: 로컬 STT 연동 (Whisper) + 핫키 - Phase 3: 텍스트 삽입 + 기본 UI (Dashboard, RecordingTip) - Phase 3.5: 커서 위치 히스토리 팝업 (D3RO 고유 기능) - Phase 4: Ollama LLM 연동 (텍스트 다듬기, 번역) - Phase 5: TTS + 히스토리/사전 DB - Phase 6: 커스텀 명령어 + 설정 UI 고도화 - Phase 7: 테스트 + 빌드 + 배포 ## 설계 문서 (구현 시 반드시 참조) @docs/design/00-master-architecture.md @docs/design/01-service-specifications.md @docs/design/02-ipc-and-types.md @docs/design/03-db-and-ui.md ## 페이즈 문서 @docs/phases/phase-1.md @docs/phases/phase-2.md @docs/phases/phase-3.md @docs/phases/phase-3.5.md @docs/phases/phase-4.md @docs/phases/phase-5.md @docs/phases/phase-6.md @docs/phases/phase-7.md ## RE 노하우 (패턴 적용 근거) @docs/re-findings/speakly-architecture.md @docs/re-findings/voice-pipeline-patterns.md @docs/re-findings/text-insertion-patterns.md @docs/re-findings/ui-patterns.md @docs/re-findings/native-dll-patterns.md