settings:configure-sync IPC 핸들러가 `git -C <syncDir> init` 호출 전에
syncDir 디렉토리를 생성하지 않아, sync 첫 설정 시 git 이 chdir 단계에서
`fatal: cannot change to '<profileDir>/sync': No such file or directory` 로
실패하던 문제. SyncService.runSync() 의 동일 패턴 (mkdir recursive) 을
핸들러에도 추가.
연쇄 증상: SyncSection 의 "연결 테스트" 버튼 disabled 조건이 저장된 url
state 기반이라, 저장 실패로 url 영영 비어 있어 버튼 활성화 불가 (닭/달걀).
mkdir fix 로 자동 해소.
회귀: sync-ipc.test.ts 에 mkdir 호출 순서 검증 1건 추가 (18 pass).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
final code review (Opus) 발견 minor issues 중 valuable 2건:
1. settings:refresh-vision-cache 가 settings.ollama.endpoint 만 체크 — env / default
fallback 누락. dev 환경 (env var only) 사용자가 manual 다시 감지 시 'no_endpoint'
silent fail. → index.ts 의 resolvedEndpoint 와 동일 fallback 체인 (settings → env →
DEFAULT_OLLAMA_ENDPOINT).
2. AiWorker 의 5MB cap 이 readFile + base64 변환 후 throw — retry 마다 동일 비용 반복.
note.media[].bytes 가 DB 에 이미 있으니 readFile 전 fast-fail. 비용 절감 + 동일 회로
(markAiFailed 도달).
회귀 test 영향 없음 (기존 5MB throw 시나리오 그대로 — fast-fail 도 throw 분기 동일).
final code review (Opus) 발견 2 important issues:
1. SyncConflict.noteId 가 실제로 export filename slug (date-id8-slug) 였음 — UUID 가
아니라 git checkout path 의 stem. 명명 혼동 → 'path' 로 rename (실제 의미와 일치).
2. ConflictModal preview 가 항상 빈 문자열이라 사용자가 비교 없이 local/remote 선택해야
했음. runSync 의 conflict 분기에서 `git show :2:<path>` (ours) + `:3:<path>`
(theirs) 호출 추가하여 localText/remoteText 채움.
영향:
- SyncService.SyncConflict + shared/types.ts.SyncConflict: noteId → path
- SyncService.resolveConflict(path, choice) — 'notes/...md' 그대로 받음
- pathToNoteId 헬퍼 제거 (불필요)
- ConflictModal: c.noteId → c.path, busy 상태 + 표시 모두 path 키
- IPC handler / preload bridge / InboxApi 시그니처 모두 path 로 통일
- SyncService.bidirectional/resolveConflict/sync-ipc/ConflictModal 4 test 갱신
regression 회귀 패턴 검사: rename 후 NoteRepository / SyncService / IPC / UI 의 모든
conflict-related path 일관 (typecheck 0).