threejslisted
Install: claude install-skill snwlee/Nereus
# threejs
nereus:common 규칙을 따른다. 담당 에이전트: graphics-engineer.
구현 절차(TDD·게이트)는 **`nereus:build` 의 것을 그대로 쓴다** — 여기서 다시 정의하지 않는다.
## 0. 문서를 여기 복사하지 않는다
three.js API·예제·TSL 은 **Context7 `/mrdoob/three.js`(21,304 스니펫)** 으로 조회한다.
R3F·drei 는 `pmndrs/claude-code-plugin`(MIT)과 `docs.pmnd.rs/api/mcp` 가 갖는다.
복사본은 상류가 리비전을 올리는 순간 **낡았다는 표시 없이** 틀린다.
이 스킬이 갖는 것은 문서가 아니라 **검사기**다. 조사에서 확인했다:
`awesome-claude-skills` 목록 셋(74,938 · 15,047 · 10,125★) **전부 3D 매치 0건**,
스킬팩 3종(`cloudai-x/threejs-skills` 3,291★ 포함)은 전부 *문서*이고 **셋 다 라이선스가 없다**.
## 1. 왜 정적 검사인가 — 조용히 틀리기 때문이다
도너(FindDifferences3D, 읽기 전용)의 같은 저장소 안에 두 구현이 있었다.
| 위치 | 코드 | 결과 |
|---|---|---|
| `game_view.html:616` | `for (key in material) if (value.isTexture) value.dispose()` | **완전** |
| `js/difference_engine.js:358` | `if (material.map) material.map.dispose()` | **`.map` 만** |
두 번째는 `normalMap`·`roughnessMap`·`aoMap`·`emissiveMap` 을 GPU 에 남긴다.
**예외도 경고도 나지 않는다.** 프레임만 떨어지고, 리뷰에서는 둘 다 "dispose 한다"로 보인다.
`disposeSubtree` 는 정의돼 있었지만 **호출이 한 곳뿐**이었다.
선언은 정리가 된다는 착각을 만든다. 그래서 **호출 지점을 세지 않고 결함이라 부르지 않고,
세지 않고 통과라 부르지도 않는다.**
## 2. 부르는 법
```bash
echo '{"sources":[{"file":"a.js","text":"..."}]}' \
| node plugins/nereus-3d/lib/scene-scan.mjs
```
모듈로도 쓴다:
```js
import { scanScene } from "./plugins/nereus-3d/lib/scene-scan.mjs";
const { violations, unmeasured, disposeHelpers } = scanScene({ sources });
```
`sources` 는 `{ file, text }` 배열이다. **전체 소스를 한 번에 넘긴다** —
파일 하나만 넘기면 다른 파일에 있는 호출을 못 보고 거짓 `dispose-unwired` 를 낸다.
## 3. 무