## 2026-04-17 — CLI 모델 레지스트리 + Gemini/Codex Interactive + 대화형 로그 뷰어 + 세션 Cleanup

### 배경

프로젝트/TODO 설정에서 하드코딩된 모델 목록을 CLI 자체에서 동기화 받아 deprecated 모델을 표시하고, Gemini/Codex도 세션 탭에서 인터랙티브로 사용 가능하도록 확장. 기존 LogViewer는 모든 출력을 평면 `[OUT]` 라인으로만 표시하여 대화 흐름을 따라가기 어려웠던 문제를 Chat/Raw 모드 토글로 해결. 세션에도 워크트리 cleanup 버튼 추가.

### 주요 변경

#### 1. CLI 모델 레지스트리 + deprecated 자동 감지 (`813797f`, `ebe4a8f`, `8b461bc`, `5ba031e`, `da1cf55`, `d232d46`, `8d719e2`)

- **서버**: `model-sync.ts` 신규 — CLI `--help` 파싱 + `src/server/data/cli-models-registry.json` 레지스트리 fallback을 병합(probe 결과 없으면 레지스트리 사용, 있으면 probe 결과로 보강)
- **DB**: `cli_versions` 테이블 + `cli_models.deprecated`, `cli_models.source` 컬럼 추가
- **서버**: `cli-status.ts` — 버전 체크 시 fire-and-forget으로 모델 동기화 트리거
- **클라이언트**: `ModelSettings`, `ProjectHeader`에 deprecated 뱃지 + 포털 기반 tooltip으로 fix guidance 표시
- **빌드**: `build:server`에서 `src/server/data/`를 `dist/server/data/`로 복사(레지스트리 패키징)
- **.gitignore**: `data/` → `/data/`로 좁혀 서버 데이터 디렉토리 추적

#### 2. Gemini/Codex Interactive 모드 활성화 (`8ad5ad5`)

- **서버**: `cli-adapters.ts` — Gemini/Codex 어댑터에 `supportsInteractive: true` 추가
- **클라이언트**: `cli-tools.ts` 동기화 (세션 폼 드롭다운에서 Claude 외에도 선택 가능)

#### 3. 대화형 로그 뷰어 — Chat/Raw 모드 토글 (`a3f5554`)

- **서버**: `log-streamer.ts` — Claude stream-json 이벤트를 평면 `output`이 아닌 `assistant`/`tool_use`/`tool_result` 타입으로 분류, 전체 텍스트 블록을 개행 분리 없이 단일 엔트리로 저장
- **서버**: `session-manager.ts` — 인터랙티브 PTY 출력에 휴리스틱 분류 적용 (● 프리픽스를 assistant 텍스트로, `[Tool:]`/⏺ 패턴을 tool_use로 감지, 연속된 assistant 라인을 하나의 블록으로 누적)
- **클라이언트**: `LogViewer.tsx` 재작성 — Chat 모드(마크다운 assistant 블록 + `▸`/`▾` 접이식 tool_use) / Raw 모드(기존 평면 터미널 뷰). 로그 타입에 따라 자동 모드 감지
- **클라이언트**: `.markdown-content-dark` CSS 추가 (다크 터미널 배경용 마크다운 스타일)
- **PTY 필터**: `pty-output-filter.ts` — 번호 프롬프트 에코(`3> ...`), CLI 상태 바, thinking 애니메이션, block char + 사이드바 텍스트 조합, 워크트리 경로, TUI 메뉴/모드 지시자(☰ ○) 등 노이즈 패턴 확장
- **타입**: `TaskLog.log_type`, `SessionLog.log_type` 유니온 확장
- **i18n**: Chat/Raw 토글 번역 키 추가

#### 4. PTY 스피너/TUI 노이즈 필터 강화 (`77a4fdb`, `6063ad9`, `23849ce`, `2b55f15`)

- **서버**: `pty-output-filter.ts` — 연속 스피너 프레임 접합, 베어 `\r` 애니메이션 라인, 단일 스피너 프리픽스 단편 redraw 필터링
- **서버**: 커서 시퀀스를 제거할 때 공백으로 치환하여 단어 간격 보존 (기존에는 공백이 전부 사라져 단어 경계가 붙던 문제)

#### 5. 세션 워크트리 Cleanup 버튼 + 브랜치 삭제 확인 (`56dc48d`, `fa723aa`, `b2fb1e0`, `ac80db4`)

- **서버**: `POST /api/sessions/:id/cleanup` 엔드포인트 추가
- **서버**: `worktreeManager.cleanupWorktree()`에 `deleteBranch` 파라미터 추가 (기본 true, false면 브랜치 보존)
- **서버**: todo/session cleanup 엔드포인트가 body의 `delete_branch` 수용, false면 DB에 `branch_name` 보존
- **클라이언트**: `SessionList.tsx` — 워크트리 존재 + 실행 중이 아닐 때 Archive 아이콘 버튼 표시
- **클라이언트**: `TodoItem`/`SessionList` — 브랜치 삭제 전 `confirm()` 다이얼로그 (기본 체크), 워크트리 없는 세션에는 cleanup 버튼 숨김
- **i18n**: `session.cleanup`, `cleanup.confirmDeleteBranch` 추가

### 수정된 주요 파일

| 파일 | 변경 내용 |
|------|----------|
| `src/server/services/model-sync.ts` | **신규** — CLI --help 파싱 + 레지스트리 fallback/병합 |
| `src/server/data/cli-models-registry.json` | **신규** — Claude/Gemini/Codex 기본 모델 목록 |
| `src/server/services/cli-status.ts` | 버전 체크 시 model sync fire-and-forget 트리거 |
| `src/server/services/cli-adapters.ts` | Gemini/Codex `supportsInteractive: true` |
| `src/server/services/log-streamer.ts` | stream-json 이벤트 타입 분류 (assistant/tool_use/tool_result) |
| `src/server/services/session-manager.ts` | 인터랙티브 PTY 출력 휴리스틱 분류 + `/cleanup` 지원 |
| `src/server/services/pty-output-filter.ts` | 스피너/TUI 노이즈 패턴 대거 추가 |
| `src/server/services/worktree-manager.ts` | `cleanupWorktree(path, deleteBranch?)` |
| `src/server/routes/sessions.ts` | `POST /:id/cleanup` 라우트 |
| `src/server/db/schema.ts` | `cli_versions` 테이블, `cli_models.deprecated/source` 컬럼 |
| `src/client/src/components/LogViewer.tsx` | Chat/Raw 이중 모드 렌더링 |
| `src/client/src/components/ModelSettings.tsx` | deprecated 뱃지 + tooltip |
| `src/client/src/components/ProjectHeader.tsx` | deprecated 모델 경고 tooltip (포털) |
| `src/client/src/components/SessionList.tsx` | cleanup 버튼 추가 |

### 아키텍처 결정

1. **모델 레지스트리 + probe 병합**: probe만 사용하면 CLI가 `--help` 포맷을 바꿀 때 빈 리스트가 되고, 레지스트리만 사용하면 신규 모델이 누락됨. 둘을 병합(union)하여 안정성과 최신성을 동시에 확보
2. **대화 로그 분류**: 로그를 DB에 저장할 때부터 의미 있는 타입(assistant/tool_use/tool_result)으로 분류해두어 클라이언트 렌더링 비용 최소화. 기존 flat `output`만 있는 레거시 로그는 Raw 모드로 fallback
3. **PTY 필터 패턴 누적**: 스피너/TUI는 CLI 업데이트마다 새 패턴이 추가되므로 `pty-output-filter.ts`에 패턴을 누적 등록하는 방식 유지 (개별 라인 차단 vs 라인 정규화 방식 혼용)
4. **Cleanup 브랜치 보존 옵션**: 워크트리 정리가 항상 브랜치를 삭제하는 기존 동작이 과도했음. confirm 다이얼로그로 "브랜치도 삭제" 여부를 명시적으로 받아 git 이력 보존 가능

---
