diff --git a/hosts/heather/caddy.nix b/hosts/heather/caddy.nix index f3ad079..d53e2b7 100644 --- a/hosts/heather/caddy.nix +++ b/hosts/heather/caddy.nix @@ -19,6 +19,14 @@ let # (на heather: nix-shell -p caddy --run 'caddy hash-password ...') # Защищает syncthing GUI снаружи (GUI слушает только 127.0.0.1:8384, # Caddy проксирует sync.iscg.dev + basicauth). + # pi-web basicauth. Пароль в pass iscg.dev/pi-web/auth (plaintext). + # Hash сгенерить на heather: nix-shell -p caddy --run 'caddy hash-password --plaintext ...' + piBasicAuth = '' + basicauth { + mikl $2a$14$yqYiMGLvtPs0sLRZhu1/VOfiRO.CARIBcGGrFpo4iwOd9s4o4IVCy + } + ''; + syncBasicAuth = '' basicauth { mikl $2a$14$ozHN9/aa4VhPX43NN8MKdODKvOoJ5MBpOUFhzkxwvb58ZI5b6eqEK @@ -93,6 +101,12 @@ in { "home.iscg.dev".extraConfig = '' reverse_proxy 127.0.0.1:3002 ''; + + # pi-web (web UI для pi coding agent) + # basicauth защищает весь vhost включая SSE /api/agent — leak нет. + "pi.iscg.dev".extraConfig = piBasicAuth + '' + reverse_proxy 127.0.0.1:30141 + ''; }; }; } diff --git a/hosts/heather/default.nix b/hosts/heather/default.nix index 46afe3b..45cf60d 100644 --- a/hosts/heather/default.nix +++ b/hosts/heather/default.nix @@ -20,6 +20,7 @@ ./caddy.nix # edge proxy, TLS, роутинг по доменам ./syncthing.nix # sync + relay ./tuwunel-admin.nix # matrix admin web UI (systemd, статический бинарник) + ./pi-web.nix # pi-web (web UI для pi coding agent, systemd + npm global) ]; # Arion-проект как systemd-сервис: arion-compose.nix → docker-compose → up. diff --git a/hosts/heather/pi-web.nix b/hosts/heather/pi-web.nix new file mode 100644 index 0000000..d8de312 --- /dev/null +++ b/hosts/heather/pi-web.nix @@ -0,0 +1,48 @@ +# heather — pi-web (web UI для pi coding agent). +# +# https://github.com/agegr/pi-web, npm-пакет @agegr/pi-web +# Next.js 16 + lobehub-ui. Читает ~/.pi/agent/sessions/*.jsonl напрямую, +# общается с pi через RPC (spawn бинаря pi). НЕ демон — запускается как +# systemd-сервис, который держит next-server на 127.0.0.1. +# +# Слушает 127.0.0.1:30141 → Caddy pi.iscg.dev терминирует TLS + basicauth +# (см. caddy.nix, piBasicAuth). Auth-пароль в pass iscg.dev/pi-web/auth. +# +# Установка pi и pi-web — ручная (npm global в ~/.npm-global, НЕ в nix store): +# npm config set prefix ~/.npm-global +# npm i -g @earendil-works/pi-coding-agent @agegr/pi-web +# Это разовая операция на хосте (как tuwunel-admin бинарник вне nix-store). +# nodejs ставим через systemPackages — нужен и для npm, и для next-server. + +{ config, pkgs, lib, ... }: +{ + # Node.js: нужен для pi-web (next-server) и для spawn'а pi из pi-web. + environment.systemPackages = [ pkgs.nodejs ]; + + systemd.services.pi-web = { + description = "pi-web (web UI for pi coding agent)"; + after = [ "network-online.target" ]; + wants = [ "network-online.target" ]; + wantedBy = [ "multi-user.target" ]; + + # PATH: nodejs (node/npm) + ~/.npm-global/bin (где лежат pi и pi-web). + path = [ pkgs.nodejs "/home/mikl/.npm-global/bin" ]; + + environment = { + # Где pi-web ищет sessions/pi-конфиг. Совпадает с ~/.pi/agent на heather. + PI_CODING_AGENT_DIR = "/home/mikl/.pi/agent"; + HOME = "/home/mikl"; + NODE_ENV = "production"; + }; + + serviceConfig = { + Type = "simple"; + User = "mikl"; + Group = "users"; + ExecStart = "/home/mikl/.npm-global/bin/pi-web --hostname 127.0.0.1 --port 30141"; + WorkingDirectory = "/home/mikl"; + Restart = "on-failure"; + RestartSec = 5; + }; + }; +}