Files
ClaudeMeter/README.md
T

137 lines
6.3 KiB
Markdown

# Claude Meter
Минимальное Wear OS приложение для **Galaxy Watch 6 Classic** (и любых Wear OS 3+).
Показывает утилизацию rate-limit Claude Code прямо на часах — 5h и 7d окна.
灵感: [Clawdmeter](https://github.com/HermannBjorgvin/Clawdmeter) — но на часах, без ESP32 и без ПК-демона.
## Архитектура
```
┌─────────────────┐ Data Layer API ┌──────────────────┐
│ mobile (телефон) │ ──────────────────▶ │ wear (часы) │
│ │ /token │ │
│ • ввод OAuth │ │ • опрос API │
│ • спаривание │ │ • Compose UI │
│ • установка APK │ ──── WiFi ADB ──────▶ │ • EncryptedShared │
│ │ pair → connect → │ Preferences │
│ │ pm install │ │
└─────────────────┘ └──────────────────┘
```
## Модули
| Модуль | Назначение |
|--------|-----------|
| `wear/` | Часы: Compose for Wear UI, HTTP-опрос `api.anthropic.com`, хранение токена |
| `mobile/` | Телефон: ввод токена, отправка через Data Layer API, ADB-спаривание + установка |
## Сборка
```bash
gradlew assembleDebug
```
APK:
- `mobile/build/outputs/apk/debug/mobile-debug.apk` — телефон (38 МБ, включает wear APK в assets)
- `wear/build/outputs/apk/debug/wear-debug.apk` — часы (22 МБ)
## Установка и использование
### Шаг 1: Установить mobile-приложение на телефон
```bash
adb install mobile/build/outputs/apk/debug/mobile-debug.apk
```
### Шаг 2: Спаривание с часами
1. На часах: **Settings → Developer options → Wireless debugging → «Pair device with pairing code»**
2. На телефоне в приложении **Claude Meter Setup**:
- Ввести IP часов (виден на экране Wireless debugging)
- Ввести pairing порт (виден на экране pairing)
- Ввести 6-значный код
- Нажать «Спарить»
3. Дождаться «✅ Спарено!»
### Шаг 3: Установка приложения на часы
1. На часах: вернуться на главный экран Wireless debugging (виден session порт)
2. На телефоне: ввести session порт → «Установить на часы»
3. APK пушится через `shell:cat` и устанавливается через `pm install`
### Шаг 4: Отправка токена
1. На ПК: найти `accessToken` в `~/.claude/.credentials.json`
2. На телефоне: вставить токен → «Отправить токен»
3. На часах: открыть **Claude Meter** → видит проценты
## Технические детали
### API
Опрашивает `https://api.anthropic.com/v1/messages` — POST (haiku, max_tokens=1).
Rate-limit заголовки:
- `anthropic-ratelimit-unified-5h-utilization` (0–1) — 5-часовое окно
- `anthropic-ratelimit-unified-5h-reset` (unix timestamp) — сброс 5h
- `anthropic-ratelimit-unified-7d-utilization` (0–1) — 7-дневное окно
- `anthropic-ratelimit-unified-7d-reset` (unix timestamp) — сброс 7d
- `anthropic-ratelimit-unified-5h-status` — статус (ok/throttled/blocked)
### WiFi ADB
Использует [libadb-android](https://github.com/MuntashirAkon/libadb-android) — полный ADB протокол на Kotlin:
- **SPAKE2 pairing** — ключевой обмен с 6-значным кодом
- **TLS 1.3** — через Conscrypt
- **RSA 2048** — самоподписанный X.509 сертификат, хранится в `filesDir`
- **HiddenApiBypass** — доступ к `android.sun.security.x509.*`
Поток: pair (pairing port + code) → connect (session port) → push APK → `pm install`
### Стек
| Компонент | Технология |
|-----------|-----------|
| UI (wear) | Compose for Wear, ScalingLazyColumn |
| UI (mobile) | Compose Material3 |
| HTTP | `HttpURLConnection` (stdlib) |
| Хранение токена | `EncryptedSharedPreferences` |
| Передача токена | Wearable Data Layer API |
| ADB | libadb-android (SPAKE2 + TLS) |
| TLS | Conscrypt |
| Build | AGP 8.7.3, Gradle 8.13, Kotlin 1.9.22, compileSdk 35 |
## Структура проекта
```
ClaudeMeter/
├── settings.gradle.kts # :mobile, :wear
├── build.gradle.kts # AGP 8.7.3, Kotlin 1.9.22
├── gradle.properties
├── gradle/wrapper/
├── mobile/
│ ├── build.gradle.kts # libadb-android, Conscrypt, Compose, Data Layer
│ └── src/main/
│ ├── AndroidManifest.xml
│ └── java/com/eps/claudemeter/
│ ├── App.kt # HiddenApiBypass + Conscrypt init
│ ├── AdbConnectionManager.kt # RSA ключ + X.509 сертификат
│ └── MainActivity.kt # UI: токен + спаривание + установка
├── wear/
│ ├── build.gradle.kts # Compose for Wear
│ └── src/main/
│ ├── AndroidManifest.xml
│ └── java/com/eps/claudemeter/
│ ├── ApiPoller.kt # HTTP-опрос + парсинг заголовков
│ ├── TokenStore.kt # EncryptedSharedPreferences
│ ├── TokenReceiverService.kt # WearableListenerService
│ └── MainActivity.kt # Compose for Wear UI
└── README.md
```
## Ограничения (v0)
- Обновление по тапу, не фоновое (WorkManager — отложено)
- Нет complication (виджет на циферблате — отложено)
- Токен протухает → нужно перепастить на телефоне