From fc27c08fa8238630107dd7b45106cb99149b94bd Mon Sep 17 00:00:00 2001 From: mikl Date: Wed, 9 Sep 2026 20:15:28 +0300 Subject: [PATCH] heather: add paseo daemon (systemd + caddy vhost paseo.iscg.dev, dual auth) --- flake.lock | 28 ++++++++++------------ flake.nix | 7 +++--- home/cli.nix | 43 ++++++++++++++++++++++++++++++--- home/kitty.nix | 4 ++-- home/zsh.nix | 2 +- hosts/heather/caddy.nix | 15 ++++++++++++ hosts/heather/default.nix | 1 + hosts/heather/paseo.nix | 50 +++++++++++++++++++++++++++++++++++++++ hosts/poppy/apps.nix | 1 + 9 files changed, 125 insertions(+), 26 deletions(-) create mode 100644 hosts/heather/paseo.nix diff --git a/flake.lock b/flake.lock index a2e7ec8..be58fbc 100644 --- a/flake.lock +++ b/flake.lock @@ -86,18 +86,14 @@ ] }, "locked": { - "lastModified": 1784157266, - "narHash": "sha256-wRs7/KNxLTZpW/tYJg62dk8IvkT6BM4cmMUl4m8jWrc=", - "ref": "master", - "rev": "691458497c8e965be38ac06084b72d7a0167e541", - "revCount": 5, - "type": "git", - "url": "ssh://git@git.iscg.dev:2222/mikl/lem.git" + "lastModified": 1786394750, + "narHash": "sha256-zv8tPWY3vQUgCQ9XpMININTMtPZixUEMwrPgesIdVYg=", + "path": "/Users/mikl/repos/lem", + "type": "path" }, "original": { - "ref": "master", - "type": "git", - "url": "ssh://git@git.iscg.dev:2222/mikl/lem.git" + "path": "/Users/mikl/repos/lem", + "type": "path" } }, "nix-darwin": { @@ -107,11 +103,11 @@ ] }, "locked": { - "lastModified": 1781761792, - "narHash": "sha256-rCPytmKNjctLloB6UgK5CRrHSwV4b0ygxtJLPPp8R14=", + "lastModified": 1785389976, + "narHash": "sha256-0tLW8Ff5yt8AH97jw4ZpFJ0OCJ122zIlgWGDmOfU/VU=", "owner": "LnL7", "repo": "nix-darwin", - "rev": "a1fa429e945becaf60468600daf649be4ba0350c", + "rev": "15abb8c98f336cd8bd840d71059adebabe60bf04", "type": "github" }, "original": { @@ -122,11 +118,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1782545840, - "narHash": "sha256-PkBPmP5ofNtunCU7/tfn6wi9OLlzFGcHAqqmY+/mwUI=", + "lastModified": 1785301185, + "narHash": "sha256-eoS3KQTO0aPWXZvIaRbRAzSSHW3l5wdMFXtT1ISfoKA=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "3d46470bb3030020f7e1361f33514854f5bfa86d", + "rev": "9bc02893134c733dd85de46ee4fb2fac696b5529", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index e66840d..d5ea563 100644 --- a/flake.nix +++ b/flake.nix @@ -24,16 +24,15 @@ inputs.nixpkgs.follows = "nixpkgs"; }; - # Personal CLIs built from own repos + # Personal CLIs. Local path avoids the SSH flake-fetch problem under sudo. lem = { - # ssh fetch via flake; ssh key available to nix-daemon. Private repo. - url = "git+ssh://git@git.iscg.dev:2222/mikl/lem.git?ref=master"; + url = "path:/Users/mikl/repos/lem"; inputs.nixpkgs.follows = "nixpkgs"; }; }; outputs = - { self, nixpkgs, nix-darwin, home-manager, sops-nix, arion, lem, ... }: + { self, nixpkgs, nix-darwin, home-manager, sops-nix, arion, lem, ... }: let mkNixos = hostname: nixpkgs.lib.nixosSystem { diff --git a/home/cli.nix b/home/cli.nix index bb078b9..b41b5c0 100644 --- a/home/cli.nix +++ b/home/cli.nix @@ -49,7 +49,7 @@ python313 uv - # Personal CLIs (from own flake inputs) + # Personal CLIs (local flake input; avoids SSH fetch under sudo) inputs.lem.packages.${pkgs.system}.default ]; @@ -109,6 +109,43 @@ git = true; }; - # Fastfetch - system info (using package only, no home-manager module) - # Config is in ~/.config/fastfetch/config.jsonc manually for now + # Fastfetch - system info. Packages module disabled: scanning 8800 nix store + # entries takes ~1.5s on cold cache and delays terminal startup. Structure + # mirrors the fastfetch default minus Packages (and unsupported Icons/LocalIp/PowerAdapter). + xdg.configFile."fastfetch/config.jsonc".text = '' + { + "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", + "logo": { + "type": "auto" + }, + "display": { + "separator": " " + }, + "modules": [ + "break", + "os", + "host", + "kernel", + "uptime", + "shell", + "display", + "wm", + "wmtheme", + "theme", + "font", + "cursor", + "terminal", + "terminalfont", + "cpu", + "gpu", + "memory", + "swap", + "disk", + "battery", + "locale", + "break", + "colors" + ] + } + ''; } diff --git a/home/kitty.nix b/home/kitty.nix index 5e07421..84febce 100644 --- a/home/kitty.nix +++ b/home/kitty.nix @@ -15,10 +15,10 @@ size = 12; }; - themeFile = "Catppuccin-Mocha"; + themeFile = "mellow"; settings = { - background_opacity = "1"; + background_opacity = "0.96"; dynamic_background_opacity = "yes"; background_blur = 16; cursor_shape = "beam"; diff --git a/home/zsh.nix b/home/zsh.nix index 89f417d..abe4b6b 100644 --- a/home/zsh.nix +++ b/home/zsh.nix @@ -75,7 +75,7 @@ # Init content initContent = lib.mkMerge [ '' - # Show fastfetch on shell start + # Show fastfetch on shell start (packages module disabled via config — nix store too slow on cold cache) echo fastfetch echo diff --git a/hosts/heather/caddy.nix b/hosts/heather/caddy.nix index d0bbb0d..6cd49ac 100644 --- a/hosts/heather/caddy.nix +++ b/hosts/heather/caddy.nix @@ -33,6 +33,15 @@ let } ''; + # paseo basicauth — внешний слой. Внутренний: парольная auth самого демона + # (PASEO_PASSWORD, /var/lib/paseo-secrets/paseo.env). Пароли в pass: + # iscg.dev/paseo/basicauth (caddy) и iscg.dev/paseo/daemon (paseo daemon). + paseoBasicAuth = '' + basicauth { + mikl $2a$14$4ZfTWjquFPOoKyq9NA.IJeX9y3lxQO1l0J7iXSnr/.8oqJoblM8jy + } + ''; + in { services.caddy = { enable = true; @@ -125,6 +134,12 @@ Allow: /" 200 reverse_proxy 127.0.0.1:30141 ''; + # paseo (self-hosted web UI для CLI-агентов, systemd paseo.service) + # Два слоя auth: basicauth (здесь) + парольная auth демона (PASEO_PASSWORD). + "paseo.iscg.dev".extraConfig = paseoBasicAuth + '' + reverse_proxy 127.0.0.1:6767 + ''; + # File explorer (directory listing) для раздачи файлов через браузер. # browse включает Caddy's built-in directory listing. Корень /var/www/pub. # Без auth — класть только публичные файлы. diff --git a/hosts/heather/default.nix b/hosts/heather/default.nix index e546a2d..eda8b5f 100644 --- a/hosts/heather/default.nix +++ b/hosts/heather/default.nix @@ -21,6 +21,7 @@ ./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) + ./paseo.nix # paseo daemon (web UI для CLI-агентов, systemd + npm global) ./mesh-clients.nix # Sol-style client pool (wg-clients1) ./mesh-egress.nix # Sol-style selected-destination egress policy ]; diff --git a/hosts/heather/paseo.nix b/hosts/heather/paseo.nix new file mode 100644 index 0000000..f417b39 --- /dev/null +++ b/hosts/heather/paseo.nix @@ -0,0 +1,50 @@ +# heather — paseo daemon (self-hosted web UI для CLI-агентов: pi, codex и др.). +# +# https://github.com/getpaseo/paseo, npm-пакет @getpaseo/cli +# Daemon управляет агентами как дочерними процессами (provider = CLI на хосте, +# со своими кредами). Слушает 127.0.0.1:6767 → Caddy paseo.iscg.dev терминирует +# TLS + basicauth (внешний слой, см. caddy.nix paseoBasicAuth). +# +# Auth два слоя: +# 1) встроенная парольная auth демона (bcrypt, Bearer header + WS subprotocol, +# без пароля — 401). Пароль: PASEO_PASSWORD из EnvironmentFile +# /var/lib/paseo-secrets/paseo.env (mikl:users 600), plaintext в +# pass iscg.dev/paseo/daemon. +# 2) Caddy basicauth, пароль в pass iscg.dev/paseo/basicauth. +# +# Конфиг демона: ~/.paseo/config.json (hostnames: paseo.iscg.dev — DNS rebinding +# protection, webUi enabled, relay off, dictation/voice off — не качать +# speech-модели). Хост-allowlist проверен: чужой Host → 403. +# +# Установка @getpaseo/cli — ручная (npm global в ~/.npm-global, как pi-web): +# npm i -g @getpaseo/cli # node-pty собирается без тулчейна (prebuilds) +# Провайдеры: pi уже стоит (~/.local/bin/pi). + +{ config, pkgs, lib, ... }: +{ + systemd.services.paseo = { + description = "paseo daemon (self-hosted web UI for CLI coding agents)"; + after = [ "network-online.target" ]; + wants = [ "network-online.target" ]; + wantedBy = [ "multi-user.target" ]; + + # PATH: nodejs (node/npm) + ~/.npm-global/bin (paseo) + ~/.local/bin (pi). + path = [ pkgs.nodejs "/home/mikl/.npm-global/bin" "/home/mikl/.local/bin" ]; + + environment = { + PASEO_HOME = "/home/mikl/.paseo"; + HOME = "/home/mikl"; + }; + + serviceConfig = { + Type = "simple"; + User = "mikl"; + Group = "users"; + ExecStart = "/home/mikl/.npm-global/bin/paseo daemon start --foreground --web-ui --no-relay"; + EnvironmentFile = "/var/lib/paseo-secrets/paseo.env"; + WorkingDirectory = "/home/mikl"; + Restart = "on-failure"; + RestartSec = 5; + }; + }; +} diff --git a/hosts/poppy/apps.nix b/hosts/poppy/apps.nix index 2f0e4a8..234ed6d 100644 --- a/hosts/poppy/apps.nix +++ b/hosts/poppy/apps.nix @@ -37,6 +37,7 @@ "element" "prismlauncher" "losslesscut" # lossless-нарезка/remux видео (GUI на базе ffmpeg) + "obs" # запись экрана и окон ]; };