From 89942524feb2fa75e1f2841d8ba00b4cd8679f64 Mon Sep 17 00:00:00 2001 From: Seungpyo1007 Date: Fri, 7 Aug 2026 12:02:57 +0900 Subject: [PATCH] =?UTF-8?q?Phase=202=20=EC=A1=B0=EC=82=AC=20=EA=B2=B0?= =?UTF-8?q?=EA=B3=BC=EB=A5=BC=20=EC=A0=81=EA=B3=A0,=20=EB=81=9D=EC=9D=98?= =?UTF-8?q?=20=EC=A0=95=EC=9D=98=EB=A5=BC=20=ED=99=95=EC=A0=95=ED=95=9C?= =?UTF-8?q?=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 무엇이 있고 무엇이 빠졌는지 모르는 채로는 "끝냈다" 를 말할 수 없다. 네 기둥 (DESIGN.md 2.1~2.4)을 기준으로 코드를 훑어 표로 정리한다. 먼저 나온 것은 표가 아니라 이것이다 — 끝의 정의가 두 문서에서 다르고 둘 다 현실과 다르다. DESIGN.md 의 Phase 2 는 "Code-OSS 포크로 이전" 이고 README 는 "에디터 코어 렌더러 레벨 시각 효과 심화" 인데, 이 앱은 포크가 아니라 Electron + React + Monaco 로 처음부터 자기 렌더러를 갖고 있다. 포크가 필요했던 이유가 애초에 없다. 원래 목표는 다른 방법으로 이미 달성됐고, 남은 것은 포크 여부가 아니라 네 기둥이 화면에 있느냐다. 판정: - 2.3 작업 상태·계획 패널은 끝났다. 현재 행동·계획 뷰·툴 로그·토큰 미터 네 항목 모두 실제 경로로 채워진다. - 2.1 은 글로우와 잔광, undo 한 덩어리가 있고 커서 고스트가 없다. 스트리밍 삽입은 완성된 텍스트의 재생이라 모델이 쓰는 속도와 무관하다. - 2.2 는 거터 색이 git 기준이고, 사유는 카드에만 있으며, CodeLens 는 registerCodeLensProvider 호출이 0건이다. - 2.4 는 배지·진행 표시·점프가 있고 그리드가 아니라 막대 목록이다. 그래서 완료 조건을 셋으로 확정한다 — 커서 고스트, 변경 사유 툴팁, CodeLens 수락/거절. 설계가 이름으로 적었는데 코드에 없는 것들이고, 셋 다 데코레이션 계층 위에 얹힌다. 포크 항목은 아키텍처가 달라져 해당 없음으로 닫는다. 나머지 △ 는 설계와 다른 방식으로 이미 답이 있는 것들이라(전체 diff 는 별도 탭, 파일 개요는 목록) 문구에 맞춰 바꾸는 것은 Phase 2 완료가 아니라 별개의 UI 결정으로 남긴다. --- docs/PHASE2-SURVEY.md | 75 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 docs/PHASE2-SURVEY.md diff --git a/docs/PHASE2-SURVEY.md b/docs/PHASE2-SURVEY.md new file mode 100644 index 0000000..4bd6f9e --- /dev/null +++ b/docs/PHASE2-SURVEY.md @@ -0,0 +1,75 @@ +# Phase 2 조사 — 무엇이 있고 무엇이 빠졌나 + +작성일: 2026-08-05 · 기준 커밋: `develop` (main 대비 50커밋) · 목적: "Phase 2 를 끝냈다" 고 말하려면 끝의 정의가 먼저 필요하다 + +--- + +## 0. 먼저: 끝의 정의가 두 문서에서 다르고, 둘 다 현실과 다르다 + +- [DESIGN.md](DESIGN.md) 의 **Phase 2 는 "Code-OSS 포크로 이전"** 이다. 확장 API 로 불가능한 시각 효과를 위해 VSCodium 방식으로 포크한다는 계획이었다. +- [README.md](../README.md) 의 **Phase 2 는 "에디터 코어의 렌더러 레벨 시각 효과 심화"** 로 적혀 있고 *(in progress)* 다. +- **실제로는 둘 다 아니다.** 이 앱은 Code-OSS 포크가 아니라 Electron 43 + React 18 + Monaco 로 **처음부터 자기 렌더러를 갖고** 있다. 포크가 필요했던 이유(렌더러에 손댈 수 없다)가 애초에 없다. + +즉 Phase 2 의 원래 목표는 **다른 방법으로 이미 달성됐고**, 남은 것은 포크 여부가 아니라 **네 기둥(DESIGN.md 2.1~2.4)이 실제로 화면에 있는가** 다. 아래 표의 기준은 그 네 기둥이다. + +판정은 코드로 확인한 것만 적는다. △ 는 "비슷한 것이 있으나 설계가 말한 자리에 없다" 는 뜻이다. + +--- + +## 1. 2.1 편집 과정 애니메이션 + +| 항목 | 상태 | 확인한 것 | +|---|---|---| +| 스트리밍 삽입 | △ | [editAnimator.ts](../ide/src/editor/editAnimator.ts) 가 16ms마다 3글자씩 모델에 밀어 넣는다(최대 2200ms). 다만 흘리는 것은 **이미 완성된 최종 텍스트의 재생**이지 모델의 토큰 스트림이 아니다. 설계는 "토큰 스트림을 그대로 흘려서" 라고 적었다. | +| 글로우/하이라이트 | ✓ | `.sz-ai-typing`(쓰고 있는 줄) + `.sz-ai-changed`(1.4초 잔광, `szAiFade`). `reducedMotion()` 을 직접 물어 모션 최소화도 지킨다. | +| 커서 고스트 | ✗ | 없다. 코드베이스 어디에도 유령 커서가 없다. | +| undo 한 덩어리 | ✓ | 타이핑 시작에 `pushStackElement` 한 번 — Ctrl+Z 로 AI 편집 전체가 한 번에 돌아온다. | + +## 2. 2.2 변경 diff 시각화 + +| 항목 | 상태 | 확인한 것 | +|---|---|---| +| 인라인 diff 색 | △ | 거터 막대는 있다(`.sz-gd-add/mod/del`, [MonacoPane.tsx](../ide/src/editor/MonacoPane.tsx) 245~254). 그런데 그건 **git 기준 변경**이다. 아직 수락하지 않은 제안은 편집기 안에 안 보이고, 전체 diff 는 별도 탭([DiffPane.tsx](../ide/src/editor/DiffPane.tsx), `createDiffEditor`)에서 본다. | +| 변경 사유 툴팁 | △ | `rationale` 은 있고 제안 카드에 보인다(App.tsx:8387). 설계가 말한 자리 — **바뀐 줄 위의 툴팁** — 에는 없다. | +| 라인 단위 수락/거절 | △ | 헝크 단위 선택이 있다([review/hunks.ts](../ide/src/review/hunks.ts), `hunkSel`). 다만 카드 안에서 고르는 것이고, 설계가 적은 **CodeLens** 는 없다(`registerCodeLensProvider` 호출이 0건). | +| 변경 그룹핑 | △ | 한 제안 안에서 헝크로 묶인다. 파일을 가로지르는 "논리적 변경 하나" 묶음은 없다. | + +## 3. 2.3 AI 작업 상태·계획 패널 + +| 항목 | 상태 | 확인한 것 | +|---|---|---| +| 현재 행동 | ✓ | `statusKey` 가 도구 실행·편집·검토를 따라간다. | +| 계획 뷰 | ✓ | `set_plan` 도구 → `plan` 상태 → 패널. 체크·진행·예정이 구분된다. | +| 툴 호출 로그 | ✓ | `addTool`/`setTool` 로 타임라인에 남고 펼쳐서 출력까지 본다. | +| 토큰/비용 미터 | ✓ | `bumpAgent(tin, tout)` + 잔여량 조회. | + +**이 기둥은 끝났다.** 네 항목 모두 실제 경로로 채워진다. + +## 4. 2.4 멀티파일 동시 편집 뷰 + +| 항목 | 상태 | 확인한 것 | +|---|---|---| +| 미니 파일 그리드 | △ | `renderChangeOverview`(App.tsx:8532)가 있다. 다만 **카드 그리드가 아니라 막대가 붙은 목록**이고, 파일이 2개 이상일 때만 뜬다. | +| 변경량 배지 | ✓ | 파일마다 `+N / −N`, 가장 큰 파일 기준 상대 막대. | +| 동시 진행 표시 | ✓ | 파일마다 점 색으로 pending·failed·담당 에이전트를 구분한다. | +| 카드 클릭 → 점프 | ✓ | 누르면 그 파일을 연다. | + +--- + +## 5. 그래서 Phase 2 의 "끝" 을 무엇으로 둘 것인가 + +포크는 판단에서 뺀다 — 이 구조에서는 할 이유가 없고, 하지 않은 것이 맞다. 남은 것은 네 기둥의 빈칸이고, 그중 **설계가 이름으로 적었는데 코드에 없는 것**은 셋이다. + +1. **커서 고스트** (2.1) — 없다. AI 가 지금 어디를 고치는지 눈으로 따라가게 하는 장치인데, 지금은 줄 하이라이트만 있다. 작고, 데코레이션으로 되고, 효과가 바로 보인다. +2. **변경 사유 툴팁** (2.2) — `rationale` 은 이미 있다. 바뀐 줄에 붙이기만 하면 된다. 이것도 데코레이션 hover 로 된다. +3. **CodeLens 수락/거절** (2.2) — 헝크 선택 로직이 이미 있으므로 편집기 안에 그 버튼을 다는 일이다. 셋 중 가장 크다. + +나머지 △ 는 **설계와 다른 방식으로 이미 답이 있는 것**들이다(전체 diff 는 별도 탭, 파일 개요는 목록). 굳이 설계 문구에 맞춰 바꿀 값어치는 없어 보이고, 바꾼다면 그건 Phase 2 완료가 아니라 별개의 UI 결정이다. + +"스트리밍 삽입" 만 애매하다. 지금은 완성된 텍스트를 재생하는 것이라 **모델이 실제로 쓰는 속도와 무관**하다. 진짜 토큰 스트림을 흘리려면 제안 경로(도구 호출 → 카드 → 수락)를 건드려야 하는데, 그건 시각 효과가 아니라 승인 모델의 변경이다. 별건으로 남긴다. + +### 제안하는 완료 조건 + +> Phase 2 는 **커서 고스트 · 변경 사유 툴팁 · CodeLens 수락/거절** 셋이 실제 앱에서 동작하면 끝난 것으로 한다. 포크 항목은 아키텍처가 달라져 해당 없음으로 닫고, DESIGN.md 와 README 의 Phase 2 문구를 그 사실에 맞게 고친다. + +셋 다 데코레이션·CodeLens 계층이라 [#70](https://github.com/SchutzScript/Schutz/pull/70) 에서 만든 것을 그대로 쓴다.