Skip to content

feat: 머지 승인 리뷰 보강 — 실제 diff 기반 리뷰 시트 + 충돌 사전검사 - #31

Merged
redsunjin merged 7 commits into
mainfrom
feat/merge-review
Jul 22, 2026
Merged

feat: 머지 승인 리뷰 보강 — 실제 diff 기반 리뷰 시트 + 충돌 사전검사#31
redsunjin merged 7 commits into
mainfrom
feat/merge-review

Conversation

@redsunjin

Copy link
Copy Markdown
Owner

Summary

승인 버튼이 실제 git merge를 실행하는데 승인자는 에이전트 자가 보고(제목+한 줄)만 보던 신뢰 격차를 해소합니다. 스펙: docs/superpowers/specs/2026-07-22-merge-review-design.md

서버 — 리뷰 API

  • GET /api/requests/:id/review: git 원본에서 변경 파일(+/− 수치·상태·패치)·커밋 목록·충돌 사전검사(git merge-tree --write-tree, exit 0/1 판정 + 충돌 파일 목록) 생성
  • base = 저장소 현재 HEAD 브랜치(실제 머지 대상과 일치), 상한: 파일 50 / 패치 32KB / 커밋 50 (초과 시 잘림 표시)
  • 인증은 기존 isRequestAuthorized(SERVER_TOKEN) 재사용, WS 프로토콜 무변경(HTTP 지연 로드)

대시보드 — 리뷰 시트

  • 노트 클릭 → PreviewModal이 리뷰 시트로 확장: 머지 판정 배지(머지 가능/충돌 N개/판정 불가), 파일별 실제 패치, 커밋 목록, 충돌 파일 경고
  • 시트 안 승인/반려performNoteAction 코어 분리로 열람한 바로 그 노트를 대상(레인 첫 노트 시맨틱과 분리), 반려는 기존 사유 입력 시트로 연결
  • 서버 데이터 불가 시(Mock/구버전/인증 실패) 에이전트 요약 폴백 + 안내 문구

검증

실서버 + 실제 git 레포로 브라우저 시연 완료 — 리뷰 시트가 실제 diff를 표시하고 시트 승인으로 실제 머지 실행 확인. 이미 머지된 브랜치 요청은 "파일 0·커밋 0"으로 표시되어 빈 승인 요청을 식별할 수 있음(기존 UI에서는 불가).

Test plan

  • 서버 60 tests (신규: 실제 git 픽스처로 클린/충돌/404/409/401 5시나리오)
  • UI 125 tests (신규 8: 시트 렌더·정확한 노트 승인/반려·폴백·fetch 스킵)
  • e2e 6 tests (하네스를 http+WSS로 승격, 리뷰 시트 승인 시나리오 추가)
  • npm run qa (테스트+빌드) PASS

🤖 Generated with Claude Code

selimDGAX and others added 7 commits July 22, 2026 19:31
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@redsunjin
redsunjin merged commit d8f6470 into main Jul 22, 2026
2 checks passed
@redsunjin
redsunjin deleted the feat/merge-review branch July 22, 2026 10:54

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b16fb1ed53

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

setReview(null);

try {
const response = await fetch(apiUrl);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Send the stored bearer token with review fetches

When MAESTRO_SERVER_TOKEN is enabled, the new endpoint requires Authorization: Bearer ..., but this fetch never attaches the token already stored under the shared server API token key. Consequently every review request in token-secured deployments receives the tested 401 response and the operator sees only the untrusted agent-summary fallback, defeating the feature in the recommended secured configuration.

Useful? React with 👍 / 👎.

Comment thread maestro-server.js
Comment on lines +2333 to +2335
const entries = numstatRaw.split('\n').filter(Boolean).map((line) => {
const [addRaw, delRaw, ...rest] = line.split('\t');
const filePath = rest[rest.length - 1];

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Parse rename records before requesting per-file patches

For a detected rename, Git 2.43 emits a synthetic path such as 0\t0\tsrc/{old.js => new.js} from git diff --numstat, while --name-status emits separate old and new paths. Treating the synthetic field as a real path means it cannot match statusByPath and the later path-scoped git diff returns an empty patch, so renamed files are displayed as modified with no actual diff; parse the rename tuple, preferably using the documented -z machine-readable output, before correlating stats and fetching patches.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants