Files
inkling/src/preload/index.ts
2026-05-10 04:59:12 +09:00

108 lines
7.0 KiB
TypeScript

import electron from 'electron';
const { contextBridge, ipcRenderer } = electron;
import type { InklingApi, Note } from '@shared/types';
const api: InklingApi = {
capture: {
submit: (payload) => ipcRenderer.invoke('capture:submit', payload),
hide: () => ipcRenderer.send('capture:hide')
},
inbox: {
listNotes: (opts) => ipcRenderer.invoke('inbox:list', opts),
updateAiFields: (noteId, fields) =>
ipcRenderer.invoke('inbox:updateAi', { noteId, fields }),
setDueDate: (noteId, date) => ipcRenderer.invoke('inbox:setDueDate', { noteId, date }),
deleteNote: (noteId) => ipcRenderer.invoke('inbox:trash', noteId),
setIntent: (noteId, text) => ipcRenderer.invoke('inbox:setIntent', { noteId, text }),
dismissIntent: (noteId) => ipcRenderer.invoke('inbox:dismissIntent', noteId),
getContinuity: () => ipcRenderer.invoke('inbox:continuity'),
getPendingCount: () => ipcRenderer.invoke('inbox:pendingCount'),
getOllamaStatus: () => ipcRenderer.invoke('inbox:ollamaStatus'),
getTodayCount: () => ipcRenderer.invoke('inbox:todayCount'),
// 신규 v0.2.3 #4:
restoreNote: (noteId) => ipcRenderer.invoke('inbox:restore', noteId),
permanentDeleteNote: (noteId) => ipcRenderer.invoke('inbox:permanentDelete', noteId),
emptyTrash: () => ipcRenderer.invoke('inbox:emptyTrash'),
listTrash: (opts) => ipcRenderer.invoke('inbox:listTrash', opts),
getTrashCount: () => ipcRenderer.invoke('inbox:trashCount'),
listExpired: () => ipcRenderer.invoke('inbox:listExpired'),
trashExpiredBatch: (ids) => ipcRenderer.invoke('inbox:trashExpiredBatch', { ids }),
ollamaRecheck: () => ipcRenderer.invoke('inbox:ollamaRecheck'),
onNoteUpdated: (cb) => {
const listener = (_e: unknown, note: Note) => cb(note);
ipcRenderer.on('note:updated', listener);
return () => ipcRenderer.off('note:updated', listener);
},
onOllamaStatus: (cb) => {
const listener = (_e: unknown, status: { ok: boolean; reason?: string }) => cb(status);
ipcRenderer.on('ollama:status', listener);
return () => ipcRenderer.off('ollama:status', listener);
},
retryAllFailed: () => ipcRenderer.invoke('inbox:retryAllFailed'),
getFailedCount: () => ipcRenderer.invoke('inbox:failedCount'),
listRecallCandidate: () => ipcRenderer.invoke('inbox:listRecallCandidate'),
markRecallOpened: (id: string) => ipcRenderer.invoke('inbox:markRecallOpened', id),
dismissRecall: (id: string) => ipcRenderer.invoke('inbox:dismissRecall', id),
emitRecallShown: (id: string) => ipcRenderer.invoke('inbox:emitRecallShown', id),
emitRecallSnoozed: (id: string) => ipcRenderer.invoke('inbox:emitRecallSnoozed', id),
loadOllamaSettings: () => ipcRenderer.invoke('inbox:loadOllamaSettings'),
saveOllamaSettings: (v: { endpoint: string; model: string }) => ipcRenderer.invoke('inbox:saveOllamaSettings', v),
// v0.2.7 Task 13 — 외부 (트레이) 에서 view 전환 요청 listener.
onNavigate: (cb: (view: 'inbox' | 'trash' | 'settings') => void) => {
const listener = (_e: unknown, view: 'inbox' | 'trash' | 'settings') => cb(view);
ipcRenderer.on('inbox:navigate', listener);
return () => ipcRenderer.off('inbox:navigate', listener);
},
// v0.2.7 자동 실행 (Task 22 통일) — 진단 정보 포함 응답
getAutostart: () => ipcRenderer.invoke('settings:autostart-state'),
setAutostart: (open: boolean) => ipcRenderer.invoke('settings:autostart-set', open),
// v0.2.7 백업/복원/동기화/텔레메트리 (Task 10) — 트레이 callback 의 IPC 대응
runBackup: () => ipcRenderer.invoke('settings:run-backup'),
runExport: () => ipcRenderer.invoke('settings:run-export'),
runImport: () => ipcRenderer.invoke('settings:run-import'),
runSync: () => ipcRenderer.invoke('settings:run-sync'),
runExportTelemetry: () => ipcRenderer.invoke('settings:run-export-telemetry'),
// v0.2.7 정보 섹션 (Task 11) — 트레이 showAboutDialog 의 IPC 대응
getAppInfo: () => ipcRenderer.invoke('settings:get-app-info'),
openProfileDir: () => ipcRenderer.invoke('settings:open-profile-dir'),
copyAppInfo: () => ipcRenderer.invoke('settings:copy-app-info'),
// v0.2.8 Cut A — 첨부 이미지를 OS 기본 뷰어로 열기 (Task 3).
openMedia: (relPath: string) => ipcRenderer.invoke('inbox:open-media', relPath),
// v0.2.9 Cut B Task 4 — status 별 list + counts.
listByStatus: (status, opts) => ipcRenderer.invoke('inbox:list-by-status', status, opts ?? {}),
countsByStatus: () => ipcRenderer.invoke('inbox:counts-by-status'),
// v0.2.9 Cut B Task 8 — 4분기 status 전이 + AI 자동 분류 추천.
setStatus: (id, status, reason) => ipcRenderer.invoke('inbox:set-status', id, status, reason),
classifyStatus: (id, reason) => ipcRenderer.invoke('ai:classify-status', id, reason),
// v0.2.9 Cut B Task 12 — settings read + AI/onboarding 토글 (첫 launch wizard 분기 포함).
getSettings: () => ipcRenderer.invoke('settings:get'),
setAiEnabled: (enabled: boolean) => ipcRenderer.invoke('settings:set-ai-enabled', enabled),
setOnboardingCompleted: (completed: boolean) => ipcRenderer.invoke('settings:set-onboarding-completed', completed),
// v0.2.9 Cut B Task 16 — disabled 메모 재투입 + count.
enqueueDisabled: () => ipcRenderer.invoke('inbox:enqueue-disabled'),
getDisabledCount: () => ipcRenderer.invoke('inbox:get-disabled-count'),
// v0.2.10 Cut C — raw_text 가변 + revision 보존.
updateRawText: (noteId: string, newText: string) => ipcRenderer.invoke('inbox:update-raw-text', noteId, newText),
listRevisions: (noteId: string) => ipcRenderer.invoke('inbox:list-revisions', noteId),
restoreRevision: (noteId: string, revId: number) => ipcRenderer.invoke('inbox:restore-revision', noteId, revId),
// v0.2.11 Cut D — search + 회고 aggregate.
search: (query, opts) => ipcRenderer.invoke('inbox:search', query, opts ?? {}),
reviewAggregate: (period) => ipcRenderer.invoke('inbox:review-aggregate', period),
// v0.3.0 Cut E — 양방향 sync.
configureSync: (url: string | null) => ipcRenderer.invoke('settings:configure-sync', url),
testSyncConnection: () => ipcRenderer.invoke('settings:test-sync-connection'),
listConflicts: () => ipcRenderer.invoke('sync:list-conflicts'),
resolveConflict: (path: string, choice: 'local' | 'remote') =>
ipcRenderer.invoke('sync:resolve-conflict', path, choice),
getSyncStatus: () => ipcRenderer.invoke('sync:get-status'),
setSyncAutoEnabled: (value: boolean) => ipcRenderer.invoke('settings:set-sync-auto-enabled', value),
setSyncIntervalMin: (value: number) => ipcRenderer.invoke('settings:set-sync-interval-min', value),
// v0.3.1 Cut F — vision capability + 모델 선택
getVisionModels: () => ipcRenderer.invoke('settings:get-vision-models'),
setVisionModel: (value: string | null) => ipcRenderer.invoke('settings:set-vision-model', value),
refreshVisionCache: () => ipcRenderer.invoke('settings:refresh-vision-cache'),
}
};
contextBridge.exposeInMainWorld('inkling', api);