Files
dotfiles/.scratch/proxy-client/issues/01-external-proxy-and-portable-shell.md
T
ddadmin 6e431d875e refactor(proxy-client): переименован интерфейс прокси
- Зачем:
  - прежнее имя выпячивало Xray, хотя клиент поддерживает также внешний прокси, а два каталога конфигурации были неочевидны.
- Что:
  - пакет, CLI, конфигурация, состояние, тесты и документация переименованы в proxy-client.
  - машинный конфиг, профиль и два явных примера собраны в одном пользовательском каталоге.
  - свежая установка защищена от сворачивания каталога конфигурации внутрь репозитория.
- Проверка:
  - bash tests/test_proxy_client_full.sh.
  - bash tests/test_install.sh.
  - ручные start, status и xray run -test; незавершённая сетевая приёмка записана в handoff.
2026-07-21 09:31:21 -04:00

6.3 KiB

01 — Внешний прокси и переносимый Bash-интерфейс

What to build: Самостоятельный пользовательский пакет прокси, через который можно безопасно запускать команды с уже работающим внешним прокси, например Hiddify. Привычные Bash-команды переходят на единый CLI-контракт, но прежний сценарий без машинного конфига продолжает работать.

Blocked by: None — can start immediately.

Status: done

Часть требований пересмотрена в 06 — см. 06-simplification-pass.md.

  • CLI работает на Python 3.8+ без сторонних библиотек, ничего не устанавливает и не запускает без явной подкоманды и выдаёт понятную ошибку на более старом Python.

  • Машинный INI явно различает типы external и xray, проверяет имя, адрес, порт и добавку к NO_PROXY; отсутствие файла сохраняет внешний прокси hproxy.local:12334 без неявного переключения на другой тип.

  • Канонический машинный INI содержит единственную секцию [proxy] и ровно по одному ключу type, name, address, port, no_proxy_extra:

    [proxy]
    type = external
    name = Hiddify
    address = hproxy.local
    port = 12334
    no_proxy_extra = .example.internal,git.example.internal
    

    Все ключи обязательны при наличии файла; no_proxy_extra может быть пустым. Неизвестные секции и ключи, повторы, пропуски, многострочные или содержащие NUL значения, пустые имя или адрес и порт вне диапазона 1–65535 отклоняются. Добавки к NO_PROXY задаются через запятую, окружающие пробелы удаляются, пустые элементы отклоняются.

  • address принимает IPv4, IPv6 без квадратных скобок либо ASCII DNS-имя из корректных непустых меток; схема URL, встроенный порт, скобки, zone ID, пробелы, /, @ и другие URL-разделители отклоняются. При формировании proxy-URL CLI сам заключает IPv6-литерал в квадратные скобки.

  • Для типа external команды status, env и run -- COMMAND ARG... проверяют только настроенный адрес и порт; недоступный прокси запрещает запуск дочерней команды с понятным сообщением.

  • До реализации управляемого процесса конфиг с type=xray обрабатывается безопасным отказом: status, env, run и start не считают один открытый порт доказательством управляемого Xray и не запускают дочернюю команду.

  • env при успехе печатает только восемь разрешённых proxy-переменных в двух регистрах, а при ошибке не печатает частичный результат; базовый NO_PROXY включает loopback и узел прокси, затем дополняется машинной настройкой.

  • Документированный PROXY_PREFLIGHT_TIMEOUT сохраняется как положительное число секунд с прежним значением по умолчанию 2 для проверок доступности из status, env и run; ошибочное значение даёт понятный отказ.

  • run без искажений сохраняет аргументы и код возврата команды, передаёт proxy-переменные только дочернему процессу и возвращает отдельную понятную ошибку, если команда отсутствует в PATH.

  • Переносимый Bash-модуль становится единственным владельцем proxy_on, proxy_off, pclaude, pcodex, myip и внутренних proxy-помощников; WSL-функция обновления hproxy.local остаётся независимой.

  • Обычный запуск dotfiles подключает общий Bash-файл и переносимый proxy-модуль независимо: после установки доступны все пять proxy-команд и update_hproxy; подключение одного переносимого модуля без остальных dotfiles также предоставляет все пять proxy-команд.

  • Bash-модуль принимает вывод env атомарно, проверяет белый список и наличие каждого из восьми ключей ровно один раз, не использует eval и при любом неверном выводе оставляет прежние восемь переменных без изменений; proxy_on и proxy_off больше не делают автоматический запрос внешнего IP.

  • Автоматические тесты подтверждают прежний внешний Hiddify-сценарий, fail-fast, оба регистра переменных, настраиваемый NO_PROXY, отсутствие протечки окружения, обычное и самостоятельное подключение Bash-модуля, безопасный отказ для type=xray и атомарный разбор полного вывода env.