Skip to content

Releases: Yjason-K/Damwha

Damwha 0.4.1 (macOS)

Choose a tag to compare

@Yjason-K Yjason-K released this 27 Sep 06:06

macOS 15.0 이상, Apple Silicon.

새로 생긴 것

  • 영어 화면. 처음 켜면 맥의 언어를 따라 한국어 또는 영어로 떠요(그 밖의 언어는 영어). 설정 › 일반의 "화면 언어"에서 바꾸면 앱 메뉴까지 바로 바뀌어요. 이번 판에서 번역된 곳은 설정의 일반 카드와 앱 메뉴이고, 나머지 화면은 다음 판부터 차례로 옮겨요.
  • 요약 언어. 설정 › 처리 방식에서 요약·렌즈를 어느 언어로 쓸지 고를 수 있어요(녹취 언어 따름 / 한국어 / 영어). 고르기 전에는 맥의 언어를 따라요. 이미 만든 요약은 바뀌지 않고, 다음 처리나 "다시 만들기"부터 적용돼요.
  • 허깅페이스 토큰을 앱 안에서 넣어요. 토큰이 없어도 앱이 떠요. 첫 실행 안내나 설정의 토큰 섹션에서 넣으면 되고, 토큰이 필요한 작업은 그때 알려 줘요.
  • 다크 테마. 맥의 화면 모드를 따르거나, 사이드바 아래 메뉴에서 밝게·어둡게를 직접 골라요.
  • 모델 받기·삭제. 설정 › 모델에서 쓸 모델을 미리 받고, 안 쓰는 전사·요약 모델을 지워 디스크를 비울 수 있어요. 각 모델의 크기와 남은 용량을 보여 줘요.

고친 것

  • 실시간 녹음이 소리 없이 저장되던 문제를 고쳤어요(마이크 권한 설정 누락).

업데이트할 때

0.4.0에서 올라오면 데이터베이스가 한 단계 올라가요(기존 회의·설정은 그대로예요). 업데이트 전 상태는 앱이 먼저 떠 두니, 문제가 있으면 앱 메뉴 "업데이트 전으로 되돌리기…"를 쓰면 돼요. 앱 안의 새 버전 알림으로 이 판을 받을 수 있어요.

shasum -a 256 -c Damwha-0.4.1-arm64.dmg.sha256으로 받은 파일을 확인할 수 있어요.

Damwha 0.4.0 (macOS)

Choose a tag to compare

@Yjason-K Yjason-K released this 25 Sep 00:19

macOS 15.0 이상, Apple Silicon.

이 판부터 릴리스 태그가 desktop-v 없이 v0.4.0 형식이에요.

새로 생긴 것

  • 새 버전 알림. 앱이 GitHub Releases에서 새 버전을 확인해 알려 줘요(시작할 때 한 번, 그 뒤 24시간마다, 앱 메뉴 "업데이트 확인…"으로 직접). 설치는 지금처럼 DMG를 받아서 해요. 이 알림은 0.4.0부터 작동하므로, 0.3.x에서 0.4.0으로는 이번 한 번만 직접 받아야 해요.
  • 업데이트 전으로 되돌리기. 새 버전을 처음 열 때, 데이터베이스를 올리기 전에 녹음·회의 데이터를 그대로 떠 둬요(최근 2개 보관). 업데이트 뒤 문제가 있으면 앱 메뉴 "업데이트 전으로 되돌리기…"로 업데이트 직전 상태로 돌아간 뒤 이전 버전 앱을 설치하면 돼요. 앱이 메뉴까지 뜨지 않을 때의 수동 절차는 docs/RESTORE.md에 있어요.
  • 강제 종료가 재시도 횟수를 먹지 않아요. 처리 중 앱이 꺼지거나 잠자기로 끊긴 것은 이제 일시 실패 재시도 횟수와 따로 세요. 여러 번 끊겨도 재시도 기회가 줄지 않아요.

업데이트할 때

0.3.x에서 올라오면 데이터베이스가 한 단계 올라가요(기존 회의·설정은 그대로예요). 토큰과 마이크 권한은 다시 묻지 않아요. 소스로 빌드한 이전 버전을 쓰던 맥에서는 키체인 암호를 한 번 물을 수 있어요.

shasum -a 256 -c Damwha-0.4.0-arm64.dmg.sha256으로 받은 파일을 확인할 수 있어요.

Damwha 0.3.1 (macOS)

Choose a tag to compare

@Yjason-K Yjason-K released this 22 Sep 15:43

macOS 15.0 이상, Apple Silicon.

0.3.0에서 모델 다운로드 전 디스크 점검이 필요한 용량을 실제보다 크게 계산해,
공간이 충분한데도 다운로드를 막을 수 있던 문제를 고쳤어요.

설치 후 첫 실행에서 Hugging Face 토큰을 한 번 넣어야 해요.
0.3.0에서 올라오면 토큰과 마이크 권한을 다시 묻지 않아요.
소스로 빌드한 이전 버전을 쓰던 맥에서는 업데이트 후 키체인 암호를 한 번 물을 수 있어요.

shasum -a 256 -c Damwha-0.3.1-arm64.dmg.sha256으로 받은 파일을 확인할 수 있어요.

Damwha 0.3.0 (macOS)

Choose a tag to compare

@Yjason-K Yjason-K released this 21 Sep 12:41

macOS 15.0 이상, Apple Silicon.

0.3.1이 나왔어요. 이 버전에는 모델 다운로드 전 디스크 점검이 필요한 용량을 실제보다 크게 계산해,
공간이 충분한데도 다운로드를 막을 수 있는 문제가 있어요. 가능하면 0.3.1을 받아 주세요.

설치 후 첫 실행에서 Hugging Face 토큰을 한 번 넣어야 해요.
소스로 빌드한 이전 버전을 쓰던 맥에서는 업데이트 후 키체인 암호를 한 번 물을 수 있어요.

shasum -a 256 -c Damwha-0.3.0-arm64.dmg.sha256으로 받은 파일을 확인할 수 있어요.

v0.2.3

Choose a tag to compare

@Yjason-K Yjason-K released this 09 Sep 01:56
c3570ae

Self-hosted install. Setup: deploy/README.md inside the tarball.

v0.2.2

Choose a tag to compare

@Yjason-K Yjason-K released this 08 Sep 05:26
7ea3cd1

Self-hosted install. Setup: deploy/README.md inside the tarball.

v0.2.1

Choose a tag to compare

@Yjason-K Yjason-K released this 07 Sep 13:39

v0.2.0 이후 패치. 스키마 변경은 없다 — 새 마이그레이션이 없고 024까지 그대로다.

v0.2.0을 설치했다면 아래 "업그레이드 시 주의"를 먼저 읽을 것. compose 프로젝트 이름이 바뀌어 옛 DB 볼륨이 새 스택에 따라오지 않는다.

설치가 막히던 문제

v0.2.0의 배포용 compose에는 name:이 없어 프로젝트 이름이 폴더에서 유도됐다. 릴리스 tarball을 풀면 damwha, 레포를 클론하면 deploy가 되는데, 앞의 것은 개발용 be/docker-compose.yml의 name: damwha와 정면으로 겹친다. 컨테이너 이름도 damwha-postgres/damwha-api로 같아서, 이 레포를 클론해 개발 스택을 한 번이라도 띄운 사람은 배포 스택을 시작할 수 없었다 — 중지만으로는 이름이 풀리지 않고 컨테이너를 지워야 했다.

name: damwha-deploy로 고정하고 컨테이너도 damwha-deploy-*로 바꿨다. 볼륨은 이제 폴더 위치와 무관하게 항상 damwha-deploy_pgdata다.

호스트 포트도 3000/5432에서 13000/15432로 옮겼다. 앞의 둘은 pnpm dev와 pnpm db:up이 쓰는 번호라, 레포를 클론한 사람은 개발 스택과 배포 스택을 동시에 띄울 수 없었다. 둘 다 DAMWHA_API_PORT/DAMWHA_DB_PORT로 덮을 수 있다.

새 기능 — make 한 줄로 설치·운영

deploy/Makefile이 README에 흩어져 있던 절차를 타깃으로 묶는다. 릴리스 tarball에도 동봉되므로 레포를 클론한 사람과 tarball로 받은 사람이 같은 명령을 쓴다.

make setup   # .env 생성 + 최신 릴리스 버전으로 맞춤
make check   # 준비물·포트·HF 토큰 점검
make up      # Postgres + API
make worker  # 워커 (포그라운드)
make upgrade # 안전 확인 후 새 판으로

절차 몇 가지는 문서 대신 코드로 강제된다.

  • preflight — 두 포트가 비었는지, DATABASE_URL의 포트가 DAMWHA_DB_PORT와 같은지 본다. 어긋나면 워커가 이 스택이 아닌 Postgres에 붙어 조용히 아무 job도 집지 않으므로 시작 전에 거절한다. 포트 점유 판정에 lsof를 쓰지 않는다 — 포트를 찾고도 접근 거부로 종료해 조용히 무시되는 경우가 있어, docker에 직접 묻고 bash의 /dev/tcp로 도커 밖 리스너까지 본다.
  • check — HF_TOKEN으로 gated 저장소 세 곳을 실제로 찔러 200/401/403을 가른다.
  • upgrade — 진행 중인 녹음(meeting.status='recording' 또는 live_session job)이 하나라도 있으면 아무것도 하지 않는다. 024가 더한 job.committed_bytes를 진행 중인 세션에 사후로 채울 방법이 없기 때문이다.

설치 문서도 make 기준으로 다시 썼다(README 242→185줄, HUGGINGFACE 108→71줄). 대부분 중복이었다.

고친 것 — 실시간 녹음의 마이크 선택

마이크 목록이 "녹음 시작"을 한 번 누른 뒤에야 나왔다. 게이트가 제출 처리 안에만 있어 첫 클릭이 장치 확인, 두 번째가 실제 시작이었는데 버튼 라벨은 두 단계 모두 "녹음 시작"이라 첫 클릭이 아무 일도 안 한 것처럼 보였다.

  • 게이트를 live 탭이 열릴 때로 옮기고 권한을 실제로 요청한다. 승인 전 enumerateDevices()는 label이 빈 문자열이라 "마이크 1/2"밖에 못 띄운다 — 권한을 먼저 받아야 사용자가 무엇으로 녹음하는지 보고 고른다. 프롬프트용 스트림은 그 자리에서 닫는다(붙들면 다이얼로그를 열어 둔 내내 녹음 표시등이 켜져 있다).
  • 마이크 권한 거절을 사유별로 가른다. 장치 없음, 다른 앱이 점유 중(새 안내), 권한 거부가 각각 다른 문구를 받는다 — 전부 "권한이 거부됐어요"로 뭉개면 아무 문제 없는 브라우저 설정으로 사용자를 보낸다.
  • 게이트를 통과하고 마이크를 고른 뒤에만 시작 버튼이 열리며, 실패하면 다이얼로그를 닫았다 열지 않고도 **"다시 확인"**으로 재시도한다. 권한 대기가 탭 전환과 파일 업로드를 잠그지도 않는다.
  • 마이크 목록이 브라우저 기본 드롭다운에서 나머지 UI와 같은 컴포넌트로 바뀌었다.

고친 것 — 요약·렌즈가 인덱스 하나로 통째로 죽던 문제

실시간 녹음 회의(186초)의 요약이 네 번 재시도해서 네 번 다 실패했다.

segments are not in transcript order at utt_6116
segment cites index 10, but valid indexes are 1..4

이 회의의 발화는 4개뿐인데 마지막 하나가 134초(녹음의 72%)에 여섯 가지 주제를 담고 있었다. 모델은 줄 수가 아니라 내용으로 나누므로 6~10개 챕터를 만들려 하고, 쓸 수 있는 경계가 4개뿐이라 마지막 발화를 재사용하거나 없는 번호를 지어낸다. 프롬프트도 모델도 temperature도 그대로라 재시도가 넘어갈 성질이 아니었다.

  • 요약 — 경계를 거절하는 대신 바로잡는다. 범위 밖 인덱스는 범위 안으로 접고, 겹치는 구간은 정규화한다(뒤집힌 경계 되돌리기 · 순서 정렬 · 부분 겹침은 시작을 밀기 · 완전 포함은 앞 구간에 합치기). 불릿은 한 줄도 버리지 않으며 구간의 시간은 여전히 DB 행에서만 파생된다.
  • 렌즈 — 같은 all-or-nothing이 렌즈 추출에도 있었다. 다만 접지 않는다: 렌즈의 근거 인덱스는 "이 발화가 근거다"라는 지목이라 범위 안으로 접으면 엉뚱한 발화에 주장을 붙이게 되고 근거 점프가 관계없는 곳으로 간다. 그 항목만 버리고 로그를 남기며, 보조 근거는 범위 밖인 것만 뺀다.
  • 두 프롬프트에 고를 수 있는 인덱스 범위를 못 박아 애초에 어긋날 확률을 줄인다.

업그레이드 시 주의

1. 옛 DB 볼륨을 옮긴다 (v0.2.0 이하에서 올라오는 경우, 한 번만)

프로젝트 이름이 damwha-deploy로 바뀌면서 옛 볼륨은 새 프로젝트에 따라오지 않는다. 그대로 올리면 빈 DB로 뜬다. 올리기 전에 옮긴다(옛 이름은 docker volume ls | grep pgdata로 확인):

docker volume create damwha-deploy_pgdata
docker run --rm -v <옛이름>_pgdata:/from -v damwha-deploy_pgdata:/to alpine \
  sh -c 'cd /from && cp -a . /to'

옛 볼륨은 되돌릴 자리로 남겨 둔다. 옛 컨테이너(damwha-postgres, damwha-api)는 docker rm -f로 치운다.

동봉된 README.md의 이 안내가 "0.2.0 이전에서 올라오는 경우"라고 적혀 있는데 "0.2.1 이전"이 맞다. 이름·포트 변경이 v0.2.0 태그 뒤에 들어가서, v0.2.0 설치본에도 이 이사가 필요하다.

2. 포트가 바뀌었다

브라우저는 이제 http://localhost:13000, Postgres는 15432다. .env의 DATABASE_URL 포트도 같이 옮겨야 한다 — .env 안에서는 값을 참조할 수 없어 자동으로 맞출 방법이 없다. 어긋나면 워커가 다른 Postgres에 붙어 조용히 아무 job도 집지 않으므로 make check가 그 불일치를 거절한다.

3. 활성 녹음을 비운다

v0.2.0과 같다. 구·신 writer 혼용은 지원하지 않으므로 API와 워커를 함께 갱신한다.

SELECT count(*) FROM meeting WHERE status='recording';
SELECT count(*) FROM job WHERE type='live_session' AND status IN ('queued','running');

둘 다 0인 상태에서 정지 → 새 API·워커 함께 기동. make upgrade가 이 확인을 대신 해 준다. 이미지와 wheel은 같은 태그를 써야 한다(job payload 계약이 그 경계에서만 검사된다).

검증

  • pnpm be test --runInBand — 41 suites / 454 tests
  • uv run --directory be/worker pytest -q — 519 passed
  • pnpm fe test — 61 files / 549 tests
  • pnpm build, pnpm lint, ruff check, pnpm fe verify:worklet — 전부 exit 0

요약 수정은 실패했던 실제 데이터로 확인했다. 네 번 연속 실패하던 그 회의의 요약 job이 수정 뒤 done으로 끝났고 주제 3건·구간 2건이 저장됐다.

미검증: 마이크 권한 게이트의 브라우저 실사용(단위 테스트로만 확인했다 — 실시간 녹음 자체는 돌렸으나 게이트 변경 이전 코드였다). Firefox는 권한을 세션 한정으로 주는 것이 기본이라 게이트와 실제 캡처에서 프롬프트가 두 번 뜰 수 있다(Chrome·Edge·Safari는 origin에 권한이 남아 한 번). HTTPS origin·다른 기기에서의 브라우저 녹음도 v0.2.0과 같이 미검증이다.

설치

damwha-deploy-0.2.1.tar.gz를 풀고 make setup → make check → make up. 자세한 절차는 tarball 안의 README.md에 있다. 이미지는 ghcr.io/yjason-k/damwha-api:0.2.1, ghcr.io/yjason-k/damwha-postgres:0.2.1 (linux/arm64).

v0.2.0

Choose a tag to compare

@Yjason-K Yjason-K released this 07 Sep 07:58

v0.1.2 이후 누적분. 실시간 녹음(라이브 캡처) 이 이번 릴리스의 본체다.

브라우저가 마이크를 잡아 PCM을 올리고, API가 공유 저장소의 WAV에 append하며, 파이썬 워커가 같은 파일을 tail해 미리보기를 전사한다. 회의가 끝나면 그 WAV가 그대로 정본 처리로 들어간다.

새 기능

  • 실시간 녹음 (#15). 브라우저 마이크 캡처 → 32,768바이트 청크 업로드 → 워커의 라이브 미리보기 전사. 녹음 중 배너에 경과 시간과 실시간 전사가 뜬다. 워커 heartbeat가 90초를 넘으면 "신호 끊김"을 표시하고, 그 상태의 버튼은 종료 대신 회의를 닫는 취소가 된다.
  • 공개 데모 배포와 안내형 둘러보기 (#14). 데모 빌드는 GET 외 요청을 클라이언트에서 먼저 막는다.
  • 회의 기준일시 필수화 (#13). meeting.recorded_at이 NOT NULL이 됐다.

캡처 정합성 (#16)

라이브 녹음 경로에 남아 있던 네 가지 실패를 닫았다.

  • 파일 길이가 append 오프셋의 진실이었다. 쓰기 도중 죽으면 미확정 꼬리가 남고 그 아래 전부가 그걸 신뢰했다. 이제 job.committed_bytes — fdatasync 후 DB commit한 연속 prefix — 가 유일한 진실이고, job.sealed_bytes가 최종 길이를 표시한다. 크래시 시 미확정 꼬리는 truncate되고 같은 요청을 재전송해 복구한다.
  • 워커 장애가 녹음 전체를 죽였다. OOM·SIGTERM·연속 클립 실패가 회의를 실패로 만들었다. 이제 미리보기 실패는 job에만 격리되고 회의는 recording으로 남아 append를 계속 받는다.
  • orphan 스캐너가 살아 있는 세션을 덮어 봉인했다. 후보 조회와 실제 봉인 사이에 성공한 append가 끼면 그 녹음이 끝났다. 이제 잠금 획득 뒤 생존 조건을 재검증한다.
  • 브라우저가 마이크를 얻기 전에 회의를 만들었고, Worklet에 자투리를 요청하지 않고 그래프를 끊었다. 권한 거절이 빈 회의를 남겼고 마지막 최대 511샘플이 유실됐다. 이제 준비를 끝낸 뒤에만 회의를 만들고, flush ACK를 받은 뒤 종료하며, 자투리는 stop 본문에 실려 간다.

정본 처리 job은 정확히 하나만 생긴다 — 워커는 running + locked_by + sealed=committed일 때만, API는 queued/failed일 때만 finalize하며 서로소다.

마이그레이션

순서대로 적용된다. 전부 additive이며 024의 CHECK는 type='live_session'에만 걸린다.

파일 내용
021_meeting_recorded_at_not_null.sql meeting.recorded_at NOT NULL
022_live_session.sql live_session job 타입과 live_utterance
023_live_browser_capture.sql job.sealed_bytes, job.last_input_at
024_live_committed_bytes.sql job.committed_bytes + CHECK

업그레이드 시 주의

구·신 writer 혼용은 지원하지 않는다. 활성 녹음을 비운 유지보수 창에서 API와 워커를 함께 갱신해야 한다.

SELECT count(*) FROM meeting WHERE status='recording';
SELECT count(*) FROM job WHERE type='live_session' AND status IN ('queued','running');

둘 다 0인 상태에서 API·워커 정지 → 024 적용 → 새 API·워커 함께 기동. 이미지와 wheel은 같은 태그를 써야 한다(job payload 계약이 그 경계에서만 검사된다).

검증

  • pnpm be test --runInBand — 41 suites / 454 tests
  • uv run --directory be/worker pytest -q — 512 passed
  • pnpm fe test — 61 files / 537 tests
  • pnpm build, pnpm lint, ruff check, pnpm fe verify:worklet — 전부 exit 0

크래시 복구는 실제 자식 API 프로세스를 SIGKILL하는 e2e로 검증한다. 경합은 임의 sleep이 아니라 DB 잠금과 pg_blocking_pids로 순서를 강제한다.

미검증: HTTPS origin·다른 기기에서의 브라우저 녹음(검증 환경에 HTTPS origin과 두 번째 기기가 없었다), pre-024 레거시 세션 분기(위 절차가 녹음을 비우므로 실사용 도달 불가).

설치

damwha-deploy-0.2.0.tar.gz를 풀고 README.md를 따른다. 이미지는 ghcr.io/yjason-k/damwha-api:0.2.0, ghcr.io/yjason-k/damwha-postgres:0.2.0 (linux/arm64).

v0.1.2

Choose a tag to compare

@Yjason-K Yjason-K released this 27 Aug 04:22

Team trial. Setup: deploy/README.md inside the tarball.

v0.1.1

Choose a tag to compare

@Yjason-K Yjason-K released this 27 Aug 02:01

Team trial. Setup: deploy/README.md inside the tarball.