UI 복잡 버전 234 RED→GREEN 완료(docs/UI_USECASES.md §A~§J): 라이브 테마 전환(DynamicResource 전환+ThemeResolver+HighContrast 테마, 재시작 없음), 디자인 토큰 체계·WCAG 대비 결함 5건 수정, 설정창 카테고리 내비/검색 재구성+AppConfig 40여 속성, 다운로드 관리자(속도/ETA/세그먼트맵/전체 일시정지-이어받기/CSV 내보내기/예약 게이트/중복 확인), 라이브러리·아카이브·작업공간·재생목록·즐겨찾기 편집 뷰, 접근성(자동화 속성 30여 개·커스텀 피어·docs/ACCESSIBILITY.md), 인터랙션(휠 클릭 새 탭·XButton 탐색·F12·영역 캡처·프로필 전환), 상태/알림(토스트·알림센터·온보딩·CrashReportDialog). 보강 테스트 35건+실창 E2E 4건(StaDispatcher 기반 — 프록시 설정이 기시작 핸들러를 건드리는 크래시 실결함 수정 포함) — 453/453 GREEN. 이전 미커밋 작업(CI 워크플로·Mdns·QueueHub·UpdateChecker·AGENTS/CLAUDE·빌드 스크립트) 일괄 포함
This commit is contained in:
parent
5a0ce730b2
commit
17f2f91152
88 changed files with 9463 additions and 1127 deletions
90
AGENTS.md
Normal file
90
AGENTS.md
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
# AGENTS.md — VideoDownloader 에이전트 작업 계약
|
||||
|
||||
이 파일은 도구 중립 표준(AGENTS.md)이다. Claude Code · Codex · Cursor 등 어떤 코딩 에이전트든
|
||||
작업 시작 시 이 파일을 읽고, 여기 적힌 명령·규약·완료 기준을 따른다.
|
||||
Claude Code 는 `CLAUDE.md` 가 이 파일을 `@AGENTS.md` 로 임포트해 함께 읽는다.
|
||||
|
||||
## 1. 프로젝트 개요
|
||||
|
||||
브라우저 내장 데스크톱 영상 다운로더 + 모바일 컴패니언. 앱 내 브라우저가 재생 중인 미디어
|
||||
(HLS/DASH/MP4)를 감지 → 쿠키·Referer 를 물려받아 다운로드 → 내장 서버로 휴대폰에 스트리밍/전송.
|
||||
|
||||
| 프로젝트 | TFM | 역할 |
|
||||
|---|---|---|
|
||||
| `VideoDownloader.Core` | net8.0 | 다운로드 엔진 (HLS/DASH 파싱, AES-128, 병렬·이어받기, 감지, ffmpeg 리먹스) |
|
||||
| `VideoDownloader.Browser` | net8.0-windows | WebView2 탭 컴포넌트 |
|
||||
| `VideoDownloader.App` | net8.0-windows | 메인 WPF 앱 (브라우저 + 다운로드 UI + 서버 호스팅) |
|
||||
| `VideoDownloader.Server` | net8.0 | ASP.NET 라이브러리. App 안에서 기동, 모바일/웹에 API 제공 |
|
||||
| `VideoDownloader.Mobile` | net10.0-android (+ios on macOS) | MAUI 컴패니언 |
|
||||
| `VideoDownloader.Mobile.Core` | net8.0 | 모바일 공용 로직 (UI 없이 테스트 가능하게 분리) |
|
||||
| `VideoDownloader.Avalonia` | net8.0 | macOS/Linux 셸 (진행 중) |
|
||||
| `VideoDownloader.Cli` | net8.0 | 엔진 검증용 개발 도구 |
|
||||
| `VideoDownloader.Tests` | net8.0-windows | xUnit. Mobile 을 제외한 전 영역 + E2E |
|
||||
|
||||
## 2. 명령 (이 명령들이 진실이다 — 추측하지 말 것)
|
||||
|
||||
```powershell
|
||||
dotnet test VideoDownloader.Tests # 전체 검증. 증분 ~13초, 현재 180/180 통과
|
||||
dotnet build VideoDownloader.App # 데스크톱 빌드
|
||||
dotnet run --project VideoDownloader.App # 데스크톱 실행
|
||||
dotnet build VideoDownloader.Mobile -f net10.0-android # 모바일 (MAUI 워크로드 필요)
|
||||
./build/publish.ps1 -Config Release -Version 1.0.0 # Windows 설치자 → out/
|
||||
bash build/remote/build-remote.sh all # macOS/Linux 원격 빌드 → out/remote/
|
||||
```
|
||||
|
||||
- 솔루션 전체 빌드(`dotnet build VideoDownloader.slnx`)는 MAUI 워크로드가 있어야 통과한다.
|
||||
워크로드 없이 작업할 땐 프로젝트를 개별 지정한다.
|
||||
- 단위 테스트 하나만: `dotnet test VideoDownloader.Tests --filter "FullyQualifiedName~HlsMuxerWiring"`
|
||||
- 환경: Windows 11 · .NET 8/10 SDK 공존 · ffmpeg PATH 필요 · 셸은 PowerShell 7 (Git Bash 도 사용 가능)
|
||||
|
||||
## 3. 작업 방식 — TDD 폐쇄루프
|
||||
|
||||
이 저장소는 **RED → GREEN → 증거** 사이클로 개발해 왔다. 이 순서를 지킨다.
|
||||
|
||||
1. **RED**: 변경 전에 실패하는 테스트를 먼저 쓴다. 실패를 눈으로 확인한다.
|
||||
2. **GREEN**: 최소 구현으로 통과시킨다. `dotnet test` 전체가 통과해야 한다.
|
||||
3. **증거**: UI·플랫폼 동작을 바꿨다면 테스트만으로 부족하다. 실제 앱 실행/에뮬레이터/스크린샷으로
|
||||
확인하고, 무엇을 어떻게 확인했는지 보고에 적는다.
|
||||
4. **문서 동기화**: 계획 대비 구현 상태는 `docs/IMPLEMENTATION_AUDIT.md`, 작업 항목은
|
||||
`docs/BACKLOG.md` 체크박스에 반영한다.
|
||||
|
||||
## 4. 완료 기준 (Definition of Done)
|
||||
|
||||
아래를 모두 만족하기 전에는 "완료"라고 보고하지 않는다.
|
||||
|
||||
- [ ] `dotnet test VideoDownloader.Tests` — **실패 0건**. 테스트 수는 줄지 않는다(180 이상).
|
||||
- [ ] 빌드 **오류 0**. 새로 만든 경고를 남기지 않는다.
|
||||
(기존 경고: `MainWindow.xaml.cs`·테스트의 CS8602 몇 건, xUnit 분석기 경고 — 늘리지 말 것)
|
||||
- [ ] 동작을 바꿨으면 그 동작을 검증하는 테스트가 있다.
|
||||
- [ ] UI/플랫폼 변경이면 실행 증거가 있다.
|
||||
- [ ] 관련 문서(`docs/`)를 갱신했다.
|
||||
|
||||
실패한 것을 통과한 것처럼 보고하지 않는다. 막혔으면 막혔다고 쓴다.
|
||||
|
||||
## 5. 코드 규약
|
||||
|
||||
- **C#**: file-scoped namespace, 4스페이스, Allman 중괄호, `_camelCase` private 필드, nullable enable.
|
||||
세부는 `.editorconfig` 가 강제한다. 공통 빌드 속성은 `Directory.Build.props`.
|
||||
- **주석·커밋 메시지·문서는 한국어.** 기존 코드가 한국어 주석이므로 섞지 않는다.
|
||||
- **테스트**: xUnit. 파일은 `VideoDownloader.Tests/<영역>/<대상>Tests.cs`.
|
||||
영역 = `Browser` · `E2E` · `Infrastructure` · `Mobile` · `Platform` · `Server`.
|
||||
- 에러를 삼키지 않는다. 근본 원인을 고친다. 빈 `catch`, 가짜 폴백 데이터 금지.
|
||||
|
||||
## 6. 경계 — 하지 말 것
|
||||
|
||||
- `.env` 를 커밋하거나 그 값을 출력·로그·문서에 남기지 않는다. 실제 Cloudflare 토큰과
|
||||
빌드머신 SSH 비밀번호가 들어 있다. 템플릿은 `.env.example` 만 추적한다.
|
||||
- `out/`, `publish/`, `bin/`, `obj/` 는 산출물이다. 커밋하지 않고, 내용을 소스로 참조하지 않는다.
|
||||
- `VideoDownloader.App/Assets/*.min.js`(hls/dash/readability)는 서드파티 번들이다. 수정 금지.
|
||||
- 사용자가 요청하지 않은 커밋·푸시·배포를 하지 않는다.
|
||||
- 대규모 리팩터링을 임의로 시작하지 않는다. `MainWindow.xaml.cs` 는 86KB 로 비대하지만,
|
||||
분할은 별도 승인 후 진행한다.
|
||||
|
||||
## 7. 알아둘 함정
|
||||
|
||||
- **WebView2**: 탭마다 인스턴스, Environment 는 공유. dispose 순서를 어기면 UI 스레드에서 죽는다.
|
||||
- **MAUI**: 링커가 안 싣는 타입은 런타임 `FileNotFoundException` 으로만 드러난다
|
||||
(실제 사례: 모달 NavigationPage → `Xamarin.AndroidX.LocalBroadcastManager` 명시 참조로 해결).
|
||||
- **ffmpeg**: stderr 를 읽지 않으면 파이프 버퍼가 차서 hang 한다. 취소 시 `Kill(entireProcessTree)`.
|
||||
- **Avalonia 12.1** 은 .NET 10 SDK 를 요구한다. 8만 있으면 CS0103 으로 실패한다.
|
||||
- 테스트는 `VD_DATA_DIR` 로 사용자 데이터 경로를 격리한다. 실제 사용자 폴더를 건드리지 않는다.
|
||||
Loading…
Add table
Add a link
Reference in a new issue