Phase 14 구현: 회의 모드 (Meeting Mode)

실시간 녹음 + 타임스탬프 메모 + STT 전사 + LLM 구조화 회의록 + PDF/MD 내보내기.
CaptionService 연동, 동시 사용 충돌 방지, 긴 회의 2-pass 요약 지원.
DB 2테이블, IPC 15채널, UI 3뷰(목록/녹음/상세), 12개 locale i18n.
This commit is contained in:
Yun Chan 2026-04-08 01:16:52 +09:00
parent dd68fc9ccd
commit d0c4f9ee53
38 changed files with 2550 additions and 769 deletions

366
CLAUDE.md
View file

@ -1,339 +1,59 @@
# D3RO-VOICE — 로컬 AI 음성 어시스턴트
Genspark Speakly를 리버스엔지니어링하여 얻은 노하우를 기반으로 만드는 **완전 로컬** 음성 어시스턴트.
클라우드 의존성 없이 Ollama + Whisper + TTS를 사용한다.
Speakly RE 기반 완전 로컬 음성 어시스턴트. 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
## 기술 스택
Electron 33+ | React 19 + MUI 7 + Vite | TypeScript 5.7+ strict
better-sqlite3 + drizzle-orm | faster-whisper (Python sidecar) | Ollama REST
uiohook-napi | @nut-tree-fork/nut-js | electron-store | electron-log
## 프로젝트 구조
```
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
npm run dev # Electron + Vite dev
npm run build # 프로덕션 빌드
npm run test # vitest
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 금지
- strict mode, any 금지, console.log 금지 (logger 사용)
- 서비스: 싱글톤 + EventEmitter
- IPC: `${feature}:${action}`, D3ROError + ErrorCode
- 메인앱=React+MUI, 팝업=Vanilla JS
- 테마 SSOT: d3roPalette/d3roShadow만 사용, hex 하드코딩 금지 (theme.ts 제외)
- i18n: t() 함수, 하드코딩 한국어/영어 금지
- Co-Authored-By, Claude 관련 커밋 문구 금지
## 절대 하지 말 것
- 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 애니메이션
## 핵심 패턴 (Speakly 차용)
- RecognitionState(9) + AudioState(4) 이중 상태머신
- 이중 조건 플러시 (모델 로딩 + 오디오 버퍼링 병렬)
- 텍스트 삽입: clipboard save→set→Ctrl+V→restore
- 윈도우: 프리로딩 + 2-phase 리사이즈
- 녹음 UI: 9개 웨이브 바, cos 분포, 100ms
## 현재 상태
Phase: 13 전체 완료 + 랜딩 페이지 완성 (Phase 1~13 + site/)
마지막 작업: 랜딩 페이지 디자인 통합 + 10개 국어 i18n
다음 작업: 빌드/배포 안정화, E2E 테스트, 또는 새 피처
Phase 1~14 전체 완료 + 랜딩 페이지(site/).
차단 이슈: @nut-tree-fork/nut-js 포크 사용
### 랜딩 페이지 (site/)
- Vite + React 19 + TypeScript + Tailwind CSS
- 4가지 디자인 레퍼런스 통합 (KKG 3종 + Meteorological → D3RO 인더스트리얼)
- SSOT: tokens.ts + tailwind.config.js 토큰 중앙 관리
- 재사용 컴포넌트 8개: Badge/Container/Crosshair/DataPoint/GlowButton/InstrumentCard/Led/SectionHeader
- CSS 이펙트: CRT scanline, crosshair, noise texture, glow button (WebGL 없음)
- i18n 10개 국어: en/ko/ja/zh/es/fr/de/pt/ru/vi (Context+Hook, LanguageSwitcher, CJK line-height 보정)
- GitHub Pages 자동 배포: .github/workflows/deploy-site.yml
## 설계 문서 (구현 시 Read 도구로 참조)
- docs/design/00-master-architecture.md — 시스템 아키텍처, 초기화/종료, 서비스 목록
- docs/design/01-service-specifications.md — 서비스 인터페이스, 상태머신, 이벤트
- docs/design/02-ipc-and-types.md — IPC 채널 전체, 타입, 에러코드, preload API
- docs/design/03-db-and-ui.md — DB 스키마, React 컴포넌트, 팝업 명세, MUI 테마
### DS 컴포넌트 현황 (src/renderer/components/ds/)
- CrtDisplay.tsx: WebGL CRT 셰이더 (파형+스캔라인+비네팅+글리치) ✅
- InstrumentPanel.tsx: 메탈 섀시 컨테이너 (각인 텍스트, 노이즈) ✅
- Led.tsx: LED 인디케이터 (amber/green/red/orange, pulse) ✅
- PhysicalButton.tsx: 물리 버튼 (돌출 그림자, 눌림 피드백) ✅
- MetalCard.tsx: 메탈 카드 컨테이너 ✅
- PhosphorText.tsx: 인광 텍스트 (13종 변형: hero/title/value/heading/body/compact/small/meta/label/dim/engrave/micro/nano) ✅
- MetalDial.tsx: 메탈 다이얼 (동심원 텍스처, 드래그 회전, conic-gradient 금속 광택) ✅
- ScreenPanel.tsx: 글래스 스크린 패널 (CRT 없는 인셋 베젤 + 반사) ✅
- ButtonGroup.tsx: 인셋 버튼 클러스터 (레퍼런스 .button-group) ✅
## 서비스 목록 (src/main/services/)
Core: LoggerService, ConfigService, VoiceModeService(오케스트레이터)
Audio: AudioCaptureService, LocalSTTService, LocalLLMService, TTSPlaybackService
Input: HotkeyService, TextInsertService, SoundEffectService, AutoLaunchService
Data: HistoryService, DictionaryService, CustomInstructionService, LicenseService
Phase10+: MemoService, VoiceCommandService, ScreenContextService, ChainService, CaptionService
Phase12+: FileTranscriptionService, MeetingSummaryService, DictationTemplateService
Phase13+: VoiceConversationService, RAGService, VoiceActionService
Phase14: MeetingModeService
### 디자인 토큰 현황 (theme.ts)
- d3roTypo: 13단계 타이포 (hero 42px ~ nano 7px, size/weight/spacing/line)
- d3roShadow: 10종 그림자 (chassis/card/inset/button/dialog/tooltip 등)
- d3roRadius: 7종 반경 (outer 24px ~ pill 999px)
## DS 컴포넌트 (src/renderer/components/ds/)
CrtDisplay, InstrumentPanel, Led, PhysicalButton, MetalCard,
PhosphorText(13변형), MetalDial, ScreenPanel, ButtonGroup
### Phase 13.2 구현 내용 (로컬 RAG)
- **RAGService**: Ollama nomic-embed-text 임베딩, SQLite에 JSON 벡터 저장, 코사인 유사도 검색
- **문서 관리**: .txt/.md/.pdf/.docx 지원, 500자 청크 분할 (50자 오버랩), 비동기 인덱싱
- **벡터 검색**: 쿼리 임베딩 → 전체 청크 코사인 유사도 → topK 결과 → LLM 컨텍스트 주입
- **KnowledgeBasePage**: 전용 UI (문서 목록, 인덱싱 진행률, 질문 입력, 답변+참조 소스 표시)
- **AppLayout**: 'knowledge' 라우트 + RAG 네비 항목
- **DB 테이블**: rag_documents + rag_chunks (Phase 13.2 신규)
- **IPC**: RAG 네임스페이스 9채널
- **ErrorCode**: 870-874 (DocumentNotFound, IndexingFailed, EmbeddingFailed, QueryFailed, UnsupportedFormat)
### Phase 13.3 구현 내용 (OS 자동화)
- **VoiceActionService**: 음성→LLM이 JSON 액션 플랜 생성→실행, 프리셋 6개 (크롬/메모장/탐색기/볼륨)
- **액션 타입**: open_app, open_url, open_file, keyboard_shortcut, type_text, system_command
- **안전장치**: 위험 명령어 블랙리스트 (rm, del, format, shutdown 등), safe=false 시 차단
- **IPC**: VOICE_ACTION 네임스페이스 9채널
- **ErrorCode**: 875-878 (PlanFailed, ExecutionFailed, Blocked, InvalidPlan)
### Phase 13.1 구현 내용 (음성 대화 모드)
- **VoiceConversationService**: STT→LLM→TTS 대화 루프 오케스트레이션, 세션 관리, 대화 히스토리 최근 10턴
- **TTSPlaybackService**: Windows SAPI (PowerShell System.Speech) 기반 로컬 TTS, 문장 단위 큐 재생
- **LocalLLMService.chatStream**: Ollama /api/chat 스트리밍, 대화 히스토리 messages 배열 전달
- **VoiceConversationPage**: 전용 대화 UI (채팅 메시지 목록, 녹음/정지/취소 버튼, 텍스트 입력)
- **AppLayout**: 'conversation' 라우트 + TALK 네비게이션 항목 추가
- **IPC**: VOICE_CONVERSATION 네임스페이스 15채널 (startSession, sendMessage, assistantDelta 등)
- **Preload**: voiceConversation API 네임스페이스 (17메서드/이벤트)
- **ErrorCode**: 795-798 (ConversationSessionAlreadyActive, TTSFailed, LLMFailed 등)
- **i18n**: conversation.* 번역 키 추가 (ko/en)
### Phase 12 구현 내용 (Pro+ 피처)
- **FileTranscriptionService**: ffmpeg(fluent-ffmpeg + @ffmpeg-installer/ffmpeg)로 미디어→PCM 변환, 30초 청크 분할 STT, 진행률 이벤트, 히스토리 자동 저장 (mode: 'file-transcription')
- **MeetingSummaryService**: CaptionService session-saved 이벤트 → Ollama 자동 요약, 마크다운 파싱 (요약/결정/할일), history.summaryText 컬럼 저장, 마크다운 내보내기
- **DictationTemplateService**: 템플릿 CRUD (electron-store), 세션 상태 머신 (idle→field-prompting→field-recording→completing), 프리셋 3개 (이메일/회의록/보고서), 출력 포맷 mustache 치환
- **FileDropZone UI**: DashboardPage 드래그앤드롭 존, 진행률/결과/에러 상태 표시
- **HistoryEntryCard 확장**: 요약 배지(Chip), 확장 뷰(요약/결정/할일), 요약 생성/내보내기 버튼
- **TemplateSection UI**: CommandsPage 하단 섹션, 템플릿 목록/생성/편집/삭제/세션 시작
- **DB 마이그레이션**: history 테이블 summary_text 컬럼 추가 (ALTER TABLE), mode enum에 'file-transcription' 추가
- **IPC**: FILE_TRANSCRIPTION(6채널) + MEETING_SUMMARY(5채널) + DICTATION_TEMPLATE(11채널) = 22개 신규 채널
- **Preload**: fileTranscription/meetingSummary/dictationTemplate 3개 API 네임스페이스
- **ErrorCode**: 780-794 범위 (FFmpegFailed, InvalidFormat, ChunkFailed, SummaryGenerationFailed, TemplateNotFound 등)
- **i18n**: fileTranscription.*/meetingSummary.*/template.* 번역 키 추가 (ko/en)
### Phase 11 구현 내용 (수익화 기반)
- **LicenseService**: Free/Pro/Pro+ 3단계 티어, electron-store 대신 별도 JSON 파일, 오프라인 우선 설계
- **Feature Gating**: Feature enum (16개 기능), 티어별 접근 매핑, 쿼터 한도 (Free: 받아쓰기 20회/일, LLM 10회/일)
- **daily_usage DB 테이블**: 날짜+기능별 사용량 추적 (drizzle-orm, UPSERT)
- **LemonSqueezy 연동**: 키 활성화/검증 API, variant_name→tier 매핑, 오프라인 유예 30일
- **IPC**: LICENSE 네임스페이스 9개 채널 (getInfo, activate, deactivate, checkFeature, getUsage, getAllUsage, getTierComparison, upgradePrompt, tierChanged)
- **Preload**: license API 네임스페이스 추가 (9개 메서드 + 2개 이벤트 리스너)
- **ErrorCode**: 850-862 범위 라이센스 에러 (LicenseKeyInvalid, QuotaExceeded, TierRequired 등)
- **UpgradePromptModal**: 쿼터 소진/잠긴 기능 접근 시 업그레이드 유도 모달 (혜택 목록, 쿼터 바)
- **SettingsModal License 탭**: 티어 표시, 키 입력/활성화, 사용량 바, 티어 비교표
- **DashboardPage 사용량**: Free 티어에서 오늘 사용량 바 (받아쓰기/LLM) 표시
- **ProBadge + useProFeature**: 잠긴 기능 오버레이 래퍼 컴포넌트 + 훅
- **VoiceModeService gating**: startSession에서 DICTATION 쿼터 체크/소비
- **LocalLLMService gating**: processText에서 LLM_PROCESS 쿼터 체크/소비 (차단 시 원본 텍스트 폴백)
- **i18n**: license.* 네임스페이스 40+ 키 추가 (ko/en)
### Phase 10 구현 내용 (서비스 레이어 + UI 통합)
- **MemoService**: memo_tags DB 테이블 + 태그 CRUD + 마크다운 내보내기
- **VoiceCommandService**: 키워드→명령어 매칭 엔진, 프리셋 키워드 4종 (번역/요약/다듬기/설명)
- **ScreenContextService**: 활성 윈도우 감지(PowerShell) + 선택 텍스트 캡처(Ctrl+C)
- **ChainService**: LLM 명령어 순차 실행 파이프라인, 단계별 진행 이벤트
- **CaptionService**: 3초 청크 연속 전사, caption-overlay 팝업(Vanilla JS)
- **VoiceModeService 통합**: 파이프라인 훅 3개 (컨텍스트 캡처→키워드 매칭→체인/컨텍스트 주입)
- **공유 컴포넌트**: EmptyStateCard, SearchInput, PageHeader, HistoryEntryCard
- **공유 유틸**: formatters.ts (formatDuration, getDateKey, formatNumber 등)
- **IPC**: 5개 새 네임스페이스 (MEMO, VOICE_COMMAND, CONTEXT, CHAIN, CAPTION)
- **Preload**: 5개 API 네임스페이스 추가 (memo, voiceCommand, context, chain, caption)
- **HistoryPage 태그 통합**: HistoryEntryCard에 태그 표시/추가/삭제, 태그 필터 바, 마크다운 내보내기
- **CommandsPage 키워드/체인**: VoiceCommandService 키워드 편집 섹션 + ChainService 체인 CRUD/실행 UI
- **DashboardPage 자막 토글**: 실시간 자막 시작/종료 버튼, CaptionState LED 표시
- **SettingsModal 설정 추가**: 음성 명령어 on/off, 스크린 컨텍스트 on/off 토글 (LLM 탭)
- **i18n**: memo/voiceCommand/chain/context/dashboard.caption 번역 키 추가 (ko/en)
### Phase 9 구현 내용
- **Settings About 탭**: 앱/Electron 버전, 기술 스택, 프로젝트 링크, 정밀기기 디자인
- **녹음 WAV 저장**: VoiceModeService 세션 완료 시 WAV 파일 저장 + HistoryService audioLocalPath 연동
- **마이크 테스트 UI**: Settings Audio 탭 레벨 바 (3초 캡처, audio-level 이벤트)
- **온보딩 플로우**: 4단계 위저드 (환영→마이크 설정→핫키 설정→Ollama 설정→완료)
- **MetalDial 컴포넌트**: 동심원 텍스처, 드래그 회전, 금속 광택 — 시안 A 핵심 요소 완성
- **오디오 디바이스 선택**: AudioEndpoint + 디바이스 캐싱, Settings에서 실시간 전환
- **Commands CRUD IPC 연결**: instruction:* 핸들러 완전 연동 + 활성 명령어 선택 UI
- **Ctrl+Shift+C 커맨드 팝업**: 커서 위치에 명령어 선택 팝업, 키보드 탐색 (Arrow/Enter/ESC)
- **Dictionary 편집**: 인라인 편집 + STT initialPrompt에 사전 단어 주입
- **Ollama 설치 안내**: OllamaGuideModal + 넛징 버블 (Ollama 미실행 시 자동 표시)
- **실시간 UI 갱신**: app:dataChanged IPC 이벤트 → Dashboard/History/Dictionary 자동 리프레시
- **Settings 속도 개선**: 비동기 디바이스 로드 + 부팅 시 프리캐싱으로 모달 열기 지연 제거
### Phase 8 구현 내용
- **SSOT 완료**: d3roPalette에 11개 토큰 추가 (sidebar, chassis, inactive, dimLabel 등)
- **매직넘버 제거**: tsx/ts 파일 매직넘버 0개 달성 (theme.ts 제외)
- **DS 컴포넌트 SSOT**: 6개 모두 d3roPalette 참조로 교체
- **HotkeyRecordModal**: 신규 — 커스텀 핫키 녹화 모달 (키 조합 입력→Chip 표시→저장)
- **SettingsModal 재작성**: 음성 모드 3개(받아쓰기/Agent/원터치) 토글+핫키 표시+변경 UI
- **DashboardPage 재작성**: 기능 중심 — Hero(핫키 표시) + 통계 4카드 + CRT 서비스 상태 + 최근 히스토리(날짜 그룹핑)
- **recording-tip 수정**: 웨이브 바/프로그레스 바 색상 #1F5DF2(파란)→#f25b29(앰버)
- **페이지 SSOT**: AppLayout, StatusBar, HistoryPage, DictionaryPage, CommandsPage 모두 완료
- **설계 문서**: docs/phases/phase-8.md, docs/re-findings/speakly-settings-ui.md 작성
### Phase 7.5 구현 내용
- SoundEffectService: WAV 프리로드, fire-and-forget, PowerShell SoundPlayer로 재생
- AutoLaunchService: app.setLoginItemSettings, ConfigService 연동, syncWithConfig
- TextInsertService: 간이 삽입 검증 (EditMonitor 경량), 클립보드 확인
- VoiceModeService 효과음 연동: session-started(start), completed(stop), cancelled(cancel), error(error)
- IPC: system:playSound/setSoundEnabled/isSoundEnabled, config:setAutoLaunch/setCloseToTray
- Bootstrap: sound-effects, auto-launch 초기화 단계 추가
- 효과음 WAV 파일: scripts/generate-sounds.js로 생성 (recording-start/stop, error)
### Phase 7 구현 내용
- vitest 테스트 환경: vitest.config.ts, tests/setup.ts (electron/electron-log 모킹)
- 테스트 헬퍼: tests/helpers/createTestDb.ts (in-memory SQLite + drizzle)
- 단위 테스트 41개: HistoryService, DictionaryService, CustomInstructionService, VoiceModeService, D3ROError
- electron-builder: electron-builder.yml (NSIS, asarUnpack, extraResources)
- GitLab CI/CD: .gitlab-ci.yml (lint, typecheck, test, build, release)
- 빌드 스크립트: pack, dist, test:unit 추가
- 참고: better-sqlite3는 Electron용 빌드라 vitest에서 직접 사용 불가 → DB 서비스는 모킹 테스트
- 번들링 인프라: SoX 다운로드 스크립트, PyInstaller 빌드 스크립트, 경로 해상도 유틸
- src/main/utils/paths.ts: dev vs production 경로 자동 감지 (SoX, sidecar, sounds)
- AudioCaptureService: 번들 SoX 경로 사용 (getSoxPath)
- LocalSTTService: 번들 sidecar 경로 사용 (getSidecarCommand)
- scripts/download-sox.ps1: SoX Windows 바이너리 다운로드 → resources/sox/
- scripts/build-sidecar.py: PyInstaller → sidecar-dist/sidecar/sidecar.exe
### Phase 6 구현 내용
- CustomInstructionService: electron-store 기반, 프리셋 5개 (번역/요약/전문리라이트/코드설명/자유프롬프트)
- 커스텀 명령어 CRUD: create/update/delete/reorder, 프리셋 보호 (삭제 불가)
- CommandsPage: React MUI 명령어 목록 + 추가/편집 다이얼로그
- i18n: ko.json/en.json 리소스, t() 함수, React 컨텍스트 (useI18n)
- IPC: instruction:getAll/getById/create/update/delete/reorder 핸들러
### Phase 3.5 구현 내용
- HistoryPopup: Vanilla JS 팝업, 다크 카드(#242427), 앰버 악센트(#f25b29)
- Ctrl+Shift+V 글로벌 단축키 → 커서 위치에 최근 10건 히스토리 팝업
- Arrow↑↓ 선택, Enter 붙여넣기, 1-9 직접 선택, ESC 닫기
- focusable: false → 활성 앱 포커스 유지
- 2-phase 리사이즈, 등장/퇴장 애니메이션 (0.15s/0.1s)
### Phase 5 구현 내용
- DB: better-sqlite3 + drizzle-orm (history/dictionary/stats 테이블, WAL 모드)
- HistoryService: CRUD + 검색 + 통계 + 보존 정책(30일), 세션 완료 시 자동 이력 저장
- DictionaryService: CRUD + 검색 + 사용 횟수 추적 + STT 프롬프트 힌트
- History UI: 목록 + 검색 + 삭제 + 복사 + 페이지네이션
- Dictionary UI: 목록 + 검색 + 추가 다이얼로그 + 삭제
- Dashboard: 실데이터 통계 (총/오늘 세션수, 시간, 단어수, 연속일수)
- IPC: history, dictionary, stats 핸들러 + preload API
- Bootstrap: DB 초기화 단계 추가 (critical)
### Phase 4 구현 내용
- LocalLLMService: Ollama REST API 연동, 스트리밍 NDJSON 파싱, 가용성 폴링(5초)
- 시스템 프롬프트: refine/translate/summarize/grammar/expand/custom 6개 액션
- VoiceModeService LLM 연동: 전사→LLM 후처리→텍스트 삽입, LLM 실패 시 원본 폴백
- LLM IPC 핸들러: llm:getStatus/getModels/setModel/process/cancelProcess/getServerUrl/setServerUrl
- StatusBar: Ollama 연결 상태 + 활성 모델 표시
- Bootstrap: LLM 가용성 폴링 초기화 단계 추가
### Phase 3 구현 내용
- TextInsertService: clipboard save→set→Ctrl+V→restore (@nut-tree-fork/nut-js, lazy dynamic import)
- RecordingTip 팝업: Vanilla JS, 9개 웨이브바 cos분포 가중치, thinking 점근수렴, 2-phase 리사이즈
- ResultPopup 팝업: Vanilla JS, 복사 버튼, auto-close(5초), 마우스 호버 유지, 다크모드
- WindowManager 리팩토링: 팝업 프리로딩, 커서 위치 표시, 멀티모니터 보정
- Settings 모달: General/Audio/STT/LLM 탭, 실시간 설정 변경
- VoiceModeService 연동: 전사 완료 시 자동 텍스트 삽입 + RecordingTip→ResultPopup 전환
- Bootstrap: 9단계 초기화 (popup-preload 추가)
- electron-vite: 팝업 HTML 멀티 엔트리 + popup preload 빌드
### Phase 2 구현 내용
- AudioCaptureService: node-record-lpcm16 + SoX 실제 마이크 캡처 (PCM16 16kHz mono, 60ms 프레임, RMS 레벨)
- HotkeyService: uiohook-napi 글로벌 키후킹, 더블프레스(300ms), holdMode/toggleMode, VK→uiohook 매핑
- LocalSTTService: faster-whisper Python sidecar 관리, STTState 상태머신, 이중 조건 플러시, 자동 재시작(3회)
- VoiceModeService: RecognitionState(9상태) + AudioState(4상태) 이중 상태머신, Action Queue 직렬화, accidentalPress(<700ms), Dictation/HandsFree 모드
- Python sidecar: FastAPI (GET /health, POST /load, POST /transcribe, POST /shutdown)
- IPC 핸들러: voice, stt, hotkey 추가 (기존 audio, config, window, system에 추가)
- Preload: voice/stt/hotkey API 전체 노출
- Bootstrap: 7단계 초기화 (logger→config→windows→tray→ipc→hotkey→voice-mode)
### Phase 1 구현 내용
- 프로젝트 초기화: package.json, TypeScript strict, electron-vite, ESLint, Prettier
- shared 타입: ipc-channels.ts (113채널), types.ts, errors.ts (ErrorCode enum), constants.ts
- 메인 프로세스: index.ts (단일 인스턴스), bootstrap.ts, lifecycle.ts
- 서비스: LoggerService, ConfigService (ESM dynamic import)
- Renderer: React 19 + MUI 7, AppLayout (Drawer 240px), DashboardPage
- 시스템 트레이, closeToTray
## 페이즈 로드맵
- 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: 테스트 + 빌드 + 배포
- Phase 7.5: Speakly 패턴 보강 (SoundEffect, AutoLaunch, EditMonitor, 오디오 뮤트)
- Phase 8: UI 디자인 재설계 + SSOT + DS 컴포넌트 정비
- Phase 9: 품질 보강 + UX 개선 (온보딩, 마이크 테스트, WAV 저장, 커맨드 팝업, Ollama 안내)
- Phase 10: 킬러 피처 — Speakly를 넘어서 (실시간 자막, 스크린 컨텍스트, 음성 메모장, 멀티 LLM 체인, 음성 단축키)
- Phase 11: 수익화 기반 — LicenseService + Feature Gating + Freemium UI
- Phase 12: Pro 피처 — 파일 전사, 회의록 자동 요약, 딕테이션 템플릿 ✅
- Phase 13.1: Pro+ 프리미엄 — 음성 대화 모드 (STT→LLM→TTS 루프) ✅
- Phase 13.2: Pro+ 프리미엄 — 로컬 RAG (문서 임베딩+검색) ✅
- Phase 13.3: Pro+ 프리미엄 — OS 자동화 (음성→JSON 액션) ✅
## 설계 문서 (구현 시 반드시 참조)
@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
@docs/phases/phase-7.5.md
@docs/phases/phase-8.md
@docs/phases/phase-9.md
@docs/phases/phase-10-killer-features.md
@docs/phases/phase-11-monetization.md
@docs/phases/phase-12-pro-features.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
## 디자인 토큰 (theme.ts)
d3roPalette(색상) | d3roTypo(13단계) | d3roShadow(10종) | d3roRadius(7종)