Skip to main content
CHANGELOG

What shipped

Released versions only, generated at build time from the product Keep a Changelog file. Unreleased work is not listed here: if it is not in a version heading, it has not shipped.

Latest released v3.23.4 · · 61 releases

Currently downloadable v3.25.2-preview.1 · preview channel

Those are two different questions. This page lists versions that have been released, from the product changelog. The download page serves whatever the live preview channel points at, which moves ahead of the last released version with every build. Download the current build from /download. Channel and exact version always come from the live release manifest.

Releases 61–61 of 61

Page 13 of 13

v2.6.0

Stability & Persistence Hardening

이번 릴리스는 daemon 안정성과 세션 영속성을 강화하는 방어·복원 작업이다. 사용자 데이터 파일 포맷 자체는 동일하되, 저장 경로와 에러 처리에 내부 변화가 있다. 업그레이드 시 추가로 할 일은 없다. 자동 마이그레이션으로 처리된다.

Added

  • src/daemon/util/atomicWrite/ — 공통 atomic-write 모듈. tmp→bak→rename 순서와 __proto__/constructor/prototype sanitizer를 한 곳에서 관리한다. SessionManager와 StateWriter의 중복 구현이 이 모듈로 통합된다.
  • src/daemon/util/AsyncQueue.ts — 30~50줄 수준의 자체 Promise 큐. saveDebounced 경로에서 concurrent write 경합을 제거한다. flushSync() 메서드로 종료 시점의 synchronous drain을 보장한다.
  • src/main/ipc/wrapHandler.ts — ipcMain.handle 전용 래퍼. 핸들러 예외를 구조화 JSON 로그({ts, level, event, channel, error_code, stack})로 메인 프로세스 stderr에 기록하고, 에러에 code 속성을 부여한다.
  • .bak rotation chain — save 성공 시 .bak.2→.bak.3, .bak.1→.bak.2, .bak→.bak.1 rename 체인이 실행되어 최근 3개 스냅샷이 유지된다. 읽기 경로는 primary → .bak → .bak.1 → .bak.2 → .bak.3 순서로 fallback한다.
  • Lazy 마이그레이션 프레임워크 — src/daemon/migrations/. load 시점에 스키마 버전을 확인하고 메모리에서만 체이닝 변환한다. 새 포맷 기록은 다음 save에서 이루어진다. 프로덕션 레지스트리는 CURRENT_VERSION=1로 identity 유지 상태다.
  • 손상 파일 격리 — validate 실패 시 파일을 {userData}/corrupted/ 서브디렉토리로 이동하고 CORRUPT_FILE 이벤트를 JSON 로그로 남긴다. 30일 경과 또는 10개 초과 시 오래된 격리 파일이 자동 정리된다.
  • Premigrate 스냅샷 — 스키마 업그레이드가 발생하는 load 경로에서 원본을 {basename}.v{N}.premigrate.bak로 일회성 보존한다. 롤백 자료로 사용된다.

Changed

  • IPC 에러 포맷이 통일된다. 이전에는 핸들러 예외가 renderer로 그대로 promise rejection 되어 stack이 불분명했다. 이번 릴리스부터 메인 프로세스 stderr에 JSON line으로 기록되고, 에러 객체에 code 속성이 붙는다. 사용 가능한 코드는 DAEMON_DISCONNECTED, VALIDATION_ERROR, NOT_FOUND, PERMISSION_DENIED, UNKNOWN이다. renderer 호출부의 응답 값 자체는 그대로 raw value를 반환한다 (정규화는 후속 작업인 T4 useIpc 훅에서 수용 예정).
  • StateWriter와 SessionManager의 내부 구조 — atomic-write 중복 경로를 공통 모듈 호출로 치환했다. 외부 API 시그니처는 변경 없다. saveImmediate는 기존 동기 시그니처를 유지한다(shutdown/suspend emergency sync 경로 호환).
  • Rotation allowlist regex가 ^sessions\.json\.bak(\.[123])?$ 패턴에 한정된다. corrupted/ 디렉토리와 *.premigrate.bak 파일은 rotation 대상에서 제외된다.

Fixed

  • StateWriter/SessionManager의 concurrent save race — AsyncQueue coalescing (같은 key 재진입 시 마지막 값만 실행, key 간은 FIFO 보장)로 해결.
  • IPC 핸들러에서 던진 예외가 메인 로그에 남지 않는 문제 — wrapHandler가 전 핸들러 공통 try/catch 경로로 흡수하고 stderr JSON 로그로 기록한다.
  • validate 실패 시 무음으로 빈 세션이 출발하던 문제 — 손상 파일을 corrupted/로 격리하고, .bak 체인에서 fallback을 시도한다. 복구에 성공하면 즉시 승격 save.

Migration Notes

사용자 데이터 손실은 발생하지 않는다. 업그레이드 절차에서 수동 작업은 없다. 다만 {userData} 디렉토리 내부에 다음 두 종류의 새 경로가 등장한다.

  • {userData}/corrupted/ — validate 실패로 격리된 파일의 보관소. 30일 경과 또는 10개 초과 시 자동 정리된다.
  • {basename}.premigrate.bak — 스키마 업그레이드 load 시점에 생성되는 원본 스냅샷. 자동 정리 대상이 아니다. 수동 삭제 가능(향후 릴리스에서 자동 정리 검토).

플랫폼별 {userData} 경로와 롤백 절차는 docs/upgrade-2026-04-17.md를 참고한다.