feat(desktop): sync knowledge, recordings and shared settings; play any recording

Knowledge documents travel as source-text chunks; each surface embeds them
with its own model, the server index is requested through embed-chunks, and
documents from the phone are stored without a file and indexed from their
chunks. Chunk text is now kept when local embedding fails, so reindexing no
longer needs the original file.

Recordings upload to the mobile storage contract (audio bucket under the
user's folder plus an audio_files row, 50 MiB cap, a Settings > Cloud
toggle) and are removed with their record. The history card gains a play
button that uses the local file or, for phone recordings, a signed URL.

Language (ko/en), system/light/dark theme, auto-polish and the active user
command follow the phone's user_settings with its revision rule; changes that
arrive from the phone reach the open window.
This commit is contained in:
Yun Chan 2026-09-27 14:44:56 +09:00
parent cee4ab9317
commit 9a8f7e6aa6
34 changed files with 1405 additions and 64 deletions

View file

@ -146,6 +146,8 @@ export const IPC_CHANNELS = {
DELETE: 'history:delete',
DELETE_ALL: 'history:deleteAll',
SET_FAVORITE: 'history:setFavorite',
/** 녹음 재생 소스: 로컬 파일 바이트 또는 다른 기기 녹음의 서명 URL */
GET_AUDIO: 'history:getAudio',
SEARCH: 'history:search',
EXPORT: 'history:export',
// Main → Renderer events

View file

@ -485,6 +485,8 @@ export interface AppConfig {
* 원격 해제된 id는 재사용할 수 없어(서버 규칙) 재로그인 때 새로 발급한다.
*/
deviceInstallationId: string | null
/** 로그인 시 녹음 파일도 클라우드에 올려 모바일·웹에서 재생 (파일당 50MiB 이하) */
cloudSyncAudio: boolean
/** 빅뱅 Phase 2: 첫 실행 온보딩 완료 여부 (로컬 모드 entry point) */
onboardingCompleted: boolean
/** Phase 6: Custom instructions (CustomInstructionService) */
@ -660,6 +662,11 @@ export interface HistorySetFavoriteParams {
isFavorite: boolean
}
/** 녹음 재생 소스. 이 기기에서 녹음했으면 파일 바이트, 모바일·웹 녹음이면 5분짜리 서명 URL */
export type HistoryAudioSource =
| { kind: 'local'; bytes: Uint8Array; mimeType: string }
| { kind: 'remote'; url: string }
export interface HistorySearchParams {
query: string
page: number