되돌리기와 영수증이 달린 터미널 코딩 에이전트 Codewhale, 어떤 모델이든 붙는다
Tools18분 읽기

되돌리기와 영수증이 달린 터미널 코딩 에이전트 Codewhale, 어떤 모델이든 붙는다

Codewhale은 MIT 오픈소스 터미널 코딩 에이전트다. 명령 하나가 거치는 아홉 관문, 권한 3단계와 샌드박스, /undo 스냅샷, /receipts 영수증, 모델 연결을 짚었다.

금요일 저녁, 실패하는 테스트 하나를 에이전트에게 맡기고 퇴근했다고 하자(편집부가 만든 장면입니다). 월요일에 돌아와 보니 로그에 셸 명령이 열두 줄 찍혀 있습니다. 그때 궁금한 것은 세 가지입니다. 에이전트가 무엇에 손을 댔는지, 마음에 안 들면 되돌릴 수 있는지, 그리고 애초에 건드려서는 안 되는 곳에 닿을 수 있었는지. Codewhale(저장소 codewhale-hq/Codewhale)은 이 세 질문에 각각 영수증(/receipts), 되돌리기(/undo), 아홉 단계 권한 판정과 운영체제 샌드박스로 답하는 오픈소스 터미널 에이전트입니다. 이 글은 기능 소개 순서가 아니라 “에이전트가 어디까지 닿고, 그 길목마다 무엇이 서 있나”라는 지도 순서로 읽습니다. 확인 기준(2026-10-27 UTC)으로 GitHub 별은 4만 1천 개 남짓(41.1k), 포크 3천 6백 개 안팎, MIT 라이선스, Rust로 작성되었고 최신 릴리스는 v0.10.2(10월 24일 17:31 UTC)다.

자리를 비운 사이에 에이전트가 건드릴 수 있는 것

Codewhale은 올해 1월 19일에 만들어진 저장소로, DeepSeek 모델용 터미널 앱 deepseek-tui에서 출발했고 지금도 그 프로젝트의 설정과 세션을 읽습니다. README는 DeepSeek을 비롯한 어떤 제공자와도 제휴 관계가 아니라고 밝히며, 기본 모델만 DeepSeek 쪽으로 정해져 있습니다. 공식 사이트에는 기여자 393명이 올라 있습니다.

에이전트가 닿는 곳은 크게 다섯 군데입니다. 작업 폴더의 파일, 내 계정 권한으로 도는 셸, 외부 MCP 서버와 네트워크, 프롬프트와 코드가 건너가는 모델 제공자, 그리고 Codewhale 자체의 통계 수신 서버입니다. 새로 설치하면 Work 모드에 Ask 권한으로 시작하는데, 이 기본 자세에서 각 길이 어떻게 처리되는지를 먼저 한 장으로 봅니다.

에이전트에서 파일, 셸, 보호 경로, 모델 제공자, MCP, 통계 서버로 가는 길과 기본 처분을 보인 지도 그림 1. 기본 자세(Work + Ask)에서 에이전트가 닿는 곳. 초록 영역은 운영체제 샌드박스 안, 붉은 영역은 기기 밖으로 나가는 길

같은 화살표라도 왼쪽 초록 영역과 오른쪽 붉은 영역에서는 성격이 다릅니다. 작업 폴더의 파일 수정은 묻지 않고 적용되고 diff만 보여 줍니다. 읽기 전용이 아닌 셸 명령은 먼저 묻습니다. ~/.ssh, ~/.aws, .env 같은 자격 증명 보관소는 샌드박스 안에서도 보호 경로로 막힙니다. 반대편의 모델 제공자에게는 내가 보내는 프롬프트와 코드가 가고, 익명 사용 통계는 기본으로 켜져 있습니다. 이 글의 나머지는 이 여섯 화살표 중 어느 것을 어디서 조일 수 있는지를 하나씩 따라가는 일입니다.

명령 하나가 아홉 관문을 지나는 순서

모델이 도구를 부르면 호출 하나는 공식 문서(AUTHORIZATION_ORDER.md)가 정리한 아홉 관문을 정해진 순서로 지납니다. 아래 그림은 순서와 각 관문이 쓸 수 있는 동작을 색으로만 표시했고, 관문별 세부는 그 뒤의 표에 둡니다.

아홉 관문이 1번 설정부터 9번 샌드박스까지 이어지는 도식. 6번부터는 결과가 조이는 방향으로만 바뀐다 그림 2. 호출 하나가 지나는 관문. 위 줄은 왼쪽에서 오른쪽, 아래 줄은 오른쪽에서 왼쪽으로 읽습니다

색을 보면 관문마다 맡은 일이 다릅니다. 파랑인 1번은 설정을 정리하는 단계이고, 빨강인 2번과 9번은 막는 일을 하며, 호박색인 4·6·7번은 질문이나 차단을 더할 수 있고, 보라색인 3번(훅)과 5번(규칙 파일)은 막기·묻기·허용을 모두 낼 수 있습니다. 사람에게 묻는 8번은 사용자가 직접 답하는 자리입니다. 각 관문의 세부는 다음과 같습니다.

관문 하는 일 눈여겨볼 점
1 설정과 자세 사용자 설정, 실행 중 덮어쓰기, 프로젝트 덮개를 합쳐 이번 턴의 자세를 정함 덮개는 승인·샌드박스·셸 사용을 조이는 쪽으로만 반영
2 모드와 도구 허용 Plan 모드 제한, 거부 목록, 해석 실패, 실행 등록이 없는 도구를 차단 허용 목록과 거부 목록에 함께 있으면 거부
3 준비와 tool_call_before 훅 훅이 차단·질문·허용을 냄 거부가 질문보다, 질문이 허용보다 앞섬. 판정을 내지 않는 엄격 훅은 닫는 쪽으로 처리
4 도구 기본 요건 도구가 스스로 요구하는 승인 Plan 모드는 쓰기 가능 도구를 여기서 막음
5 규칙 파일(permissions.toml) 일치하는 deny는 차단, ask는 질문, allow는 일반 승인만 면제 allow가 훅의 ask나 풀 수 없는 보류까지 지우지는 못함
6 자동 검토와 안전 바닥 질문이나 차단을 더함 안전 바닥이 숨은 유니코드가 든 셸 명령, 게시형 작업, 파괴적 백그라운드 작업, 자격 증명을 올리는 curl/wget을 막거나 보류
7 저장소 규칙 보호 경로 불변 조건으로 질문이나 차단을 더함 Full Access에서는 질문이 곧 차단
8 사람 승인 남은 질문이 사용자에게 도달 승인은 이번 호출 하나에만 적용. 세션·영구 허용도 뒤 관문을 건너뛰게 하지는 않음
9 도구 권한과 샌드박스 작업자 권한, 경로 검사, 운영체제나 외부 샌드박스 샌드박스의 거부는 사용자가 따로 승격을 허가하지 않는 한 거부로 남음

표에서 놓치기 쉬운 것이 6번의 위치입니다. 자격 증명 업로드 보류와 숨은 유니코드 거부는 0.10.2에서 들어왔고, 사람에게 묻기(8번)보다 앞의 관문이 처리합니다. 그래서 사람이 무심코 승인 버튼을 누를 수 있는 자리에 도달하기 전에 걸러집니다.

뒤 관문이 앞 관문을 풀 수 없는 이유

아홉 관문의 핵심 설계는 단조성입니다. 문서는 규칙 파일 단계 뒤로는 결과가 조이는 방향으로만 바뀐다고 적습니다. 자동 검토와 저장소 규칙은 질문이나 차단을 더할 수 있어도, 앞에서 생긴 차단이나 질문을 검토 없는 실행으로 바꾸지 못합니다. 몇 가지 규칙이 이 원칙을 구체화합니다.

  • 하드 거부가 항상 먼저입니다. 거부로 지정한 명령 접두사는 전체 명령과 이어 붙인 각 조각에 대해 검사되고, 어떤 허용 규칙도 이를 덮지 못합니다.
  • 이어 붙인 명령은 한 조각만 걸려도 전체가 막힙니다. a && b에서 신뢰하는 접두사가 있어도 사슬 전체를 승인하지는 않습니다.
  • 규칙은 출처 층이 먼저, 동작이 다음입니다. 사용자 층, 에이전트 층, 기본 제공 층 순서로 보고, 같은 층 안에서는 deny가 ask를, ask가 allow를 이깁니다. 그래서 사용자 층의 allow가 에이전트 층의 deny를 넘을 수 있습니다.
  • 규칙 파일은 사용자 설정 옆에만 있습니다. permissions.toml에는 프로젝트 쪽 원천이 없어서, 내려받은 저장소가 내 규칙을 바꿀 수 없습니다.
  • 프로젝트 덮개는 조이기만 합니다. 저장소의 .codewhale/config.toml에서 받아들이는 키는 model, reasoning_effort, approval_policy, sandbox_mode, max_subagents, allow_shell(false만)이고, api_key, base_url, provider, providers, 훅, MCP 설정은 무시합니다. 심볼릭 링크로 된 덮개 파일은 거부되며, 한 번만 건너뛰려면 --no-project-config를 줍니다.

Full Access는 이 구조에서 예외 지점이 분명합니다. 풀 수 있는 보류는 질문 없이 자동 승인되고, 규칙의 ask는 세션을 질문 상태로 낮추지 않으며, 안전 바닥은 건너뜁니다. 저장소 규칙의 질문은 모달이 없으므로 곧바로 차단됩니다. 그래도 규칙 파일의 deny, 치명적인 백그라운드·헤드리스 보류, 저장소 규칙의 차단은 여전히 닫는 쪽으로 작동합니다.

Ask 모드에서 명령 네 개의 운명

같은 Ask 권한이라도 명령에 따라 결과가 네 갈래로 갈립니다. 아래 터미널 그림은 문서의 규칙으로 편집부가 구성한 주석 예시이고, 실제 화면의 문구와는 다릅니다.

같은 Ask 권한에서 읽기 전용 명령은 실행, 일반 명령은 질문, 자격 증명 업로드는 보류, 보이지 않는 문자가 든 명령은 거부되는 주석 화면 그림 3. Ask 권한에서 명령 네 개가 받는 판정(편집부 구성 예시)

첫 줄 git diff --stat은 읽기 전용이라 묻지 않고 돕니다. 둘째 줄 cargo test -p parser는 읽기 전용이 아니어서 승인 카드가 뜨고, 답은 한 번만(y), 같은 종류를 이 대화 동안(a), 거부(n) 중 하나입니다. 셋째 줄은 자격 증명을 외부로 올리려는 curl이라 안전 바닥에서 보류됩니다. 넷째 줄은 눈에 보이지 않는 양방향 유니코드 문자가 든 명령으로, 승인 카드나 검토 모델 호출 이전에 거부됩니다. 이런 문자는 화면에 보이는 명령과 실제로 실행되는 명령을 달라 보이게 만들 수 있어서, 승인 화면만 믿는 방식의 맹점을 닫는 장치입니다.

여기서 a는 편하지만 가장 넓게 열리는 답입니다. 이 대화가 끝날 때까지 같은 종류의 호출이 묻지 않고 지나가며, 영수증에는 “by session rule”로 남습니다. 다만 앞서 본 대로 세션 허용은 뒤 관문을 건너뛰게 하지 않습니다.

모드는 하는 일, 권한은 묻는 정도

Codewhale은 “무엇을 하느냐(모드)“와 “얼마나 묻느냐(권한)“를 따로 둡니다. 모드는 Tab(입력창이 비었을 때) 또는 /mode로, 권한은 Shift+Tab으로 바꾸고, 모델이 한 턴을 도는 중에는 바꿀 수 없어서 Esc로 멈춘 뒤에 바꿉니다.

구분 선택지 동작
모드(Tab) Plan 읽고 검색만 함. 파일 쓰기와 셸 실행은 거부, 웹 검색은 가능
Work 파일을 고치고 명령을 실행
Operate Work와 같은 권한. 요청을 목표로 보고 할 일 목록을 보이며, 여러 갈래는 병렬 하위 에이전트로 나누고, 중요한 변경은 독립 검토자를 붙이며, 긴 명령은 백그라운드로 돌림
권한(Shift+Tab) Ask 저장소 안 파일 수정은 묻지 않고 적용, 읽기 전용이 아닌 셸 명령은 먼저 물음
Auto-Review 규칙과 검토용 모델이 일상적인 호출을 승인하고 고위험은 거부
Full Access 묻지 않고 Codewhale 샌드박스도 끔(저장소 규칙과 관리 정책은 유지)

Operate는 새 권한을 주는 모드가 아니라 일하는 방식을 바꾸는 모드입니다. Plan에서 계획이 끝나면 Work(Ask), Work(Auto-Review), 계속 계획 중에서 고르라고 묻습니다.

Auto-Review는 두 겹으로 일합니다. 첫 겹은 결정적인 규칙으로, 안전하다고 증명되는 호출은 통과시키고 게시형 작업과 파괴적인 백그라운드 작업은 막습니다. 규칙이 증명하지 못한 호출만 둘째 겹인 모델 감시자로 가는데, 감시자는 대화 기록 없이 문제의 호출과 관찰 결과만 받아 위험도와 허용 여부, 이유를 돌려줍니다. 위험이 높음이나 치명이면 자동 실행하지 않고, 시간 초과나 응답 형식 오류, 제공자 장애도 거부로 처리합니다. 연속 3번 거부되거나 최근 50번 검토 중 10번이 거부되면 그 턴을 멈추는 회로 차단기도 있습니다. 화면 없이 도는 exec에서는 첫 겹만 씁니다.

마지막 문, 운영체제 샌드박스

아홉 번째 관문은 운영체제가 지키는 문입니다. 이 문은 앞선 여덟 관문이 모두 통과시킨 호출에도 마지막으로 걸립니다.

운영체제 방식 비고
macOS Seatbelt(sandbox-exec) 사전 시험이 통과하면 자동 적용
Linux bubblewrap(/usr/bin/bwrap) 시험이 통과하면 기본 적용, prefer_bwrap = false로 끔. 없으면 샌드박스 없음
Windows 없음 문서가 “현재 구현에는 OS 샌드박스가 없다”고 밝힘
어디서나 OpenSandbox 호환 외부 서비스 sandbox_backend = "opensandbox". 격리 강도는 그 서비스에 달림

Ask와 Auto-Review는 작업 폴더 쓰기만 허용하는 workspace-write, Plan은 read-only, Full Access는 래퍼 자체가 없습니다. 설정값은 허용 범위를 좁히기만 하고 넓히지 못합니다. 샌드박스 안에서 ~/.ssh, ~/.aws, .env는 보호 경로로 막히며, 0.10.2부터 터미널 세션과 더 많은 파일 도구가 같은 보호를 받습니다. 내 기기에서 샌드박스가 실제로 걸리는지는 codewhale doctor나 codewhale setup --status로 볼 수 있습니다.

Windows에는 운영체제 샌드박스가 없고, Full Access나 exec --auto는 어디서든 샌드박스를 끕니다. 이 경우 지켜 주는 것은 승인 프롬프트와 저장소 규칙뿐입니다. 믿을 수 없는 저장소나 비밀이 든 개인 기기에서는 쓰지 않는 편이 맞습니다.

되돌릴 지점과 기록이 놓이는 곳

방어가 뚫렸을 때를 위한 장치가 되돌리기입니다. 파일을 바꿀 수 있는 턴 앞뒤로 작업 폴더의 스냅샷을 찍어 내 저장소가 아닌 별도의 side-git에 보관합니다. 아래 트리는 그 위치와, 영수증·설정이 놓이는 곳, 스냅샷에서 빠지는 곳을 한 번에 보입니다.

홈 폴더의 설정·세션·스냅샷 위치와 작업 저장소에서 스냅샷 대상과 제외 대상을 나눈 파일 트리 그림 4. 기록과 되돌릴 지점이 놓이는 곳. 내 .git은 어느 쪽에도 끼지 않습니다

초록으로 표시한 곳이 되돌리기의 재료입니다. ~/.codewhale/snapshots/<프로젝트 해시>/<워크트리 해시>/.git에 턴 앞뒤 상태가 쌓이고, /restore N과 revert_turn 도구는 이 스냅샷으로 파일 상태를 되돌리면서 대화 기록과 내 .git은 건드리지 않습니다. 같은 트리에서 .env, node_modules, target 같은 .gitignore 대상과 작업 폴더 밖은 스냅샷에 포함되지 않습니다.

두 명령은 범위가 다릅니다. /undo는 가장 최근 요청과 그 요청이 바꾼 모든 파일을 한 단계로 되돌리고 트러스트 모드가 필요 없습니다. 0.10.2부터 여러 줄짜리 프롬프트도 한 요청으로 취급합니다. /restore N은 작업 폴더를 지정한 스냅샷 시점으로 복원하는 더 거친 도구여서 그 뒤의 수정까지 덮어쓰고, 그래서 /trust on이나 Full Access가 필요합니다.

한계도 문서에 적혀 있습니다. 스냅샷은 최신 50개만 유지하고, 기능이 꺼져 있거나 작업 폴더가 너무 크면 건너뜁니다. 에이전트가 .env를 고치거나 node_modules를 지워도 스냅샷으로는 돌아오지 않을 수 있다는 뜻입니다. 그래서 첫 실행 전에 커밋하거나 스태시해 두라는 안내가 형식이 아니라 실제 안전장치입니다. Git 이력이 되돌리기의 마지막 보루로 남습니다.

영수증이 적는 것과 못 적는 것

영수증은 모델을 새로 불러 만드는 요약이 아닙니다. 세션이 이미 저장해 둔 기록(도구 호출 순서, 턴마다의 권한 상태, 승인 요청과 결정)을 읽어 조립하는 읽기 전용 보고서입니다. 만들 때 모델 제공자를 호출하지 않고 도구를 실행하지 않고 파일도 쓰지 않으므로, 같은 세션의 영수증은 몇 번을 뽑아도 같습니다. 터미널에서는 /receipts(전체), /receipts json, 특정 턴만 보려면 턴 번호를 붙이고, 세션을 종료한 뒤에는 codewhale receipts --last, 특정 세션이면 ID와 --format md|json을 씁니다. 문서에 실린 출력 모양은 이렇습니다.

# Receipt: Fix the parser
thread thr_19a0141a · /work/repo · deepseek-flash · Ask · ...
Changed 1 file (+2 −1) · ran 1 command · made 1 MCP call · ...
1. edited `src/parse.rs` (+2 −1) · 1.0s
2. ran `cargo test -p parser` in /work/repo — exit 0 · 2.5s · approved by you
3. did not run `rm -rf build` · denied by you

세 번째 줄이 영수증의 성격을 보여 줍니다. 실행한 일뿐 아니라 실행하지 않은 일도 남습니다. 각 작업에는 종류(파일 변경, 명령, 네트워크, MCP, 하위 에이전트, 승인, 실패한 턴 등)와 상태(성공, 실패, 승인에서 멈춤, 시작 전에 차단됨, 중단됨 등)가 붙어서 “무엇이 막혔고 무엇이 통과했는지”를 가를 수 있습니다.

승인 줄에는 누가 답했는지도 적힙니다. by you는 터미널·앱·웹 미러 또는 사람을 대신하는 API 클라이언트가 응답한 경우, by session rule은 앞서 a로 기억시킨 규칙이 자동 승인한 경우, by posture는 Auto-Review나 Full Access처럼 자세 자체가 묻지 않고 처리한 경우입니다. 시간 초과나 물을 사람이 없던 경우는 거부가 아니라 “응답 없음”으로 셉니다. 0.10.1 이전에 기록된 승인과 하위 에이전트의 승인에는 “decider not recorded”가 붙습니다.

한도와 빈칸도 분명합니다. 한 영수증에는 작업 2,000개까지 나열하고 넘친 만큼은 omitted_actions로 셉니다. 명령 한 줄은 200자, 검색어는 120자, 오류 줄은 160자까지 표시하며 비밀은 마스킹합니다. 추론 텍스트와 원시 도구 출력은 아예 내보내지 않고, 터미널 세션에서는 명령의 종료 코드와 소요 시간(실패한 셸 호출 제외)이, 런타임 스레드에서는 셸 명령이 바꾼 파일이 기록되지 않습니다.

영수증은 안전 인증서가 아닙니다. 문서는 영수증이 안전 인증이나 호환 인증, 호스팅된 보증이 아니라고 적고, JSON의 claim_ceiling 필드에도 같은 취지가 담깁니다. 기록은 감사의 출발점이고, 중요한 변경은 git diff와 테스트로 다시 확인해야 합니다.

스크립트 실행의 저장 규칙도 알아 둡니다. 도구를 쓰는 exec 실행(--auto 포함)은 모든 출력 형식에서 세션이 저장되어 나중에 codewhale receipts --last로 볼 수 있습니다. 도구 없이 답만 받는 텍스트 실행과 --json 실행은 대화 압축이 시작될 때만 저장되므로, 항상 남기려면 --output-format stream-json을 씁니다.

확장이 권한을 넓히지 못하게 하는 장치

MCP 서버, 훅, 하위 에이전트, GitHub Action은 에이전트의 손을 늘리는 도구들이라 지도에서 가장 먼저 새는 곳입니다. 문서는 각각에 상한을 둡니다.

MCP 서버(에이전트가 외부 도구에 연결하는 표준 방식)는 ~/.codewhale/mcp.json에 적거나 codewhale mcp add로 추가하고 codewhale mcp list, codewhale mcp validate로 점검하며, 화면 안에서는 /mcp reload로 재시작 없이 반영합니다. 부작용이 있는 MCP 도구는 승인을 거치고, Full Access도 하드 보류는 넘지 못합니다. 문서는 MCP 설정을 “내 컴퓨터에서 코드를 실행하는 것과 같다”고 경고합니다.

훅 이벤트는 15가지인데 동작을 바꾸는 것은 message_submit, tool_call_before, shell_env 셋뿐이고 나머지는 관찰용입니다. tool_call_before 훅이 종료 코드 2로 끝나면 stdout과 상관없이 하드 거부이고, 종료 코드 0과 함께 {"decision": "deny", "reason": "..."}를 내보내도 차단되어 모델에는 사유가 담긴 거부 결과가 돌아갑니다. 빈 출력이나 JSON이 아닌 출력은 허용으로 봅니다. 화면 없는 exec는 --hooks를 붙여야 훅을 돌리지만 tool_call_before는 예외로 항상 적용됩니다.

하위 에이전트는 역할별로 권한이 다릅니다.

역할 파일 쓰기 셸
general, implement 가능 가능
test 불가 제한된 검증
explore, reviewer 불가 제한된 조사
planner 불가 읽기 전용 확인
advisor 불가 없음

모든 역할이 기본으로 네트워크 읽기는 쓸 수 있습니다. 기본 동시 실행 상한은 64개이고 설정으로 128개까지 올립니다. 자식의 권한은 부모의 현재 권한을 넘지 못하고, 거부 목록은 부모의 것을 합쳐 상속하며, 데스크톱 제어 권한은 자식에게 주지 않습니다(0.10.0부터). Ask에서는 자식이 막힌 호출이 부모 화면에 승인 요청으로 올라옵니다.

PR 리뷰 쪽은 codewhale review --pr N이 기본으로 조언만 하고 --post를 붙여야 게시합니다. 같은 기능의 GitHub Action은 두 단계로 나누도록 권합니다. 분석 단계는 읽기 전용 토큰과 모델 키만 갖고 결과 파일을 만들고, 게시 단계는 쓰기 토큰만 갖고(모델 키 없이) COMMENT 리뷰 하나를 답니다. 승인·변경 요청·커밋은 하지 않는 리뷰 전용이며, pull_request_target에서는 쓰지 말라고 경고하고 포크 PR과 초안 PR은 제외합니다. 에이전트 여러 대를 동시에 굴릴 때의 관리는 Herdr 글에서 다룬 방식과 견줘 볼 만합니다.

코드와 키가 나가는 길, 모델 연결

지도 오른쪽의 붉은 영역을 가장 크게 좌우하는 선택이 어느 모델 제공자에 연결하느냐입니다. 내장 제공자 ID는 약 50개로 Anthropic, OpenAI, DeepSeek, Google, Mistral, Moonshot, OpenRouter, xAI 등이 들어 있고, OpenAI 호환 엔드포인트면 직접 추가할 수 있습니다. 기본 제공자는 DeepSeek, 기본 모델은 deepseek-flash이며 이 별칭이 10월 17일 DeepSeek-V4.1-Flash-1017로 옮겨 갔다는 점은 DeepSeek V4.1 Flash 1017 글의 변경과 이어집니다. 다른 제공자의 기본 모델은 문서에 이렇게 적혀 있습니다.

제공자 기본 모델 메모
anthropic claude-sonnet-5-5 0.10.2에서 기본값이 바뀜
openai gpt-5.6 ChatGPT 계정 로그인용 openai-codex는 gpt-6.1-sol
google gemini-3.1-pro-preview
xai grok-4.6
ollama 로컬 태그 자동 로컬 데몬이 서빙하는 대화 모델 중에서 고름
custom 직접 지정 사내 게이트웨이 같은 OpenAI 호환 주소

설정은 ~/.codewhale/config.toml 한 곳에서 합니다. 키는 파일에 쓰는 대신 codewhale auth set --provider <ID>로 저장하거나 OPENAI_API_KEY 같은 환경 변수로 넘길 수 있습니다. 사내 게이트웨이 같은 사용자 정의 주소는 이렇게 씁니다.

provider = "my-gateway"

[providers.my-gateway]
kind = "openai-compatible"
base_url = "https://gateway.example/v1"
api_key = "YOUR_GATEWAY_API_KEY"
model = "your-model-id"

로컬 모델은 키가 필요 없고 코드가 기기 밖으로 나가지 않습니다. Ollama는 http://localhost:11434/v1, vLLM은 http://localhost:8000/v1, SGLang은 http://localhost:30000/v1이 기본 주소이고 codewhale --provider ollama --model <모델>처럼 고릅니다. 아무 설정이 없어도 Ollama가 대화 모델을 서빙 중이면 그것을 쓰며, 0.10.2부터는 첫 메시지를 보낼 때 그렇게 해도 되는지 제안합니다. 로컬이 아닌 http:// 주소는 기본으로 거부되고, 저장소 안의 설정 파일은 제공자·키·주소를 바꾸지 못합니다.

모델은 /model로 턴 사이에 바꾸고 /model auto는 턴마다 알아서 고릅니다(/router로 구성). /turn inspect가 그 턴에 쓴 모델과 비용, 걸린 시간을 보여 줍니다. 쉬운 일을 싼 모델로 보내는 발상은 LLM 라우팅 글과 같은 계열입니다. 가격을 아는 제공자는 달러로, 모르면 cost: unknown으로 표시하고 무료처럼 보이게 하지 않습니다. 구독형 요금제는 남은 할당량을 보여 줍니다.

Codewhale 쪽으로 가는 길은 통계 하나입니다. 0.9.12(9월 5일)부터 익명 사용 집계가 기본으로 켜졌고, 버전, 운영체제, 세션 길이 구간, 쓴 제공자 종류, 기능·오류 횟수 같은 집계만 보냅니다. 프롬프트, 코드, 파일·저장소 이름, 모델 이름, 키, IP는 보내지 않는다고 문서가 밝히며 설치 ID는 90일마다 바뀝니다. 끄려면 codewhale config set telemetry false, 한 번만 끄려면 CODEWHALE_TELEMETRY=0이고, 명시적으로 끈 값은 다른 설정보다 우선합니다. 시작할 때 GitHub 릴리스를 확인하는 동작은 CODEWHALE_NO_UPDATE_CHECK=1로 끕니다.

설치하고 권한부터 확인하는 첫 작업

macOS와 Linux는 공식 설치 스크립트가 체크섬을 검증한 codewhale과 짧은 이름 codew를 ~/.local/bin에 둡니다. Windows는 winget install HunterBown.CodeWhale(Scoop과 GitHub 릴리스 설치 파일도 있음), 그 밖에 npm, Cargo, Nix, 컨테이너 방법이 있고 Android(Termux)는 미리 보기입니다. 한 기기에는 설치 방식을 하나만 쓰라는 안내가 있어 복사본이 PATH에 둘 생기는 상황을 피해야 합니다. 한 줄 스크립트보다는 패키지 관리자를 쓰거나 스크립트를 먼저 열어 본 뒤 실행하는 편이 낫습니다.

npm install -g codewhale    # 같은 릴리스 바이너리를 감싼 패키지
codewhale update            # 업데이트
codewhale doctor            # 이 기기에서 샌드박스가 걸리는지 확인
  1. 작업 중인 저장소를 커밋하거나 스태시한 뒤, 저장소 루트에서 codewhale doctor로 샌드박스 상태를 보고 codewhale을 실행합니다.
  2. /provider(또는 F3)로 제공자를 고르고 키를 넣습니다. 키가 없다면 Ollama 같은 로컬 런타임을 고릅니다. 계정은 필요 없고 키는 로컬에만 저장됩니다.
  3. Tab으로 Plan 모드를 고르고 "이 저장소 구조를 설명하고 실패하는 테스트가 있으면 원인만 찾아 줘"처럼 읽기만 시킵니다.
  4. 계획이 마음에 들면 Work(Ask)로 이어 가 작은 수정 하나를 시킵니다. 읽기 전용 명령은 바로 돌고 나머지 셸 명령은 묻습니다.
  5. 끝나면 /receipts로 기록을 보고, 결과가 마음에 들지 않으면 /undo를 눌러 파일이 원래대로 돌아오는지 직접 확인합니다.

화면 없이 돌리는 자동 수정에는 함정이 하나 있습니다. exec는 도구 없이 답만 받는 것이 기본이고 --auto를 붙여야 도구를 쓰는데, 이때 --auto의 기본 권한은 Full Access라 묻지도 않고 샌드박스도 없습니다. 샌드박스를 유지하려면 --sandbox workspace-write를 함께 줍니다.

codewhale exec --auto --sandbox workspace-write "fix the failing tests and explain what changed"
codewhale receipts --last   # 다음 날 아침에 무엇을 했는지 확인

되돌리는 자리가 다른 도구들

터미널 코딩 에이전트는 이미 여럿이고, 각 저장소 README에서 확인한 사실만 놓으면 되돌리기와 권한을 두는 자리가 갈립니다.

도구 라이선스 눈에 띄는 설계
Codewhale MIT 요청 단위 /undo(별도 스냅샷), 작업 영수증, 권한 3단계, 40여 제공자
Aider Apache-2.0 편집할 때마다 자동 커밋. /undo로 마지막 변경 취소. 변경 전 미커밋분은 먼저 따로 커밋
OpenAI Codex CLI Apache-2.0 로컬 실행. ChatGPT 구독 로그인 또는 API 키로 인증
OpenCode MIT build(전체 권한)와 plan(읽기 전용) 에이전트를 Tab으로 전환

Aider는 Git 커밋 이력 자체가 되돌리기 장치이고 에이전트가 만든 커밋에는 작성자 이름에 “(aider)“가 붙습니다. Codewhale은 내 Git과 분리된 스냅샷 저장소에 되돌릴 지점을 두고 작업 기록은 영수증으로 따로 남깁니다. 커밋 이력을 어지럽히고 싶지 않다면 후자가, 모든 변경이 Git에 남기를 원한다면 전자가 맞습니다. Codewhale이 내세우는 또 하나는 모델 중립이라서, 특정 회사 모델의 구독에 묶이지 않고 키만 갈아 끼웁니다. 이미 쓰던 도구의 설정은 AGENTS.md를 자동으로 읽고, CLAUDE.md와 .cursorrules 같은 지침 파일은 project_instruction_imports로 켠 경우에만 읽으며, /import-claude로 Claude Code의 설정과 MCP 서버를 가져올 준비를 할 수 있습니다(내용은 사람이 확인). 스킬 형식이 낯설다면 Agent Skills 표준 글이 배경이 됩니다. 릴리스 번호가 0.10대여서 명령과 설정은 바뀔 수 있고, 9월 5일 0.9.12부터 10월 24일 0.10.2까지 일곱 주 사이에 릴리스가 다섯 번 나왔습니다. 필요한 기능은 CHANGELOG.md로 확인합니다.

팀 저장소에 두는 권장 설정

지금까지의 지도를 설정으로 옮기면 저장소에 둘 것과 내 홈 폴더에 둘 것이 갈립니다. 저장소의 .codewhale/config.toml은 조이는 값만 받으므로 팀원 모두에게 같은 하한선을 줄 수 있습니다. 아래 값은 문서의 키와 허용 값(on-request|untrusted|never, read-only|workspace-write|danger-full-access|external-sandbox)으로 편집부가 구성한 예시입니다.

# <저장소>/.codewhale/config.toml  (조이는 방향으로만 반영됨)
approval_policy = "on-request"
sandbox_mode = "workspace-write"
max_subagents = 2

내 홈 폴더 쪽에는 훅을 둡니다. tool_call_before 훅은 저장소 설정이 못 건드리는 사용자 전역 영역이고, 종료 코드 0과 decision: deny JSON으로 호출을 막습니다. 훅은 도구 이름과 인자를 DEEPSEEK_TOOL_NAME, DEEPSEEK_TOOL_ARGS 환경 변수로 받습니다. 아래는 git push가 든 호출을 항상 막는 편집부 예시입니다.

# ~/.codewhale/config.toml
[hooks]
enabled = true

[[hooks.hooks]]
event = "tool_call_before"
command = "~/.codewhale/hooks/gate.sh"
name = "gate"
#!/bin/sh
# ~/.codewhale/hooks/gate.sh — push는 사람이 직접 한다
case "$DEEPSEEK_TOOL_ARGS" in
  *"git push"*) echo '{"decision": "deny", "reason": "push is manual"}' ;;
esac
exit 0
#Codewhale#코딩 에이전트#터미널#DeepSeek#Ollama#오픈소스