<< All versions

Skill v1.0.0

currentAutomated scan100/100
shakhruz/mila-companion/subscription
──Details
PublishedSeptember 28, 2026 at 04:41 AM
Content Hashsha256:69beedf182256fd9...
Git SHA
──Files
Files (1 file, 12.6 KB)
SKILL.md12.6 KBactive
SKILL.md · 182 lines · 12.6 KB

version: "1.0.0" name: subscription description: Состояние подписок Claude — окна лимитов (5 часов, неделя, помодельные), темп расхода, прогноз упора и местный расход в долларах. Применять, когда хозяин спрашивает «сколько осталось», «как подписка», «на чём мы», «не упрёмся ли», а также в утреннем ритуале и перед тяжёлой работой.


subscription — сколько осталось от подписки

Что даёт

· Хозяин видит остаток раньше, чем упрётся в стену посреди работы. · Ответ числом и с временем сброса, а не «вроде хватает». · Одна и та же картина у всех агентов флота — считается одинаково.

Когда

Спросили про лимиты, остаток, расход или «почему всё встало». Утренний ритуал. Перед большой работой, если неделя уже за 80%.

Не по своей инициативе в течение дня: эндпоинт режет частые запросы, и лишний опрос делает хуже всем.

Как

python3 ~/.claude/skills/subscription/subscription.py # отчёт python3 ~/.claude/skills/subscription/subscription.py --telegram # готовый блок в чат python3 ~/.claude/skills/subscription/subscription.py --card # PNG-дэшборд (путь) или пусто python3 ~/.claude/skills/subscription/subscription.py --json # машине python3 ~/.claude/skills/subscription/subscription.py --local # без сети, только расход python3 ~/.claude/skills/subscription/subscription.py --force # спросить сервер вне очереди

В Telegram отправлять `--telegram`. Отчёт держится на выравнивании, а обычный текст в Telegram не моноширинный — колонки разъедутся. Ключ заворачивает вывод в блок кода: format: "markdownv2", внутри блока экранировать ничего не нужно.

--force — только по прямой просьбе. Без причины не дёргать.

Команды в чате (mila-companion, 10.09.2026)

Хозяин пишет боту команду — агент отвечает сразу, без вопросов:

КомандаЧто делает
/usage (или слово «подписки», «usage»)своя подписка: текстовый блок --telegram (слово владельца 10.09: в Telegram и терминале — текст в стиле claude code, картинки не слать); /usage card — картинка по просьбе
/usage allвсе подписки из accounts.json и агенты на них — текстовый блок + строка совета «кого переключить»; /usage all card — картинкой
/usage watch on / offвключить/выключить часовой сторож (`subscription_watch.py --on--off`)
/usage jsonсырой --json файлом (для старшей и разборов)

Порядок хода: python3 ~/.claude/skills/subscription/subscription.py --telegram → блок markdownv2 одним сообщением; card в команде → --card → reply(files=[png]), пусто → тот же текст. Одна строка вывода под картинкой обязательна: «неделя 46 %, сильная модель 7 % — до среды тяжёлое на Sonnet», без пересказа цифр с картинки.

Картинка (rich media)

subscription_card.py рисует card.html в фирменных цветах и печатает PNG через Chrome. В контейнере Chrome нет — тогда берётся общий PNG старшей: в accounts.json поле "card": {"path": "/home/companion/state/subscription-card.png", "max_age_min": 75}; старшая кладёт его раз в час вместе с отчётом. Устарел или нет — текстовый блок, без извинений. Статус агента на картинке: 🟢 работает · 🟡 данным N ч · 🔴 стоит (5-часовой бак < 3 %).

Сторож (раз в час)

subscription_watch.py по cron/launchd: история снимков, темп по своей истории (не раньше чем через 2 ч точек), сигнал хозяину один раз на повод, повтор через 3 ч: неделя/сильная модель ≤ 20 % или «кончится раньше сброса»; 5-часовой бак ≤ 30 %. Доставка: Компаньон — --tg-token-env TELEGRAM_BOT_TOKEN --chat <id хозяина>; Мила Админ — --outbox ~/.claude/channels/telegram/outbox --chat <id>. Картинка прикладывается, если собралась. --off / --on — состояние в $SUBSCRIPTION_STATE/subscription-watch.off.

Утренний отчёт

В утренний ритуал (WAKE.md) — одна строка из --telegram блока или картинка --card после дел дня; не первой строкой, не отдельным сообщением, если нет сигнала.

Как читать отчёт

бак · осталось 5 часов ███████████░ 99% ровно неделя ████░░░░░░░░ 36% ровно нед · Fable █░░░░░░░░░░░ 2% пусто

сброс 5 часов сегодня 18:50 — через 2 ч 45 мин неделя сб 12.09 08:00 — через 2 дн 15 ч

Время сброса — точное, с днём недели, и всегда с обратным отсчётом (просьба хозяина 09.09: «дата, время и сколько осталось в днях-часах»). Окна с общим сроком — неделя и помодельные — сводятся в одну строку: ключ группировки по минуте, потому что у них метки расходятся на микросекунды.

Показываем остаток, а не расход — так просил хозяин 09.09: «мне понятней видеть бак». Полоса и число — сколько осталось до сброса. Проценты — доля окна, не деньги.

Правая колонка сравнивает скорость расхода с ходом времени в окне:

ровно — тратим примерно по ходу окна, остатка хватит до сброса. тает быстро — расход обгоняет время больше чем на 15 пунктов, кончится раньше срока. с запасом — идём медленнее окна. пусто — осталось 5% и меньше, окно можно считать закрытым до сброса.

Строка «при этом темпе … кончится …» появляется только при заметном перерасходе и пока в баке что-то есть — иначе это шум.

Расход в долларах — пересчёт по прайсу API, а не счёт. Подписка так не тарифицируется. Так и говорить: «мера, не счёт». Числом меряем нагрузку, а не выставляем сумму.

Несколько подписок

accounts.json рядом со скриптом. Одна запись — одна подписка:

{"accounts": [ {"name": "Основная", "credentials": "~/.claude/.credentials.json"}, {"name": "Вторая", "credentials": "~/work/tools/accounts/second.credentials.json"} ]}

Вместо файла можно {"name": "…", "env": "ИМЯ_ПЕРЕМЕННОЙ"}.

Чужой контейнер недостижим по устройству. Файл входа виден только тот, что смонтирован в свой дом. Токен от claude setup-token не подойдёт: он только для вывода, окон лимитов не отдаёт (нет области user:profile).

Поэтому чужая подписка берётся готовым отчётом, а не входом:

{"name": "Мила Админ", "report": "/home/companion/state/subscription-ashotashirov.json"}

Файл — вывод этого же скрипта с --json, его кладёт тот агент, у кого этот вход живёт. К нам приезжают только проценты и время сброса; чужой вход остаётся у чужого агента. Так с 09.09 подключена вторая подписка владельца (<email> — рабочий вход старшей на Маке, обновление раз в полчаса).

Возраст отчёта проверяется всегда. Старше часа — в отчёте «отчёт устарел, снят N часов назад»; нет файла — «не подключена — отчёт не приходил». Чужие цифры без отметки о времени не показывать.

На Маке вход Claude Code лежит не в файле, а в связке ключей — там читается через security find-generic-password -s 'Claude Code-credentials' -w (доработка старшей от 09.09; в контейнерах Linux не нужна).

Устройство — чтобы чинить, а не гадать

Токен — ~/.claude/.credentials.json, объект claudeAiOauth. Каталог переопределяется переменной CLAUDE_CONFIG_DIR.

Окна — GET https://api.anthropic.com/api/oauth/usage, заголовки Authorization: Bearer … и anthropic-beta: oauth-2025-04-20. Без beta-заголовка приходит 401. Имя и план — соседний /api/oauth/profile.

Ответ: five_hour и seven_day с utilization (0–100) и resets_at. Помодельные недельные окна лежат в массиве limits, записи kind: "weekly_scoped" с scope.model.display_name и percent; старые ключи seven_day_<модель> возвращают null.

Местный расход — state/usage-daily.json, его считает хук.

Механизм разобран по исходникам OpenUsage (MIT, github.com/robinebers/openusage, Sources/OpenUsage/Providers/Claude/). Реализация своя.

Чего делать нельзя

Не обновлять токен самому. Claude Code перевыпускает его сам; запись ротированного токена ломает живую сессию. Просроченный — просто сказать.

Не показывать токен. Ни в чат, ни в лог, ни в кэш. В кэше лежат только проценты и время сброса — проверено грепом.

Не долбить `--force`. 429 прилетает легко, держится часами, Retry-After бывает не всегда. В скрипте кэш на 15 минут и выдержка с удвоением до часа — это защита, а не помеха.

Не называть доллары счётом клиенту. Это внутренняя мера нагрузки.

Что ломается со временем

anthropic-beta: oauth-2025-04-20 — дата в заголовке однажды сменится, и окна молча перестанут читаться. Если в отчёте вдруг «вход просрочен» на живом входе — смотреть сюда первым делом.

All versions