Возможности

Запуск Claude Code

Обновлено 19 октября 2026 г.
Проверено с ccam 0.6.0 и Claude Code 2.1.302

Эта страница переведена с английского машинным способом. Исправления приветствуются. Редактировать эту страницу на GitHub

На этой странице

ccam work запускает Claude Code от имени аккаунта work, а всё, что идёт после имени, передаётся в claude как есть. Используйте его везде, где вы набрали бы claude: в терминале, в скрипте или с вводом через конвейер.

Использование

ccam work                        # Claude Code as the account work
ccam 2                           # the account with number 2 (see ccam list)
ccam work --resume               # claude --resume, as work
ccam work -p "fix the tests" --output-format json
cat log.txt | ccam work -p "find the cause"
ccam -p "summarise"              # no name: the default account
ccam use work                    # make work the default account
ccam run work --continue         # same as ccam work --continue
ccam                             # the picker on a terminal, the list otherwise
ccam --dry-run work -p hi        # print the command instead of running it

Укажите имя аккаунта или его номер из ccam list. ccam не читает аргументы после имени, поэтому ccam work --help показывает справку Claude Code. Указывать -- после имени необязательно. Стандартный ввод, код возврата и сигналы работают так же, как с claude.

Если первый аргумент начинается с - и не является собственным флагом ccam, ccam запускает аккаунт по умолчанию со всеми аргументами. Аккаунт по умолчанию задаётся командой ccam use, а если вы его не задали, используется аккаунт с наименьшим номером.

Меню выбора

ccam без аргументов открывает меню выбора, если стандартный ввод и вывод подключены к терминалу, а в остальных случаях выводит ccam list. Меню показывает для каждого аккаунта номер, email, использование за 5 часов, время последнего использования и общие элементы; данные об использовании появляются по мере того, как отвечает каждый аккаунт.

Клавиша Действие
Enter Запустить Claude Code от имени выбранного аккаунта
1 to 9 Запустить аккаунт с этим номером
Up/Down, k/j Переместить выделение
a Закрыть меню и запустить мастер ccam add
s Изменить общие элементы выбранного аккаунта (Space или x переключает, Enter применяет, Esc возвращает назад)
d Сделать выбранный аккаунт аккаунтом по умолчанию
r Заново получить данные об использовании, минуя короткий кэш
q, Esc, Ctrl+C Выйти

Меню закрывается до выполнения действия, поэтому терминал восстанавливается до запуска Claude Code. После d или изменения общего доступа меню открывается снова. При изменении общего доступа сначала показывается план и задаётся вопрос, как в ccam share.

Параметры

Параметр Действие По умолчанию
--dry-run Вывести окружение и команду, которые ccam выполнил бы, и завершиться выкл.
-v, --version Вывести ccam <version> (только как первый аргумент)
-h, --help Справка ccam, как ccam --help или ccam run --help

Правила разбора аргументов:

  • ccam читает собственные флаги только до имени аккаунта. После имени каждый аргумент принадлежит Claude Code, включая --dry-run и --help.
  • --dry-run работает в виде ccam --dry-run work, ccam run --dry-run work и ccam --dry-run (аккаунт по умолчанию). Он учитывается, а не отклоняется.
  • ccam run <name|number> [claude args] является полной формой ccam <name>. ccam run без имени использует аккаунт по умолчанию.
  • Имена аккаунтов не могут совпадать с именами команд ccam, например add, list, run или usage, поэтому ccam <word> никогда не бывает неоднозначным.

Пробный запуск выводит одну строку, которую можно вставить в оболочку:

$ ccam --dry-run work -p "fix the tests"
CLAUDE_CONFIG_DIR=/home/me/.local/share/ccam/profiles/work /home/me/.local/bin/claude --mcp-config=/home/me/.local/share/ccam/groups/default/mcp.json -p 'fix the tests'

Как это работает

Каждый запуск проходит одни и те же шаги, от командной строки до exec:

Каждый блок подсвечивается, когда выполняется его шаг, а строки под ним показывают окружение и аргументы, с которыми запускается Claude Code.

  1. cmd/ccam/main.go вызывает app.Main. Если ccam запущен под другим именем, это короткая команда, и она сразу передаётся запуску.
  2. app.parse просматривает os.Args до того, как подключается cobra. В cli.Execute попадают только ccam без аргументов (меню выбора), имя команды ccam (config.Reserved), -h/--help и -v/--version. Всё остальное считается запуском.
  3. launcher.Launch читает ~/.config/ccam/config.toml, единственный файл, который он разбирает.
  4. launcher.Prepare находит аккаунт по имени или номеру, отбрасывает один начальный -- и находит исполняемый файл claude через ResolveClaude. Результат поиска в PATH кэшируется в ~/.local/state/ccam/claude-path вместе со временем изменения файла, поэтому ccam не ищет в PATH при каждом запуске. Если файл изменился или отсутствует, поиск выполняется заново. Путь claude_bin в config.toml используется как есть. ccam отклоняет claude, который является самим ccam (сравнение по inode), потому что это привело бы к зацикливанию.
  5. checkLinks сравнивает папку аккаунта ~/.local/share/ccam/profiles/<name>/ с её настройками общего доступа через share.Check, который вызывает только lstat и readlink, один или два системных вызова на элемент. Отсутствующая ссылка создаётся на месте. Всё, что может привести к потере данных, останавливает запуск.
  6. applyMCP добавляет общие MCP-серверы (см. ниже).
  7. session.Register регистрирует сессию. ccam записывает маркер с именем по своему PID, содержащий время запуска процесса, в $XDG_RUNTIME_DIR/ccam/profile-<name>/<pid> (или в ~/.local/state/ccam/locks/, если XDG_RUNTIME_DIR не задана). Для аккаунта, который делит историю разговоров, historyCheck сначала ищет запущенную сессию в history-<group>-<hash>, где хэш вычисляется от текущей папки, и тоже регистрируется там. exec сохраняет PID, поэтому маркер затем указывает на сам процесс Claude Code. Используется именно маркер, а не удерживаемая блокировка, потому что процессы, запущенные Claude Code, унаследовали бы блокировку и сохранили бы её после завершения сессии.
  8. Plan.Exec устанавливает заголовок терминала claude · <name> (если стандартный поток ошибок подключён к терминалу), записывает время запуска в ~/.local/state/ccam/last-used/<name> без fsync и вызывает syscall.Exec.

Claude Code работает с CLAUDE_CONFIG_DIR, указывающим на папку аккаунта, и CCAM_PROFILE, равным имени аккаунта. ccam удаляет унаследованные значения этих переменных. Для папки ~/.claude, зарегистрированной через ccam import в macOS, он также задаёт CLAUDE_SECURESTORAGE_CONFIG_DIR пустое значение, чтобы аккаунт и обычный claude использовали один и тот же вход из Связки ключей.

Почему exec

syscall.Exec заменяет процесс ccam на claude, поэтому ccam не остаётся в памяти, нажатия клавиш, сигналы и код возврата принадлежат самому Claude Code, а аргументы остаются массивом и никогда не становятся строкой оболочки. Работа после сессии, например обнаружение серверов, добавленных через claude mcp add, выполняется при следующем запуске: ccam сравнивает время изменения .claude.json с ~/.local/state/ccam/mcp/<name>/seen и разбирает файл, только если он изменился.

Как обрабатывается командная строка

Три командные строки и три пути через internal/app:

Короткая команда распознаётся по argv[0], ccam <name> по первому аргументу, и оба пути заканчиваются syscall.Exec. До cobra доходит только команда ccam, например ccam usage.

Общие MCP-серверы

Со стратегией по умолчанию flag ccam передаёт MCP-серверы группы в Claude Code в виде аргумента, который ставится перед вашими:

mcp.FlagArgs возвращает аргумент, только если mcp.json группы существует, а Plan.InsertArgs ставит его сразу после claude. Ваши собственные --mcp-config или --strict-mcp-config при этом по-прежнему применяются поверх. Это один аргумент, --mcp-config=<path>, потому что --mcp-config в Claude Code принимает несколько значений: если записать его двумя аргументами, следующий за ним запрос тоже был бы прочитан как файл конфигурации.

С mcp_strategy = "sync" в config.toml ccam вместо этого записывает серверы в .claude.json аккаунта и пропускает этот шаг, если аккаунт уже запущен.

Remote Control

ccam work rc (или ccam work remote-control) запускает Remote Control из Claude Code от имени аккаунта work. claude remote-control отклоняет --mcp-config перед своей командой и не принимает его после неё, а его сессии читают MCP-серверы только из .claude.json аккаунта. Поэтому стратегия с флагом здесь работает иначе:

  1. remoteControl считает командой Claude Code первый аргумент после аккаунта, который не начинается с -. Если это remote-control или rc, mcp.FlagArgs ничего не добавляет.

  2. mcp.Synced сравнивает время изменения mcp.json группы с sync-stamp аккаунта. Если .claude.json уже содержит текущие серверы группы или у группы их нет, Remote Control запускается без вопроса.

  3. В противном случае ccam называет серверы, которых не будет в сессиях, и спрашивает:

    ccam: Remote Control sessions only get MCP servers stored in account work's .claude.json, not the shared MCP servers (ctx, fs).
    Copy them into .claude.json (a backup is kept)? [y/N]
  4. При ответе y функция mcp.Sync копирует их так же, как стратегия sync: под блокировкой Claude Code, после создания резервной копии и с сохранением собственных серверов аккаунта. При ответе N или без терминала Remote Control запускается без них, а ccam указывает на mcp_strategy = "sync", которая копирует их перед каждым запуском.

ccam спрашивает при каждом запуске Remote Control, пока серверы не скопированы, а после копирования — только когда mcp.json группы снова изменится. Копия в .claude.json побеждает --mcp-config при последующих обычных запусках, поэтому ccam mcp add, remove и import обновляют копии, которые хранятся у других аккаунтов (Общие MCP-серверы).

Бюджет в 10 мс

ccam добавляет не более 10 мс (p95) до запуска Claude Code. На пути запуска никогда не строится дерево команд cobra, не запускается Bubble Tea и не открывается сетевое соединение, а TestPackageInitIsCheap завершается ошибкой, если функции init() пакетов в сумме занимают больше 5 мс. scripts/perf-check.sh измеряет ccam --dry-run work, ccam work и короткую команду с помощью hyperfine и завершается ошибкой при превышении 10 мс, а BenchmarkLaunchPath в internal/launcher выполняет эти шаги в цикле. Чтобы увидеть время каждого шага, задайте CCAM_TRACE=1:

$ CCAM_TRACE=1 ccam --dry-run work >/dev/null
ccam trace: start                 2.830ms (total 2.830ms)
ccam trace: load config           0.397ms (total 3.227ms)
ccam trace: prepare               0.112ms (total 3.339ms)
ccam trace: check links           0.238ms (total 3.578ms)
ccam trace: prelaunch             0.083ms (total 3.661ms)

Безопасность и особые случаи

  • Неизвестное имя или номер останавливает запуск с сообщением no account "<name>" и ссылкой на ccam list. Если аккаунтов нет совсем, ccam предлагает добавить аккаунт командой ccam add <name>.
  • Если общий путь стал обычным файлом или указывает не туда, ccam останавливается с сообщением stopped because of share link problems:, перечисляет проблемы и предлагает выполнить ccam doctor --fix. На пути запуска он не перемещает данные.
  • Если в той же папке работает другой Claude Code, который делит историю разговоров с этим аккаунтом (та же группа), ccam предупреждает, что история может перемешаться, и спрашивает Run anyway? [y/N]. Без терминала он показывает предупреждение и продолжает.
  • --dry-run пропускает синхронизацию MCP, уведомление о новых серверах, проверку истории, маркер сессии, заголовок и время последнего использования и не выполняет exec. При этом он всё равно проверяет ссылки общего доступа и создаёт отсутствующую ссылку, как при обычном запуске.
  • ccam work rc, когда work уже запущен, не трогает .claude.json, сообщает об этом и запускает Remote Control без серверов группы; чтобы скопировать их, выполните команду снова после завершения сессии. С --dry-run выводится сообщение, но ccam ничего не спрашивает и не копирует.
  • С mcp_strategy = "sync" при неудачной синхронизации выводится ccam: MCP sync failed (launching anyway): …, и Claude Code запускается с теми серверами, которые у него уже были.