Возможности
Запуск Claude Code
Эта страница переведена с английского машинным способом. Исправления приветствуются. Редактировать эту страницу на 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.
cmd/ccam/main.goвызываетapp.Main. Если ccam запущен под другим именем, это короткая команда, и она сразу передаётся запуску.app.parseпросматриваетos.Argsдо того, как подключается cobra. Вcli.Executeпопадают толькоccamбез аргументов (меню выбора), имя команды ccam (config.Reserved),-h/--helpи-v/--version. Всё остальное считается запуском.launcher.Launchчитает~/.config/ccam/config.toml, единственный файл, который он разбирает.launcher.Prepareнаходит аккаунт по имени или номеру, отбрасывает один начальный--и находит исполняемый файлclaudeчерезResolveClaude. Результат поиска в PATH кэшируется в~/.local/state/ccam/claude-pathвместе со временем изменения файла, поэтому ccam не ищет вPATHпри каждом запуске. Если файл изменился или отсутствует, поиск выполняется заново. Путьclaude_binвconfig.tomlиспользуется как есть. ccam отклоняетclaude, который является самим ccam (сравнение по inode), потому что это привело бы к зацикливанию.checkLinksсравнивает папку аккаунта~/.local/share/ccam/profiles/<name>/с её настройками общего доступа черезshare.Check, который вызывает толькоlstatиreadlink, один или два системных вызова на элемент. Отсутствующая ссылка создаётся на месте. Всё, что может привести к потере данных, останавливает запуск.applyMCPдобавляет общие MCP-серверы (см. ниже).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, унаследовали бы блокировку и сохранили бы её после завершения сессии.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 аккаунта. Поэтому стратегия с флагом здесь работает иначе:
remoteControlсчитает командой Claude Code первый аргумент после аккаунта, который не начинается с-. Если этоremote-controlилиrc,mcp.FlagArgsничего не добавляет.mcp.Syncedсравнивает время измененияmcp.jsonгруппы сsync-stampаккаунта. Если.claude.jsonуже содержит текущие серверы группы или у группы их нет, Remote Control запускается без вопроса.В противном случае 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]При ответе
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 запускается с теми серверами, которые у него уже были.