<!-- task=01+browser_native_ws plan=1 tag=REVIEW_BNW -->

# Browser Native WebSocket 후속 계획 - REVIEW_BNW

## 배경

이전 리뷰(`code_review_cloud_G08_0.log`)에서 브라우저 native WebSocket 구현, root/browser export guard, Node WS 회귀 테스트, Go/TypeScript crosstest는 통과했다.
다만 `proto-socket/node` subpath가 `ws`를 런타임 import하면서 `package.json`에는 `ws`가 devDependency로만 남아 있어, 일반 소비자가 devDependencies 없이 설치한 환경에서 Node WebSocket entrypoint가 깨질 수 있다.

## 실패 사유

- Required: `typescript/src/node_ws_client.ts`와 `typescript/src/node_ws_server.ts`가 `ws`를 런타임 import하지만, `typescript/package.json`은 `ws`를 Node entrypoint의 소비자-facing 의존성 계약으로 선언하지 않는다.

## 구현 체크리스트

- [x] [REVIEW_BNW-1] `proto-socket/node`의 `ws` 런타임 의존성 계약을 manifest와 README에 명시한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [REVIEW_BNW-1] Node WebSocket 런타임 의존성 계약 정리

#### 문제

`package.json`은 `./node` subpath를 공개한다.

```json
"./node": {
  "types": "./dist/src/node.d.ts",
  "default": "./dist/src/node.js"
}
```

그러나 Node WebSocket 구현은 런타임에 `ws`를 import한다.

```ts
import WebSocket, { type ClientOptions, type RawData } from "ws";
```

현재 `ws`는 devDependency에만 있어 패키지 소비 환경에서 `proto-socket/node` import가 실패할 수 있다.

#### 해결 방법

브라우저 root 사용자가 불필요하게 `ws`를 설치하지 않도록 `ws`를 optional peer dependency로 선언하고, 로컬 테스트용 devDependency는 유지한다.

```json
"peerDependencies": {
  "ws": "^8.18.1"
},
"peerDependenciesMeta": {
  "ws": {
    "optional": true
  }
}
```

`package-lock.json`도 같은 manifest 상태를 반영하도록 갱신한다.
`typescript/README.md`에는 Node WebSocket entrypoint를 사용할 때 `ws` 설치가 필요하다는 문장을 추가한다. TCP-only Node 사용자는 별도 `ws` 설치가 필요 없다는 점도 함께 적어 혼동을 줄인다.

#### 수정 파일 및 체크리스트

- [x] `typescript/package.json`에 `peerDependencies.ws`와 `peerDependenciesMeta.ws.optional`을 추가한다.
- [x] `typescript/package-lock.json`을 package manifest와 동기화한다.
- [x] `typescript/README.md`에 Node WebSocket 사용 시 `ws` 설치 필요성을 문서화한다.
- [x] root/browser entrypoint가 여전히 `ws`, `node:*`, `Buffer`를 끌지 않는지 확인한다.

#### 중간 검증

```bash
cd typescript && node -e "const fs=require('fs'); const p=JSON.parse(fs.readFileSync('package.json','utf8')); if (p.dependencies?.ws) throw new Error('ws must not be a root dependency'); if (p.devDependencies?.ws !== '^8.18.1') throw new Error('ws devDependency missing'); if (p.peerDependencies?.ws !== '^8.18.1') throw new Error('ws peerDependency missing'); if (p.peerDependenciesMeta?.ws?.optional !== true) throw new Error('ws peerDependency must be optional');"
```

예상 결과: 출력 없이 exit code 0.

## 최종 검증

```bash
cd typescript && npm run check
cd typescript && npm test
cd go && go run ./crosstest/go_typescript.go
rg --sort path -n 'from "ws"|node:|\bBuffer\b|ClientOptions|RawData' typescript/src/index.ts typescript/src/browser_ws_client.ts
```

마지막 `rg` 명령의 예상 결과는 출력 없음.
