a54f134343
Merge pull request 'v0.3.0 Cut E — 양방향 git sync + Configure UI + Conflict resolution (F21)' ( #30 ) from worktree-v030-cut-e-bidirectional-sync into main
...
Reviewed-on: #30
v0.3.0
2026-05-09 19:24:42 +00:00
altair823
401414608b
fix(v030): SyncConflict noteId→path + populate localText/remoteText (final review fix)
...
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).
2026-05-10 04:10:59 +09:00
altair823
2ef4802050
chore(release): v0.3.0 — Cut E (양방향 git sync + Configure UI + Conflict resolution)
...
- F21 promoted (✅ v0.3.0 Cut E — A+B+C 옵션, both deferred)
- version 0.2.11 → 0.3.0 (semver MINOR — Major 영역 진입)
- 단위 608 → 680 (+72): GitClient 5 + upsertFromSync 5 + ImportService 18 + SyncService bidirectional 5 + resolveConflict 4 + SettingsService 6 + sync IPC 17 + SyncSection 4 + ConflictModal 3 + SyncTimer 5
- typecheck 0 errors
2026-05-10 04:01:41 +09:00
altair823
e3f6c711a7
feat(v030): SyncTimer — 자동 주기 sync (settings 변경 시 reconfigure)
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-10 03:59:52 +09:00
altair823
87c18a4c2d
feat(v030): SyncSection + ConflictModal — Configure UI + 충돌 해결 UI
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-10 03:56:00 +09:00
altair823
9e48624495
feat(v030): sync IPC + preload (configure / test / list-conflicts / resolve / status)
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-10 03:49:10 +09:00
altair823
62e68dcfe7
feat(v030): settings.sync_repo_url + sync_auto_enabled + sync_interval_min
...
- zod schema 확장: sync_repo_url (nullable), sync_auto_enabled (default true), sync_interval_min (int >= 5, default 30)
- getter/setter 6개 추가 (기존 ai_enabled / onboarding_completed 패턴)
- setSyncIntervalMin 은 non-integer / < 5 reject
2026-05-10 03:44:09 +09:00
altair823
8436846657
feat(v030): SyncService.resolveConflict — local/remote 2 choice (both deferred)
2026-05-10 03:42:50 +09:00
altair823
33588b09df
feat(v030): SyncService.sync — 양방향 6단계 (export/commit/fetch/rebase/re-import/push) + conflict 반환
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-10 03:40:09 +09:00
altair823
9a1f0e269a
feat(v030): ImportService.applySyncFromDir + frontmatter status/dueDate/moveReason round-trip
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-10 03:33:48 +09:00
altair823
bbfd0cccda
feat(v030): NoteRepository.upsertFromSync — sync 전용 3 분기 upsert + single write path
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-10 03:27:49 +09:00
altair823
dba64c546f
feat(v030): GitClient — fetch/rebaseOnto/rebaseAbort/hasUncommittedChanges/listConflicts
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-10 03:23:00 +09:00
altair823
662abdb508
docs(plan): v0.3.0 Cut E — 양방향 git sync (spec 정정: 단위 608, ImportService.run 활용, 'sync' enum 미도입, both deferred)
2026-05-10 03:19:16 +09:00
2e9a82face
Merge pull request 'v0.2.11 Cut D — FTS5 search + 회고 view (F19 A+D)' ( #29 ) from worktree-v0211-cut-d-fts5-review into main
...
Reviewed-on: #29
v0.2.11
2026-05-09 15:52:16 +00:00
altair823
735d5494f2
fix(v0211): importNote 가 rebuildFtsTagsForNote 호출 (final review fix)
...
final code review 발견: F5 import path 가 note_tags INSERT 후 notes_fts.tags 갱신
안 해서 import 한 노트의 tag 가 keyword 검색에서 매칭 안 되는 회귀.
Cut C 의 importNote capture revision 누락 패턴과 동일 — single write path
정책 (Cut D 도입) 의 강제 검사 누락. importNote transaction 끝에서 호출하도록
fix + 회귀 test 2건 (insert path / fork path) 추가.
NoteRepository 안 note_tags INSERT path 는 updateAiResult / updateUserAiFields /
importNote 3곳, 셋 다 rebuildFtsTagsForNote 호출 보장 — invariant 회복.
2026-05-10 00:46:58 +09:00
altair823
5801a98a00
chore(release): v0.2.11 — Cut D (FTS5 search + 회고 view)
...
- F19 promoted (✅ v0.2.11 Cut D — A+D 옵션)
- version 0.2.10 → 0.2.11 (package.json + package-lock.json)
- 단위 569 → 606 (m007 6 + tags sync 2 + ftsHelpers 7 + search 6 + reviewAggregate 5 + IPC 3 + store 3 + SearchBox 2 + ReviewView 3 = 37 신규)
- typecheck 0 errors
2026-05-10 00:41:42 +09:00
altair823
9feb712c60
feat(v0211): ReviewView — 일/주/월 회고 + 헤더 dropdown 진입점
2026-05-10 00:39:36 +09:00
altair823
be125b8ace
feat(v0211): SearchBox + 헤더 mount + inbox 결과 렌더 분기
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-10 00:35:34 +09:00
altair823
f5e43133be
feat(v0211): store — search + reviewData state + actions + view enum 확장
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-10 00:31:53 +09:00
altair823
143684ce8a
feat(v0211): InboxApi.search + reviewAggregate (types + IPC + preload)
2026-05-10 00:27:43 +09:00
altair823
e60a2a23c8
feat(v0211): ftsHelpers + NoteRepository.search + reviewAggregate
...
- ftsHelpers: sanitizeFtsQuery (FTS5 special char escape) + computeCutoff (period → KST 자정)
- search: notes_fts MATCH + status filter + rank order + sanitize + 빈 query → []
- reviewAggregate: period 별 totalCount/recentNotes(50)/tagCounts(DESC)/dueProgress(passed/pending)
2026-05-10 00:24:24 +09:00
altair823
726d155d04
feat(v0211): rebuildFtsTagsForNote 헬퍼 + tags 변경 path 통합 (single write)
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-10 00:19:14 +09:00
altair823
19edeab7b1
feat(v0211): m007 migration — notes_fts FTS5 + trigger 3 + backfill
2026-05-10 00:16:35 +09:00
altair823
1104a8c666
docs(plan): v0.2.11 Cut D — FTS5 search + 회고 view (spec m006→m007 정정 + ai_title/ai_summary + note_tags JOIN)
2026-05-10 00:11:12 +09:00
c4e7536086
Merge pull request 'v0.2.10 Cut C — raw_text 가변 + revision history (F20)' ( #28 ) from worktree-v0210-cut-c-raw-text-revisions into main
...
Reviewed-on: #28
v0.2.10
2026-05-09 14:52:26 +00:00
altair823
39b8d1e728
fix(v0210): importNote 가 capture revision 을 함께 INSERT (final review fix)
...
final code review 발견: F5 import 후 first user edit 시 import 시점 본문이
note_revisions 에 없어 history 에서 사라지는 회귀. importNote transaction 안
INSERT 추가 (createdAt = edited_at).
부수 작업: ImportNoteInput / importNote 의 "raw_text invariant guard" 주석을
v0.2.10 의 'fork-on-id-collision (sync determinism)' 정확한 의미로 갱신.
테스트 +2 — insert path / fork path 모두 capture revision 검증.
2026-05-09 20:59:37 +09:00
altair823
e32223d28c
chore(release): v0.2.10 — Cut C (raw_text 가변 + revision history)
...
- F20 promoted (✅ v0.2.10 Cut C)
- version 0.2.9 → 0.2.10 (package.json + package-lock.json)
- 단위 548 → 567 (m006 5 + create rev 1 + repo 6 + IPC 4 + NoteCard 1 + Modal 2 + findById 회귀 1)
- typecheck 0 errors
2026-05-09 20:53:18 +09:00
altair823
81fbacb21e
feat(v0210): RevisionHistoryModal — 이력 목록 + 회수 confirm + chain 보존
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-09 20:51:13 +09:00
altair823
ff1a015226
feat(v0210): NoteCard 원문 영역 편집 UI (textarea + 저장/취소 + updateRawText)
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-09 20:47:51 +09:00
altair823
b4c2d85b26
feat(v0210): inbox:{update-raw-text,list-revisions,restore-revision} IPC
2026-05-09 20:44:52 +09:00
altair823
7541d3c9e4
feat(v0210): NoteRepository revision API + NoteRevision type + InboxApi 시그니처
...
- updateRawText: raw_text 갱신 + user revision INSERT (atomic)
- listRevisions: edited_at DESC 순 hydrate
- restoreRevision: 옛 raw_text 를 새 user revision 으로 복원 (chain 보존)
- shared/types: NoteRevision + InboxApi 3 메서드 (updateRawText/listRevisions/restoreRevision)
- preload: 3 IPC stub 추가 (inbox:update-raw-text / inbox:list-revisions / inbox:restore-revision)
2026-05-09 20:41:17 +09:00
altair823
18deee5900
feat(v0210): NoteRepository.create 가 capture revision 을 함께 INSERT
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-09 20:36:09 +09:00
altair823
76c23457ee
feat(v0210): m006 migration — note_revisions 테이블 + capture backfill
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-09 20:32:32 +09:00
altair823
88ce78d860
docs(plan): v0.2.10 Cut C plan + spec m005→m006 정정 (Cut B 가 m005 선점)
2026-05-09 20:28:02 +09:00
altair823
07e61bc9e1
docs(plan): v0.2.9 Cut B implementation plan
...
17 task / 9 phase:
- Phase 1 (T1-2): m004 schema (status/status_changed_at/move_reason) + NoteRepository.setStatus/listByStatus + restoreNote 재구현
- Phase 2 (T3): ai_status 'disabled' enum + CaptureService aiEnabled 분기 (skip pending_jobs)
- Phase 3 (T4-5): useInbox view enum 4탭 + 헤더 4탭 UI + listByStatus IPC
- Phase 4 (T6-8): NoteCard 액션 메뉴 + MoveStatusModal (사유 입력 + 4 status 버튼) + setStatus IPC
- Phase 5 (T9-10): classifyStatus AI prompt + ai:classify-status IPC + AI 추천 UI
- Phase 6 (T11-12): OnboardingWizard 3 옵션 + 설치 가이드 + App.tsx 첫 launch 분기
- Phase 7 (T13-14): NoteCard ai_status='disabled' fallback (raw_text 첫 줄) + Banner ai_enabled=false 비활성 + HealthChecker polling 중단
- Phase 8 (T15-16): AiProviderSection AI 자동 처리 토글 + requeueDisabled (ON 전환 후 처리 버튼)
- Phase 9 (T17): 회귀 + dogfood F17/F18/F23 promoted + version 0.2.9 bump
선행 spec: 2026-05-09-v029-cut-b-design.md.
단위 472 → 약 510 (+38) 목표.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-09 17:59:00 +09:00
d59e8388b6
Merge pull request 'v0.2.9 Cut B — status 4분기 + 사유 + Ollama-less (F17/F18/F23)' ( #27 ) from worktree-v029-cut-b-status-reason-ailess into main
...
Reviewed-on: #27
v0.2.9
2026-05-09 08:43:10 +00:00
altair823
3fab44b466
chore(v029): final review minor cleanup — statusLabelWithParticle + initialTarget drop
...
- 한국어 조사 분기: '보관로/휴지통로/활성로' → '보관으로/휴지통으로/활성으로'
('완료로' 만 받침 X). 받침 jongseong 검사 helper.
- MoveStatusModal 의 unused initialTarget prop 제거 + caller (NoteCard) 정리
548/548 + typecheck 0 유지.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-09 16:46:55 +09:00
altair823
f42d03f70c
fix(v029): e2e smoke test 가 OnboardingWizard dismiss 후 inbox 진입
...
Task 11-12 의 wizard 가 첫 launch e2e 환경 차단 — "나중에 설정" 클릭으로
wizard dismiss 후 inbox 헤더/empty state 검증. 회귀 1/1 pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-09 16:42:14 +09:00
altair823
ba08190722
chore(release): v0.2.9 — Cut B (status 4분기 + 사유 + Ollama-less)
2026-05-09 16:40:06 +09:00
altair823
6070562358
feat(v029): NoteRepository.requeueDisabled + countByAiStatus + AiProviderSection 처리 버튼
2026-05-09 16:35:53 +09:00
altair823
c21fca57dd
feat(v029): AiProviderSection AI 자동 처리 토글 + OFF 시 안내문
2026-05-09 16:31:24 +09:00
altair823
49fbed050a
feat(v029): Banner + HealthChecker ai_enabled=false 시 비활성 (store ai_enabled field)
2026-05-09 16:25:24 +09:00
altair823
bc67dea2c8
feat(v029): NoteCard ai_status='disabled' fallback (raw_text 첫 줄 + summary/tags hide)
2026-05-09 16:25:17 +09:00
altair823
c65d6c810e
feat(v029): settings:* IPC (ai-enabled/onboarding-completed/get) + App.tsx 첫 launch 분기
2026-05-09 16:18:27 +09:00
altair823
d2c7bf1b39
feat(v029): OnboardingWizard 3 옵션 + 설치 가이드 link
2026-05-09 16:18:19 +09:00
altair823
d3150976d4
feat(v029): classifyStatus AI prompt + ai:classify-status 정식 구현 (Task 8 stub 대체)
...
- src/main/ai/classifyStatus.ts: prompt + JSON parse + 안전 fallback (archived).
- InferenceProvider.generateRaw 추가 (optional) + LocalOllamaProvider 구현
(Ollama /api/generate format:'json' 으로 raw JSON 응답 반환).
- inboxApi 의 ai:classify-status 핸들러를 stub 에서 정식 호출로 교체
(deps.repo.findById + deps.providerHolder.get + classifyStatus()).
- 신규 테스트 7건 (classifyStatus 단위) + IPC 3건 (note 없음 / AI throw / 정상).
- 회귀: 513 → 522 통과.
2026-05-09 16:09:33 +09:00
altair823
495c3d12a2
feat(v029): NoteCard 이동 메뉴 (status 4분기 dropdown)
...
Cut B Task 6 — 모든 view 공통 "이동 ▾" dropdown.
- 기존 휴지통/삭제 버튼 위치에 dropdown 추가 (모든 mode 공통)
- 현재 status 외 3개 목적지만 표시 (active 노트 → 완료/보관/휴지통)
- 메뉴 항목 클릭 → MoveStatusModal(initialTarget) 열기
- onMoved → local 상태 갱신 + onUpdated + (status 변경 시) onDeleted (list 제거)
- trash mode 의 영구 삭제/복구 버튼은 보존 (휴지통 단독 액션)
- 사용되지 않게 된 handleDelete 제거 (deleteNote 는 capture path 만)
- NoteCard 메뉴 단위 테스트 2건 (메뉴 표시 / 클릭 → modal → setStatus)
2026-05-09 16:03:40 +09:00
altair823
9eb7abc831
feat(v029): MoveStatusModal — 사유 입력 + 4 status 버튼 + AI 자동 분류 placeholder
...
Cut B Task 7 — NoteCard 메뉴가 여는 modal.
- 사유 textarea (선택) + 활성/완료/보관/휴지통 버튼 (옮기기 즉시 setStatus + onMoved)
- 빈 사유 → null reason 전달 (trim 처리)
- AI 자동 분류 버튼 → classifyStatus(stub) 호출 + 추천 표시 + 확정 버튼
- statusLabel helper export (NoteCard 메뉴에서 재사용)
- 4 단위 테스트 (render / 버튼 클릭 / AI 추천 흐름 / 빈 사유 null)
2026-05-09 16:00:51 +09:00
altair823
d4dce9bf34
feat(v029): inbox:set-status + ai:classify-status (stub) IPC
...
Cut B Task 8 — Modal/NoteCard 메뉴 path 의 IPC backbone.
- inbox:set-status: id + status + reason → repo.setStatus, invalid status 거부
- ai:classify-status: stub (Task 9 에서 Ollama provider 호출로 정식 구현)
- types.ts InboxApi.setStatus / classifyStatus 시그니처 + preload wire-up
- 4 단위 테스트 (valid/null reason/invalid status/stub shape)
2026-05-09 15:59:43 +09:00
altair823
92375edc31
feat(v029): 헤더 4탭 (Inbox/완료/보관/휴지통) + count badge
...
- App.tsx: 기존 2탭 (Inbox/휴지통) → 4탭. setView/counts 사용.
- onNavigate 도 setView 로 위임 (mirror state 동기 갱신).
- App.test: 4탭 렌더 + 클릭 → setView('completed') + aria-pressed (3 cases).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-09 15:51:59 +09:00