🔥 프로젝트 상태를 한 줄로 비울 수 있게 됐다 — Claude Code 2.1.126

#Claude Code#Anthropic#CHANGELOG#claude project#OpenTelemetry#ANTHROPIC_BASE_URL
1467자
17분

claude project purge --dry-run 터미널 한 줄 아래 transcripts, tasks, file history, config entry 네 storage role이 한 명령으로 묶이는 것을 보여주는 다이어그램

지난주에 옛날 프로젝트 하나를 정리하다가 ~/.claude/projects/ 아래에 인코딩된 절대 경로 폴더가 그대로 남아 있는 것을 발견했다. 그 안에 세션 transcript .jsonl 파일이 수십 개씩 묶여 있었고, 한 사이드 프로젝트 폴더에는 16MB가 쌓여 있었다.

손으로 지우려다 멈칫했다. transcript는 그 폴더에 있다고 쳐도 file history database와 tasks 데이터가 어디에 사는지 정확히 기억나지 않았다. config entry도 별도 위치에 있었다. rm -rf ~/.claude/projects/<encoded>/를 직접 치려다가 매뉴얼을 한 번 더 보고 손을 멈췄다. 결국 정리를 미뤘다.

2.1.126의 첫 줄이 그 망설임을 한 줄로 줄여 줬다.

claude project purge가 한 명령으로 묶는다

Claude Code 한 프로젝트의 상태가 사는 네 곳을 한 도식으로 보여주는 stack diagram — transcripts, tasks, file history, config entry 각각의 경로

CHANGELOG 원문은 Added claude project purge [path] to delete all Claude Code state for a project (transcripts, tasks, file history, config entry) -- supports --dry-run, -y/--yes, -i/--interactive, and --all (claude project purge [path]를 추가했다. 한 프로젝트의 모든 Claude Code 상태(transcripts, tasks, file history, config entry)를 삭제한다. --dry-run, -y/--yes, -i/--interactive, --all을 지원한다).

이 한 줄이 의미하는 건 두 가지다. 첫째, 그 프로젝트의 상태가 어디 어디에 사는가를 외울 필요가 없다. CLI가 위치를 알고 있다. 둘째, --dry-run이 있다는 것은 지우기 전에 무엇이 지워질지를 먼저 보여준다는 뜻이다. 손으로 rm을 쳤으면 위치 검증과 사전 확인을 직접 했어야 했다.

플래그 네 개의 구성이 친숙하다. --dry-run은 무엇이 지워질지만 출력하고 실제 삭제는 안 한다. -y/--yes는 인터랙티브 confirm을 건너뛴다. -i/--interactive는 항목별로 묻는다. --all은 한 프로젝트가 아니라 모든 프로젝트의 상태를 한꺼번에 비운다. cron이나 CI에서 굴리려면 -y --dry-run으로 먼저 점검하고 -y로 실제 실행하는 흐름이 자연스럽다.

손으로 정리하던 시절의 빈틈은 어느 폴더가 그 프로젝트와 묶여 있는가를 매번 다시 확인해야 했다는 점이다. CLI에 그 매핑이 들어오면서 [path] 인자가 그 매핑의 입력이 된다. 같은 워크스페이스 안에서 사이드 프로젝트 여러 개를 굴리는 사람일수록 이 한 줄이 가장 빨리 와 닿는다.

--dangerously-skip-permissions의 보호 영역이 줄었다

Before 2.1.126과 After 2.1.126 두 패널 비교 — .claude/, .git/, .vscode/, shell config가 이전엔 보호되다가 이제는 모두 bypass 대상으로 들어오고, catastrophic rm만 남는 모습

같은 2.1.126에서 --dangerously-skip-permissions가 더 멀리까지 묻지 않게 됐다. CHANGELOG 원문은 --dangerously-skip-permissions now bypasses prompts for writes to `.claude/`, `.git/`, `.vscode/`, shell config files, and other previously-protected paths (catastrophic removal commands still prompt as a safety net) (--dangerously-skip-permissions가 이제 .claude/, .git/, .vscode/, shell 설정 파일, 그리고 이전에 보호되던 다른 경로의 쓰기에 대해 prompt를 건너뛴다. catastrophic 제거 명령은 안전망으로 여전히 prompt가 뜬다).

이전 동작을 모르는 사람한테는 한 줄짜리 변화처럼 보이지만, 자동화로 Claude Code를 굴리는 사람한테는 그동안 묻던 곳들의 목록이다. .claude/skills/, .claude/agents/, .claude/commands/2.1.121에서 이미 prompt가 안 뜨도록 손봤다. 2.1.126은 그 흐름의 다음 한 걸음이다. .git/, .vscode/, shell 설정 파일까지 같이 올라온다.

shell config files라는 표현이 한 가지 신경 쓰이는 부분이다. .bashrc, .zshrc, .profile 같은 파일은 한 줄 잘못 적으면 다음 셸 세션이 안 뜨는 부류다. 그래도 --dangerously-skip-permissions라는 이름 자체가 그 위험을 알고 켠다는 옵션이고, catastrophic 제거 명령(rm -rf / 같은 류)은 여전히 prompt가 떠서 마지막 안전망 한 겹은 남아 있다. 평상시 인터랙티브 세션에서는 이 플래그를 켤 일이 적고, CI나 cron 같은 비대화 자동화에서 어차피 매번 같은 답을 누르던 prompt를 빼주는 길로 보면 자연스럽다.

이 변화는 Anthropic이 자동화 진입점을 정리하는 방향(직전 글 2.1.116~2.1.123)과 같은 줄기다. 한 묶음의 결정이라고 적힌 적은 없으니 단정은 안 한다. 다만 같은 방향을 가리키는 fix가 같은 시기에 계속 도착하는 것은 사실이다.

/model 피커가 게이트웨이의 /v1/models를 따라간다

Claude Code CLI가 게이트웨이로 GET /v1/models를 보내고 게이트웨이가 200 OK로 모델 목록을 돌려주면 그 응답이 /model 피커에 그대로 뜨는 sequence diagram

다른 한 변화는 사내 프록시나 LiteLLM 같은 게이트웨이를 끼고 Claude Code를 굴리는 환경 쪽이다. CHANGELOG 원문은 The /model picker now lists models from your gateway's /v1/models endpoint when ANTHROPIC_BASE_URL points at an Anthropic-compatible gateway (/model 피커가 이제 ANTHROPIC_BASE_URL이 Anthropic-compatible 게이트웨이를 가리킬 때 그 게이트웨이의 /v1/models endpoint에서 모델 목록을 가져온다).

이전엔 /model 피커가 Anthropic 본사 카탈로그(Opus, Sonnet, Haiku 등)를 그대로 띄웠다. 게이트웨이가 그중 일부만 노출하거나 별도 별칭을 붙여 둔 환경에서는 피커에 보이는 이름과 게이트웨이가 받는 이름이 어긋났다. 2.1.126부터는 게이트웨이의 /v1/models 응답이 그 목록을 채우므로, 피커에서 고른 이름이 그대로 게이트웨이의 라우팅 키로 들어간다.

이 fix가 가장 빨리 와 닿는 환경은 두 군데다. 첫째, 회사가 LiteLLM이나 OneAPI 같은 게이트웨이로 Anthropic SDK 호환 endpoint를 셋업해 놓은 곳. 둘째, AWS Bedrock이나 Vertex로 Claude를 호출하지만 그 앞에 사내 프록시 한 단을 더 둔 환경. 두 경우 모두 게이트웨이가 노출하는 모델 목록과 본사 카탈로그가 일치하지 않는데, 2.1.126부터는 그 차이가 피커 자체에서 사라진다.

본사 endpoint(api.anthropic.com)를 직접 쓰는 사람한테는 변화가 안 보인다. ANTHROPIC_BASE_URL이 다른 호스트를 가리킬 때만 Claude Code가 /v1/models를 호출한다.

OTel skill_activated 이벤트에 invocation_trigger가 붙었다

invocation_trigger 세 값 user-slash, claude-proactive, nested-skill을 세 swimlane으로 갈라 각 발화 원인을 한 줄로 적어둔 도식

OpenTelemetry로 Claude Code 사용을 외부에서 관측하는 환경 쪽 변화. CHANGELOG 원문은 claude_code.skill_activated OpenTelemetry event now fires for user-typed slash commands and carries a new invocation_trigger attribute (`"user-slash"`, `"claude-proactive"`, or `"nested-skill"`) (claude_code.skill_activated OpenTelemetry 이벤트가 이제 사용자가 직접 친 슬래시 커맨드에 대해서도 발화하고, 새 invocation_trigger 속성을 함께 실어 보낸다. 값은 "user-slash", "claude-proactive", "nested-skill" 중 하나).

이 한 줄이 푸는 모호함이 두 가지다. 첫째, 같은 skill이 하루에 100번 발화했을 때 몇 번이 사용자 의도였고 몇 번이 모델 자체 판단이었나를 텔레메트리가 갈래로 나눈다. "user-slash"는 사용자가 키보드로 /skill-name을 친 케이스, "claude-proactive"는 어시스턴트가 스스로 호출한 케이스, "nested-skill"은 다른 skill 안에서 다시 호출된 케이스다. 둘째, skill의 비용 책임 추적이 한 단계 더 명확하다. proactive 호출이 누적되면서 한 skill의 비용이 자기도 모르게 커질 수 있는데, 그 부분을 attribute 한 개로 구분한다.

OTel exporter를 켜놓고 Datadog이나 Honeycomb 같은 백엔드로 흘려보내는 팀이 가장 즉시 의미 있는 fix다. 평상시 인터랙티브 사용자한테는 보이지 않는 곳에서 일어나는 변화지만, 사용량을 분석하는 단계에서 한 차원이 늘어났다.

그 외 사용자 체감 변화

본문 한 줄을 따로 받을 분량은 아니지만 알고 있어야 손이 움직이는 fix가 같은 묶음에 더 있다.

Read tool의 per-file 멀웨어 평가 리마인더 제거. 원문은 removed the per-file malware-assessment reminder that could cause spurious refusals and "this is not malware" commentary on legacy models (legacy 모델에서 생기던 spurious refusal"this is not malware" 코멘트의 원인이던 per-file 멀웨어 평가 리마인더 제거). legacy 모델 한정 케이스라 Opus 4.7 / Sonnet 4.6 사용자한테는 보이던 동작이 아닐 수 있다. 그래도 같은 코드 베이스의 정리라 알고는 있는 게 좋다.

같은 2.1.126의 Security: 라벨 fix가 한 줄 들어왔다. Fixed allowManagedDomainsOnly / allowManagedReadPathsOnly being ignored when a higher-priority managed-settings source lacked a sandbox block (allowManagedDomainsOnly / allowManagedReadPathsOnly가 우선순위 높은 managed-settings 소스에 sandbox 블록이 없으면 무시되던 버그를 fix). 회사 단위로 managed settings를 푸시하는 환경에서 도메인 락이 조용히 빠져 있던 케이스다. 그 룰이 정상 동작하는지 확인하는 단계에서 한 번 더 점검할 만한 fix.

OAuth 흐름 fix가 여러 곳 들어왔다. 가장 큰 한 줄은 claude auth login이 OAuth 코드 paste를 받는다는 것. WSL2, SSH, devcontainer처럼 브라우저 콜백이 localhost로 못 돌아오는 환경에서 코드를 직접 터미널에 붙이면 로그인이 끝난다. 같은 줄기에서 IPv6-only devcontainer의 OAuth timeout, 프록시 환경의 OAuth login 실패, drift된 refresh token 클리어 race도 같이 fix됐다. 원격이나 컨테이너 환경에서 Claude Code를 처음 켜는 마찰이 줄어든다.

WSL2, SSH, devcontainer 세 환경별로 브라우저 콜백이 막히는 원인을 적고 OAuth 코드를 터미널에 붙이면 로그인이 끝난다는 흐름을 세 칼럼으로 정리한 비교 도식

이미지 처리에서는 paste한 이미지가 2000px보다 크면 세션을 깨뜨리던 버그가 fix됐다. 이제는 paste 시점에 다운스케일이 들어가고, 이미 history에 들어 있는 oversized 이미지는 자동 제거 후 retry 된다. 직전 글에서 다룬 장기 세션 메모리 leak 묶음과 같은 줄기로 보인다.

Windows 사용자한테는 한 줄이 더 있다. --dangerously-skip-permissions와 별개로, PowerShell tool이 enabled된 상태에서 Claude가 PowerShell을 primary shell로 취급한다. 이전엔 Bash를 default로 두고 PowerShell을 부가 옵션처럼 다뤘는데, Claude가 PowerShell을 우선순위에 둔다. 같은 Windows 묶음에서 클립보드 쓰기가 process command-line 인자에 노출되어 EDR / SIEM 텔레메트리에서 보이던 보안 이슈도 같이 fix됐다.

deferred tool fix도 작은 한 줄이지만 의미가 분명하다. WebSearch, WebFetch 같은 deferred tool이 context: fork 설정의 skill과 다른 subagent의 첫 턴에서 안 보이던 버그를 잡았다. cruze 같은 자동화 루프에서 첫 턴에 WebSearch가 비어 있던 경험이 있다면 이 fix와 같은 줄기다.

다음에 내가 굴려 볼 것

claude project purge --dry-run을 워크스페이스 옆 사이드 프로젝트 폴더 두 곳에 한 번씩 돌려서 무엇이 잡히는지 확인한다. 인코딩된 transcripts 폴더만 잡히는지, 아니면 file history database나 별도 config entry까지 같이 잡히는지가 궁금하다. 결과가 깨끗하면 --all로 한 번에 비운다.

OTel exporter는 평소에 안 켜고 쓰는데, invocation_trigger 한 attribute 보려고 한 번 켜 둔다. 자체 cruze 루프가 하루에 어떤 skill을 몇 번 발화시키는지, 그중 proactive 비율이 얼마나 되는지가 숫자로 보일지 궁금하다.

--dangerously-skip-permissions는 평상시 안 켠다. 그래도 agent-pro의 이전 자동화 길에서 cruze 같은 비대화 흐름을 굴리고, 어느 단계에서 prompt가 사라지는지 한 사이클 체크한다.

참고 자료


시리즈: Claude Code CHANGELOG 추적

YouTube 영상

채널 보기
숫자 하나가 AI 모델의 운명을 바꾼다? | 선형대수학
마지막편, 트라이 노드를 50% 이상 줄이는 방법? 압축 트라이 성능 분석 | Trie 자료구조 이야기
벡터의 정의와 덧셈 연산 | 선형대수학
스칼라 곱셈과 내적의 기하학적 의미 | 선형대수학
내적의 기하학적 의미와 코사인 유사도 원리 | 선형대수학
트라이(Trie)에서 단어를 삭제하는 방법 | Trie 자료구조 이야기
숫자 하나가 AI 모델의 운명을 바꾼다? | 선형대수학
우리가 매일 쓰는 맞춤법 검사기와 라우터 속에 숨겨진 알고리즘은? | Trie 자료구조 이야기