# Запуск Claude Code

> Запускайте Claude Code от имени любого аккаунта через ccam <name|number>, ccam run или меню выбора ccam; аргументы передаются в claude без изменений, а --dry-run показывает команду.

Source: https://ccam.dev/ru/features/launch/ · Updated 2026-10-19

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

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

```sh
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>` никогда не бывает неоднозначным.

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

```console
$ 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 запущен под другим именем, это [короткая команда](https://ccam.dev/ru/features/shortcuts.md), и она сразу передаётся запуску.
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` аккаунта и пропускает этот шаг, если аккаунт уже запущен.

### Бюджет в 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`:

```console
$ 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. При этом он всё равно проверяет ссылки общего доступа и создаёт отсутствующую ссылку, как при обычном запуске.
- С `mcp_strategy = "sync"` при неудачной синхронизации выводится `ccam: MCP sync failed (launching anyway): …`, и Claude Code запускается с теми серверами, которые у него уже были.

## См. также

- [Короткие команды](https://ccam.dev/ru/features/shortcuts.md)
- [Управление аккаунтами](https://ccam.dev/ru/features/accounts.md)
- [Справочник команд](https://ccam.dev/ru/docs/commands.md)
- [Общие MCP-серверы, настройки и история](https://ccam.dev/ru/docs/sharing.md)
- [Как работает CLAUDE_CONFIG_DIR](https://ccam.dev/ru/guides/claude-config-dir.md)
