Commit Graph

19 Commits

Author SHA1 Message Date
f38776d71f feat: 구간 JSON에 title_top/title_main 선택 필드 — 검토 화면 제목 자동 채움
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-07 12:13:19 +09:00
b49946a4cd feat: 배경 흰색 체크 상태를 localStorage 로 기억
체크를 해제하고 쓰는 사용자가 매번 다시 해제해야 했다 — 바꿀 때마다
저장하고 페이지를 열 때 복원한다(저장값 없으면 기본 체크 유지).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-06 11:46:22 +09:00
b5586ecb9c feat: 배경 검정이면 댓글 카드를 흰색 테마로 캡처
검은 카드가 검은 배경에 묻혀 윤곽이 안 보이던 문제 — 캡처 공용 함수
captureCard() 가 흰색 배경 체크 상태를 보고 캡처 순간에만 .light(흰 바탕
+ 짙은 글씨)를 붙였다 뗀다. 세 탭 공용, 검토 화면 표시는 어두운 테마 유지.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-06 09:23:15 +09:00
9b2cc96e3e fix: 긴 댓글 카드가 출처를 덮던 문제 — 캡처 5줄 말줄임 + 드래프트 축소 안전망
카드 캡처는 댓글 길이만큼 세로로 자라는데 배치 높이 한계(영상 아래~출처
사이 약 640px)가 어디에도 없어 장문 댓글이 출처(@채널)와 화면을 덮었다.
1차: 카드 본문을 최대 5줄 말줄임(검토 화면 = 캡처 결과라 WYSIWYG).
2차: 그래도 표시 높이가 한계를 넘는 카드는 draft 배치에서 비율 축소.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 15:59:43 +09:00
5295d92dfc fix: 같은 컷 그룹 안에 같은 댓글 카드가 두 장 뜨던 중복 제거
컷별 '채우기' 섹션(cand)이 그 컷 추천(rec)에 이미 나온 카드를 제외하지 않아,
타임스탬프 없는 댓글이 추천되면 추천 섹션과 채우기 섹션에 쌍으로 떴다.
다른 컷의 복사본은 '이동'용 쌍둥이라 그대로 두고, 같은 컷 안에서만 거른다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 15:51:00 +09:00
7ea17127b1 fix(important): 자동 탭 "무음 제거" 체크박스를 붙여넣기 탭과 동일하게 숨김
/auto/prepare가 댓글 매칭을 위해 remove_silence=True·asr_bottom=True를
고정하고 /auto/build도 remove_silence 값을 아예 받지 않아, 공통 옵션의
무음 제거 체크박스가 자동 탭에서 죽은 컨트롤이었다(꺼도 무음이 제거됨).
붙여넣기 탭과 대칭으로 setMode()에서 자동 탭일 때도 체크박스를 숨기고,
네 가지 방식(full/whole/wpaste/paste) 도움말 문구에 "무음 제거·받아쓰기는
항상 적용됨"을 명시해 "아래 공통 옵션을 따른다"던 옛 오해성 문구를 바로잡았다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 13:27:44 +09:00
e88571e5e9 fix(important): 자동/구간/붙여넣기 탭 간 검토 상태(byIdx·sel·selCut) 오염 방지
세 result 핸들러(onPrepareResult/onYtResult/onPasteResult)가 byIdx는
전역 리셋하면서 sel/selCut은 자기 탭 키만 건드려, 한 세션에서 두 탭을
쓰면 칩이 다른 탭 댓글을 가리키거나 "ID n 사용중" 오표시가 뜨고, 이미
그려진 다른 탭 카드를 클릭하면 sel[hlId]가 undefined라 toggle()에서
TypeError가 났다(const selCut 재할당 시도 자체도 원래 런타임 에러였음
— let로 변경). "검토는 한 번에 하나" 원칙으로 세 핸들러 모두 byIdx·
sel·selCut을 전역 리셋하고, 다른 탭의 검토 DOM·빌드 버튼도 clearOtherPanels()
로 함께 지워 클릭 경로 자체를 없앴다.

grep 대조: byIdx/sel/selCut을 읽고 쓰는 곳(toggle/sortSel/cutFull/
refreshSel/wrapOf/usedByOthers/applyUsedMarks/buildAll류)은 모두 hlId로
키를 참조하므로 이번 전역 리셋과 일관되게 동작한다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 13:27:25 +09:00
6ab3d998e9 fix(critical): 유튜브 구간 탭 시간 형식 불일치로 전면 불능이던 것 수정
ytRanges()가 구간을 초 숫자로 /yt/analyze에 보내는데 다운로드 경로의
cut_youtube()→valid_time()은 MM:SS/HH:MM:SS만 통과시켜, 모든 분석이
다운로드 단계에서 "시간 형식 오류"로 죽고 있었다. 프런트는 입력칸에
이미 들어있는 fmtTime 포맷 문자열을 그대로 보내도록 되돌리고, 서버
(_parse_ranges)도 parse_time()으로 초 환산 후 valid_time이 통과하는
형식으로 재포맷해 프런트가 무엇을 보내든 다운로드 경로까지 안전하게
닿도록 방어를 추가했다. 스크래치패드 스크립트로 정상 케이스·구
버그 케이스·1시간 이상 구간까지 valid_time 통과를 확인했다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 13:26:55 +09:00
e650cfb992 자동 탭: 분석→준비→검토 3단계로 쪼개 받아쓰기를 제외 선택 뒤로 미룸
검토 화면의 ✕ 제외 버튼 때문에, 받아쓰기(다운로드·Whisper)를 제외 선택 전에
돌리면 CPU를 낭비한다. /auto/stream은 이제 편집안·타이틀 후보(highlights)만
내고 댓글 매칭을 하지 않는다. 새 /auto/prepare(POST)+/auto/prepare/{pid}(SSE)가
제외 안 한 ID만 순차로 다운로드·받아쓰기 + h-lab 댓글 매칭을 돌려 PSTATES에
담고, /auto/build는 그 상태로 paste_draft만 실행한다(다운로드·받아쓰기 재실행
없음). 화면은 1차 검토(하이라이트 카드: 제목 선택·제외·편집안 접기)와 2차
검토(기존 컷별 댓글 선택 화면, renderCutPanel 등 캡처 루프 그대로 재사용)로
분리했다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 12:33:47 +09:00
3c013dcc88 유튜브 구간 탭에 붙여넣기 탭과 같은 분석→검토→생성 흐름 연결 (Task 6)
죽은 /yt/comments, /youtube 를 부르던 구식 화면(💬 구간 댓글 매칭 버튼, ytMatch,
window.ytCC)을 걷어내고 "편집 시작"이 /yt/analyze→SSE /yt/stream 을 돌게 했다.
검토 영역 위에 제목·출처 입력칸을 둬 분석 후에도 고칠 수 있게 하고, 생성
(/yt/build) 때 그 값을 보낸다 — bg_draft 가 title_*/channel 을 state 에서만
읽으므로 /yt/build 에도 그 세 필드를 추가해 state 를 덮어쓰게 했다(server/app.py,
브리프의 파일 목록엔 없었지만 이 요구사항 자체가 성립하려면 꼭 필요했다).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 12:05:19 +09:00
447e8808ff 붙여넣기 탭에 댓글 선택 화면 추가 (Task 4) + 서버 매니페스트 보정
병렬 세션에서 구현된 것을 검증 후 커밋. Task 3 리뷰가 짚은 (a)~(e) 전부 반영:
analyze manifest 에서 draft 스텝 제외(영원히 대기하던 것), comments start 이벤트,
build 스트림 manifest, 무음 제거 체크박스 숨김(항상 켜지므로), cuts_from_state
try/except(실패 시 cuts=None 으로 / 폴백 화면).

캡처 함정 3종(검색 해제·컷 펼침·selonly 해제)과 append/push 쌍 실행, 캡처 실패
n-- 까지 자동 탭과 동일하게 처리됨을 확인함.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 11:14:47 +09:00
011c042778 자동 탭: 🔤 단어겹침 배지 표시 + AI 추천 실패 경고 문구 명확화
WHY 배지 맵에 word:"🔤" 를 더해 3순위(단어 겹침)로 배정된 카드가 화면에서
구분되게 했다(다른 곳엔 why 값을 쓰는 곳이 없어 auto.js 한 곳만 고치면 된다).
"AI 추천 실패 — 타임스탬프만으로 배정했습니다" 문구는 로그 영역에 묻혀
사용자가 못 보던 경고였다. 무엇이 실패했고(Gemini 응답 없음) 그래서 어떻게
됐는지(분:초·자막단어·좋아요로 대체)가 한 문장에서 드러나도록 고쳤다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 18:43:39 +09:00
058f03265c 리뷰 반영: selonly 캡처 함정 차단, 더보기/검색 재렌더 링 오류, 검색 중 접힌 컷 결과 숨김 수정
Critical: wrapOf가 ci를 몰라 '선택한 것만 보기' 중 배정 안 된(=display:none) 쌍둥이를
캡처하는 조용한 실패가 있었다. wrapOf(hlId,idx,ci)로 정확한 복사본을 찾게 하고,
buildAll에서 selonly를 이중으로 꺼서 방어한다. 칩 클릭 스크롤도 같은 방식으로 고쳤다.

Important: cardSection.render()가 컷 판정 없이 링을 붙여 '더보기'·검색 재렌더 때 증상이
되살아났다 — refreshSel과 같은 판정식을 render()에 직접 넣었다(패널이 아직 document에
안 붙어 있는 초기 구성 중에도 정확히 동작해야 하므로 refreshSel 재호출 대신 선택).

Important: 검색이 섹션 단위로만 display를 토글해 닫힌 컷 아코디언 안의 결과가 안 보였다.
검색 중엔 그 패널의 컷을 전부 펼치고, 지우면 검색 시작 전 열림 상태로 되돌린다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 18:13:00 +09:00
d1ebfaff74 자동 탭: 컷별 쌍둥이 카드 혼동 해소 + 컷 섹션 아코디언
같은 댓글이 컷마다 반복 렌더되는데 카드 DOM에 컷 번호가 없어 refreshSel()이
모든 복사본에 선택 링을 붙였다(1컷에서 고른 게 2컷에도 체크된 것처럼 보임).
쌍둥이를 눌러도 다른 컷으로 옮기려는 의도인데 무조건 해제됐다.

- cardEl에 data-ci를 남기고, refreshSel은 실제 배정된 컷의 복사본에만 링을 부여
- 다른 컷에 배정된 쌍둥이는 기존 .ccused 배지 구조를 재사용해 "컷 N에서 사용중"으로 표시
- 이미 선택된 쌍둥이를 다른 컷에서 누르면 해제 대신 그 컷으로 이동(sortSel로 순서 유지)
- 컷마다 추천+채우기 섹션을 아코디언으로 묶어 한 번에 한 컷만 펼침(카드 폭증 완화),
  헤더에 컷 채움 상태를 실시간 표시
- 빌드 캡처 직전 expandAllCuts()로 모든 컷 섹션을 강제로 펼침
  (검색 필터 때와 같은 함정 — 접힌 섹션의 카드는 domToBlob이 빈 이미지로 찍는다)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 18:02:55 +09:00
22a9758e74 auto.js: 카드 패널 렌더러를 renderCutPanel()로 통합
onResult(자동 탭)과 ytMatch(구간 탭)에 각각 있던 검색창+컷별/ 섹션+후보
렌더 블록이 두 갈래로 갈라져 있어, 곧 붙여넣기 탭까지 더해지면 한 곳만
고치는 실수가 나기 쉬웠다. 두 블록을 renderCutPanel(box,panelId,data,opts)
하나로 합쳐 배지·검색·선택 상한 로직을 한 곳에 모았다.

화면 문구는 완전히 동일하게 보존했다 — 특히  폴백 라벨은 onResult가
"이 구간을", ytMatch가 "구간을"로 이미 서로 달랐기에, unit 값에 따라
원문 그대로 재현하도록 분기했다(무작정 unit을 문자열에 꽂지 않음).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 17:20:21 +09:00
20a7c0c0a2 feat: 댓글 선택 화면에 검색(필터) 추가
카드가 수백~수천 장이라 원하는 댓글을 눈으로 찾기 어려웠다. 패널마다 검색창을
두고 모든 카드 섹션이 자기 전체 목록에서 필터링한다 — '더보기'로 안 펼친 카드도
검색되면 나온다.

캡처 누락 방지: 빌드/캡처는 wrapOf() 로 DOM에서 카드를 찾고 없으면 조용히
건너뛴다. 검색으로 선택 카드가 DOM에서 빠질 수 있으므로 buildAll 과
ytCC.capture 시작 시 clearSearch() 로 강제 해제한다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 16:05:41 +09:00
c6092a93ac 섹션을 컷 안으로 흡수 — 고른 카드가 마지막 컷에 처박히지 않게
독립 " 좋아요 상위 후보" 섹션은 cardSection 에 ci 를 안 넘겨서
toggle(hlId,idx,undefined) → selCut 에 기록 안 됨 → 빌드 때 마지막 컷으로 폴백했다.
계획서는 "맨 뒤로 가니 마지막 컷 뒤에 붙는다, 배치상 문제 없다"고 적었는데 틀렸다.
_cards_by_cut 은 컷 뒤에 붙이지 않고 **컷 안에서 균등 분할**한다 —
4초짜리 마지막 컷에 5장이 들어가면 0.8초씩 번쩍인다.

AI 프롬프트가 "억지로 채우지 마라, 없으면 빈 배열로 둬라"라고 지시하므로
quota 미달이 기본 동작이고, 스펙 §7 은 그 미달을 "사람이 에서 채운다"로 풀었다.
즉 이건 예외가 아니라 주 워크플로다.

- hl.cuts 가 있으면 컷마다 두 섹션(둘 다 ci=cu.i):
  ① 컷 N · X초 · 카드 Q장 — 자막   ② ↳ 좋아요 상위에서 채우기
  ②는 컷마다 반복되므로 초기 렌더를 6장(CUT_FILL_PAGE)으로 줄이고 나머지는 더보기.
- 마지막 컷 폴백 제거. ci 가 없으면 엉뚱한 컷에 넣지 말고 그 카드를 건너뛴다
  (fd.append("cards") 와 sentCuts.push 는 반드시 쌍으로 — 하나만 돌면 전부 어긋난다).
- hl.cuts 가 없는 폴백 경로( + 독립 )는 그대로 둔다.

같이: 컷 섹션의 '나머지'를 그 컷 시간대 언급 댓글로 좁혔다.
hl.matched 전체를 컷마다 복제하면 컷 12개 × 30장 = 360장, 하이라이트 5개면 1800장으로
부풀고(기존 300장) 같은 댓글이 여러 섹션에 중복돼 한쪽을 고르면 쌍둥이까지 하이라이트됐다.
데이터(byIdx[i].times, paste.cuts[i].start/end)는 이미 클라이언트에 다 있다.
호출되지 않는 죽은 함수 cutOf() 도 제거.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 14:15:06 +09:00
5b58e94ad1 검토 화면을 컷별 카드 묶음으로 렌더
서버가 하이라이트마다 컷 단위 추천(hl.cuts)을 내려주기 시작해서(6~8번
커밋), 화면도 컷 소속을 알아야 카드를 그 컷 구간 안에 배치할 수 있다.
카드가 어느 컷에 속하는지(selCut)를 추적해 컷별 상한(quota)을 걸고,
sel[hlId]를 항상 컷 순서로 정렬해 업로드 파일명(001.png…)과
card_cuts 배열 인덱스가 어긋나지 않게 했다. hl.cuts가 없으면(추천
실패) 기존  통짜 화면으로 그대로 폴백한다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 12:28:11 +09:00
bf1b387d6d chore: git 저장소 초기화 (기존 코드 스냅샷)
컷별 댓글 추천 작업을 태스크 단위로 되돌릴 수 있게 버전관리를 시작한다.
.gitignore 로 영상·캐시(.downloads 2.7G, .comments 72M, .media 28M)와
비밀키(.gemini_key)를 제외했다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 11:36:05 +09:00