Skip to content

Формат хранения аккаунтов и управление версиями

Что вы сможете делать после изучения

  • Понимать структуру файла хранения и значение каждого поля
  • Редактировать файл хранения вручную (только при необходимости)
  • Понимать механизмы миграции версий и совместимости
  • Мигрировать конфигурацию аккаунтов между машинами

Текущие затруднения

Вы можете столкнуться со следующими ситуациями:

  • Необходимость резервного копирования или миграции аккаунтов на другую машину
  • Ручное изменение projectId или удаление неактивных аккаунтов
  • Появление предупреждений о версиях или логов миграции, желание понять, что происходит
  • Синхронизация состояния аккаунтов между несколькими машинами

Расположение файла

Файл хранения аккаунтов находится по следующим путям:

Операционная системаПуть
macOS/Linux~/.config/opencode/antigravity-accounts.json
Windows%APPDATA%\opencode\antigravity-accounts.json

Предупреждение безопасности

Этот файл содержит OAuth refresh tokens, что эквивалентно паролю. Не делитесь им с другими и не добавляйте в Git-репозиторий.

Версии формата хранения

Формат хранения имеет версионирование, текущая версия — v3. Плагин автоматически обрабатывает миграцию версий, ручное вмешательство не требуется.

Формат v3 (текущая версия)

json
{
  "version": 3,
  "accounts": [
    {
      "email": "[email protected]",
      "refreshToken": "1//0abc...",
      "projectId": "my-gcp-project",
      "managedProjectId": "managed-project-123",
      "addedAt": 1737600000000,
      "lastUsed": 1737603600000,
      "lastSwitchReason": "initial",
      "rateLimitResetTimes": {
        "claude": 1737607200000,
        "gemini-antigravity": 1737607200000,
        "gemini-cli": 1737607200000
      },
      "coolingDownUntil": 1737600000000,
      "cooldownReason": "auth-failure"
    }
  ],
  "activeIndex": 0,
  "activeIndexByFamily": {
    "claude": 0,
    "gemini": 0
  }
}

Описание полей:

ПолеТипОбязательноеОписание
versionnumberДаВерсия формата хранения (фиксировано 3)
accountsarrayДаСписок аккаунтов
activeIndexnumberДаИндекс текущего активного аккаунта (начиная с 0)
activeIndexByFamilyobjectНетОтслеживание активного аккаунта по модельным семействам (claude/gemini)

Поля объекта аккаунта:

ПолеТипОбязательноеОписание
emailstringНетEmail аккаунта Google
refreshTokenstringДаOAuth refresh token (уникальный идентификатор)
projectIdstringНетID проекта GCP (требуется для моделей Gemini CLI)
managedProjectIdstringНетID управляемого проекта
addedAtnumberДаМетка времени добавления (Unix в миллисекундах)
lastUsednumberДаМетка времени последнего использования
lastSwitchReasonstringНетПричина переключения: "rate-limit" / "initial" / "rotation"
rateLimitResetTimesobjectНетВремя сброса ограничения скорости (отдельное отслеживание по пулам квот)
coolingDownUntilnumberНетМетка времени окончания охлаждения аккаунта
cooldownReasonstringНетПричина охлаждения: "auth-failure" / "network-error" / "project-error"

Формат v2 (историческая версия)

Формат v2 похож на v3, но имеет следующие отличия:

  • rateLimitResetTimes имеет только два поля: claude и gemini
  • Нет coolingDownUntil и cooldownReason
  • Нет activeIndexByFamily (все модели используют один активный аккаунт)

При миграции поле gemini отображается на gemini-antigravity, пул квот gemini-cli инициализируется пустым.

Формат v1 (историческая версия)

Формат v1 использует булевы флаги и единую метку времени:

json
{
  "version": 1,
  "accounts": [
    {
      "email": "[email protected]",
      "refreshToken": "1//0abc...",
      "isRateLimited": true,
      "rateLimitResetTime": 1737607200000
    }
  ],
  "activeIndex": 0
}

При миграции, если isRateLimited равен true и rateLimitResetTime не истёк, устанавливается время сброса и для claude, и для gemini.

Механизм миграции версий

При загрузке файла хранения плагин автоматически определяет версию и выполняет миграцию:

mermaid
flowchart LR
    A[Чтение файла хранения] --> B{Версия?}
    B -->|v1| C[Миграция v1 → v2]
    C --> D[Миграция v2 → v3]
    B -->|v2| D
    B -->|v3| E[Использовать напрямую]
    B -->|Неизвестная| F[Игнорировать файл]
    D --> E
    E --> G[Сохранить на диск]

Правила миграции:

  1. Автоматическая миграция: После миграции новый формат автоматически сохраняется на диск
  2. Сохранение данных: Неистёкшие состояния ограничения скорости сохраняются
  3. Понижение при ошибке: Если сохранение не удалось, данные продолжают использоваться в памяти
  4. Совместимость вперёд: Новая версия плагина может читать старый формат файла

Детали механизма хранения

Блокировка файла

Используется proper-lockfile для безопасного доступа из нескольких процессов:

  • Механизм блокировки: Создание файла блокировки при записи (.antigravity-accounts.json.lock)
  • Таймаут: Файл блокировки истекает через 10 секунд (предотвращение взаимоблокировки)
  • Стратегия повторов: Максимум 5 попыток, время ожидания увеличивается от 100мс до 1000мс
  • Атомарная запись: Сначала во временный файл (.tmp), затем переименование в целевой

Слияние аккаунтов

При одновременной записи файла хранения несколькими процессами выполняется стратегия слияния:

typescript
// Логика слияния
function mergeAccountStorage(existing, incoming) {
  // Слияние аккаунтов по refreshToken
  // Сохранение вручную настроенных projectId/managedProjectId
  // Слияние rateLimitResetTimes
  // Сохранение большего lastUsed
}

Механизм дедупликации

Дедупликация на основе email, сохраняется последний аккаунт для каждого email (по lastUsed, затем по addedAt):

typescript
// Правила дедупликации
1. Аккаунты без email → сохраняются (невозможно дедуплицировать)
2. Аккаунты с одинаковым email → сохраняется с наибольшим lastUsed
3. Если lastUsed одинаковый → сохраняется с наибольшим addedAt

Руководство по ручному редактированию

Риск ручного редактирования

При редактировании файла хранения процесс плагина не должен быть запущен, иначе изменения могут быть перезаписаны. Рекомендуется остановить OpenCode перед редактированием.

Добавление аккаунта

При ручном добавлении аккаунта требуется указать как минимум refreshToken:

json
{
  "accounts": [
    {
      "refreshToken": "Скопируйте с другой машины или получите из процесса OAuth",
      "email": "[email protected]",
      "addedAt": Date.now(),
      "lastUsed": Date.now()
    }
  ]
}

Удаление аккаунта

Удалите соответствующую запись из массива accounts, затем скорректируйте activeIndex:

json
{
  "accounts": [
    { "email": "[email protected]", "refreshToken": "..." },  // Сохранить
    // { "email": "[email protected]", "refreshToken": "..." },  // Удалить
    { "email": "[email protected]", "refreshToken": "..." }   // Сохранить
  ],
  "activeIndex": 0  // Убедитесь, что индекс в допустимом диапазоне
}

Изменение projectId

Добавьте или измените projectId для аккаунта:

json
{
  "accounts": [
    {
      "email": "[email protected]",
      "refreshToken": "1//0abc...",
      "projectId": "your-gcp-project-id"  // Добавить или изменить
    }
  ]
}

Очистка состояния ограничения скорости

Вручную очистите метки ограничения скорости:

json
{
  "accounts": [
    {
      "email": "[email protected]",
      "refreshToken": "1//0abc...",
      "rateLimitResetTimes": {}  // Очистить или удалить это поле
    }
  ]
}

Миграция между машинами

Простая миграция

Просто скопируйте файл хранения в директорию конфигурации целевой машины:

bash
# macOS/Linux
cp ~/.config/opencode/antigravity-accounts.json /path/to/backup/

# Windows
copy %APPDATA%\opencode\antigravity-accounts.json backup\

Слияние аккаунтов

Если на целевой машине уже есть аккаунты, плагин автоматически объединит их (дедупликация на основе refreshToken).

Шаги ручного слияния:

  1. Создайте резервную копию файлов хранения обеих машин
  2. Откройте оба файла, скопируйте массивы аккаунтов целевой машины в исходный файл
  3. Скорректируйте activeIndex и activeIndexByFamily
  4. Сохраните и перезапустите плагин

Часто задаваемые вопросы

Что делать, если миграция не удалась?

Если миграция не удалась, плагин запишет предупреждение в логи:

Failed to persist migrated storage: { error: "..." }

Решение:

  1. Проверьте права доступа к файлу
  2. Убедитесь, что достаточно свободного места на диске
  3. Вручную создайте резервную копию старого файла, удалите его и добавьте аккаунты заново

Ошибка несовместимости версий

Если вы видите ошибку «Unknown storage version»:

json
{
  "version": 99  // Неизвестная версия
}

Решение:

  1. Создайте резервную копию текущего файла
  2. Вручную измените version на 2 или 3
  3. Перезапустите плагин для запуска миграции
  4. Если миграция не удалась, удалите файл и добавьте аккаунты заново

Потеря аккаунтов при дедупликации

Если обнаружено, что дублирующиеся аккаунты были удалены:

Причина: Плагин выполняет дедупликацию на основе email, сохраняя последний использованный аккаунт.

Решение: Если необходимо сохранить два аккаунта с одинаковым email (редкий сценарий), отредактируйте файл вручную, убедившись, что поле email пустое или различается.

Резюме урока

  • Расположение файла: ~/.config/opencode/antigravity-accounts.json
  • Текущая версия: v3, поддерживает двойные пулы квот и механизм охлаждения
  • Автоматическая миграция: v1/v2 автоматически обновляются до v3
  • Блокировка файла: используется proper-lockfile для обеспечения безопасности при параллельном доступе
  • Ручное редактирование: рекомендуется остановить плагин перед редактированием, чтобы избежать перезаписи

Анонс следующего урока

В следующем уроке мы изучим все параметры конфигурации.

Вы узнаете:

  • Полный список параметров конфигурации
  • Значения по умолчанию и области действия каждого параметра
  • Продвинутые техники конфигурации

Приложение: ссылки на исходный код

Нажмите, чтобы развернуть расположение исходного кода

Обновлено: 2026-01-23

ФункциональностьПуть к файлуСтроки
Определение формата храненияsrc/plugin/storage.ts128-198
Миграция v1 → v2src/plugin/storage.ts366-395
Миграция v2 → v3src/plugin/storage.ts397-431
Загрузка аккаунтовsrc/plugin/storage.ts433-518
Сохранение аккаунтовsrc/plugin/storage.ts520-536
Механизм блокировки файлаsrc/plugin/storage.ts219-257
Слияние аккаунтовsrc/plugin/storage.ts259-299
Механизм дедупликацииsrc/plugin/storage.ts301-364

Ключевые определения типов:

  • AccountStorageV1: формат хранения v1
  • AccountStorageV2: формат хранения v2
  • AccountStorageV3: формат хранения v3 (текущий)
  • RateLimitStateV3: состояние ограничения скорости v3 (поддержка нескольких пулов квот)

Ключевые функции:

  • loadAccounts(): загрузка аккаунтов и выполнение миграции
  • saveAccounts(): сохранение аккаунтов (с блокировкой файла и слиянием)
  • migrateV1ToV2(): миграция v1 → v2
  • migrateV2ToV3(): миграция v2 → v3
  • mergeAccountStorage(): слияние двух объектов хранения
  • deduplicateAccountsByEmail(): дедупликация аккаунтов на основе email