Commit graph

82 commits

Author SHA1 Message Date
yunchan8804
77d514222e feat(V2-5): macOS 빌드 지원 — 플랫폼 분기 + electron-builder mac 타겟 + CI
플랫폼 분기 (paths.ts):
- EXE_SUFFIX 상수로 sox/sidecar/ffmpeg 실행파일 확장자 통합
- Windows에선 .exe 자동 부착, Mac/Linux에선 빈 문자열
- 미사용 getProjectRoot 헬퍼 제거

런타임 서비스 Mac 분기:
- SoundEffectService: darwin → /usr/bin/afplay,
  linux → aplay 분기 추가 (execFile로 안전하게)
- ScreenContextService._getActiveWindowInfo:
  win32 → PowerShell + user32.dll (기존),
  darwin → osascript (System Events frontmost process + 윈도우 타이틀)
  Linux는 미지원 (null)

electron-builder.yml:
- mac 타겟 추가 (dmg + zip, arm64 + x64 매트릭스)
- hardenedRuntime, gatekeeperAssess, entitlements 설정
- extendInfo로 NSMicrophoneUsage / NSCameraUsage / NSAppleEvents /
  NSSystemAdministration 권한 메시지
- dmg 레이아웃 (드래그 to /Applications)
- linux AppImage placeholder
- notarize: false 기본, NOTARIZE 환경변수로 활성화

build/entitlements.mac.plist:
- allow-jit, allow-unsigned-executable-memory (Electron 필수)
- audio-input, camera, network.client
- automation.apple-events (활성 윈도우 조회용)
- files.user-selected.read-write
- allow-dyld-environment-variables (sox/ffmpeg 라이브러리 로드)

scripts/build-sidecar.py:
- IS_WINDOWS / IS_MACOS / EXE_SUFFIX 도입
- Windows에서만 --noconsole 플래그
- 빌드 결과 경로 + size 출력 플랫폼 통합

scripts/install-sox.sh (신규):
- Mac/Linux용 SoX 번들 스크립트
- macOS는 otool로 dylib 의존성 식별 후 함께 복사,
  install_name_tool로 rpath를 @loader_path로 변경
- electron-builder의 extraResources 대상 디렉토리에 배치

resources/icons/ (신규):
- README.md만 커밋, 실제 아이콘 파일은 분리
- sips/iconutil/imagemagick으로 .icns/.ico/.png 생성 가이드

.github/workflows/build-mac.yml (신규):
- macos-14 runner (Apple Silicon), arm64/x64 matrix
- brew sox, npm install, @electron/rebuild,
  install-sox.sh, build-sidecar.py, electron-builder dist
- CSC/NOTARIZE 환경변수 자동 처리
- artifact 업로드 (dmg + zip, retention 7일)

docs/v2/phase-V2-5-mac-guide.md (신규):
- 사전 조건, 시스템 의존성, dev 실행, dist 빌드,
  Code signing + Notarization, CI 트리거, 트러블슈팅

검증 (Windows에서):
- typecheck 통과 (Mac 분기 추가에도 회귀 없음)
- build 통과
- dev 런타임 정상

Mac 검증은 사용자 본인 Mac에서 수행 (V2-5 사용자 액션).
2026-04-08 15:57:16 +09:00
yunchan8804
97eb886ec3 feat(V2-2): Supabase 인프라 — 스키마 + RLS + Edge Functions 스캐폴딩
server/supabase/ 신규 디렉토리:

config.toml — Supabase CLI 설정
  - 프로젝트 ID, DB 포트, auth providers (Google/GitHub/Apple),
    edge_runtime, functions.*.verify_jwt 설정

migrations/ (PostgreSQL DDL, 시간순):
  - 20260409000001_initial_schema.sql
    12개 테이블: profiles, teams, team_members, meetings,
    meeting_memos, meeting_documents, transcripts, history,
    dictionary, memo_tags, daily_usage, subscriptions
    + 인덱스 + FK CASCADE + transcripts Realtime publication
  - 20260409000002_rls_policies.sql
    개인 전용(history/dictionary): user_id = auth.uid()
    팀 공유(meetings 등): 본인 OR team_members 조회 subquery
    daily_usage: 읽기만, 쓰기는 service_role RPC
  - 20260409000003_auth_triggers.sql
    handle_new_user — auth.users INSERT → profiles+subscriptions 자동 생성
    moddatetime — 8개 테이블 updated_at 자동 갱신
    increment_daily_usage — service_role 전용 쿼터 RPC
  - 20260409000004_storage_buckets.sql
    audio/exports/avatars 3개 버킷 + 경로 기반 접근 정책
    (파일 경로가 {user_id}/...로 시작해야 쓰기 허용)

functions/ (Deno/TypeScript Edge Functions):
  - _shared/cors.ts — CORS 헤더 + preflight 핸들러
  - _shared/auth.ts — requireUser (JWT 검증 + User 반환)
  - _shared/quota.ts — 티어별 쿼터 체크 + consume + service role client
  - stt-proxy/index.ts — Google Cloud STT 래퍼 스캐폴딩
    placeholder 응답, 실제 API 호출 코드는 주석으로 포함
  - llm-proxy/index.ts — Anthropic Messages API 래퍼 스캐폴딩
    티어별 허용 모델 정책 (free=Haiku, pro=Sonnet, team=Opus)

설계 문서:
  - docs/v2/phase-V2-2.md — 상세 설계 (스키마/RLS/Edge Functions/Realtime)
  - docs/v2/phase-V2-2-setup.md — 사용자 액션 가이드 (Supabase 계정/
    OAuth 등록/CLI/배포/검증)

apps/desktop typecheck 통과 (server/는 Deno 런타임이라 별도).
실제 Supabase 프로젝트 배포는 사용자가 phase-V2-2-setup.md 따라 수행.
2026-04-08 15:21:08 +09:00
yunchan8804
3524e958ba feat(V2-1d): packages/i18n 추출 — Electron 독립 i18n 엔진
packages/i18n (@d3ro/i18n) 신규:
- src/locales/ 12개 JSON (ko/en/ja/zh/zh-TW/es/fr/de/pt/ru/vi/th)
- src/index.tsx: TFunction/Locale/LOCALE_META/resolveTranslation/
  포맷 유틸(createFormatDate/Number/RelativeDate/Time)/
  I18nContext/useI18n/I18nProvider

Electron 독립성 확보 (monorepo 원칙 준수):
- I18nStorage interface 신설 (load/save 어댑터 추상화)
- window.electronAPI.config 직접 호출 제거
- I18nProvider는 storage prop으로 영속화 어댑터 주입
- 기본값 noopStorage (메모리 한정, 세션 범위)
- 결과: packages/i18n은 React에만 의존, web/mobile에서 재사용 가능

apps/desktop 어댑터:
- App.tsx에 electronI18nStorage 구현 (config.get/set 래핑)
- <I18nProvider storage={electronI18nStorage}>로 주입

apps/desktop 설정:
- package.json: @d3ro/i18n '*' dep 추가
- tsconfig.node/web.json paths에 @d3ro/i18n 추가
- electron.vite.config.ts alias + externalize exclude 추가
- vitest.config.ts alias 추가

일괄 치환 (29 파일):
- ./i18n, ../i18n, ../../i18n → @d3ro/i18n

apps/desktop/src/renderer/i18n/ 디렉토리 완전 제거.

검증: typecheck + build + dev 런타임 모두 통과.
Phase V2-1 전체 완료 (a/b/c/d).
2026-04-08 14:57:27 +09:00
yunchan8804
a041f1b6a9 feat(V2-1c): packages/ui 추출 — DS 컴포넌트 + theme + theme-vars 분리
packages/ui (@d3ro/ui) 신규:
- src/theme.ts (d3roPalette/d3roTypo/d3roShadow/d3roRadius SSOT)
- src/theme-vars.ts (팝업/main 프로세스용 CSS 변수 맵)
- src/components/ds/ (CrtDisplay, InstrumentPanel, Led, MetalCard,
  MetalDial, PhosphorText, PhysicalButton, ScreenPanel, ButtonGroup)
- src/index.ts barrel
- subpath exports: ./theme, ./theme-vars, ./components/ds
- React/MUI/Emotion은 peerDependencies로 선언
- @d3ro/core만 직접 의존성

apps/desktop/src/shared/ 디렉토리 완전 제거:
- theme-vars가 마지막 남은 파일이었음
- tsconfig include에서 src/shared/**/* 제거

일괄 치환 (renderer 전역):
- ../theme, ../../theme, ./theme → @d3ro/ui/theme
- ../components/ds, ../../components/ds, ./ds, ../ds → @d3ro/ui/components/ds
- ../ds/<Component>, ../../ds/<Component> → @d3ro/ui/components/ds
  (세부 파일 import는 barrel로 통합)
- @shared/theme-vars → @d3ro/ui/theme-vars (WindowManager)

apps/desktop 설정:
- package.json: @d3ro/ui: '*' dep 추가
- tsconfig.node/web.json: @shared/* paths 완전 제거, @d3ro/ui,
  @d3ro/ui/* paths 추가
- electron.vite.config.ts: @shared alias 제거, @d3ro/ui alias 추가,
  externalize exclude에 @d3ro/ui 추가
- vitest.config.ts: alias 교체

DS 컴포넌트 내부의 '../../theme' 상대 경로는 packages/ui 구조에서
동일하게 해결되어 그대로 유효.

검증: typecheck + build + dev 런타임 모두 통과.
2026-04-08 14:50:33 +09:00
yunchan8804
3b0eb3393b feat(V2-1b): packages/core 추출 — 공유 타입/에러/채널/유틸 분리
packages/core (@d3ro/core) 신규 생성:
- types.ts, errors.ts, ipc-channels.ts, constants.ts (shared에서 이동)
- utils/meeting-markdown.ts, utils/markdown-to-docx.ts (main/utils에서 이동)
- subpath exports 정의 (./types, ./errors, ./ipc-channels, ./constants,
  ./utils/meeting-markdown, ./utils/markdown-to-docx)
- src/index.ts barrel export 추가
- docx를 core 자체 dependency로 선언

apps/desktop 연결:
- package.json에 @d3ro/core: '*' dep 추가
- tsconfig.node/web.json paths에 @d3ro/core/* 추가
- electron.vite.config.ts 3개 섹션 alias 추가 (main/preload/renderer)
- externalizeDepsPlugin exclude에 @d3ro/core (workspace 소스 번들 대상)
- vitest.config.ts alias 추가

일괄 치환 (79 파일, 167건):
- @shared/{types,errors,ipc-channels,constants} → @d3ro/core/*
- static/dynamic import + type expression import 모두 포함
- MeetingModeService.ts의 ../utils/* 상대 경로 → @d3ro/core/utils/*
- @shared/theme-vars는 V2-1c 범위로 남김 (WindowManager만 사용)

M1 수정 포함:
- electron.vite.config.ts의 resolve('src/shared') → resolve(__dirname, ...)
  CWD 독립적으로 동작하도록 견고화

검증:
- typecheck 통과
- build 통과 (main+preload+renderer)
- dev 런타임 → DB/핫키/Ollama 모두 정상, 기존 데이터 연속성 유지
2026-04-08 14:39:46 +09:00
yunchan8804
a4cb4c0805 fix(V2-1a): 루트 workspace 설정 3파일 보충
이전 커밋(45a5808)에서 다음 파일들이 누락되어 추가:
- package.json: 루트가 monorepo workspace로 재구성된 내용
- tsconfig.json: apps/desktop references 구조
- package-lock.json: workspace install 결과

파일시스템에는 반영되어 있었으나 스테이징 누락으로 git 히스토리에서
빠져 있던 것을 보충. 체크아웃 시 빌드 깨지는 문제 방지.
2026-04-08 14:29:40 +09:00
yunchan8804
45a580878a feat(V2-1a): Monorepo 구조 전환 — apps/desktop으로 V1 이동
- npm workspaces 루트 (apps/*, packages/*) 세팅
- V1 전체를 apps/desktop/으로 git mv (src, resources, tests, sidecar,
  scripts, electron.vite.config.ts, electron-builder.yml, vitest.config.ts,
  tsconfig.node.json, tsconfig.web.json)
- apps/desktop/package.json 신규 (name=@d3ro/desktop)
- productName: 'd3ro-voice' 명시 — app.getName()을 고정하여 userData 경로
  %APPDATA%\d3ro-voice\ 그대로 유지 (기존 DB/설정 연속성 보장)
- 루트 package.json을 workspace 루트로 재구성, 공통 devDep만 유지
  (typescript, eslint, prettier)
- turbo.json, tsconfig.base.json 추가 (Turborepo 자체 설치는 별도 sub-phase)
- memory/project_status.md 생성 (규칙 13)

검증:
- npm run typecheck 통과
- npm run build 통과 (electron-vite main+preload+renderer)
- npm run dev 실제 실행 → DB/핫키/Ollama 자동 실행 모두 정상
2026-04-08 14:04:41 +09:00
yunchan8804
3a160b9032 feat: Ollama 미실행 시 설치 경로 탐색 후 자동 스폰
- LocalLLMService.ensureRunning(): /api/tags 핑 → 바이너리 탐색 → detached 스폰
- 플랫폼별 기본 설치 경로 + where/which PATH 폴백
- bootstrap initLLMPolling에서 startPolling 전에 호출
- 감지는 기존 5초 폴링이 담당, 블로킹 없음
2026-04-08 13:49:42 +09:00
Yun Chan
c5eea6f7db skill updated 2026-04-08 13:23:51 +09:00
Yun Chan
d9fb12763a docs: V2 설계 리뷰 반영 — Adapter 패턴, Local-first 동기화, CRDT 협업
IPC Adapter 패턴, Local-first + Cloud sync, 실시간 협업(Yjs),
GitLab Runner 직접 CI, 기존 레포 monorepo 전환 결정.
2026-04-08 12:36:31 +09:00
Yun Chan
a18ecdeb3c docs: V2 멀티플랫폼 마스터 플랜 + 로드맵
Mac+Web+iOS+Android 동시 진출 전략.
하이브리드 AI(로컬+클라우드), Supabase, Monorepo, 프리미엄 구독.
Phase V2-1~V2-8 세부 로드맵.
2026-04-08 12:30:14 +09:00
Yun Chan
3045fbf612 feat: Phase 15.5-2 — 오디오 보존 + pyannote 실제 화자 구분
녹음 중 PCM 데이터를 WAV 파일로 저장 (meeting-audio/ 디렉토리).
diarizeSession에서 WAV 존재 + HF 토큰 있으면 sidecar /diarize 호출.
pyannote 실패 시 LLM 폴백. 전사 세그먼트-화자 시간 매칭.
2026-04-08 12:17:37 +09:00
Yun Chan
fc7628327a Phase 15.5 구현: 화자 구분 (Speaker Diarization)
- Sidecar: pyannote /diarize 엔드포인트 + requirements.txt 업데이트
- LLM 기반 화자 추정 (Phase 1 — 오디오 보존 없이 전사 텍스트 분석)
- CaptionSegment에 speaker 필드 추가
- EditableSegment: 화자별 색상 바 + 화자 Chip 표시
- TranscriptTab: 화자 구분 버튼 + 진행률
- 설정: HuggingFace 토큰 입력 + Diarization 토글
- IPC: DIARIZE + DIARIZATION_PROGRESS 채널
- 에러코드: 895-897
- 12개 locale i18n
2026-04-08 12:14:00 +09:00
Yun Chan
da25791c75 feat: MTG 카드 세로 풍성한 레이아웃
제목 heading 크기 + 2줄, 날짜/소요시간/메모수 구조적 배치,
하단 구분선 + 상태 LED + UPPERCASE 상태 텍스트.
2026-04-08 11:59:25 +09:00
Yun Chan
4b14fa9553 fix: 히스토리 그리드 오버플로우 수정
MetalCard에 overflow: hidden 추가.
HistoryPage 컨테이너에 overflow: hidden 추가.
2026-04-08 11:56:56 +09:00
Yun Chan
239fb820b8 feat: 히스토리 자동 타이틀 + 카드 UI 분리
전사 완료 후 LLM이 10단어 이내 제목 자동 생성 (fire-and-forget).
DB에 title 컬럼 추가 + 마이그레이션.
HistoryEntryCard: 제목(볼드, ellipsis) + 내용(2줄 미리보기) 분리.
2026-04-08 11:54:37 +09:00
Yun Chan
b452ebbe52 feat: 히스토리 페이지 반응형 그리드 레이아웃
단일 열 리스트 → CSS Grid (1~3열 반응형).
maxWidth: 900 제한 제거 → 전체 너비 활용.
2026-04-08 11:50:57 +09:00
Yun Chan
588147280e feat: 회의 목록 반응형 그리드 레이아웃 + ellipsis UX 개선
단일 열 리스트 → CSS Grid (1~4열 반응형).
제목/메타 text-overflow: ellipsis, hover translateY 효과,
상태 LED+날짜 상단 배치, d3roTypo 토큰 사용.
2026-04-08 11:48:19 +09:00
Yun Chan
6dd4846de7 fix: generateDocument 반환값 불일치 + documents undefined 방어
ipcSuccess(doc)가 MeetingDocument를 직접 반환하는데 UI에서
resp.data.document로 접근하여 undefined 크래시.
resp.data로 직접 접근하도록 수정. preload 타입도 수정.
2026-04-08 11:39:09 +09:00
Yun Chan
f0e221058d fix: /simplify 리뷰 — UX/코드 품질 10건 수정
- EditableSegment: readOnly prop 추가, hover 배경색 효과
- MeetingDetailTabs: useMemo(parseSegments), 이중 debounce 제거, cleanup
- MeetingChatPanel: sessionId deps, 에러 표시, key=timestamp
- ExportMenu: i18n 위반 수정 (하드코딩 → t())
- MeetingModePage: 에러 Snackbar 피드백 (startRecording, viewDetail)
- TranscriptTab: polish 실패 피드백
- 12개 locale i18n 키 5개 추가
2026-04-08 11:34:50 +09:00
Yun Chan
403985e2cd fix: 문서 생성 시 메모 참조 누락 + documents 배열 undefined 방어
generateDocument 프롬프트에 참석자 메모(📝) 포함.
MeetingDetailTabs에서 documents ?? [] 폴백 추가.
2026-04-08 11:23:26 +09:00
Yun Chan
8c10ba1844 feat: 설정에 LLM 모델 선택 드롭다운 추가
Ollama에서 사용 가능한 모델 목록을 자동 로드하고
설정 > LLM 탭에서 선택할 수 있게 추가.
기존 404 에러(qwen3:4b 미설치) 해결.
2026-04-08 11:16:06 +09:00
Yun Chan
55774b64e0 fix: MetalCard onClick 미전달 문제 수정
MetalCard가 onClick/sx props를 받지 않아 클릭 이벤트가 전달되지 않던 문제.
세션 카드와 템플릿 선택 카드를 Box로 감싸서 onClick 처리.
2026-04-08 11:11:14 +09:00
Yun Chan
2b17bf47b7 Phase 15 구현: Auto Polish + AI 채팅 + 마인드맵 + 공유
- Auto Polish: LLM으로 전사 다듬기 (필러 제거, 문장 교정)
- AI 채팅: 회의 전사 기반 Q&A (LocalLLMService.chatStream 활용, 스트리밍)
- 마인드맵: 빌트인 템플릿 추가 (마크다운 계층 트리)
- 공유: 클립보드 복사 메뉴 추가
- MeetingChatPanel UI (접기/펼치기, 스트리밍 인디케이터)
- TranscriptTab에 AI 다듬기 버튼 추가
- 12개 locale i18n 키 추가
2026-04-08 10:18:42 +09:00
Yun Chan
d4928ffa60 Phase 14.5 구현: 회의 모드 고도화 — 다중 문서 생성/편집/내보내기
PLAUD 수준의 기능 확장:
- 전사 편집: 인라인 편집 + 원본 보존 + 수정됨 표시(점선 밑줄)
- 다중 문서 생성: 회의록/보고서/아이디어노트/커스텀 템플릿
- MD 에디터: 렌더링/편집 토글 (react-markdown + remark-gfm)
- 상세 페이지 리디자인: 풀스크린 탭 전환 구조
- 내보내기: MD, PDF, TXT, DOCX 4종 (docx 패키지)
- 커스텀 프롬프트 템플릿 저장/재사용 (electron-store)
- SSOT: 마크다운 파싱 유틸 추출, 후처리에서 자동 문서 생성 제거

DB: meeting_documents 테이블 + edited_transcript 컬럼
IPC: 8+4 채널, 서비스 2개(MeetingModeService 확장 + MeetingDocTemplateService 신규)
UI: 8개 신규 컴포넌트 (meeting/ 디렉토리), 12개 locale i18n
2026-04-08 09:53:54 +09:00
Yun Chan
6197ceb132 fix: 오디오 테스트를 실시간 레벨 미터로 개선
단발성 평균값 → 100ms 간격 실시간 RMS 스트리밍.
AudioCaptureService 직접 시작/5초 자동 중지.
테스트 버튼 누르면 레벨 바가 왔다갔다 반응.
2026-04-08 09:07:29 +09:00
Yun Chan
7a925bdeb9 fix: 설정 오디오 테스트 버튼 실제 동작 연결
voice.onAudioLevel 구독(실제 캡처 없음) → audio.testDevice 호출로 변경.
2초 캡처 후 실제 RMS 레벨을 레벨 바에 표시.
2026-04-08 09:05:36 +09:00
Yun Chan
fa73ad3bb2 fix: 오디오 테스트 버튼 구현 — 스텁 제거, 실제 SoX 캡처
2초간 마이크 캡처 후 평균/피크 RMS 레벨 반환.
설정 오디오 탭에서 테스트 버튼 정상 작동.
2026-04-08 09:04:03 +09:00
Yun Chan
2a465f22e9 fix: 회의 모드 마이크 캡처 강제 — ConfigService 레벨에서 오디오 소스 변경
CaptionService.start()가 ConfigService에서 captionAudioSource를 다시 읽어
setConfig 호출이 무시되는 문제 수정. ConfigService 값을 임시 변경 후 복원.
2026-04-08 08:59:56 +09:00
Yun Chan
43a2acb89d fix: 회의 모드 녹음 개선
마이크 캡처 강제(시스템 오디오→마이크), CaptionOverlay 숨김,
오디오 레벨 인디케이터 추가, 상태 전환 꼬임 수정,
전사 타임스탬프 상대 시간 변환.
2026-04-08 08:56:38 +09:00
Yun Chan
acab319589 fix: MeetingModePage 렌더링 크래시 수정
d3roPalette.indicator → d3roPalette.tag, d3roTypo.reading → d3roTypo.body,
PhosphorText variant="reading" → "body", ScreenPanel sx prop 제거.
bootstrap.ts require() → dynamic import() 변환.
2026-04-08 08:51:24 +09:00
Yun Chan
d0c4f9ee53 Phase 14 구현: 회의 모드 (Meeting Mode)
실시간 녹음 + 타임스탬프 메모 + STT 전사 + LLM 구조화 회의록 + PDF/MD 내보내기.
CaptionService 연동, 동시 사용 충돌 방지, 긴 회의 2-pass 요약 지원.
DB 2테이블, IPC 15채널, UI 3뷰(목록/녹음/상세), 12개 locale i18n.
2026-04-08 01:16:52 +09:00
yunchan8804
dd68fc9ccd 14 phase updated 2026-04-08 00:14:12 +09:00
Yun Chan
023714442d v1.0.0 배포 준비: CHANGELOG, LICENSE, 프로젝트 메타 파일 추가
- CHANGELOG.md: Phase 1~13 + 랜딩 페이지 전체 변경 이력
- LICENSE: MIT
- CONTRIBUTING.md: 개발 환경, 코드 표준, PR 프로세스
- SECURITY.md: 보안 정책, 취약점 보고 절차
- .editorconfig: 에디터 설정 통일 (indent, charset, eol)
- .nvmrc: Node.js 20
- .gitattributes: line ending 정규화, 바이너리 선언, linguist 설정
- .gitignore: site/dist, Python, Whisper 모델 등 누락 항목 추가
2026-04-06 09:29:27 +09:00
Yun Chan
5892125740 랜딩 페이지: D3RO 브랜드 프로모션 사이트 + GitHub Pages 배포
- Vite + React 19 + Tailwind CSS
- 4가지 디자인 레퍼런스 통합 (CRT 스크린, 크로스헤어, 노이즈, 인스트루먼트)
- 섹션 9개: Hero, Features, HowItWorks, Privacy, Pricing, FAQ, CTA, Header, Footer
- 재사용 컴포넌트 8개 (Badge, Container, InstrumentCard, GlowButton 등)
- i18n 10개 국어 (en/ko/ja/zh/es/fr/de/pt/ru/vi)
- GitHub Pages 자동 배포 워크플로우
2026-04-05 23:55:13 +09:00
Yun Chan
eb83682269 Phase 12~13 전체 구현: Pro+ 피처 6종 + 음성 대화 + RAG + OS 자동화
Phase 12:
- FileTranscriptionService: ffmpeg PCM 변환 + 30초 청크 순차 STT
- MeetingSummaryService: 자막 세션 → LLM 자동 요약 + DB summaryText
- DictationTemplateService: 필드별 음성 입력 상태 머신 + 프리셋 3개

Phase 13.1:
- VoiceConversationService: STT→Ollama /api/chat→TTS 대화 루프 (10턴)
- TTSPlaybackService: Windows SAPI 문장 단위 큐 재생
- LocalLLMService.chatStream: Ollama /api/chat 스트리밍

Phase 13.2:
- RAGService: Ollama 임베딩 + SQLite 벡터 + 코사인 유사도 검색
- KnowledgeBasePage: 문서 관리 + 질문/답변 UI
- PDF 파서: zlib FlateDecode 해제 + BT/ET 텍스트 추출

Phase 13.3:
- VoiceActionService: LLM JSON 액션 플랜 생성 + 실행
- 프리셋 6개 (크롬/메모장/탐색기/볼륨), 위험 명령 차단

공통: IPC ~70채널, 에러코드 780-878, i18n 100+키
버그픽스: 라이선스 로컬 키 우선, i18n featureLabel, DOM 중첩
2026-04-05 23:52:14 +09:00
Yun Chan
a31f96bbb8 Phase 10~11 전체 구현: 킬러 피처 5종 + 수익화 시스템
Phase 10 킬러 피처:
- MemoService: 태그 CRUD + 마크다운 내보내기 (memo_tags DB)
- VoiceCommandService: 키워드→명령어 매칭, 프리셋 4종
- ScreenContextService: PowerShell 활성 윈도우 + Ctrl+C 선택 텍스트
- ChainService: LLM 명령어 순차 실행 파이프라인
- CaptionService: 6초 청크 연속 전사 + 시스템 오디오 루프백

VoiceModeService 파이프라인 통합:
- 녹음 시작 → 컨텍스트 캡처 → STT → 키워드 매칭 → LLM(체인/컨텍스트 주입) → 삽입

시스템 오디오 캡처:
- setDisplayMediaRequestHandler + audio: 'loopback' (IPC 브릿지)
- electron-audio-loopback 패키지 contextIsolation 호환 불가 → 직접 구현

Phase 11 수익화:
- LicenseService: Free/Pro/Pro+ 3티어, LemonSqueezy API
- Feature Gate: requireFeature/checkFeature/consumeFeature
- 일일 쿼터: Free dictation 20/일, LLM 10/일 (SQLite daily_usage)
- LicenseModal, ProBadge, UpgradePromptModal UI

디자인 보강:
- d3roTypo(13종), d3roShadow(10종), d3roRadius(7종) 토큰 시스템
- ScreenPanel, ButtonGroup DS 컴포넌트 신규
- PhosphorText 4→13종 변형, MetalDial conic-gradient 광택
- 공유 컴포넌트: EmptyStateCard, SearchInput, PageHeader, HistoryEntryCard

기타:
- 자막 핫키 SSOT 전체 연동 (Config→Hotkey→VoiceMode→Caption→Settings)
- StatusBar 자막 LED + 효과음, 자막 로딩 UI
- LLM 상태 이벤트 전파 수정 (폴링 제거 → onStatusChanged)
- 커맨드 팝업 "선택 해제" 항목 추가
2026-04-05 21:36:09 +09:00
Yun Chan
36d77ca224 하네스 전면 업데이트 + Phase 10 킬러 피처 설계 2026-04-05 13:52:41 +09:00
Yun Chan
561502ec36 Settings 열기 속도 개선: 디바이스 비동기 로드 + 부팅 시 프리캐싱
- SettingsModal: 설정+핫키 먼저 로드 → 즉시 표시, 디바이스는 백그라운드
- bootstrap: 앱 부팅 시 getDevices() 미리 호출 → 캐싱
- 첫 번째 Settings 열기도 빠르게 (캐시 히트)
2026-04-05 13:43:33 +09:00
Yun Chan
39eb8b20fe 넛징 버블: 10초 자동 숨김 + X 닫기 버튼 추가 2026-04-05 13:40:34 +09:00
Yun Chan
dc06a326b5 Ollama 설치 안내 UI + 온보딩 Ollama 단계
- StatusBar: 오프라인 3초 후 넛징 버블 표시 ("설치 안내 보기→" 링크)
- OllamaGuideModal: 3단계 설치 안내 (다운로드→모델 pull→자동 연결)
- OnboardingModal: Step 3에 Ollama 설치 안내 단계 추가
- Settings 정보 탭: "초기 설정 안내 다시 보기" 버튼
- system.openExternal IPC 추가 (외부 URL 열기)
2026-04-05 13:38:26 +09:00
Yun Chan
ea48168b1e 실시간 UI 갱신: 세션 완료/명령어 변경 시 렌더러 자동 리로드
- bootstrap: notifyRenderer('app:dataChanged') 이벤트 발행
  - session-completed: Dashboard 통계 + History 갱신
  - command:selected: CMD 페이지 활성 명령어 갱신
- preload: app.onDataChanged 이벤트 리스너 추가
- DashboardPage/CommandsPage/HistoryPage: onDataChanged 구독하여 자동 loadData()
2026-04-05 13:31:57 +09:00
Yun Chan
1361b95a4d 커맨드 선택 팝업 (Ctrl+Shift+C): 커서 위치에서 빠른 명령어 전환
- command-popup: Vanilla JS 팝업 (히스토리 팝업과 동일 패턴)
  Arrow↑↓ 선택, Enter 적용, 1-5 직접 선택, ESC 닫기
- WindowManager: showCommandPopup/hideCommandPopup/sendKeyToCommandPopup
- bootstrap: Ctrl+Shift+C 단축키 등록 + command:selected IPC
- electron.vite.config: command-popup HTML 빌드 엔트리 추가
- 선택한 명령어가 즉시 activeInstructionId로 설정 → 다음 녹음에 적용
2026-04-05 13:26:59 +09:00
Yun Chan
fea923d302 커맨드 활성화 기능: 클릭하면 다음 녹음에 적용
- CommandsPage: 명령어 카드 클릭 → 활성 명령어 설정 (앰버 하이라이트)
  - 상단에 ACTIVE COMMAND 표시
  - 같은 카드 다시 클릭하면 해제
  - 활성화 시 defaultLLMAction='custom' + activeInstructionId 저장
- VoiceModeService: action='custom'일 때 활성 명령어 프롬프트로 LLM 처리
  - {{text}}를 전사 텍스트로 치환
2026-04-05 13:19:19 +09:00
Yun Chan
8bd9d11ecd Settings 열기 속도 개선: 오디오 디바이스 캐싱 2026-04-05 13:17:48 +09:00
Yun Chan
4e23622c44 LLM 후처리 명령어 선택 기능 추가
- Settings LLM 탭: "기본 후처리 명령어" 드롭다운 추가
  (없음/다듬기/번역/요약/문법교정/커스텀)
- VoiceModeService: defaultLLMAction='none'이면 LLM 스킵
  (이전: 'refine' 아니면 무조건 스킵 → 수정)
- 사용자가 Settings에서 후처리 방식을 선택하면 모든 녹음에 적용
2026-04-05 13:15:54 +09:00
Yun Chan
5596a52dcb Commands/Dictionary 미연결 버그 4건 수정
1. CommandsPage: handleSave/handleDelete에 실제 IPC 호출 연결
   - instruction:create/update/delete 호출 추가
   - 프리셋은 삭제 불가 (isBuiltin 체크)

2. Preload: instruction API 추가 (getAll/create/update/delete/reorder)
   - 기존에 preload 브릿지가 없어서 렌더러에서 호출 불가했음

3. Dictionary → STT initialPrompt 주입
   - VoiceModeService._transcribe에서 DictionaryService.getPromptHints() 호출
   - 사용자 사전 단어를 Whisper initialPrompt로 전달

4. DictionaryPage: 편집 기능 추가
   - 각 항목에 Edit 버튼 추가
   - Add/Edit 공용 다이얼로그 (editId로 분기)
2026-04-05 12:45:45 +09:00
Yun Chan
6e9e8b1f29 히스토리 팝업 수정: ESC 닫기 + Arrow 키 네비게이션
- Arrow↑↓/Enter/Escape/1-9 키를 팝업 열릴 때 globalShortcut 등록, 닫힐 때 해제
- showHistoryPopup: 2-phase 제거 → 즉시 show (렌더러 비활성 문제 방지)
- hideHistoryPopup/itemSelected/popupDismissed에서 nav 키 해제
2026-04-05 12:38:54 +09:00
Yun Chan
2392d05ded 디바이스 목록 key 중복 수정: deviceId+index 조합 2026-04-05 12:34:16 +09:00
Yun Chan
9dbf5c2a08 오디오 디바이스: Win32_SoundDevice → AudioEndpoint로 변경 (실제 마이크/스피커 엔드포인트) 2026-04-05 12:32:37 +09:00