Skip to content

Contributing ko

Hermes Agent edited this page Oct 1, 2026 · 1 revision

기여하기

English | 中文 | 日本語 | 한국어 | Español | Português | Русский

명령

npm test                        # full test suite (Node built-in runner, no build needed)
node --test test/foo.test.mjs   # single file
npm run package                 # build the versioned zip (browsa-vX.Y.Z.zip)
npm run build                   # esbuild vendor bundle (only needed after build.mjs changes)
bash check-compat.sh            # static compatibility check

4GB 박스 제약: 스위트는 103개 파일(~36개 jsdom 중심)이고 2CPU/4GB VPS에서 돈다; 스크립트는 동시성을 2로 제한한다, 4GB 박스에서는 --test-concurrency=1을 선호하라. 테스트에서 수십 MB 블롭 할당은 절대 금지 (44MB짜리 목업 하나가 박스를 OOM시킨 적이 있다 — 실제 재발); 순수 함수 테스트를 선호하라(DOM 없음, 큰 버퍼 없음).

테스트 철학

  • 테스트는 실제 모듈을 임포트하기 전에 chrome 전역을 목업한다; jsdom 테스트는 대용품이 아니라 실제 벤더 marked/DOMPurify/katex/highlight.js 번들을 쓴다.
  • sidepanel.js는 익스포트가 0이다 — 그 테스트는 sidepanel.html 전체를 jsdom에 올리고 블랙박스로 구동한다(시뮬레이션된 클릭/키/포트 메시지).
  • 워커 클라이언트는 모듈 수준 싱글턴을 쥔다 → 새 싱글턴이 필요한 시나리오는 반드시 별도 테스트 파일이어야 한다(러너가 파일/프로세스별로 격리한다).
  • lockstep 규율: 여러 곳에 거울처럼 반영되는 사실(정규식, 필드 이름, CSS/힌트 쌍, 탭 순서)은 한 소스로 붕괴시키거나 소스-정규식 핀 + AGENTS.md의 "lockstep으로 둘 다 바꿔라" 노트로 고정한다. 예: subchat.test.mjs는 정확한 pushSubChatChunk(… SUBCHAT_DONE …) 소스 줄을 정규식으로 잠근다.
  • 디테일 스레드 / 스트리밍 테스트는 반드시 턴을 끝내야 한다(DONE / ■ / 닫기), 그렇지 않으면 턴 포트의 20s SW_PING 인터벌이 새어 러너를 매단다.
  • WASM은 "실제 실행 없음"의 예외다: WebAssembly.instantiate는 Node에서 돈다 — 그래서 pdf-inspector 테스트는 실제 벤더 바이너리를 실행한다.

리팩터링 원칙 (사건으로 얻은 것; AGENTS.md에서)

  • 리터럴만 다른 N개의 스위치 케이스 → 하나의 룩업 테이블; 같은 와이어 프로토콜의 손작성 구현 둘 → 훅 달린 하나의 공유 함수(DONE 핸들러 드리프트는 실제 버그 계열이었다).
  • 추출을 마칠 때마다 전체 스위트와 check-compat.sh를 돌려라 — 문법 검사는 아무것도 증명하지 않는다.
  • 익스포트를 죽었다고 선언하기 전에 저장소 전체(test/ 포함)를 grep하라; 테스트 전용 익스포트가 자동으로 죽은 것은 아니다 — 주변 주석을 읽어라.

dev-preview (헤드리스 환경에서의 확장 UI 프리뷰)

node dev-preview/gen.mjs        # regenerate preview pages from real sidepanel.html (rerun after HTML changes)
python3 -m http.server 8931     # from the repo root
# http://127.0.0.1:8931/dev-preview/sidepanel.preview.html

chrome-shim이 최소한의 chrome.* 표면을 제공한다; seed.js가 풍부한 히스토리를 주입한다. 스크린샷은 CDP Page.captureScreenshot을 거친다(plain, clip/scale 없음; page.screenshot()은 다크 모드 아티팩트가 있다). 통과한 프리뷰 ≠ 통과한 실제 확장: shim의 sendMessage 엔벨로프는 실제 계약을 바이트 단위로 거울처럼 반영해야 하고, CSP 계열 검증은 언제나 실제 확장 로드를 요구한다.

릴리스 흐름

  1. manifest.json과 package.json 둘 다에서 버전을 올린다.
  2. PR → CI 초록 → main으로 스쿼시 머지 → dev 백필: git reset --hard origin/main && git push --force-with-lease origin dev (머지 기반 백필은 main..dev를 오염시킨다; PR 페이지의 Delete branch 버튼은 dev를 지워버릴 수 있다).
  3. 버전 bump PR은 재사용 릴리스 워크플로(xiaohuzai/release-flow@v1)를 흐르며 테스트는 면제된다(PAT 모드).
  4. 스토어 리스팅 문안은 .agents/skills/cws-listing 스킬로 생성한다(태그가 버전의 진실 원본이다); 거절 이력은 기록에 남아 있다.
  5. 문서 동기화 규율(사용자에게 보이는 모든 변경, 같은 PR): 두 언어의 README(절 정렬 거울) → 문서 사이트(두 언어) → 스크린샷/배너/데모 GIF/프로모 비디오는 각각 고려된다(판독성은 그 자산 자신의 해상도에서 판정; 바뀐 GIF는 캐시를 이기려면 파일명을 바꿔야 한다) → 아키텍처 수준 사실은 AGENTS.md에 기록된다.

레드라인 (빠른 목록)

자동 커밋/패키징 없음(명시적 지시 대기) · 패키징 전 전체 테스트 실행 없음(타깃 그린이면 충분) · 현재 버전 사용, 스스로 bump 금지 · 확장 개인 키는 /root/workspace/browsa-keys/를 절대 떠나지 않는다 · 사용자 대상 문안은 전문 용어를 피한다(zh는 영어 전문 용어를 싣지 않는다) · 저장된 이미지 픽셀은 결코 파괴되지 않는다 · thinking 기본 omit.


원본 출처: AGENTS.md "Testing" / "Refactoring principles" 절; 패키징/커밋 규율 노트; 문서 동기화 규약. 권위판: Contributing(영어) / Contributing-zh(중국어) — AI 초벌 번역 스냅숏, 동기화 2026-10-01.

Clone this wiki locally