| name | knip-until-clean |
| description | knip을 돌려 죽은 export, 안 쓰는 파일, 고아(orphan) 의존성을 찾아 제거하고, knip이 깨끗(종료 코드 0)하다고 할 때까지 자동으로 반복하는 닫힌 루프입니다. 사용자가 "안 쓰는 코드 다 지워줘", "데드 코드 정리해줘", "쓰지 않는 export·파일·의존성 제거", "knip 깨끗해질 때까지 돌려줘", "사용 안 하는 deps 털어줘", "knip until clean", "remove dead exports and unused files", "find orphan dependencies"처럼 knip(또는 depcheck) 기반으로 미사용 코드·의존성을 반복 제거해 깨끗하게 만들고 싶을 때 사용하세요. (구분: 일반적인 구현 후 청소(디버그 코드·죽은 분기 제거)는 looping:de-sloppify-pass, 린트·타입체크 위반 정리는 looping:lint-typecheck-fix, 패키지를 한 번에 하나씩 업그레이드하는 건 looping:dependency-upgrade-one-by-one, 보안 취약점 의존성 패치는 looping:npm-audit-fix-loop) |
Knip 깨끗해질 때까지 (Knip Until Clean)
죽은 export, 안 쓰는 파일, 고아 의존성을 찾아 제거하고, knip이 깨끗하다고 할 때까지 반복합니다.
| 항목 | 값 |
|---|
| 카테고리 | 유지보수(Maintenance) |
| 트리거 | 수동(manual) — 사람이 직접 시작 |
| 종료 조건(Exit) | knip이 종료 코드 0으로 끝날 때 (= 안 쓰는 파일·export·의존성이 하나도 없음) |
| 반복 한도(Max iterations) | 5 |
| 매 반복 체크 명령 | npx knip |
| 가드레일 | 강화됨(Hardened) |
| 지원 에이전트 | Claude Code · Cursor · Codex |
이 루프는 언제 쓰나
리팩터링이나 기능 삭제를 반복하다 보면 아무도 import 하지 않는 export, 어디서도 참조되지 않는 파일, package.json에만 남아 있는 의존성이 슬금슬금 쌓입니다. 이걸 손으로 추적하면 "이거 지워도 되나?"를 매번 grep 해야 해서 지치죠. 이 루프는 knip을 종료 코드 0이 될 때까지 돌리며 실행 → 분류 → 제거(또는 정당화) → 재실행을 스스로 반복합니다. 핵심은 확실한 죽은 코드만 최소 diff로 지우고, 애매한 건 함부로 삭제하지 않고 ignore로 표시해 두는 것입니다.
루프 흐름
수동 시작 → knip 실행 → 제거 또는 정당화 →〔피드백 게이트〕knip 결과 깨끗?
↑ │ 아니오
└──────────────────────────────────────────────┘
│ 예
종료
매 반복(pass)마다 하는 일
- knip 실행 — knip(또는 depcheck)을 돌려 안 쓰는 파일·export·의존성을 분류합니다.
npx knip
- 제거 또는 정당화 — 확실한 죽은 코드는 삭제합니다. 오탐(false positive)은 한 줄짜리 이유를 달아 knip ignore 항목으로 등록합니다.
가드레일 (점수 조작 방지 규칙)
종료 조건을 "가짜로" 통과시키지 못하게 막는 규칙입니다. 반드시 지키세요.
- 체크 명령이나 종료 기준을 고쳐서 억지로 성공시키지 않는다.
- 체크를 건너뛰거나 비활성화·우회해서 종료 조건을 통과시키지 않는다.
- 여러 번 반복해도 막히면, 지표를 조작하지 말고 멈추고 블로커를 보고한다.
Claude Code에서 실행하기
가장 간단합니다. 아래 kickoff 프롬프트를 그대로 붙여넣으면 에이전트가 스스로 반복합니다.
"Knip 깨끗해질 때까지(Knip Until Clean)" 루프를 시작합니다.
목표: knip이 안 쓰는 코드나 의존성을 더는 보고하지 않음
최대 반복: 5
매 반복 사이 실행: npx knip
종료 조건: knip이 종료 코드 0으로 끝날 때
1단계: knip을 실행한다. 죽은 export와 안 쓰는 의존성을 최소 diff로 제거하고, 테스트가 여전히 통과하는지 확인한다.
이 루프를 스스로 페이싱(self-pace)하라. 매 반복 후 체크 명령을 실행하고 출력을 읽어, 종료
조건이 충족되지 않았을 때만 계속한다. 종료 조건이 통과하거나 최대 반복에 도달하면 멈춘다.
매 회차마다 한 줄 상태 업데이트를 남긴다.
팁: npx knip은 JS/TS 프로젝트 기준입니다. 처음 돌리면 knip이 entry 포인트를 못 잡아 오탐이 쏟아질 수 있으니, 첫 회차에서 knip.json(또는 package.json의 knip 필드)에 entry/project 경로를 잡아 주고 시작하세요.
팁 / 변형
- 다른 생태계로 체크 명령 바꾸기: knip이 안 맞으면
npx depcheck(의존성 위주), npx ts-prune(미사용 export)으로 바꾸세요. 파이썬은 vulture(데드 코드)·deptry(미사용/누락 의존성), Rust는 cargo +nightly udeps, Go는 staticcheck -unused가 비슷한 역할을 합니다.
- 삭제는 보수적으로: 동적 import, 런타임 reflection, 빌드 스크립트가 쓰는 파일은 knip이 못 보고 "unused"로 찍습니다. 한 번에 너무 많이 지우지 말고, 지운 뒤 반드시 빌드·테스트로 회귀를 확인하세요.
- 막힐 때: 같은 항목이 계속 unused로 잡히는데 실제로는 쓰이고 있다면, 가드레일대로 삭제를 멈추고
ignore에 한 줄 이유와 함께 등록한 뒤 사람에게 보고하게 하세요.
- 연관 루프: 구현 직후 전반적인 청소는
looping:de-sloppify-pass, 린트·타입 위반 정리는 looping:lint-typecheck-fix, 의존성 업그레이드는 looping:dependency-upgrade-one-by-one.
원본 영어 kickoff (loops.elorm.xyz 원문)
Start the "Knip Until Clean" loop.
Goal: knip reports no unused code or dependencies
Max iterations: 5
Between iterations run: npx knip
Exit when: knip exits 0
Step 1: Run knip. Remove dead exports and unused deps with minimal diffs; verify tests still pass.
Self-pace this loop. After each iteration, run the check command, read the output, and only continue if the exit condition is not met. Stop when the exit condition passes or max iterations is reached. Give a short status update each pass.
출처: https://loops.elorm.xyz/loops/knip-until-clean