# AGENTS.md Руководство для агентов (и людей), работающих с этим репозиторием. ## Сопровождение этого файла (ВАЖНО) - **AGENTS.md должен отражать актуальное состояние кода.** Это живой документ, а не одноразовая справка. - При любом изменении, влияющем на: архитектуру, состав пакетов/файлов, флаги CLI или env-переменные (`WEBVNC_*`), протокол/поведение гейтвея, скрипты, кодировки файлов, процесс сборки/запуска или известные ограничения — **обязательно обнови соответствующий раздел AGENTS.md в том же коммите**. - Если заметил расхождение между AGENTS.md и реальным кодом (функция переименована, файл удалён, флаг изменён и т.п.) — сначала приведи AGENTS.md в соответствие с кодом, затем продолжай работу. Не оставляй устаревшие инструкции. - Коммит, меняющий поведение/структуру, но не трогающий AGENTS.md при расхождении, считается неполным. ## Что это `web-vnc` — один Go-бинарник, который открывает доступ к рабочему столу (VNC) через браузер (noVNC) с защитой по паролю. Гейтвей сам раздаёт noVNC-клиент, проверяет пароль, ставит HMAC-сессию и прозрачно релеит WebSocket браузера в TCP VNC-сервера (RFB). Опционально сам находит и запускает VNC-сервер. ## Ключевые принципы (НЕ нарушать) - **Только стандартная библиотека Go.** Внешних Go-модулей нет и быть не должно — проект собирается офлайн (в среде сборки нет интернета/Go-proxy). WebSocket (RFC 6455) и хэш пароля (PBKDF2-HMAC-SHA256) реализованы вручную в `internal/relay` и `internal/auth`. - **noVNC-клиент скачивается отдельно** (`scripts/get-novnc.*`) во встроенную статику `internal/server/static/`. Эти папки (`core/`,`app/`,`vendor/`, `utils/`,`novnc-original.html`) в git не коммитятся (см. `.gitignore`). Наша собственная обёртка — `internal/server/static/vnc.html` (коммитится). - **Пароль** — один общий для всех (по требованию). Веб-пароль (PBKDF2) хранится как `--password-hash`; тот же пароль может передаваться VNC-серверу через `--vnc-password`/`WEBVNC_VNC_PASSWORD`, чтобы noVNC авторизовался автоматически (одно поле ввода для пользователя). ## Сборка и запуск ```powershell # среда без интернета: Go уже установлен, прокси недоступен -> stdlib-only $env:GOCACHE = "$env:TEMP\go-build" # дефолтный кэш бывает без прав на запись go build -o web-vnc.exe ./cmd/web-vnc .\web-vnc.exe --gen-hash "пароль" # напечатает хэш .\web-vnc.exe --password-hash <хэш> --spawn ``` Проверка: `go vet ./...`, `gofmt -l internal cmd` (должно быть пусто). ## Структура ``` cmd/web-vnc/main.go CLI: флаги, спавн VNC, запуск сервера, --gen-hash internal/config флаги + env (WEBVNC_*) internal/auth PBKDF2-HMAC-SHA256, HMAC session-cookie, rate-limit internal/relay websocket.go — RFC6455 на stdlib; relay.go — WS<->TCP internal/vncspawner кросс-ОС поиск/запуск VNC-сервера (build-теги по ОС) internal/server HTTP-роуты, /api/status, middleware сессии, embed.FS internal/server/static встроенные ассеты (vnc.html + noVNC core/app/vendor) scripts/get-novnc.{ps1,sh} скачать noVNC scripts/get-vnc.ps1 скачать портативный UltraVNC в vnc/ (с верификацией zip) scripts/list-ips.ps1 список IPv4 машины (используется run.bat) scripts/open-firewall.bat открыть порт 8080 в Windows Firewall (от админа) scripts/set-vnc-password.bat задать VNC-пароль сервису UltraVNC (от админа; без него noVNC получает authentication rejected) scripts/ensure-vnc-password.ps1 синхронизирует VNC-пароль UltraVNC с паролем из run.bat (пишет только при несовпадении; UAC только при смене) — вызывается из run.bat run.bat запуск в один клик (спрашивает только пароль); синхронизирует VNC-пароль UltraVNC с введённым (см. ensure-vnc-password.ps1); если 5900 уже занят (сервис UltraVNC) — не порождает второй VNC-сервер, а подключается к существующему ``` ## Соглашения и подводные камни - **Кодировка файлов `.bat`:** сохранять в кодировке **cp866** с окончаниями строк **CRLF**. PowerShell `Set-Content -Encoding UTF8` добавляет BOM и пишет LF — не использовать для `.bat`. Пиши через `[System.IO.File]::WriteAllText(path, content -replace "(?