Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Repository Guidelines

## Структура проекта и модули

Проект — Swift Package для macOS 14+ с тремя таргетами. `Sources/ClaudeWeekCore/` содержит расчёты, конфигурацию, провайдеры и обновление; ядро не должно импортировать AppKit или SwiftUI. `Sources/ClaudeWeekApp/` отвечает за меню-бар, панель, настройки и CLI. Проверки находятся в `Sources/ClaudeWeekTests/` и запускаются собственным исполняемым раннером. Ресурсы бандла лежат в `Resources/`, ресурсы таргета приложения (знаки Claude и Codex) — в `Sources/ClaudeWeekApp/Assets/`, документация — в `docs/`, а сценарии сборки и релиза — в `scripts/`. `.build/` и `dist/` — генерируемые каталоги, их не коммитят.

## Сборка, тесты и локальный запуск

- `swift build` — собирает пакет в отладочной конфигурации.
- `swift run ClaudeWeekApp` — запускает приложение из исходников; рядом с установленной копией появится вторая иконка.
- `swift run ClaudeWeekTests` — выполняет все проверки без сети и UI.
- `swift build -Xswiftc -warnings-as-errors -Xswiftc -Wwarning -Xswiftc DeprecatedDeclaration` — повторяет строгую сборку CI.
- `./scripts/make-app.sh` — создаёт `dist/ClaudeWeek.app` без установки.
- `./scripts/install.sh` — собирает, устанавливает и запускает локальную версию.

Перед PR выполните строгую сборку, тестовый раннер и `make-app.sh`.

## Стиль кода и именование

Используйте Swift 6 со строгой изоляцией акторов и четырёхпробельными отступами. Следуйте Swift-конвенциям: типы — `UpperCamelCase`, функции и свойства — `lowerCamelCase`, имена файлов совпадают с основным типом. Сохраняйте разделение Core/UI и стиль соседнего кода. Комментарии пишите по-русски и объясняйте причины решений, а не очевидные действия. Отдельного форматтера нет; предупреждения компилятора считаются ошибками.

## Правила тестирования

Добавляйте проверки изменений расчётов в `Sources/ClaudeWeekTests/`. Файлы называйте `<Область>Tests.swift`, точку входа — `run<Область>Tests(_:)`, затем регистрируйте её в `main.swift`. Формального порога покрытия нет, но все исправления ошибок и новое поведение ядра должны иметь регрессионный сценарий.

## Инструкции для агентов

При поиске кода сначала используйте настроенный `codebase-memory`: `search_graph` для символов, `trace_path` для связей и `get_code_snippet` для исходника найденного типа или функции. К `rg` переходите для строк, конфигурации, документации и сценариев либо когда граф не дал достаточного результата. Перед изменением архитектуры прочитайте `docs/ARCHITECTURE.md`, а для панели — также `docs/SPACES.md`.

## Коммиты и Pull Request

Коммит — одна русская строка до 72 символов, с глаголом прошедшего времени: `Добавил уведомление о перерасходе`. Не используйте `feat:`, `fix:` и тела коммитов. Сначала согласуйте изменение в issue, создайте ветку от `main` и держите один PR в рамках одной идеи. В описании укажите причину, проверенные команды и связанную issue; для UI приложите снимки. Пользовательские изменения внесите в раздел `Не выпущено` файла `CHANGELOG.md`, а соответствующую документацию обновите тем же PR.
34 changes: 34 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,40 @@

## [Не выпущено]

### Добавлено

- **Переключатель Claude / Codex в заголовке панели.** Для Codex приложение
получает короткий и недельный лимиты, моменты сброса и дневную токенную форму
через официальный `codex app-server`; длина короткого окна показывается такой,
какой её сообщил сервер. Дневная форма раскладывается по суткам окна через
реальное перекрытие во времени с тихоокеанскими сутками биллинга, в которых
Codex ведёт токенную статистику, — иначе в первый местный день недельного
окна она пропадала целиком. Выбранный сервис переживает перезапуск, а кеши и
история уведомлений Claude и Codex хранятся раздельно.

### Изменено

- **В переключателе Claude / Codex стоят знаки самих сервисов.** Раньше это
были ближайшие SF Symbols — звёздочка и «</>», — по которым сервис
угадывался, а не читался. Теперь кнопки несут узнаваемые знаки Claude и
Codex — шаблонные, силуэт держит альфа-канал. Рамок и подложек у них нет:
в заголовке это знаки, а не органы управления, и выбранный сервис виден по
цвету — у Claude фирменный оранжевый, у Codex цвет текста, — а невыбранный
уходит в приглушённый серый. Картинки лежат в ресурсном бандле таргета
приложения (`Sources/ClaudeWeekApp/Assets`), и `make-app.sh`
кладёт этот бандл в `.app` — без него `Bundle.module` оборвал бы программу
ещё до отрисовки панели, поэтому его отсутствие останавливает сборку.

### Исправлено

- **Полосы больше не съезжают сверху при переключении на разбивку по
моделям.** Панель приклеена верхней кромкой к строке меню, и после смены
высоты содержимого кромку возвращает на место `pinToAnchor`. Он висел на
`didResizeNotification` с `queue: .main`, то есть срабатывал следующим
проходом цикла, — между уведомлением и правкой успевал отрисоваться кадр,
где окно уже новой высоты, а стоит по старому месту. Теперь подписка
синхронная, и промежуточного кадра нет.

## [0.2.0] — 2026-08-23

### Добавлено
Expand Down
3 changes: 2 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ let package = Package(

.executableTarget(
name: "ClaudeWeekApp",
dependencies: ["ClaudeWeekCore"]
dependencies: ["ClaudeWeekCore"],
resources: [.process("Assets")]
),

// XCTest и swift-testing без Xcode недоступны, поэтому проверки —
Expand Down
33 changes: 23 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
[![Swift 6](https://img.shields.io/badge/Swift-6-F05138?logo=swift&logoColor=white)](Package.swift)
[![Лицензия MIT](https://img.shields.io/badge/лицензия-MIT-blue)](LICENSE)

Меню-бар приложение для macOS: недельный лимит Claude Code одним взглядом.
Меню-бар приложение для macOS: лимиты Claude Code и Codex одним взглядом.
Две кнопки в заголовке панели переключают сервисы; у каждого сохраняются свой
снимок, короткое окно, неделя и история уведомлений.

На каждой полосе два цвета — **план** (сколько допустимо потратить к этому
моменту) и **факт** (сколько реально потрачено). Видно не только «сколько
Expand Down Expand Up @@ -45,8 +47,9 @@

## Установка

**Требования:** macOS 14+ и установленный, авторизованный Claude Code. Ни Apple
ID, ни платной подписки разработчика не нужно.
**Требования:** macOS 14+ и установленный, авторизованный клиент того сервиса,
который вы хотите смотреть: Claude Code для Claude, Codex CLI или Codex app для
Codex. Ни Apple ID, ни платной подписки разработчика не нужно.

### Готовая сборка

Expand Down Expand Up @@ -104,8 +107,10 @@ cd ClaudeWeek
./scripts/install.sh --ref my-branch # конкретную ветку, тег или коммит
```

Ничего вводить не нужно: приложение читает OAuth-токен уже авторизованного
Claude Code из Keychain — только читает, наружу не отдаёт, на диск не пишет.
Ничего вводить не нужно: для Claude приложение читает OAuth-токен уже
авторизованного Claude Code из Keychain — только читает, наружу не отдаёт, на
диск не пишет. Для Codex оно запускает официальный `codex app-server`, который
сам использует вход Codex; его токены ClaudeWeek тоже не читает и не хранит.
Разбор — [docs/USAGE.md](docs/USAGE.md#авторизация-и-доступ).

Один раз стоит сделать вот что:
Expand All @@ -131,23 +136,26 @@ Code сбрасывает каждым обновлением токена, и

## Что показывает

- **Claude и Codex по отдельности** — две кнопки в заголовке мгновенно меняют
аккаунт панели. Выбор переживает перезапуск, кеши и уведомления сервисов друг
друга не затирают.
- **Неделя с планом** — семь суточных полос: факт, плановая зона, перерасход.
Включается в настройках галкой «Дневной план» (по умолчанию панель короче —
без разбора по дням, только сессия и итог недели). 100 % лимита
раскладываются по **рабочим часам** (по умолчанию 10:00 → 18:00), а не по
астрономическим: сон не должен весить столько же, сколько работа. Ряд идёт
с понедельника, а сутки, прошедшие сразу после сброса, стоят под чертой в
конце; в настройках его можно развернуть от дня сброса.
- **Пятичасовую сессию** — отдельной строкой над сутками, с часом сброса. Тот
лимит, в который упираются чаще недельного.
- **Короткое окно** — отдельной строкой над сутками, с часом сброса. У Claude
это пятичасовая сессия; у Codex длина приходит от сервера и может отличаться.
- **Прогноз** — «при таком темпе кончится ПТ 15:57», тоже по рабочим часам.
- **Чем потрачено** — клик по цифрам процента заменяет дни разбивкой по
моделям: доля Opus, Sonnet и Haiku теми же полосами; клик ещё раз возвращает
неделю. Считается по вашим транскриптам: сервер сообщает только итог недели.
- **Откуда цифры** — кружок у полосы сессии: зелёный залитый — живой ответ
сервера, жёлтый — кеш, красный контурный — локальная оценка. Форма дублирует
цвет, чтобы читалось при дальтонизме.
- **Честный офлайн** — без сети расход считается по вашим же транскриптам
- **Честный офлайн для Claude** — без сети расход считается по вашим же транскриптам
`~/.claude/projects` и помечается знаком `≈`. Калибруется сам, по последнему
официальному ответу.
- **Пороги цвета** — жёлтый после 81 %, красный после 93 % у недели и 95 % у
Expand Down Expand Up @@ -203,7 +211,8 @@ Code сбрасывает каждым обновлением токена, и
ставится обновление на вкладке «О программе». Тумблер у него свой: погасив
разговоры о расходе, вы не обязаны молчать и про релизы.

Сказанное запоминается в `~/.config/claude-week/alerts.json` и переживает
Сказанное запоминается в `~/.config/claude-week/alerts.json` для Claude и
`codex-alerts.json` для Codex и переживает
перезапуск: после перезагрузки посреди недели про пройденные пороги программа
молчит, а про уже объявленную версию не напоминает. Выключить можно всё разом или по лимиту в отдельности; разрешение macOS
спрашивается один раз, при первом запуске. Как баннер выглядит именно у вас,
Expand All @@ -218,6 +227,10 @@ Code сбрасывает каждым обновлением токена, и

## Смена аккаунта

Кнопки Claude и Codex в заголовке переключают **сервисы**, а не перелогинивают
их. ClaudeWeek показывает тот аккаунт, в который уже вошёл соответствующий
клиент. Последний выбранный сервис записывается в `config.json`.

Вошли другим аккаунтом — рабочим вместо домашнего — и счёт начинается заново.
Недельный процент сменяется сам: сервер узнаёт аккаунт по токену. А вот
разбивка по суткам считается по транскриптам в `~/.claude/projects`, а те
Expand All @@ -238,7 +251,7 @@ Keychain с той, на которой ведётся счёт, и при ра

```bash
swift build # обе цели
swift run ClaudeWeekTests # 477 проверок: без сети, без UI, свой раннер
swift run ClaudeWeekTests # 528 проверок: без сети, без UI, свой раннер
./scripts/make-app.sh # dist/ClaudeWeek.app — бандл, ничего не устанавливая
ARCH=arm64 ./scripts/make-dmg.sh # dist/ClaudeWeek-<версия>-arm64.dmg
```
Expand Down
Loading