Metadata-Version: 2.5
Name: token-rpg
Version: 0.14.3
Summary: Claude Code 토큰 사용량으로 성장하는 턴제 RPG
License-Expression: MIT
License-File: LICENSE
Keywords: claude,claude-code,cli,idle-game,rpg,token-usage
Classifier: Environment :: Console
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Games/Entertainment :: Role-Playing
Requires-Python: >=3.9
Description-Content-Type: text/markdown

# Token RPG

Claude Code에 쓴 토큰이 그대로 캐릭터가 되는 턴제 RPG입니다.

실제로 코딩한 만큼 강해집니다. 출력 토큰은 공격력, 캐시 재사용은 방어력,
thinking 토큰은 치명타율이 됩니다. 버그 벌레부터 토큰 한도의 군주까지, 개발자의 적 15종이 던전 보스입니다.

```
$ token-rpg open
Lv.28 코드 술사 🧑‍💻  HP 775 ATK 90 DEF 40.0 CRIT 30.5%  던전 15개
```

## 설치

```bash
pipx install token-rpg
token-rpg open              # 집계 후 브라우저로 열기 (Ctrl+C 로 종료)
```

의존성은 없습니다. 표준 라이브러리만 씁니다. Python 3.9+ 만 있으면 macOS·리눅스·윈도우에서
같은 명령으로 돕니다 (`uv tool install token-rpg`·`pip install token-rpg` 도 같습니다).

아직 안 나온 최신 커밋을 받고 싶으면 GitHub 주소를 그대로 씁니다.

```bash
pipx install git+https://github.com/YCYEOM/token-rpg
```

## 상주 앱

브라우저 탭을 띄워 두지 않고 늘 켜 두고 싶으면 OS 마다 상주 앱이 있습니다. 둘은 같은 일을
합니다 — 저장 서버를 띄우고, 5분마다 사용량을 다시 집계하고, 아이콘을 누르면 게임을 엽니다.
저장 파일 하나를 브라우저와 함께 쓰므로 어느 쪽으로 해도 진행은 이어집니다.

### 윈도우 — 알림 영역(트레이)

```powershell
token-rpg-tray                  # 알림 영역에 상주 (콘솔 창 없음)
token-rpg-tray --startup on     # 로그인할 때 자동 실행
```

왼쪽 클릭이면 게임 창이 열립니다(Edge 앱 모드 — 주소창 없이 팝오버에 가깝습니다. 없으면 기본
브라우저). 오른쪽 클릭이면 `열기 · 지금 갱신 · 자동 실행 · 종료` 메뉴가 나옵니다.

윈도우 트레이는 맥 메뉴 막대와 달리 아이콘 옆에 글자를 못 답니다. 그래서 레벨과
배지가 툴팁 첫 줄(`Lv.31 49% ⬆`)로 갑니다 — 아이콘에 마우스를 올리면 보입니다.

게임 데이터는 `%LOCALAPPDATA%\token-rpg` 에 둡니다(`token-rpg where` 로 확인).
Stop 훅은 `cmd.exe` 문법으로 등록합니다.

### macOS — 메뉴 막대

`Token RPG.app`은 메뉴 막대에 게임패드 아이콘으로 상주합니다. 아이콘 옆에 레벨과
진행률(`Lv.31 49%`)이 뜨고, 마우스를 올리면 오늘 쓴 토큰·다음 레벨까지 남은 EXP를
보여줍니다. 아이콘을 누르면 팝오버 안에서 게임 전체를 그대로 할 수 있습니다.

배지: `⬆` 레벨이 올랐는데 아직 안 열어 봄 · `⛏` 원정이 가득 참 (수령해야 다시 쌓입니다).
앱은 5분마다 사용량을 다시 집계하므로 Codex·Gemini 사용분도 반영합니다.

받는 곳은 [릴리스 페이지](https://github.com/YCYEOM/token-rpg/releases/latest) —
`Token-RPG-macOS.dmg` 를 받아 안에 든 `Token RPG.app` 을 `Applications` 로 드래그합니다.
새 버전이 나오면 같은 자리에서 다시 받아 덮어쓰면 됩니다(메뉴 막대 앱은 자기 사본을
갈아치우지 못합니다).

직접 빌드하려면 macOS Command Line Tools에서 다음을 실행합니다.

```bash
zsh scripts/build-macos-app.sh
open dist-macos/Token-RPG-macOS.dmg
```

앱은 독립적인 Swift/AppKit UI입니다. 다만 사용량 집계 로직은 번들에 든 `token_rpg.py`로
실행하므로 `python3`가 PATH에 있어야 합니다. 앱이 읽는 것은 로컬 로그뿐이고, 데이터를
외부로 보내지 않습니다.

지금 만드는 DMG는 **서명·공증하지 않은 개발 빌드**입니다. 다른 사람에게 배포하려면
Apple Developer ID로 서명하고 공증해야 Gatekeeper 경고 없이 열 수 있습니다.

## 자동 갱신

```bash
token-rpg install-hook      # Claude Code Stop 훅에 등록
```

이후 Claude Code가 응답을 마칠 때마다 스탯을 자동으로 갱신합니다(백그라운드, 1초 미만).
`token-rpg uninstall-hook`으로 되돌립니다. `~/.claude/settings.json`을 고치기 전에
항상 `.bak` 백업을 남깁니다.

## 게임 구조

**스탯** — 토큰 종류가 캐릭터 빌드를 정합니다. 사용 패턴이 곧 개성입니다.

| 스탯 | 출처 |
|---|---|
| ATK | 출력 토큰 |
| DEF | 캐시 읽기. 받는 피해를 **비율로** 깎는다 (보스 ATK 와 같으면 절반) |
| CRIT | thinking 토큰 (토큰만으로 최대 50%, 전체 상한 100% — 넘친 만큼 CDMG로) |
| CDMG | 치명타 피해. 기본 200%, 배분 +1%p/pt, 특성 '파괴의 유산' ×1.12/lv |
| SPD | API 호출 수 (+ 배분 포인트). 보스보다 N배 빠르면 한 턴에 N번 |
| EXP | 입력 + 캐시 생성 + 출력 |

**던전** — 고정 보스 15종(버그 벌레 → 무한 루프 뱀 → … → 토큰 한도의 군주)이 한 층입니다.
누구 PC에서든 같은 던전이고, 층마다 같은 보스가 지수로 강해져서 다시 나옵니다. 내 스탯은
토큰에 선형으로 크고 보스는 거듭제곱근으로 큽니다. 그래서 막힌 곳은 토큰을 더 쓰면 반드시 넘습니다.

**극초반은 완만합니다 (v0.11.0)** — 예전엔 1스테이지 보스를 잡는 데 누적 200만 토큰이
필요했습니다. 갓 깐 Lv.1 은 ATK 가 0 인데 보스 DEF 가 8 이라 데미지가 한 점도 안 들어갔습니다.
시작조차 못 하고 꺾이는 구간이었습니다. 이제 6스테이지까지 보스 능력치를 눌러 두고 거기서
원래 곡선에 합류합니다 — **토큰 0 으로도 1스테이지는 깹니다.** 레벨 곡선도 저렙만 완만해져
Lv.2 가 9배(5,460 EXP), Lv.10 이 1.8배 빠릅니다. Lv.32 에서 1.18배, Lv.70 위로는 예전과
같고 **Lv.99 총량(=초월 비용)은 그대로**입니다 — 손본 건 극초반뿐입니다.

**초월** — Lv.99 에서 레벨을 1로 되돌리고 다시 올립니다. 레벨은 배분 포인트(2pt/레벨)를
주는데 99에서 막혀, 그 위로는 토큰을 아무리 써도 포인트가 안 늘었습니다. **이미 받은
포인트는 적립해 두고** 레벨과 칭호만 처음으로 돌립니다 — 초월 1회에 198pt 가 굳습니다.
스탯 배분·혼·유물·클리어 기록은 건드리지 않습니다. EXP 는 쓴 토큰이라 줄지 않습니다.
그래서 저장에 적힌 초월 횟수만큼 덜어내고 레벨을 다시 셉니다 (`hero()` 와 JS `lvNow()`
양쪽에 같은 식이 있고, `selftest` 가 표로 붙들어 둡니다).

**환생** — 클리어 기록과 스탯 배분을 버리고 혼을 얻습니다. 혼으로 사는 영구 특성은
배율(×1.12/레벨)이라, 배분 포인트로는 따라갈 수 없는 층 벽을 넘게 해줍니다.
영구 특성은 일곱입니다 — 힘의 유산(ATK ×1.12/레벨), 파괴의 유산(CDMG ×1.12/레벨),
혼의 유산(HP ×1.16/레벨), 신속의 유산(SPD ×1.20/레벨), **벽의 유산(DEF ×1.28/레벨)**,
수확(얻는 혼 +3%), 각성(배분 포인트 +4). 배율이 제각각인 이유는 아래에 적었습니다.

**파괴의 유산은 원래 +5%p 가산이었습니다.** 보스가 스테이지마다 ×1.28 로 곱해지는 곡선이라
가산은 따라가지 못했고, 혼 23,455 를 부어도 도달 스테이지가 9 에서 9 로 그대로였습니다
(같은 혼이면 힘의 유산이 16). 배율로 바꾸니 힘의 유산보다 한 칸 뒤에 서고, CRIT 이
높을수록 좁혀집니다 — 들러리가 아니라 빌드가 고르는 선택이 됐습니다. `selftest` 가
'사면 더 깊이 가고, 힘의 유산과 세 칸 안에 서되 넘지는 않는다'를 붙들고 있습니다.

**상한이 있는 능력치는 영구 특성으로 두지 않습니다** — 되팔 수 없는데 어느 레벨부터
값이 반으로 죽으면 그건 선택이 아니라 함정입니다. 그래서 CRIT(상한 100%)은 토큰·배분
포인트·유물로만 오릅니다. 일곱 다 상한이 없어서 언제 사도 죽지 않고, 선택은 실수를
피하는 문제가 아니라 **무엇을 먼저 사느냐**의 문제가 됩니다.

**DEF 는 받는 피해를 비율로 깎습니다.** `피해 = ATK² ÷ (ATK + DEF)` 입니다. DEF 가 상대
ATK 와 같은 자리수면 절반이고, 아무리 높아도 0 이 되지는 않습니다.

예전에는 그냥 빼기였습니다(`ATK − DEF`). 49스테이지 보스 ATK 가 336만인데 배분을 전부
DEF 에 넣어도 6만이라 피해가 **1.88%** 줄었습니다. 벽의 유산은 0레벨이든 70레벨이든
도달 스테이지가 똑같았습니다. 뚫고 못 뚫고의 벼랑도 있었습니다 — 상대 DEF 를 못 넘으면
타격당 1 피해였습니다. 비율로 바꾸니 둘 다 사라집니다. 지금은 벽 54레벨이면 같은 자리에서
피해가 96.2% 줄고 도달이 53 에서 55 로 갑니다.

**보스보다 N배 빠르면 한 턴에 N번 칩니다.** 소수점은 확률로 한 번 더 칩니다 — 2.5배면
두 번은 확정, 세 번째는 절반입니다. 느리면 선공을 내줍니다(던전 목록에 빨갛게 뜹니다).
던전 목록이 스테이지마다 타격 수를 적어 줍니다. 상한은 없습니다.

상한을 뒀던 적이 있습니다. 효과가 '피해 두 배'에서 멈추니 배율 특성과 겨룰 수가 없었습니다.
힘의 유산 20레벨은 ATK ×9.65 인데 속도는 아무리 올려도 ×2 였습니다. 상한이 곧 천장이고,
천장이 있는 한 속도는 영원히 들러리였습니다. 그래서 없앴습니다.

**특성 배율은 그 스탯이 무엇과 겨루는지에 맞춥니다.** 전부 ×1.12 이던 시절에는 벽과
신속이 죽어 있었습니다. 혼을 얼마를 부어도 도달 스테이지가 그대로라, 사면 손해인
특성이었습니다.

| 유산 | 배율 | 왜 |
|---|---|---|
| 힘 · 파괴 | ×1.12 | 피해에 곱으로 붙습니다. 이걸로 충분합니다 |
| 혼(HP) | ×1.16 | 피해를 견디는 쪽. 벽과 함께 커야 합니다 |
| 신속(SPD) | ×1.20 | 보스 SPD 와의 비율 싸움. 타격 수가 배로 늘어 `STEP` 은 과했습니다 |
| 벽(DEF) | ×1.28 | 보스 ATK 와 1:1 로 맞섭니다. `STEP` 과 같으니 **1레벨이 한 스테이지분**입니다 |

| 특성 레벨 | 0 | 10 | 20 | 30 | 40 | 60 |
|---|---|---|---|---|---|---|
| 힘의 유산 도달 | 10 | 12 | 14 | 17 | 19 | 24 |
| 혼의 유산 도달 | 10 | 12 | 14 | 17 | 19 | 23 |
| 벽의 유산 도달 | 10 | 11 | 13 | 16 | 19 | 23 |
| 파괴의 유산 도달 | 10 | 11 | 13 | 16 | 18 | 23 |
| 신속의 유산 도달 | 10 | 12 | 14 | 16 | 18 | 22 |

다섯이 전 구간에서 두 칸 안에 서고 한 번도 힘의 유산을 넘지 않습니다. `selftest` 가
다섯 전부에 대해 "사면 더 깊이 가고, 힘과 세 칸 안에 서되 넘지 않는다"를 붙들고 있습니다.

SPD 는 **배분 포인트**(+3/pt)로도 올립니다. 배분분에도 특성 배율이 곱해지므로 깊은 층에서도
값을 합니다. 대신 그만큼 ATK 를 포기합니다.

타격이 50회를 넘으면 다 굴리지 않고 한 대 기댓값에 곱합니다. 수천 번을 굴리면 자동 도전이
화면을 멎게 합니다. 전투 로그는 한 턴을 한 줄로 `x132타 → 총 피해` 로 적습니다.

**수확** — 지금 세게 할지, 다음 환생부터 더 많이 벌지. 3%/레벨은 시뮬레이션으로 고른
값입니다. 더 올리면 층 벽이 무너집니다 (6%면 3층 진입이 23회 → 19회).
환생 1회에는 **기운** 하나가 듭니다. 기운은 게임을 시작한 뒤 새로 쓴 토큰 100만마다 하나씩,
3개까지 쌓입니다. 그래서 진행 속도가 실제 사용량에 묶입니다 — 하루 150~250만 쓰면
1층을 다 깨는 데 2~3일. 시작 전에 쓴 토큰은 세지 않습니다.

**원정** — 역대 최고로 깊이 간 스테이지를 자동 반복해 혼을 캡니다. 최대 8시간까지
쌓이고, 수령 이후 새로 쓴 토큰이 생산 배율이 됩니다(최대 3배).
**환생해도 멈추지 않습니다** — 기준이 이번 회차 진행이 아니라 역대 최고 기록이고,
쌓여 있던 미수령분도 그대로 남습니다.

**자동 도전** — 첫 환생 후 해금하고, **켜진 채로 시작합니다**. 지금 능력치로 이길 수 있는
다음 스테이지를 1초에 하나씩 연출 없이 깹니다. 더 못 오르면 멈추지 않고 이번 판 가장 깊은
스테이지를 계속 반복해 유물을 캡니다. 진 스테이지로는 능력치가 바뀔 때까지 다시 오르지
않습니다. 켜 둔 채 환생하면 직전 배분을 그대로 다시 걸어 목표까지 알아서 올라갑니다.

스테이지를 골라 돌리려면 `눌러서 고르기` 를 펼칩니다. 역대 클리어한 스테이지를 고르면
거기까지만 오르고 그곳을 반복합니다. 평소에는 접혀 있어서 스테이지가 늘어도 화면이
밀리지 않습니다.

**미션** — 게임 안 행동이 아니라 **실제 사용량**으로 채웁니다. 초기화 주기별로 나눠
보여줍니다 — 일일은 자정에, 주간은 월요일에 바뀝니다.

일일은 오늘 토큰 T·2T·3T 세 단이고(AI 툴을 여럿 쓰면 "오늘 2개 이상"이 하나 더 붙습니다),
주간은 5일 사용과 주간 토큰 5T입니다. 기준 T 는 지난 14일 평균의 절반이라 사용량에 맞춰집니다.
연속 사용일마다 보상 +10%(최대 7일).

보상 총합은 하루치·한 주치로 **고정**입니다(`DAY_BUDGET`·`WEEK_BUDGET`, 단위는 최고
스테이지 보스 격파 몇 번분). 그날의 미션들이 가중치로 나눠 갖습니다. 미션을 더 쪼개도 수입이
늘지 않습니다. 쉬운 단은 적게 주므로 하루치를 다 받으려면 3단까지 가야 합니다.
환생이 주 수입원으로 남도록 `selftest` 가 미션 주간 수입을 환생 수입과 견줘 상한을 지킵니다.

**혼 사냥** — 직접 손으로 버는 유일한 칸입니다. 왕복하는 표식을 과녁에서 멈춥니다.
과녁 안의 **금색 띠**가 한가운데(x1.5)이고, 보라 띠 안이면 중심에 가까울수록 더 줍니다.
벗어나면 0입니다. 멈춘 자리에 표식이 남아(한가운데 금색·명중 초록·빗나감 빨강)
얼마나 어긋났는지 %p 로 보여준 뒤 다음 발이 출발합니다. 한 판은 **5발**이고 **맞힐수록**
표식이 빨라집니다(첫 발 2.4초 왕복, 명중마다 x1.18 — 다 맞히면 마지막 발 1.25초).
빗나가면 속도는 그대로입니다 — 못 맞히는 사람에게 벌로 더 어려워지지 않습니다.
스테이지를 하나 깨면 열리고 하루 3판, 자정에 초기화합니다. 시작하는 순간 한 판이 빠지므로
불리한 발을 새로고침으로 무를 수 없습니다. 보상은 역대 최고 스테이지를 따라 오릅니다.

미션과 마찬가지로 하루 예산이 **고정**이라(`MINI_BUDGET`) 아무리 잘해도 진행 속도는
흔들리지 않습니다 — 실력은 수입의 상한이 아니라 그 상한을 채우는 속도만 바꿉니다.
`selftest` 가 미션과 함께 묶어 환생 수입과 견줍니다.

**슬롯** — 3x3 릴, 가로 셋·세로 셋·대각선 둘까지 여덟 줄. 칸은 왼쪽부터 차례로 서고,
같은 문양이 한 줄에 셋이면 혼이 붙습니다(🪙x4 · 🐛x6 · 🐍x9 · 🦇x15 · 🗿x30 · 🐉x90 · 💎x300).
여덟 줄 합쳐 **세 판 중 한 판꼴로 맞고**(실측 31.6%) 한 판 평균은 x2.41 입니다.
세로는 실제 슬롯이라면 라인이 아니지만(릴 하나가 보여주는 창일 뿐입니다) 3x3 격자를 보면
누구나 세로도 셉니다 — 화면이 말하는 것과 규칙이 어긋나면 그건 규칙이 틀린 겁니다.

혼 사냥이 실력으로 버는 칸이라면 여기는 운으로 버는 칸입니다. 잘 하고 못 하고가 없으니
하루 판수(`SLOT_TRIES`, 10판)만 주고, 지급을 평균 배당으로 나눠 **하루 기대 수입을
`SLOT_BUDGET`(1 격파분)에 못박아** 뒀습니다 — 운은 얼마를 버느냐가 아니라 언제 받느냐만 바꿉니다.
실측 20만 일로 하루 평균 0.997 격파분, 열 판 모두 꽝인 날은 2.2% 입니다.
스테이지를 하나 깨면 열리고, 돌리는 순간 한 판이 빠지며 자정에 초기화합니다.
하루 몫을 다 써도 버튼은 잠기지 않습니다 — 혼만 안 들어오는 **연습판**으로 계속 돌아갑니다.
돌리는 재미까지 하루 예산에 묶을 이유는 없습니다.

`selftest` 가 문양표(`SLOT_SYM`)의 확률 합을 100%로, `SLOT_AVG` 를 그 표에서 다시 계산한
평균 배당으로 붙들고, 슬롯 수입을 미션·혼 사냥과 묶어 환생 수입과 견줍니다. 이 상한 때문에
`SLOT_BUDGET` 은 1 이 한계입니다 — 2 로 올리면 1층에서 미션 주간 수입이 환생의 2배를 넘습니다.

**유물** — 보스가 가끔 자기 유물을 떨어뜨립니다(역대 첫 격파 30%,
재격파 1%). 반복 파밍으로 나온 중복은 혼으로 조금(1/20)만 바뀝니다 — 재격파 확률을
두 배로 올린 만큼 환산을 절반으로 낮췄습니다. 도감만 빨리 차고 켜 두기만 해서 버는 혼은 그대로입니다.
등급은 일반 60%·희귀 28%·영웅 10%·전설 1.6%·**신화 0.4%**이고 오를 때마다 효과가 두 배입니다
(ATK·HP·DEF·혼 +3/6/12/24/48%, CRIT +0.5/1/2/4/8%p). 보스마다 하나만 가지며 더 높은 등급이
나와야 바뀝니다. 환생해도 남습니다.

**어떤 능력치가 붙을지는 보스마다 고정입니다** — 무작위인 것은 등급뿐입니다. ATK·HP·DEF·CRIT·혼
다섯 종을 보스 15종에 3개씩 나눠 층 앞뒤로 흩어 놨으니, 원하는 빌드에 맞춰 어디를 먼저
깰지 고르면 됩니다. 던전 목록과 유물 도감 양쪽에 무엇이 나올지 적혀 있습니다.

| | 보스 |
|---|---|
| ATK | 버그 벌레 · 스파게티 크라켄 · 스택 오버플로 히드라 |
| HP | 레거시 전갈 · 메모리 누수 슬라임 · 프로덕션 장애 드래곤 |
| DEF | 널 포인터 박쥐 · 데드락 골렘 · 기술 부채 리치 |
| CRIT | 무한 루프 뱀 · 머지 충돌 도깨비 · 레이스 컨디션 유령 |
| 혼 | 좀비 프로세스 · 의존성 지옥 악마 · 토큰 한도의 군주 |

**환생 보너스** — 환생할 때마다 얻는 혼(환생·원정·미션·유물 중복)이 영구히 +2%씩 늡니다.
10회면 +20%, 25회면 +50%. 혼 배수는 환생·유물·수확 셋이 곱해지므로, 캐릭터 카드 아래
`얻는 혼 x1.34 (환생 +2% · 유물 +6% · 수확 +24%)` 줄에 합쳐서 보여 줍니다.

**시작점** — 설치한 날부터 셉니다. 이미 몇 달 치 로그가 쌓여 있으면 깔자마자 고레벨로
시작해 성장이 통째로 사라지기 때문입니다. 처음 실행할 때 기준을 정하고 `config.json` 에
남깁니다. 이미 쓰던 설치(스냅샷이나 저장이 남아 있는 설치)는 과거를 그대로 지킵니다.

```bash
token-rpg since              # 지금 기준 보기
token-rpg since all          # 예전 기록까지 전부 세기
token-rpg since 2026-01-01   # 특정 날짜부터
```

세션 파일 단위로 거르므로 기준일을 걸친 세션 하나는 통째로 셉니다.

## 업데이트

새 버전이 있으면 게임 화면 맨 위에 알림이 뜹니다. **업데이트** 버튼을 누르면 깔린 방식
(`uv tool`·`pipx`)을 알아서 찾아 올립니다. 끝나면 창을 다시 열면 됩니다.

```bash
token-rpg update        # 터미널에서도 같은 일을 합니다
```

메뉴 막대 앱 안의 사본은 갈아치울 수 없어서, 그때는 버튼이 **DMG 받기**로 바뀝니다.
받아서 `Applications` 에 덮어쓰면 됩니다.

버전 확인은 GitHub 릴리스 API 한 번이고, **파이썬 쪽에서 하고 결과를 6시간 재사용합니다**
(게임 페이지가 직접 바깥으로 나가지 않습니다). 보내는 것은 버전 문자열뿐이고 사용량·로그는
어디로도 나가지 않습니다. 끄려면 `config.json` 에 `"updateCheck": false` 를 넣습니다.

## 여러 PC 합산

각 PC에서 `token-rpg export`를 돌리면 4KB짜리 스냅샷만 남습니다. 스냅샷 폴더를 클라우드
동기화 폴더로 지정하면 모든 기기가 합쳐집니다. 양쪽 OS 에서 같은 폴더를 가리키면 됩니다.

```bash
# macOS · 리눅스 (~/.zshrc 나 ~/.bashrc 에)
export TOKEN_RPG_SNAPSHOTS=~/Dropbox/token-rpg
```
```powershell
# 윈도우 — setx 는 새로 여는 창부터 적용됩니다
setx TOKEN_RPG_SNAPSHOTS "$env:USERPROFILE\Dropbox\token-rpg"
```

지정한 뒤 각 PC 에서 `token-rpg export` 를 한 번 돌리면 그 폴더에 스냅샷이 생깁니다.
기존 `snapshots` 폴더에 있던 파일은 새 폴더로 옮깁니다 (`token-rpg where` 로 위치 확인).

**사용량은 알아서 합칩니다.** PC 마다 `<호스트이름>.json` 을 따로 쓰고 합산할 때 전부
더하므로, 파일당 PC 하나라 충돌이 구조적으로 없습니다. 여러 PC 에서 동시에 코딩해도 됩니다.

**게임 진행은 한 번에 한 PC 에서만 합니다.** `game.save` 는 파일 하나를 기기끼리 같이 씁니다.
한 PC 안에서는 브라우저 탭과 상주 앱이 `rev` 번호로 서로를 막아 줍니다(오래된 창이
덮어쓰려 하면 거부하고 최신 저장을 불러옵니다). 다른 PC 끼리는 서로의 `rev` 를 볼 수 없습니다.
두 기기에서 동시에 켜 두면 동기화 서비스가 충돌 사본을 만들거나 늦게 쓴 쪽이 덮어씁니다.
한쪽에서 게임 창과 상주 앱을 닫고 동기화가 끝난 뒤 다른 쪽을 열면 됩니다.

**진행 저장은 봉인해서 적습니다.** `game.save` 는 v0.10.0 부터 `base64(JSON).서명` 한 줄이라
텍스트 편집기로 열어 혼·환생·배분을 고칠 수 없습니다. 서명이 맞지 않으면 불러오지 않습니다.
쓰던 설치는 처음 갱신할 때 자동으로 봉인하니 따로 할 일은 없습니다 — **다만 이 파일을 같이 쓰는
설치본은 전부 v0.10.0 이상이어야 합니다.** 한 PC 안에서도 설치본이 여러 개일 수 있으니
(`uv tool`·`pip`·맥 앱 번들) `token-rpg update` 를 각각 돌려야 합니다.

스냅샷(`snapshots/*.json`)도 봉인해서 쓰지만 **평문도 받아 줍니다.** 옛 설치본의 훅이 평문으로
덮어쓰는 일이 흔한데 거기서 거부하면 그 PC 토큰이 0 이 되기 때문입니다. 스냅샷은 매번 진짜
로그에서 다시 만들므로 손대도 다음 갱신에 덮어씁니다.

열쇠가 소스 안에 있어 작정하면 위조할 수 있습니다. 막는 대상은 "파일 열어서 0 하나 더 붙이기"입니다.

## 명령

| 명령 | 하는 일 |
|---|---|
| `token-rpg` / `build` | 사용량 재집계 후 `game.html` 갱신 |
| `open` | 갱신 후 로컬 서버(`127.0.0.1:8765`)로 브라우저에서 열기. Ctrl+C로 종료 |
| `serve` | 게임과 저장만 제공 (메뉴 막대 앱이 띄웁니다) |
| `export` | 이 PC의 스냅샷만 갱신 |
| `balance` | 난이도·환생 곡선 표 출력 |
| `selftest` | 집계·병합·밸런스 자체 검증 |
| `where` | 데이터 위치 출력 |
| `update` | 새 버전 확인 후 업그레이드 |
| `since [all\|now\|YYYY-MM-DD]` | 언제부터의 토큰을 셀지 보기/바꾸기 |
| `install-hook` / `uninstall-hook` | 자동 갱신 등록/해제 |

## 데이터

`~/.claude/projects/**/*.jsonl`의 `usage` 필드만 읽습니다. **읽기 전용이고,
아무것도 밖으로 보내지 않습니다.** 게임 데이터는
`~/.local/share/token-rpg/`(또는 `$XDG_DATA_HOME`)에 저장하고, 진행 상황은
브라우저 localStorage에 있습니다.

## 프로바이더

여러 AI 툴의 사용량을 한 캐릭터로 합산합니다.

```bash
token-rpg providers                          # 목록과 스캔 위치
token-rpg scan add codex '~/backup/*/sessions'   # 로그가 기본 위치 밖일 때
token-rpg disable codex                      # 특정 프로바이더 끄기
```

| 프로바이더 | 기본 위치 | 상태 |
|---|---|---|
| `claude-code` | `~/.claude/projects` | 검증됨 |
| `codex` | `~/.codex/sessions` | 검증됨 (codex cli 0.153.4) |
| `gemini` | `~/.gemini/tmp` | 검증됨 (gemini cli 0.59.0) |

Codex CLI는 `cached_input_tokens`·`reasoning_output_tokens`를 남겨 DEF·CRIT까지
그대로 대응합니다. `token_count` 이벤트의 `total_token_usage`는 세션 누적이라
파일마다 마지막 값만 셉니다.

Gemini CLI는 텔레메트리 없이도 세션 로그(`chats/session-*.jsonl`)의 답변마다
`tokens`(input·output·cached·thoughts)를 남깁니다. 답변 단위라 전부 더하고,
`cached`는 DEF, `thoughts`는 CRIT로 대응합니다.

**웹에서 쓴 것은 잡히지 않습니다.** ChatGPT·Gemini 웹, Cursor, GitHub Copilot은
토큰 집계를 서버에서만 하고 로컬에 숫자를 남기지 않습니다. CLI 툴을 설치해서
써야 기록이 생깁니다.

새 툴을 붙이려면 `PROVIDERS`에 "파일 하나를 읽어 토큰 합계를 돌려주는 함수"
하나만 추가하면 됩니다. 또는 스냅샷 JSON을 직접 뱉어도 됩니다:

```json
{"host": "내PC", "updated": "2026-09-10T00:00:00+00:00",
 "agg": {"input": 0, "output": 0, "cache_read": 0, "thinking": 0, "calls": 0},
 "projects": {"프로젝트명": 0}, "days": ["2026-09-10"]}
```

## 라이선스

MIT
