Files
ddadmin 203e515479 feat(proxy-client): добавлен мастер установки системной службы
- Зачем: установка с нуля и переход из ручного Xray одной командой.
- Что: план с подтверждением или --yes, скрытый ввод ссылки, проверка Xray,
  перенос настроек, запуск службы и переключение домашнего профиля;
  безопасное продолжение после сбоя и сохранение существующих настроек.
- Проверка: cross-review Claude и исправление находок; по 108 тестов на
  Python 3.8 и 3.14 под PTY, 18 Bash-проверок. После аудита уточнена
  фикстура повторного запуска и отдельно проверена на обеих версиях Python.
  Настоящие службы и настройки машины не изменялись.
2026-11-04 21:15:23 +01:00

40 KiB
Raw Permalink Blame History

proxy-client

proxy-client — переносимый Linux/Bash-интерфейс для запуска команд через внешний прокси или через управляемый Xray. Он добавляет команды proxy_on, proxy_off, pclaude и pcodex, но не подменяет обычные claude и codex.

CLI требует Python 3.8+ и использует только стандартную библиотеку. Он не запускает Xray и не переключает режим прокси без явной команды пользователя.

Установка

Только пакет proxy-client

Скопируйте каталог в постоянное место и запустите пакетный установщик. Текущий рабочий каталог не важен:

~/src/proxy-client/install.sh

Установщик создаёт три ссылки на исходный каталог: CLI, Bash-модуль и каталог шаблонов. Поэтому исходный каталог после установки нельзя перемещать. Если какой-то из путей уже занят чужим файлом или ссылкой, установщик ничего не меняет и перечисляет все такие пути. Повторный запуск безопасен.

По умолчанию установщик дописывает в ~/.bashrc блок между строками # >>> proxy-client >>> и # <<< proxy-client <<<: он добавляет ~/.local/bin в PATH и подключает Bash-модуль. Если блок уже есть, файл не меняется. После установки откройте новый Bash или примените блок в текущей сессии:

source ~/.bashrc

Чтобы оставить ~/.bashrc без изменений, запустите:

~/src/proxy-client/install.sh --no-shell-setup

В этом случае подготовьте только текущую сессию вручную:

export PATH="$HOME/.local/bin:$PATH"
source ~/.config/proxy-client/shell.bash

Для следующих сессий добавьте эти строки в подходящий Bash-конфиг сами.

Установщик не создаёт машинный config и закрытый default.url, не устанавливает Xray и не проверяет сеть. После подключения команд выберите режим по разделу «Настройка режима». Без машинного конфига действует режим Hiddify по умолчанию.

В составе dotfiles

Корневой установщик dotfiles подключает тот же пакет через Stow и загружает Bash-функции в новых интерактивных сессиях:

cd ~/dotfiles
./install.sh

Он заранее создаёт ~/.local/bin и ~/.config/proxy-client, чтобы Stow размещал ссылки внутри них, а не превращал сами каталоги в ссылки на репозиторий. После установки откройте новый Bash или выполните:

export PATH="$HOME/.local/bin:$PATH"
source ~/.bash_custom

Если ~/.local/bin отсутствует в PATH и в новых сессиях, добавьте ту же строку export в свой Bash-конфиг: корневой установщик dotfiles его не изменяет.

Как выбирается прокси

Без выбора профиля режим определяется файлом ~/.config/proxy-client/config:

Машинный конфиг Используется Что запускать
Файла нет Hiddify на hproxy.local:12334 Ничего
type = external Указанный внешний прокси Ничего
type = xray Управляемый локальный Xray proxy-client start

Доступность процесса не меняет выбранный режим. Если в конфиге указан Xray, но он не запущен, status, env, run, proxy_on, pclaude и pcodex завершатся с ошибкой. Автоматического перехода на Hiddify или другой прокси нет.

Текущий выбор и доступность проверяет команда:

proxy-client status

Настройка режима

Hiddify в Windows, команды в WSL

Это режим по умолчанию. Если Hiddify доступен из WSL как hproxy.local:12334, создавать config не нужно:

getent hosts hproxy.local
proxy-client status
pclaude --version

WSL NAT mode

IP Windows-шлюза меняется при перезапуске WSL, поэтому hproxy.local нужно обновлять. В отдельно скопированном пакете системных помощников нет. Узнайте адрес шлюза:

ip route show default | awk 'NR == 1 {print $3}'

Затем откройте /etc/hosts через sudoedit и оставьте одну отдельную строку с полученным адресом:

sudoedit /etc/hosts
<адрес-шлюза> hproxy.local

Не удаляйте другие имена на той же строке: при необходимости перенесите их на отдельную строку. Повторяйте обновление после перезапуска WSL.

С полным dotfiles запустите корневой ~/dotfiles/install.sh интерактивно: он предложит автоматическое обновление при старте WSL. Обновить адрес сразу можно так:

sudo ~/dotfiles/scripts/setup-hproxy.sh
# после настройки автозапуска и загрузки общих Bash-функций:
update_hproxy

В NAT mode Hiddify должен слушать адрес, доступный через Windows-шлюз, а не только 127.0.0.1.

WSL mirrored mode

В mirrored mode (networkingMode=mirrored) Windows-сервисы доступны из WSL через 127.0.0.1. Чтобы сохранить адрес по умолчанию, добавьте алиас в Windows hosts:

# C:\Windows\System32\drivers\etc\hosts
127.0.0.1  hproxy.local

Альтернатива — настройте внешний режим по следующему разделу и укажите address = 127.0.0.1. Алиас проверяйте через getent hosts hproxy.local, а активный конфиг — через proxy-client status.

Другой внешний прокси

Скопируйте пример и измените адрес, порт и локальные исключения:

cp ~/.config/proxy-client/examples/config.external \
  ~/.config/proxy-client/config
[proxy]
type = external
name = Office proxy
address = proxy.example.internal
port = 12334
no_proxy_extra = .example.internal,git.example.internal

Для внешнего прокси на той же Linux-машине можно указать 127.0.0.1 напрямую.

Локальный Xray

Создайте машинный конфиг:

cp ~/.config/proxy-client/examples/config.xray \
  ~/.config/proxy-client/config

Закрытый профиль должен содержать ровно одну VLESS-ссылку:

cp ~/.config/proxy-client/examples/default.url \
  ~/.config/proxy-client/default.url
$EDITOR ~/.config/proxy-client/default.url
chmod 600 ~/.config/proxy-client/default.url

Установите проверенную версию Xray без root:

proxy-client install

Запустите Xray в отдельном терминале или панели tmux:

proxy-client start

Другой файл VLESS-ссылки можно выбрать без замены default.url:

proxy-client start -f ~/.config/proxy-client/work.url

Для смены ссылки работающего экземпляра сначала выполните proxy-client stop. Все файлы с настоящими VLESS-ссылками должны иметь права 600 и не должны попадать в Git.

Именованные профили

Профиль объединяет настройки локального входа, исключения и, для Xray, VLESS-ссылку. Без указания имени используется default: прежние config и default.url остаются на своих местах. Дополнительные профили живут в ~/.config/proxy-client/profiles/<имя>/. При заданном XDG_CONFIG_HOME вместо ~/.config используется этот каталог.

Например, создайте профиль work:

mkdir -p ~/.config/proxy-client/profiles/work
cp ~/.config/proxy-client/examples/config.xray ~/.config/proxy-client/profiles/work/config
$EDITOR ~/.config/proxy-client/profiles/work/config

В config задайте свободный порт, например 12335, если основной прокси занимает 12334. Поместите VLESS-ссылку в profiles/work/default.url и ограничьте доступ:

chmod 600 ~/.config/proxy-client/profiles/work/default.url
proxy-client --profile work start

Команда остаётся в терминале. В другом терминале можно проверить или остановить именно этот профиль:

proxy-client --profile work status
proxy-client --profile work stop

Параметр --profile ставится перед подкомандой. Неизвестный профиль даёт ошибку; перехода на default нет. Разные профили могут работать одновременно на разных портах. Остановка одного не затрагивает остальные.

start -f FILE переопределяет только файл ссылки выбранного профиля на этот запуск. Его порт и исключения по-прежнему берутся из config.

Ежедневное использование

Задача Команда Область действия
Запустить Claude через прокси pclaude [ARG...] Только дочерний процесс
Запустить Codex через прокси pcodex [ARG...] Только дочерний процесс
Запустить другую команду proxy-client run -- COMMAND ARG... Только дочерний процесс
Включить прокси proxy_on Текущая Bash-сессия
Выключить прокси proxy_off Текущая Bash-сессия
Проверить прокси proxy-client status Без изменения окружения
Получить proxy-переменные proxy-client env Машинный вывод в stdout
Показать внешний IP myip С учётом текущего окружения

run, pclaude и pcodex передают дочернему процессу восемь вариантов HTTP_PROXY, HTTPS_PROXY, ALL_PROXY и NO_PROXY, включая имена в нижнем регистре. После завершения команды переменные не остаются в оболочке.

proxy_on применяет те же переменные к текущей Bash-сессии только после успешной проверки прокси. proxy_off удаляет их. Обычные claude и codex не обёрнуты и не выполняют предварительную проверку, но после proxy_on наследуют прокси-переменные, как и любой другой дочерний процесс.

Для именованного профиля:

proxy_on --profile work
pclaude --proxy-profile work
pcodex --proxy-profile work --search
proxy-client --profile work run -- COMMAND ARG...

У pclaude и pcodex параметр --proxy-profile должен быть первым. Обычный --profile передаётся запускаемой программе.

proxy_on --profile work меняет окружение терминала, но не профиль по умолчанию: обычный codex наследует это окружение, а pcodex без параметра выберет default. proxy_off только очищает переменные — работающие прокси, включая системную службу, остаются запущенными. myip использует текущее окружение.

Жизненный цикл Xray

proxy-client install [--replace]
proxy-client start [-f PROFILE]
proxy-client status
proxy-client stop

start сначала проверяет версию и конфигурацию Xray, затем остаётся на переднем плане. Скрытого запуска из run нет; системная служба устанавливается отдельно. Один loopback-порт принимает HTTP CONNECT и SOCKS5.

Остановить Xray можно двумя способами: Ctrl+C в окне start или proxy-client stop из любого терминала. Оба гасят Xray и удаляют служебные файлы. Если процесс start был убит (например, закрыли окно tmux), Xray может остаться работать: status и env тогда сообщат об ошибке, а stop добьёт его и уберёт файлы. stop работает и после изменения машинного типа на external.

Второй start того же профиля, пока первый работает, завершится ошибкой.

Системная служба

Этот режим нужен, когда приложения должны получать прокси после загрузки Linux, до входа пользователя. Требуются systemd, systemd-sysusers и права администратора для установки. Служба одна; именованные профили остаются пользовательскими.

Установка и переход из tmux

Запустите от своего пользователя, без sudo:

proxy-client service install

В терминале команда показывает план и просит одно подтверждение. Если настроек нет, она запросит VLESS-ссылку скрытым вводом и предложит локальный порт 12334. Если Xray отсутствует, скачает закреплённую версию и проверит контрольную сумму. Ссылка не попадает в аргументы процессов и журнал.

Если профиль уже настроен, используются его config и default.url. После подтверждения команда проверяет конфигурацию Xray, устанавливает системные файлы через sudo, останавливает свой ручной Xray и запускает службу с автозапуском. Текущие соединения при переходе прервутся. Чужой процесс, занимающий порт, команда не останавливает.

Когда служба активна и локальный порт доступен, домашний config переключается на type=external. Поэтому proxy_on, status и run сразу работают со службой. Прежний файл сохраняется рядом как config.before-service.*. Готовность локального порта не гарантирует доступность удалённого сервера.

Если файлы службы уже установлены через --install-only, но домашний профиль ещё имеет type=xray, мастер завершит перенос. Сначала он проверит совпадение настроек с системными; другой профиль не заменит уже настроенную службу.

Для именованного профиля:

proxy-client --profile work service install

Для принятия плана без вопроса есть --yes и его синоним --auto-yes:

proxy-client service install --yes

При настройке с нуля без терминала передайте закрытый файл со ссылкой:

chmod 600 ~/connection.url
proxy-client service install --auto-yes --file ~/connection.url --port 12334

--file также подходит, если ручной Xray запускался с разовой ссылкой через start -f. Без него берётся сохранённый default.url. --yes принимает план, но не заменяет ввод недостающей ссылки и не отменяет проверки или запрос пароля sudo.

Ошибка или прерывание

До успешной установки системных файлов ручной Xray продолжает работать. Если запуск службы не удался после его остановки, домашний профиль остаётся прежним. Команда пытается отключить неудачно запущенную службу и показывает, как вернуть ручной запуск. Восстановить прежние соединения и процесс в tmux автоматически нельзя.

Повторите proxy-client service install: незавершённый переход продолжится по закрытому снимку service-setup.json в каталоге состояния выбранного профиля. Снимок содержит VLESS-ссылку, имеет права 600 в каталоге 700 и удаляется после успеха. Если домашние или системные настройки успели измениться, команда остановится, чтобы их не затереть. Проверяется также исходный default.url или файл, переданный через --file, до остановки ручного Xray. После запуска служба использует свою копию ссылки; позднее изменение исходной ссылки не отменяет завершение перехода.

Чтобы отказаться от старого снимка и прочитать текущие настройки заново, удалите только service-setup.json: точную команду rm -- … CLI печатает при конфликте. Для профиля по умолчанию без переопределения XDG это:

rm -- ~/.local/state/proxy-client/service-setup.json
proxy-client service install

Сброс снимка не меняет домашние файлы, настройки службы и работающие процессы. Если системные настройки уже отличаются от желаемых, их нужно изменить отдельно в /etc/proxy-client — мастер их не перезаписывает.

Только установка файлов

Для прежнего режима без мастера и переключения домашнего профиля:

proxy-client service install --install-only

Без терминала явно выберите --yes для полного перехода или --install-only для установки файлов; команда без выбора режима завершится с подсказкой. Режим установки файлов требует готовые настройки и Xray, а при их отсутствии выдаёт подсказку до вызова sudo. --enable, --start и --restart явно включают автозапуск, запуск сейчас или перезапуск с проверкой готовности. Без этих флагов служба не запускается.

Xray ищется в ~/.local/bin, затем в PATH и системной установке. Параметр --xray FILE переопределяет выбор. Для установки из произвольного каталога есть --config-dir DIR: он тоже выбирает режим установки файлов. Пути должны быть абсолютными; --config-dir несовместим с именованным --profile. Прямой запуск через sudo подходит для --install-only; нестандартный каталог XDG в этом случае задавайте через --config-dir.

Доступ к прокси

Xray слушает только числовой loopback-адрес: 127.0.0.1 или ::1. Проверка выполняется при установке и каждом запуске. Адреса всех интерфейсов (0.0.0.0, ::) и локальной сети не принимаются. Другие процессы на этой же машине могут пользоваться прокси.

Установщик копирует настройки в /etc/proxy-client/, а CLI и Xray — в /usr/local/lib/proxy-client/. Служба больше не зависит от домашнего каталога. Изменения исходного пользовательского профиля на неё не влияют. Системные настройки имеют владельца root, группу proxy-client и права 640; каталог — 750. Процесс работает под отдельным пользователем proxy-client. Временные файлы находятся в закрытом /run/proxy-client/.

Управление и журнал:

sudo systemctl status proxy-client
sudo systemctl stop proxy-client
sudo systemctl start proxy-client
sudo systemctl restart proxy-client
sudo journalctl -u proxy-client -b
sudo journalctl -u proxy-client -f

Для изменения настроек отредактируйте /etc/proxy-client/config или /etc/proxy-client/default.url с правами администратора, затем перезапустите службу. Сохраняйте владельца, группу и права файлов.

После аварии systemd повторяет запуск с паузой в пять секунд. Явная команда stop оставляет службу остановленной, но не отменяет запуск при следующей загрузке. Чтобы отключить автозапуск и остановить её сразу:

sudo systemctl disable --now proxy-client

Чтобы включить обратно:

sudo systemctl enable --now proxy-client

При обновлении повторите команду из актуальной копии пакета:

proxy-client service install

Мастер предложит обновить и перезапустить службу. Настройки в /etc/proxy-client сохраняются, домашний профиль не меняется и может отсутствовать. Без терминала используйте --yes для этого же действия. Режим --install-only по-прежнему не перезапускает службу без явного флага.

Чужие или вручную изменённые исполняемые файлы и unit-файл установщик не заменяет; изменения параметров systemd делайте через sudo systemctl edit proxy-client. Файлы заменяются по одному атомарно, общего отката всей установки при сбое нет. После устранения причины сбоя повторите установку: журнал незавершённой установки позволяет продолжить её, сохраняя проверку принадлежности файлов.

Вывод CLI поступает в journald. Сырой вывод Xray в системном режиме подавлен, чтобы сообщения с фрагментами конфигурации не раскрывали секреты; детальные сетевые журналы Xray поэтому недоступны. Установщик сообщает настройку хранения journald, но не меняет её. Сохранение журнала после перезагрузки зависит от настроек машины; проверить предыдущие загрузки можно через sudo journalctl --list-boots.

Открытый локальный порт не гарантирует доступность удалённого сервера. На ноутбуке сеть может появиться позже службы. Приложениям без повторения запросов понадобится отдельная настройка ожидания готовности.

Для proxy_on, pclaude, pcodex и run системная служба — внешний прокси: укажите в нужном пользовательском профиле type = external, адрес 127.0.0.1 и порт службы. Дополнительный профиль типа xray запускайте вручную на другом порту. Пользовательский stop системной службой не управляет.

Для проверки размещения файлов без установки на машину есть service install --config-dir DIR --xray FILE --root /absolute/staging. Этот режим не вызывает systemd, не создаёт системную учётную запись и не назначает ей владельцев; он несовместим с --enable и --start.

Прокси в настройках Codex и Claude Code

Codex и Claude Code умеют брать proxy-переменные из собственных настроек. Значения оттуда перекрывают окружение, унаследованное от запускающего приложения, поэтому маршрут не зависит от того, откуда агент запущен: терминал, IDE или фоновый демон Codex. С такими настройками pcodex и pclaude не обязательны.

Установщики эти настройки не трогают. Шаблоны лежат в ~/.config/proxy-client/examples/: прокси 127.0.0.1:12334 и короткий список исключений. Скопируйте нужный и поправьте под свою машину.

Codex читает ~/.codex/.env:

cp ~/.config/proxy-client/examples/codex.env ~/.codex/.env
codex app-server daemon restart

Запросы к API отправляет общий демон Codex, а он читает .env только при старте. Перезапуск демона прерывает открытые сессии Codex.

Claude Code берёт переменные из блока env в ~/.claude/settings.json. Перенесите туда блок из examples/claude-settings.json; остальные ключи файла не трогайте. Настройки подхватятся при следующем запуске Claude Code. Claude Desktop этот блок не использует: само приложение ходит в сеть через Chromium.

Чтобы агент на машине работал без прокси, даже если его запустило приложение с прокси в окружении, очистите адреса (HTTP_PROXY, HTTPS_PROXY, ALL_PROXY в обоих регистрах) и задайте NO_PROXY=* и no_proxy=*.

Диагностика

Начните с проверки выбранного режима:

proxy-client status

Для внешнего Hiddify в WSL проверьте имя и порт:

getent hosts hproxy.local
curl --proxy http://hproxy.local:12334 https://example.com
curl --proxy socks5h://hproxy.local:12334 https://example.com

Для запущенного Xray можно дополнительно проверить созданный JSON:

xray run -test -c \
  "${XDG_STATE_HOME:-$HOME/.local/state}/proxy-client/client.json"

Если выбран type = xray, но процесс не запущен, запустите его отдельно — proxy_on и run этого не делают. Профиль XHTTP с ALPN h3 требует доступного UDP-маршрута до сервера; автоматического перехода на H2 нет.

Таймаут предварительной проверки по умолчанию равен двум секундам. Его можно изменить положительным числом:

export PROXY_PREFLIGHT_TIMEOUT=5

Справочник

Ручное подключение без установщика

Если пакетный установщик запустить нельзя, выберите постоянный абсолютный путь к исходному каталогу и создайте те же ссылки вручную. Команды предполагают, что назначения ещё не заняты:

mkdir -p ~/.local/bin ~/.config/proxy-client
ln -s /absolute/path/to/proxy-client/.local/bin/proxy-client \
  ~/.local/bin/proxy-client
ln -s /absolute/path/to/proxy-client/.config/proxy-client/shell.bash \
  ~/.config/proxy-client/shell.bash
ln -s /absolute/path/to/proxy-client/.config/proxy-client/examples \
  ~/.config/proxy-client/examples
chmod 755 /absolute/path/to/proxy-client/.local/bin/proxy-client

Подготовьте текущую Bash-сессию:

export PATH="$HOME/.local/bin:$PATH"
source ~/.config/proxy-client/shell.bash

Для следующих сессий добавьте эти две строки в свой Bash-конфиг. Исходный каталог после этого нельзя перемещать: созданные ссылки зависят от его пути.

Машинный конфиг

Формат строгий: одна секция [proxy] и пять обязательных ключей без повторов и неизвестных полей:

  • type — external или xray;
  • name — имя для диагностики;
  • address — IPv4, IPv6 без квадратных скобок или ASCII DNS-имя без схемы и порта;
  • port — TCP-порт локального входа;
  • no_proxy_extra — IP и домены через запятую, значение может быть пустым. Список замещает встроенный DEFAULT_NO_PROXY_EXTRA целиком, а не дополняет его: домены, нужные постоянно, придётся перечислить здесь заново.

Поддержка CIDR в NO_PROXY различается между программами, поэтому надёжнее указывать точные IP и домены. Без машинного файла внешний режим дополнительно включает .concept-software.ru, dementev.space и .dementev.space в NO_PROXY. Для type = xray адрес обязан быть адресом обратной петли, например 127.0.0.1 или ::1.

Поддерживаемые профили

Поддерживаются VLESS TCP/RAW с REALITY и VLESS XHTTP с TLS. Неизвестные, повторные и несовместимые query-параметры отклоняются. XHTTP поддерживает ALPN http/1.1, h2 и h3; extra должен быть JSON-объектом, его содержимое проверяет xray run -test.

Параметры ссылок передаются по спецификации Xray:

В ссылке В конфигурации Xray
ech TLS echConfigList
pqv, spx REALITY mldsa65Verify, spiderX
fm streamSettings.finalmask, JSON-объект
x_padding_bytes, xPaddingBytes XHTTP extra.xPaddingBytes
scMaxEachPostBytes, scMinPostsIntervalMs, uplinkChunkSize Одноимённые поля XHTTP внутри extra

Для XHTTP пустой или отсутствующий host допустим; при отсутствии path используется /. Имена sessionPlacement и sessionKey в extra, включая отдельное соединение скачивания, преобразуются в sessionIDPlacement и sessionIDKey. Если старое и новое имя задают разные значения, профиль отклоняется. Новые sessionIDTable и sessionIDLength передаются ядру. Параметры XHTTP с именами как в JSON имеют приоритет над extra, а extra.xPaddingBytes — над x_padding_bytes.

При отсутствии encryption используется none, sni — адрес сервера, TLS fp — chrome. Для REALITY fp и pbk обязательны, а flow и sid могут быть пустыми или отсутствовать; type=raw принимается как type=tcp. Пустые ech, pqv, spx, pcs, vcn допустимы. SHA-256 в pcs может содержать двоеточия и пробелы по краям. Метка support-x25519mlkem768=true в REALITY принимается для совместимости со ссылками 3x-ui и не создаёт поле в JSON Xray.

Кроме encryption=none, принимается VLESS-шифрование encryption=mlkem768x25519plus.… из новых ссылок Hiddify; остальную часть значения проверяет сам Xray. Только с таким шифрованием XHTTP допускает flow=xtls-rprx-vision. Косая черта перед параметрами (…:443/?type=…) допустима, другой путь в ссылке — нет.

Xray 26.10.10 использует pcs и vcn. Устаревшие allowInsecure и insecure принимаются с любым значением, но не переносятся: при значении 1 или true выводится предупреждение, а сертификат проверяется обычным способом.

Последняя версия Xray, где allowInsecure ещё применяется, — 25.12.8; опция удалена в 26.2.6. proxy-client эти версии не поддерживает и не устанавливает.

Проверяемая установка Xray

proxy-client install устанавливает Xray 26.10.10 в ~/.local/bin/xray. Для x86_64/amd64 используется Xray-linux-64.zip, для aarch64/arm64 — Xray-linux-arm64-v8a.zip; остальные архитектуры отклоняются.

Выпуск 26.10.10 помечен как предварительный. Обновление уже установленного клиента:

proxy-client install --replace

CLI скачивает официальный архив и файл .dgst, сверяет SHA-256 и фактическую версию бинарника, а затем атомарно заменяет назначение. При любой ошибке старый файл остаётся на месте. Если нужная версия уже установлена, сеть не нужна и ничего не меняется. Другой файл или симлинк не заменяется без --replace (симлинк заменяется сам, файл по ссылке не трогается); каталог не заменяется никогда. Если после установки PATH находит другой xray, install сообщает об ошибке и подсказывает команду.

Устанавливать можно и при работающем Xray: он продолжит работу со старым файлом, а install напомнит перезапустить start.

start использует первый xray из PATH и принимает только версию 26.10.10.

Файлы и безопасность

Путь Назначение
~/.config/proxy-client/config Несекретный машинный выбор режима
~/.config/proxy-client/default.url Закрытая VLESS-ссылка, права 600
~/.config/proxy-client/examples/ Синтетические примеры без секретов, шаблоны для Codex и Claude Code
$XDG_STATE_HOME/proxy-client/ или ~/.local/state/proxy-client/ Состояние и сгенерированный JSON

Сводка скрывает UUID и ключи, а для XHTTP показывает только длину path. Если файл профиля доступен другим пользователям, start не запустится и покажет готовую команду chmod 600 для конечного файла (у симлинка — для файла, на который он указывает). Служебный каталог закрыт для других пользователей (700, файлы в нём — 600) и очищается после остановки Xray. Сбой определения внешнего IP показывается как предупреждение и не останавливает уже готовый процесс.

Изменение кода

Перед правкой proxy-client прочитайте спецификацию: там сказано, от чего клиент защищается, от чего нет и почему, и где живут тесты.

Все тесты пакета (из корня dotfiles):

tests/test_proxy_client_full.sh