# Inkling 기록 습관이 없는 사람도 3초 안에 던지고, 로컬 AI가 정리하고, 나중에 업무 자산으로 회수할 수 있게 해주는 데스크톱 메모 앱이다. "메모 = 잊기 전에 머리에서 꺼내는 1회 행동"으로 행동 기준을 낮추고, 정리는 Ollama가 맡는다. 이 저장소는 슬라이스 v0.4 단계다 — 가장 얇은 종단 경로(Quick Capture → SQLite → 로컬 Ollama → Inbox)만 동작한다. 음성·검색·내보내기·온보딩·캘린더 트리거는 후속 spec의 범위. --- ## 상태 - **버전:** Slice v0.4 - **플랫폼:** Windows(dogfood 우선) + macOS(빌드 통과 수준) - **테스트:** 단위 52/52, e2e smoke 1/1, typecheck/build 통과 - **종료 조건:** 본인 2주 dogfood 완주 + AI 결과 7/10 수용 + 크래시 0회 (spec §1.3) --- ## 사전 요구 | 항목 | 버전/메모 | |------|----------| | Node | 24.15.0 (`.nvmrc`) — Volta 권장, nvm-windows도 가능 | | Visual Studio Build Tools | 2022 + "Desktop development with C++" 워크로드 (better-sqlite3 빌드용) | | Ollama | LAN 서버에서 실행, `gemma4:e4b` 모델 pull (8.0B Q4_K_M, 효율 변형) | | Git for Windows | 최신 | LAN Ollama 엔드포인트는 환경변수 `INKLING_OLLAMA_ENDPOINT` 로 주입한다. ``` INKLING_OLLAMA_ENDPOINT=http://192.168.0.47:11434 ``` 미설정 시 `http://localhost:11434` 로 폴백. --- ## 시작하기 ```bash # 1. 의존성 설치 npm install # 2. 개발 모드 (electron-vite dev) npm run dev # 3. 프로덕션 빌드 npm run build # 4. 빌드 결과 실행 npm start ``` 전역 단축키: `Ctrl+Shift+J` (Windows) / `Cmd+Shift+J` (macOS). Quick Capture 창이 화면 중앙 상단에 뜬다. 한 줄 던지고 `Ctrl+Enter` 로 저장. --- ## 패키징 (Windows NSIS 인스톨러) ```bash # Windows 개발자 모드 ON 필요 (winCodeSign 캐시 추출 시 darwin symlink 풀어야 해서) # 설정 → 시스템 → 개발자용 → 개발자 모드 ON npm run dist # NSIS 인스톨러: dist/Inkling Setup x.y.z.exe npm run dist:dir # 패키징 없이 win-unpacked 디렉터리만 ``` 산출물: - `dist/Inkling Setup 0.2.0.exe` — 약 100MB, oneClick=false (설치 위치 선택 가능) - `dist/win-unpacked/` — portable 디렉터리, 그대로 실행 가능 설치 후: - 첫 실행 시 `app.isPackaged === true` 면 `<프로필>/.autostart-init` 마커가 없을 때 한정 자동 시작 ON 으로 설정 (`--hidden` 인자 포함, inbox 창 안 뜨고 트레이만) - 이후 트레이 메뉴 → "윈도우 시작 시 자동 실행" 토글로 조작 - 자동 시작 시 inbox 창은 안 뜸. `Ctrl+Shift+J` 또는 트레이 클릭으로 호출 --- ## 테스트 ```bash # 단위 테스트 (vitest) npm test # 통합 테스트 (실제 Ollama 호출, 게이트됨) npm run test:integration # e2e smoke 테스트 (Playwright + Electron) npm run test:e2e # 타입 체크 npm run typecheck ``` ### Native ABI 함정 `better-sqlite3` 는 두 가지 런타임에서 호출된다 — vitest(Node ABI)와 Electron(ABI 145). 한 번에 한 ABI 로만 빌드되므로 npm 스크립트가 자동으로 prebuild-install 을 돌린다. - `pretest` / `pretest:integration` → `rebuild:node` - `pretest:e2e` / `prestart` / `predev` → `rebuild:electron` 새 native dep 을 추가하거나 Electron 메이저 버전을 올리면 `package.json` 의 `rebuild:*` 스크립트도 갱신해야 한다. ### ELECTRON_RUN_AS_NODE 함정 이 환경변수가 부모 셸에 살아있으면 Electron main-process 모듈 hook 이 비활성화돼 `require('electron')` 이 path string 만 반환한다. e2e 스펙에서 launch env 단계에 명시적으로 strip 한다. 새 main-launch 스크립트를 작성할 때도 동일 strip 필요. --- ## 아키텍처 ``` src/ main/ Electron main process db/ SQLite + 마이그레이션 repository/ NoteRepository (CRUD + edited-flag overwrite guard) services/ Capture, Continuity, Hotkey, Intent, Notification, MediaStore, MediaGc, HealthChecker ai/ InferenceProvider 인터페이스 + LocalOllamaProvider + AiWorker (3-attempt backoff) ipc/ contextBridge용 IPC 핸들러 windows/ Inbox + QuickCapture BrowserWindow 팩토리 tray.ts Tray 아이콘 + 메뉴 paths.ts 프로필 디렉터리 해석 logger.ts electron-log 래퍼 (raw_text 절대 미기록) preload/ contextBridge로 typed API expose renderer/ inbox/ React 19 + Zustand 스토어 quickcapture/ React 19, frameless 640x280 shared/ types.ts IPC 계약 타입 intentPrompts.ts 의미 한 줄 회전 카피 4종 tests/ unit/ vitest, 52 cases integration/ Ollama golden test (게이트됨) e2e/ Playwright smoke docs/ superpowers/specs/ 설계 문서 superpowers/plans/ 구현 계획 superpowers/strategy/ 심리학·dogfooding 전략 handoff/ 세션 간 핸드오프 inkling.md 원본 제품 브리프 v1.4 ``` 핵심 흐름은 Capture → Clarify → Capitalize 3단계 (Strategy §2). 슬라이스에서는 Capture + Clarify 만 다루고 Capitalize(Confluence 내보내기·주간 회고) 는 후속. --- ## Load-bearing 불변 (재논의 금지) 이 규칙들은 spec, 테스트, 코드 곳곳에 박혀 있다. 변경하려면 spec v0.4 §3.3 부터 다시 검토. 1. **`raw_text` 는 불변.** update method 없음. 추가 금지. 2. **AI 재실행은 user-edited 필드를 덮어쓰지 않는다.** `*_edited_by_user` 컬럼 + CASE WHEN 가드. 3. **IntentBanner 는 노트당 정확히 1회.** `intent_prompted_at IS NULL` 이 게이트. setIntent · dismissIntent 둘 다 게이트 닫음. 4. **로그에 본문 금지.** `raw_text` / `ai_title` / `ai_summary` / `user_intent` 내용 절대 미기록. ID, 길이, 해시 prefix 만. 5. **"실패", "끊김", "연속 실패" 단어는 모든 UI 문자열에서 금지.** 회복 친화 톤이 강제. 6. **네이티브 알림은 submit 을 절대 막지 않는다.** 권한 거부 = silent fallback. 캡처는 계속 동작. 7. **버전은 정확 pin (`^` 금지).** `package.json` 갱신 시 spec §7.2 와 동시 업데이트. --- ## Quick Capture 제약 - 단일 입력창, 텍스트 + 클립보드 이미지만. - 제목·태그·폴더 선택 강요 안 함 (Strategy §2.1). - 저장 직후 OS 네이티브 토스트 1개 (회전 카피 4종). - AI 처리는 비동기 — 저장은 즉시, 정리는 백그라운드. ## Inbox 제약 - 날짜 내림차순 리스트, 같은 ms 동기화 시 `id DESC` 보조 정렬. - AI 필드(제목·요약) 는 인라인 편집 가능. 편집 시 `*_edited_by_user=1` 셋 → 이후 AI 재실행은 해당 필드 보존. - 원문은 read-only. - AI 가 생성한 필드 옆에 회색 "AI" 라벨. 사용자 편집 시 라벨 사라짐 ("내 메모" 정체성 표시). - "의미 한 줄" 배너는 AI done 직후 1회만, skip 시 해당 카드에선 다시 안 뜸. - Weekly Continuity 배지: 7건/주 (KST 월~일). 0/7 도 "이번 주 한 줄이면 시작입니다". --- ## 문서 | 문서 | 경로 | 용도 | |------|------|------| | 제품 브리프 | `inkling.md` | 원본 v1.4, 전체 비전 | | 심리학 전략 | `docs/superpowers/strategy/strategy.md` | 행동 변화 모델, 회복 친화 스트릭 | | Dogfooding 전략 | `docs/superpowers/strategy/dogfood-strategy.md` | 2주 자기 dogfood 운영안 | | 슬라이스 설계 | `docs/superpowers/specs/2026-04-24-inkling-vertical-slice-design.md` | v0.4 spec, 부하 전달 결정의 출처 | | Dogfood 피드백 | `docs/superpowers/specs/2026-04-25-dogfood-feedback.md` | 슬라이스 dogfood 중 발견된 본인 피드백 수집 (living document) | | 구현 계획 | `docs/superpowers/plans/2026-04-24-inkling-vertical-slice.md` | 33-task TDD 플랜 | | 핸드오프 | `docs/handoff/2026-04-25-linux-to-windows.md` | Linux→Windows 전환 메모 | --- ## 동기화 (Git, F21 Cut E) Inkling 데이터를 사적 git 원격으로 양방향 동기화 (Mac ↔ Windows 등). 평문 마크다운(F5 export 형식)으로 저장되니 **반드시 비공개 repo** 를 사용한다. 상세 도움말은 앱 내 설정 → 동기화 저장소 → "도움말" 버튼 (4 섹션 modal) 참조. 본 섹션은 setup + 주요 시나리오 요약. ### 일회 설정 1. 빈 사적 repo 생성 (Gitea / GitHub private) 2. 앱 → 설정 → 동기화 저장소 → URL 입력 → "저장" 3. "연결 테스트" 클릭해 인증 / 네트워크 확인 4. 자동 sync 사용 토글 + interval (기본 30분) 확인 URL 형식 (둘 중 하나): - SSH: `git@host:user/repo.git` - HTTPS: `https://host/user/repo.git` `git@https://...` 같은 혼합 형식은 거부된다. ### 일상 사용 - 자동 sync: 설정한 interval 마다 + 앱 종료 시 1회 - 수동 sync: 트레이 → "지금 동기화" - 충돌 발생 시 트레이 토스트 + 설정 페이지의 "충돌 해결…" 버튼 → ConflictModal ### 충돌 해결 (ConflictModal) 같은 노트를 두 기기에서 동시에 수정하면 path 별 결정 (내 것 / 원격) 을 받는다. - **내 것 사용**: 이 기기의 변경을 보존, 원격 변경을 폐기 - **원격 사용**: 원격 변경을 가져오고, 이 기기의 변경을 폐기 3 케이스: 1. 편집/편집 — 양 텍스트 비교 후 더 새롭고 완전한 쪽 선택. 둘 다 보존하려면 한쪽 선택 + 사후 수동 병합 ('both' 미지원) 2. 삭제/편집 — 삭제가 의도였으면 원격 사용 (trash 측), 수정이 더 중요하면 내 것 사용 (편집 측 = trash 취소) 3. AI 결과 충돌 — 한쪽 선택 후 AI 재실행 권장 ### Silent risk - **시계 어긋남 (NTP)**: 양 기기 시계가 다르면 timestamp merge 가 잘못된 결과를 낼 수 있음. NTP 동기화 끄지 말 것 - **두 기기 동시 수정 회피**: 같은 노트를 동시에 수정하면 conflict 가 잦아짐 - **자동 sync 실패 silent**: 주기적 sync 실패 시 토스트 안 뜸. 마지막 sync 시각 / 결과는 설정 페이지에서 확인 ### Troubleshoot - **"연결 테스트" 실패** — 네트워크 (브라우저로 호스트 접속) / 인증 (SSH key 또는 token) / URL 오타 점검 - **인증 실패 (push 안 됨)** — SSH 는 public key 등록 점검, HTTPS 는 OS credential helper (Windows Credential Manager / macOS Keychain) 의 저장 token 점검 - **URL 변경** — 설정 페이지에서 새 URL 입력 → 저장 (`git remote set-url origin` 자동 처리) 데이터 라이프사이클: F6-L1 (로컬 스냅샷, 자동) + F5/F6-L3 (수동 export/import) + F21 Cut E (양방향 git sync) 3-layer 구조. --- ## 라이선스 비공개. 본인 dogfood + 10인 사내 베타까지의 스코프.