--- description: "Task list for 화면 캡쳐 → 챗 첨부 (Screen Capture to Chat)" --- # Tasks: 화면 캡쳐 → 챗 첨부 (Screen Capture to Chat) **Input**: `specs/002-capture-to-chat/` (plan.md, spec.md, research.md, data-model.md, contracts/, quickstart.md) **Tests**: 포함(superpowers TDD + `npm run test`/`dotnet test` 통과 = 완료 기준). 단 오버레이·`CopyFromScreen`·캡쳐 실물은 헤드리스 검증 불가 → 순수부만 단위테스트 + 나머지 수동. **Organization**: user story 1개(P1) = 전부 = MVP. Setup 후 US1. ## Format: `[ID] [P?] [US#?] 설명 (파일경로)` - **[P]**: 다른 파일·무의존 → 병렬. **[US1]**: user story. - 핸드오프: 여기서부터 superpowers 뒷단(`subagent-driven-development` + `test-driven-development`). 단계 끝마다 `specs/002-capture-to-chat/stage-N.md`. --- ## Phase 1: Setup - [ ] T001 `System.Drawing.Common` 패키지 추가 (`3_windowsApp/CodeAssist.Shell/CodeAssist.Shell.csproj`) — `CopyFromScreen`용 - [ ] T002 [P] `PerMonitorV2` dpiAwareness 확인/추가 (`3_windowsApp/CodeAssist.App/app.manifest` — 없으면 생성·csproj `ApplicationManifest` 연결). 스케일 창서 캡쳐 좌표 정확도용 --- ## Phase 2: User Story 1 - 화면 캡쳐해서 챗에 첨부 (P1) 🎯 MVP **Goal**: `Ctrl+Shift+9` → 오버레이 드래그 → 캡쳐 → 새 대화 입력창에 이미지 첨부(썸네일+X). **Independent Test**: 핫키→드래그→놓기 → 챗 입력창에 그 영역 썸네일 첨부가 뜨는지(백엔드 없이). Esc/무효선택 취소, 멀티모니터, 제거·누적. ### Tests (RED 먼저) - [ ] T003 [P] [US1] `bridgeNavigate` capture.image 수신 + `consumePendingCaptureImage`(read-once) 단위테스트 — mock `chrome.webview`, `snippetBridge.test` 스타일 (`2_frontend/src/lib/bridge/bridgeNavigate.test.ts`) - [ ] T004 [P] [US1] `ScreenCapture` 좌표 변환 순수부(선택 DIP rect + 오버레이 원점 + DPI배율 → 물리 px rect) xUnit (`3_windowsApp/CodeAssist.Tests/ScreenCaptureTests.cs`) ### Impl — C# 캡쳐 - [ ] T005 [US1] `ScreenCapture.cs` — `CapturePng(int x,int y,int w,int h): byte[]` (`Graphics.CopyFromScreen`→`Bitmap`→PNG) + 순수 좌표변환 헬퍼(T004 대상) 분리 (`3_windowsApp/CodeAssist.Shell/Platform/ScreenCapture.cs`) - [ ] T006 [US1] `CaptureOverlayWindow.xaml(.cs)` — 전체화면(가상화면) 투명·어두운 오버레이, 십자 커서, 드래그 선택 사각형, `Esc`/무효(너무 작음·클릭만) 취소, 확정 시 DIP→물리 변환→`ScreenCapture.CapturePng`→base64 dataUrl. `event Action Captured` / `event Action Cancelled`. 처리 후 Close (`3_windowsApp/CodeAssist.App/Views/CaptureOverlayWindow.xaml`, `.xaml.cs`) - [ ] T007 [US1] `App.xaml.cs` — 3번째 핫키(id `0x1002`, `MOD_CONTROL|MOD_SHIFT|VK_9`) 등록(멀티핫키 재사용) → 눌리면 `CaptureOverlayWindow` 표시. `Captured`→`ShowPalette()`+`_palette.NavigateApp("/snap/new")`+`_palette.SendCaptureImage(dataUrl)`. `Cancelled`→무시. 핫키 상수 한 곳에 (`3_windowsApp/CodeAssist.App/App.xaml.cs`) - [ ] T008 [US1] `PaletteWindow.SendCaptureImage(string dataUrl)` → `Web.SendToWeb(new { type = "capture.image", dataUrl })` (`3_windowsApp/CodeAssist.App/Views/PaletteWindow.xaml.cs`) ### Impl — 프론트 - [ ] T009 [US1] `bridgeNavigate.ts` — `capture.image` 분기: `pendingCaptureImage` 보관 + `bridge:captureImage`(detail `{dataUrl}`) dispatch + `consumePendingCaptureImage()` export(read-once) (`2_frontend/src/lib/bridge/bridgeNavigate.ts`) - [ ] T010 [US1] `Composer.tsx` — `imageAttachments: string[]` 상태 + 썸네일 ``+X 칩 UI(텍스트 첨부 칩 옆). 마운트 시 `consumePendingCaptureImage()` push + `bridge:captureImage` 구독 push(누적, FR-008). X 제거(FR-007). **전송 시 이미지 미전송 + 정리**(FR-009) (`2_frontend/src/features/snap/components/Composer.tsx`) **Checkpoint**: US1 단독 동작(MVP). **STOP & VALIDATE** — quickstart 1~8. --- ## Phase 3: Polish & 검증 - [ ] T011 `npm run format` → `lint`+`test`+`build` 통과 + `dotnet build 3_windowsApp` + `dotnet test 3_windowsApp/CodeAssist.Tests` 통과 - [ ] T012 quickstart.md 수동 시나리오 1~8 확인(오버레이·캡쳐 내용일치·Esc/무효 취소·멀티모니터·제거·누적·v1 전송경계) - [ ] T013 [P] `specs/002-capture-to-chat/report.md`(계획 vs 결과) 작성 → 최종 승인용 --- ## Dependencies & Execution Order - **Phase 1 Setup** → **US1** → **Polish**. - US1 안: 두 갈래가 `capture.image` 계약에서 만남 — - C# 갈래: T005(캡쳐헬퍼) → T006(오버레이, T005 씀) → T007(핫키·코디, T006 씀) → T008(전송 패스스루). - 프론트 갈래: T009(수신) → T010(Composer, T009 씀). - 두 갈래는 서로 독립(파일 disjoint) → C#/프론트 병렬 가능하나 **implementer는 순차 dispatch**(같은 git index — 스니펫 때 레이스 교훈). - 테스트 T003(프론트)·T004(C#) 서로 [P]. ## Parallel Opportunities - Setup T002 [P]. - 테스트 T003·T004 [P]. - C# 갈래와 프론트 갈래는 파일 disjoint(3_windowsApp vs 2_frontend)라 논리상 병렬이지만, git index 레이스 방지 위해 implementer는 순차로. - **주의**: `App.xaml.cs`·`bridgeNavigate.ts`·`Composer.tsx`는 각 갈래 내 순차(같은 파일 확장). ## Implementation Strategy 1. Setup(패키지·manifest). 2. **US1 = MVP** — C# 캡쳐 파이프라인 + 프론트 수신·첨부. 계약(`capture.image`) 기준 양쪽 맞춤. 3. 단계 끝 `stage-N.md`, 완료 전 `verification-before-completion` + `/code-review`, `report.md` → 승인 → `/cmp` merge. ## Notes - [P] = 다른 파일·무의존. [US1] = 추적용. - 정당 편차(plan §Constitution): v1 이미지 미전송(백엔드 phase). - 재사용: 멀티핫키·SendToWeb·팔레트 소환·navigate·bridge 이벤트 패턴·Composer 첨부칩 — 새로 만들지 말 것. - 오버레이·CopyFromScreen 실물은 수동 검증(T012). 순수부(좌표변환·수신 consume)만 단위테스트.