skills/peach-e2e-browse/SKILL.md
agent-browser CLI로 Chrome Beta CDP에 연결하여 페이지 탐색, 데이터 확인, 요소 조작을 수행하는 스킬. "브라우저 확인", "페이지 봐줘", "DOM 확인", "데이터 점검", "클릭해줘", "화면 확인" 키워드로 트리거. E2E 시나리오 작성 중 셀렉터 확인이나 실행 실패 디버깅에도 사용한다. e2e/ 폴더 없이도 단독 실행 가능.
npx skillsauth add peachsolution/peach-harness peach-e2e-browseInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
agent-browser(기본) + playwright-cli(fallback)로 Chrome Beta를 제어한다.
사람이 Chrome Beta 고정 프로필에서 로그인을 완료한 브라우저를 AI가 이어받아 탐색한다.
단독 실행 가능: e2e/ 폴더나
./e2e.sh setup이 없어도 agent-browser만 설치되어 있으면 핵심 기능(탐색/검증/확인)이 동작한다.
아래 5가지는 권장이 아니라 강제 규칙이다.
cd e2e && ./e2e.sh chrome을 우선 사용한다. 직접 실행이 필요하면 반드시 --user-data-dir=$HOME/.chrome-beta-e2e-profile을 포함한다.agent-browser connect 9222 후 반드시 agent-browser tab list를 먼저 실행한다.open, tab, click, fill, press, evalagent-browser가 비정상 동작하면 OS 레벨 우회(open -a, 다른 브라우저 실행, 다른 프로필 경로 사용) 금지.
즉시 상태를 보고하고 사용자 확인을 받는다.인증이 필요한 페이지에 도달하면 AI가 직접 로그인/2차 인증을 시도하지 않는다. Chrome Beta의
$HOME/.chrome-beta-e2e-profile에서 사용자가 직접 로그인이나 인증을 완료하도록 안내한 뒤, 같은 프로필 세션을 AI가 이어받는다.
Chrome Beta를 CDP 모드로 실행할 때는 고정 프로필 옵션이 필수다. 프로필 옵션이 빠진 실행은 세션 유지 실패로 간주한다.
cd e2e && ./e2e.sh chrome--remote-debugging-port=9222, --remote-allow-origins=*, --user-data-dir=$HOME/.chrome-beta-e2e-profile, --disable-extensions/usr/bin/open -na "Google Chrome Beta" --args ...open -a "Google Chrome Beta" 단독 실행, --args 없는 open 실행, --user-data-dir 없는 Chrome Beta 실행, 다른 프로필 경로 임의 사용, 기본 Chrome 또는 다른 브라우저 우회| 용도 | 도구 | 이유 |
|------|------|------|
| 탐색/검증/확인 | agent-browser | eval 6.6x 빠름, 토큰 2.3x 절약 |
| 시나리오 실행 | playwright-cli (./e2e.sh run) | lib/connect.js 기반 시나리오 인프라 |
| fallback | playwright-cli (직접 호출) | iframe 등 agent-browser 미지원 기능 |
웹사이트 도착
│
├─ connect 9222 → tab list → 사용자 탭 번호 확인
│ ├─ 탭 미확인
│ │ → 상태만 보고하고 대기
│ ├─ Google/OAuth/관리자/결제/기존 세션 유지 작업
│ │ → 탭 번호 확인 후에도 분석만 수행, 실행은 사용자 승인 후
│ └─ 일반 탐색 작업
│ → 아래 흐름 진행
│
├─ eval "document.title + ' | ' + location.href" 로 현재 상태 파악
│
├─ 정상 텍스트 반환 (일반 HTML / SPA)
│ ├─ 데이터 읽기 → eval 한 줄로 해결
│ ├─ 셀렉터를 알고 있다 → eval로 click/value 설정
│ │ ⚠️ eval click()은 isTrusted:false — 보안 폼에서 안 될 수 있음
│ │ → 안 되면 snapshot -i -c -s "form" → click ref
│ ├─ 셀렉터를 모른다
│ │ ├─ find role button --name "버튼명" (snapshot 없이 탐색)
│ │ └─ snapshot -i -c -s "관심영역" → ref 확보 → click/fill
│ └─ SPA 로딩 대기 필요
│ → wait --load networkidle 또는 eval "!!querySelector('타겟')" 체크
│ └─ SPA 입력 후 버튼이 [disabled] 유지
│ → 이벤트 미발행 의심 (Angular ngModel / React controlled input)
│ → eval "el.dispatchEvent(new Event('input', {bubbles:true}))"
│ → 여전히 [disabled] → change 이벤트도 추가 발행
│ → 여전히 [disabled] → CDP Input.insertText (자동화 스크립트 필요)
│ (references/SPA-프레임워크-입력패턴.md §1 참조)
│ └─ 파일 업로드 필요 (input[type=file])
│ → 기본값: CDP 인터셉트 방식 (처음 시도하는 사이트는 항상 이 방법)
│ 인터셉트 스크립트 백그라운드 실행 (TAB_TARGET_ID로 탭 특정)
│ → agent-browser click (isTrusted:true 필수 — eval click은 무시됨)
│ → Page.fileChooserOpened 이벤트 → setFileInputFiles(backendNodeId)
│ ⚠️ 직접 주입(DOM.setFileInputFiles)은 OS 다이얼로그가 안 뜨는 사이트임이
│ 검증된 경우에만 허용. 다이얼로그가 열리면 CDP/Escape로 닫을 수 없어 세션 막힘.
│ (references/SPA-프레임워크-입력패턴.md §3 스크립트 템플릿 참조)
│
├─ "로딩 중입니다" or 빈 값 → Flutter/Canvas 의심
│ ├─ eval "!!querySelector('flt-semantics-placeholder')" → Flutter 확정
│ ├─ accessibility 활성화
│ │ ├─ eval "querySelector('flt-semantics-placeholder')?.click()"
│ │ └─ 안 되면 snapshot -i -c → click e2 (flutter-view)
│ ├─ 활성화 후 → snapshot -i -c로 ref 확보 → 메뉴 조작
│ ├─ ⚠️ 페이지 이동마다 accessibility 재활성화 필요
│ └─ **우회 전략 (권장)**: dart.js에서 API method 추출 → fetch 직접 호출
│ (references/Flutter-웹앱-패턴.md 참조)
│
├─ iframe 내부 접근
│ → playwright-cli fallback (references/iframe-모달-패턴.md 참조)
│
└─ 세션 끊김 (CDP error: Session not found)
→ connect 9222 → tab list → tab N → eval "document.title"
핵심: 탭 확인이 먼저, eval은 그 다음. snapshot은 최후수단. Flutter는 API 직접 호출이 최강.
1. 환경 확인 (인라인 체크 — e2e/ 폴더 불필요)
2. CDP 연결 (agent-browser connect 9222)
3. tab list → 사용자에게 탭 목록 보여주고 작업 탭 확인
4. 선택된 탭에서 작업 (eval/click/snapshot)
5. 결과를 사용자에게 보고
탐색 결과가 반복 검증 가치가 있으면 보고 마지막에 다음을 정리한다.
/peach-e2e-scenario create ...단순 확인으로 끝나는 작업이면 시나리오 파일을 만들지 않는다.
중단 조건
- 탭 번호 미확인
- Chrome Beta 고정 프로필 유지가 핵심인 작업
- 로그인/OAuth/관리자 콘솔/결제 등 민감 세션 작업
agent-browser connect,tab list,tab new가 비정상 응답인 상태위 조건이면 조작하지 말고 현재 상태만 보고한 뒤 사용자 지시를 기다린다.
e2e/ 폴더나 setup 스크립트 없이 직접 확인한다:
# a) agent-browser 설치 여부
command -v agent-browser && echo "✅ agent-browser 설치됨" || echo "❌ agent-browser 미설치 → npm i -g agent-browser"
# b) Chrome Beta CDP 연결 여부
curl -s http://127.0.0.1:9222/json/version && echo "✅ CDP 연결됨" || echo "❌ CDP 미연결"
CDP 미연결이면 자동 복구를 먼저 시도한다.
e2e/ 폴더가 있으면 cd e2e && ./e2e.sh chrome & 실행 후 sleep 4, cd e2e && ./e2e.sh status로 재확인한다.e2e/ 폴더가 없으면 아래 OS별 Chrome Beta CDP 실행 명령을 직접 실행한 뒤 재확인한다.⚠️ 프로필 경로 고정 규칙:
--user-data-dir는 반드시$HOME/.chrome-beta-e2e-profile고정. 어떤 상황에서도 다른 경로로 변경하지 않는다. 오류가 나더라도 경로는 바꾸지 않는다. 이 프로필에 Google 계정, OAuth, 사내 SSO 같은 인증을 미리 유지해 두면 이후 AI가 같은 세션을 이어받아 작업할 수 있다.
macOS:
# --disable-extensions: 확장 프로그램이 웹 콘텐츠에 다크모드를 강제 적용하는 문제 방지
/usr/bin/open -na "Google Chrome Beta" --args \
--remote-debugging-port=9222 \
"--remote-allow-origins=*" \
"--user-data-dir=$HOME/.chrome-beta-e2e-profile" \
--disable-extensions \
--no-first-run \
--no-default-browser-check
sleep 5
curl -s "http://127.0.0.1:9222/json/version"
Windows (Git Bash):
# --disable-extensions: 확장 프로그램이 웹 콘텐츠에 다크모드를 강제 적용하는 문제 방지
"/c/Program Files/Google/Chrome Beta/Application/chrome.exe" \
--remote-debugging-port=9222 \
--remote-allow-origins=* \
--user-data-dir="$(cygpath -w "$HOME/.chrome-beta-e2e-profile")" \
--disable-extensions &
e2e/ 폴더가 있다면
cd e2e && ./e2e.sh chrome으로도 실행 가능.
agent-browser connect 9222
1회 연결하면 세션 유지. 매 명령마다 재연결 불필요.
수동 검증 전 CDP 상주 세션 점검 필수
agent-browser connect 9222실행 시 상주 daemon이 생성된다. 이 daemon이 붙어 있으면 사이트의 nativealert/confirm/prompt가 자동으로 닫힐 수 있다. 사용자가 직접 dialog를 확인해야 하는 작업이면 먼저 연결 상태를 점검한다.lsof -iTCP:9222 -sTCP:ESTABLISHED -n -P # 연결 확인 ps -p <PID> -o pid,ppid,command= # daemon 식별 kill <PID> # daemon 종료상세:
references/native-dialog-주의사항.md참조
agent-browser tab list
탭 목록을 사용자에게 보여주고 "몇 번 탭에서 작업할까요?" 라고 확인한다. 출력 예:
[0] Daum - https://www.daum.net/
[1] - chrome://webui-toolbar.top-chrome/
→ [2] NAVER - https://www.naver.com/
[3] Google - https://www.google.com/
→표시는 agent-browser 내부 포커스이지 Chrome UI 포커스가 아니다. CDP는 사용자가 Chrome에서 보고 있는 탭을 알 수 없다. 따라서 작업 시작 전 반드시 사용자에게 탭 번호를 확인해야 한다.
사용자가 탭 번호를 지정하면 agent-browser tab N으로 전환 후 진행한다.
탭 번호를 받기 전에는 여기서 멈춘다.
open,tab,click,fill,press,eval을 이어서 실행하지 않는다. Google/OAuth/관리자 콘솔처럼 세션 유지가 핵심인 작업은 탭 번호를 받아도 추가 실행 승인이 없으면 분석만 수행한다.agent-browser tab N직후에는 반드시eval "document.title + ' | ' + location.href"로 예상한 탭이 맞는지 재확인한다. 다르면tab list를 다시 출력하고 재선택한다.
선택된 탭에서 eval → 판단 → 추가 eval/click.
eval 결과, 페이지 상태를 텍스트로 요약하여 사용자에게 보고.
현재 탭에서 작업. 탭 전환은 사용자 명시적 지시 시에만.
agent-browser open "URL"agent-browser tab Nagent-browser tab new "URL"탭 번호 확인 전에는 위 명령을 하나도 실행하지 않는다. 민감 세션 작업에서는 탭 번호 확인 뒤에도 사용자 실행 승인 전까지는 분석만 수행한다.
open URL --new-tab사용 금지! 기존 탭을 덮어쓴다. 새 탭은 반드시tab new "URL"사용.
agent-browser open "https://대상URL"
# 값 읽기
agent-browser eval "document.title"
agent-browser eval "document.querySelector('#field').value"
agent-browser eval "document.querySelectorAll('tr').length"
# 조건부 읽기
agent-browser eval "document.querySelector('.cls') ? document.querySelector('.cls').innerText.trim() : '없음'"
# 목록 추출 (JSON.stringify 패턴)
agent-browser eval "JSON.stringify(Array.from(document.querySelectorAll('li')).map(function(el){return el.innerText}))"
# 클릭
agent-browser eval "document.querySelector('a.link').click()"
# 값 입력
agent-browser eval "document.querySelector('#keyword').value = '검색어'"
eval은 단순 표현식만. IIFE
(function(){...})()사용 금지 -- 직렬화 오류 발생. 여러 동작은 각각 별도 eval로 나눠서 실행한다.
# 인터랙티브 요소만 + 컴팩트 출력 (필수 옵션)
agent-browser snapshot -i -c
# CSS 범위 제한 (더 절약)
agent-browser snapshot -i -c -s "table"
전체 snapshot 금지. 토큰 비교:
- 전체 snapshot: ~65,700 토큰
- snapshot -i -c: ~9,800 토큰
- eval: ~1~460 토큰
snapshot 후 ref로 조작:
agent-browser click e10
agent-browser fill e37 "검색어"
agent-browser press Enter
ref는 DOM 변경 시 무효. 클릭/이동 후 반드시 다시 snapshot.
agent-browser click e10
agent-browser fill e37 "검색어"
agent-browser press Enter
agent-browser screenshot # 터미널 출력
agent-browser screenshot result.png # 파일 저장 (토큰 미소비)
agent-browser가 지원하지 못하는 경우 playwright-cli로 전환한다.
# playwright-cli 설치 확인
command -v playwright-cli || echo "❌ 미설치 → npm i -g @playwright/cli"
# config 파일 확인 — 없으면 생성
if [ ! -f "$HOME/.playwright/cli.config.json" ]; then
mkdir -p "$HOME/.playwright"
echo '{"browser":{"cdpEndpoint":"http://localhost:9222","isolated":false}}' > "$HOME/.playwright/cli.config.json"
echo "✅ playwright-cli config 생성됨"
fi
isolated: false필수 — 기본값true면 CDP에 연결해도 새 브라우저가 열린다.
e2e/ 폴더의 pwc.sh 래퍼 없이 직접 호출한다:
# playwright-cli 세션 오픈 (1회)
playwright-cli --config="$HOME/.playwright/cli.config.json" open
# 탭 전환
playwright-cli --config="$HOME/.playwright/cli.config.json" tab-select N
# iframe 내부 읽기
playwright-cli --config="$HOME/.playwright/cli.config.json" eval "document.querySelector('iframe[src*=대상]').contentDocument.querySelector('#element').innerText"
# iframe 내부 입력 + 클릭 -- 별도 eval로 분리
playwright-cli --config="$HOME/.playwright/cli.config.json" eval "document.querySelector('iframe[src*=대상]').contentDocument.querySelector('#keyword').value = '검색어'"
playwright-cli --config="$HOME/.playwright/cli.config.json" eval "document.querySelector('iframe[src*=대상]').contentDocument.querySelector('input[type=submit]').click()"
e2e/ 폴더가 있다면
./e2e/pwc.sh래퍼를 사용해도 동일하다. 상세 패턴은references/iframe-모달-패턴.md참조
동일 시나리오 (구글 → Gmail → 메일 15개 추출), Chrome Beta CDP 9222:
| 항목 | agent-browser | playwright-cli | 배율 | |------|--------------|---------------|------| | eval 평균 속도 | 189ms | 1,249ms | 6.6x | | 총 명령 시간 | 1,521ms | 6,257ms | 4.1x | | 총 출력 바이트 | 1,918B | 4,343B | 2.3x | | eval 출력 형식 | 결과값만 | 결과+코드+탭목록+페이지정보 | - |
tab list를 보여주고 탭 번호를 명시적으로 확인한다.tab new URL -- open URL --new-tab 사용 금지 (기존 탭 덮어씀).-i -c 필수 -- 전체 snapshot 금지. 토큰 폭발.--user-data-dir은 반드시 $HOME/.chrome-beta-e2e-profile. 오류가 나도 경로 변경 금지.agent-browser daemon이 붙어 있으면 alert/confirm이 즉시 닫힐 수 있다. 새 탭/새로고침보다 lsof → ps → kill이 우선이다. (references/native-dialog-주의사항.md)window.alert/confirm override, 전역 dialog listener, 강제 dismiss 코드는 finally에서 해제한다. (references/native-dialog-주의사항.md)click() 한 줄이 아니라 load + 지연 + 직접 이동 fallback 패턴 사용. (references/외부서비스-링크전환-패턴.md)E2E_TAB_ID 우선 -- --tab N 인덱스는 흔들릴 수 있다. 특정 URL 탭 재현은 targetId 고정이 안전하다. (references/탭-선택-패턴.md)tab list는 필수 게이트다. 사용자 탭 선택 전에는 open/tab/eval/click/fill/press 실행 금지.agent-browser 실패 시 open -a, 다른 브라우저 호출, 프로필 무시 실행 금지. 보고 후 대기. (references/고정프로필-강제게이트-패턴.md)eval dispatchEvent(new Event('input', {bubbles:true}))를 반드시 시도한다. 여전히 안 되면 change 이벤트도 발행. (references/SPA-프레임워크-입력패턴.md)eval "document.title + ' | ' + location.href"로 탭이 맞는지 검증한다. 예상과 다르면 tab list 재출력 후 재선택.agent-browser press Escape 모두 macOS 네이티브 파일 다이얼로그(XPC 서비스)에는 무효다. Page.setInterceptFileChooserDialog(enabled:true) → agent-browser click → Page.fileChooserOpened → setFileInputFiles(backendNodeId) 순서로 OS 다이얼로그 자체를 차단한다. (references/SPA-프레임워크-입력패턴.md §3)| 문서 | 용도 |
|------|------|
| references/agent-browser-명령어.md | agent-browser 전체 명령어 레퍼런스 |
| references/playwright-cli-명령어.md | fallback 전용 (iframe 등 agent-browser 미지원 시) |
| references/iframe-모달-패턴.md | jQuery UI Dialog + iframe 모달 접근 패턴 |
| references/Flutter-웹앱-패턴.md | Flutter 웹앱 판별 / accessibility / API 직접 호출 |
| references/토큰-최적화-실측데이터.md | 명령별 토큰 비용 실측 비교표 + 예산 가이드 |
| references/native-dialog-주의사항.md | CDP 상주 세션의 native dialog 자동 dismiss 문제 + 점검 절차 |
| references/외부서비스-링크전환-패턴.md | 외부 서비스 링크 전환 시 fallback 패턴 |
| references/탭-선택-패턴.md | --tab N vs E2E_TAB_ID 선택 기준 |
| references/SPA-프레임워크-입력패턴.md | Angular/React controlled input 이벤트 발행, 숨겨진 file input TreeWalker 탐색, CDP Input.insertText |
| references/고정프로필-강제게이트-패턴.md | 민감 세션/고정 프로필 작업의 중단 조건과 우회 금지 규칙 |
tools
기능 브랜치용 git worktree 라이프사이클을 관리하는 스킬. 생성(create) / 상태 진단(status) / PR 준비(finish) / 병합 후 정리(closeout) / 정리(cleanup) 모드를 자동 판단한다. "워크트리 만들어줘", "worktree 생성", "워크트리 정리", "워크트리 삭제", "기능 브랜치 워크트리", "워크트리 상태", "마무리", "PR 생성", "PR 머지 후 정리", "feature worktree" 키워드로 트리거. PR 전 base 비교와 안전한 동기화 필요 여부를 진단한다. 개발 완료 후 finish/closeout 모드에서는 한 번의 통합 체크포인트로 push/PR/merge/cleanup을 안전하게 진행한다.
development
Karpathy LLM Wiki 패턴 기반 지식 관리 스킬. 코드 프로젝트와 옵시디언 노트 모두 지원. Raw Source(코드·문서)를 읽어 docs/wiki/에 누적형 지식베이스를 구축·유지한다. "wiki", "위키", "ingest", "인제스트", "wiki 점검", "wiki lint", "wiki 업데이트", "문서화해줘", "아키텍처 설명해줘", "어떻게 동작해?" 키워드로 트리거. qmd 검색 도구와 연동하여 토큰 절약 + 높은 검색 정확도 제공.
development
Backend 없이 Mock 데이터 기반 프로토타입 UI를 생성·검증하는 기획 구체화 산출물 스킬. Vue 3 + TypeScript + NuxtUI v4. 별도 ui-proto 저장소(예: peach-ui-proto-backoffice)의 src/modules-task 폴더에 태스크별 화면을 누적한다. "프로토타입 만들어줘", "Mock 화면", "proto UI", "기획 화면 빠르게", "ui-proto 작업", "기획자 검토용 화면", "태스크 폴더 추가", "팀 ui-proto" 키워드로 트리거. 기획자가 직접 작업하는 화면 기획 + 현업 검토용 산출물 스킬이며, 개발용 Spec은 후속 peach-gen-spec이 생성한다. 실제 API 연동이 필요하면 peach-gen-ui를 사용한다.
development
Spec 필수 + ui-proto 보조 기준으로 E2E 환경 세팅 + 단위 시나리오 자동 분할 + 통합 suite 생성 + 실행 + 부합 검증을 한 번에 처리하는 통합 팀 스킬. "e2e 검증해줘", "통합 검증", "전체 흐름 테스트", "팀 e2e", "스펙대로 동작하는지 확인", "ui-proto와 다른지 확인", "최종 검증", "릴리스 전 검증" 키워드로 트리거. peach-e2e-setup + peach-e2e-scenario + peach-e2e-suite 3개 스킬의 패턴을 공유하고, 검증 기준은 본 프로젝트 Spec을 필수 기준으로 삼고, ui-proto는 화면/흐름 보조 기준으로 사용한다. peach-team-dev와 함께 하나의 개발-검증 납품 흐름을 이루되, 구현 컨텍스트와 검증 컨텍스트는 분리한다. 팀 실행 방식은 E2E 범위와 런타임 도구 가용성을 분석해 single-agent / role-queue / agent-team 중 선택한다. 단순 코드 동작 검증을 넘어, 기획 의도와 부합하는지 자동 검증하는 게 핵심 차별점.