diff --git a/home/server.nix b/home/server.nix index 4d9f4cc..0e030f9 100644 --- a/home/server.nix +++ b/home/server.nix @@ -7,12 +7,35 @@ { home.stateVersion = "25.11"; - # User-level tools installed outside Nix (pi wrapper, etc.). + # User-level tools installed outside Nix (PinchTab, pi wrapper, etc.). home.sessionPath = [ "${config.home.homeDirectory}/.local/bin" "${config.home.homeDirectory}/.local/libexec" ]; + # Keep the browser control plane alive across SSH logout and reboots. + # PinchTab itself is installed outside Nix because its upstream release + # binary is dynamically linked; the local NixOS-compatible build lives in + # ~/.local/libexec/pinchtab. + systemd.user.services.pinchtab = { + Unit = { + Description = "PinchTab browser control plane"; + After = [ "dbus-broker.service" ]; + }; + Service = { + ExecStart = "%h/.local/libexec/pinchtab server"; + Restart = "on-failure"; + RestartSec = 5; + Environment = [ + "HOME=%h" + "PATH=/run/current-system/sw/bin:/home/mikl/.npm-global/bin:/home/mikl/.local/bin:/home/mikl/.local/libexec" + ]; + }; + Install = { + WantedBy = [ "default.target" ]; + }; + }; + home.file.".local/bin/pi" = { executable = true; text = '' @@ -38,9 +61,6 @@ # Редактор vim - # Node.js runtime for the user-installed pi CLI and extensions - nodejs - # Git git tea # Forgejo/Gitea CLI diff --git a/hosts/heather/arion-compose.nix b/hosts/heather/arion-compose.nix index fd12d9b..b52cc5e 100644 --- a/hosts/heather/arion-compose.nix +++ b/hosts/heather/arion-compose.nix @@ -172,7 +172,7 @@ in # /var/lib/tuwunel-secrets/tuwunel.toml (root:docker 0640, bind-mount ro) # Cinny config: /var/lib/tuwunel-secrets/cinny-config.json (bind-mount ro). tuwunel = { - service.image = "ghcr.io/matrix-construct/tuwunel:v1.9.3"; + service.image = "ghcr.io/matrix-construct/tuwunel:v1.7.1"; service.container_name = "tuwunel"; service.restart = "unless-stopped"; service.volumes = [ @@ -231,12 +231,6 @@ in service.image = "teableio/teable@sha256:04c0c041c79564de7c06fc005d5560f9553161557a776caf1ed36c9c38ea8600"; service.container_name = "teable"; service.restart = "unless-stopped"; - # Teable previously had no cgroup limit and helped trigger the host-wide - # OOM on 2026-09-24. Keep its startup/runtime spike from taking down - # SSH, Caddy, and the rest of the server. - # Arion 0.2.2 does not expose mem_limit as a typed option; use its - # raw output escape hatch so docker-compose gets the cgroup limit. - out.service.mem_limit = "2g"; service.ports = [ "127.0.0.1:2345:3000" ]; service.volumes = [ "teable-data:/app/.local-storage" diff --git a/hosts/heather/caddy.nix b/hosts/heather/caddy.nix index d3d1b4b..28104de 100644 --- a/hosts/heather/caddy.nix +++ b/hosts/heather/caddy.nix @@ -119,11 +119,6 @@ Allow: /" 200 reverse_proxy 127.0.0.1:8890 ''; - # Nick timer prototype. Public timer pages; creation has no auth for now. - "timer.michaotic.space".extraConfig = '' - reverse_proxy 127.0.0.1:8787 - ''; - # 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 2d3851a..caad7c1 100644 --- a/hosts/heather/default.nix +++ b/hosts/heather/default.nix @@ -21,31 +21,17 @@ ./syncthing.nix # sync + relay ./tuwunel-admin.nix # matrix admin web UI (systemd, статический бинарник) ./paseo.nix # paseo daemon (web UI для CLI-агентов, systemd + npm global) - ./nick.nix # Nick timer prototype (systemd, localhost:8787) ./jupyter.nix # JupyterLab (systemd, localhost:8890, лимиты) ./mesh-clients.nix # Sol-style client pool (wg-clients1) ./mesh-egress.nix # Sol-style selected-destination egress policy ]; - # Heather has 8 GiB RAM and runs several containers. Keep a 4 GiB - # swapfile so a transient application spike does not take down the host. - swapDevices = [ - { - device = "/var/swapfile"; - size = 4096; - } - ]; - # First server-to-server WireGuard backbone link: heather ↔ hyacinth. # The private key is generated on the live host and stays outside the flake. - # Basic diagnostics/admin tools must be available even in non-login SSH - # sessions (and not depend on a stale Home Manager profile). - environment.systemPackages = with pkgs; [ - wireguard-tools - tmux - jq - wget - python3 + # Chromium для PinchTab: отдельный headless-браузер для agent automation. + environment.systemPackages = [ + pkgs.wireguard-tools + pkgs.chromium ]; # NixOS uses scripted networking here (not systemd-networkd), so create the diff --git a/hosts/heather/nick.nix b/hosts/heather/nick.nix deleted file mode 100644 index 8427012..0000000 --- a/hosts/heather/nick.nix +++ /dev/null @@ -1,31 +0,0 @@ -# Nick timer prototype. -# Source is deployed separately to /home/mikl/sideprojects/other/nick. -# Caddy terminates TLS; the app only listens on localhost. - -{ config, pkgs, lib, ... }: -{ - systemd.services.nick-timer = { - description = "Nick timer prototype"; - after = [ "network-online.target" ]; - wants = [ "network-online.target" ]; - wantedBy = [ "multi-user.target" ]; - - serviceConfig = { - Type = "simple"; - User = "mikl"; - Group = "users"; - WorkingDirectory = "/home/mikl/sideprojects/other/nick"; - ExecStart = "/home/mikl/.nix-profile/bin/python3 /home/mikl/sideprojects/other/nick/app.py"; - Restart = "on-failure"; - RestartSec = 5; - NoNewPrivileges = true; - PrivateTmp = true; - }; - - environment = { - TIMER_HOST = "127.0.0.1"; - TIMER_PORT = "8787"; - TIMER_DB = "/home/mikl/sideprojects/other/nick/data/timer.db"; - }; - }; -} diff --git a/hosts/heather/paseo.nix b/hosts/heather/paseo.nix index 5ca3735..5bef755 100644 --- a/hosts/heather/paseo.nix +++ b/hosts/heather/paseo.nix @@ -34,7 +34,7 @@ # Paseo запускает `ps` при управлении дочерними agent-процессами. # Tool runner также ищет `sh` через PATH; на NixOS нельзя полагаться # на FHS /bin/sh, поэтому добавляем bashInteractive явно. - path = [ "/run/current-system/sw" pkgs.nodejs pkgs.git pkgs.procps pkgs.bashInteractive "/home/mikl/.npm-global" "/home/mikl/.local" ]; + path = [ pkgs.nodejs pkgs.git pkgs.procps pkgs.bashInteractive "/home/mikl/.npm-global" "/home/mikl/.local" ]; environment = { PASEO_HOME = "/home/mikl/.paseo"; @@ -48,9 +48,8 @@ ExecStart = "/home/mikl/.npm-global/bin/paseo daemon start --foreground --no-web-ui --no-relay"; EnvironmentFile = "/var/lib/paseo-secrets/paseo.env"; WorkingDirectory = "/home/mikl"; - Restart = "always"; + Restart = "on-failure"; RestartSec = 5; - StartLimitIntervalSec = 0; }; }; } diff --git a/hosts/heather/pay.nix b/hosts/heather/pay.nix deleted file mode 100644 index 90e49f6..0000000 --- a/hosts/heather/pay.nix +++ /dev/null @@ -1,38 +0,0 @@ -# pay — official Solana Foundation CLI for x402 / MPP payments. -# Source: https://github.com/solana-foundation/pay (upstream prebuilt binaries). -# Аналог ~/.config/nix/home/pay.nix на poppy (nix-darwin). Нужен pi-агентам -# (тулза exa_search платит за вызовы через pay; без него spawn pay ENOENT). -{ stdenv, fetchurl, lib, autoPatchelfHook, openssl }: -let - version = "0.21.0"; - tag = "pay-v${version}"; -in -stdenv.mkDerivation { - pname = "pay"; - inherit version; - - src = fetchurl { - url = "https://github.com/solana-foundation/pay/releases/download/${tag}/pay-x86_64-unknown-linux-gnu.tar.gz"; - sha256 = "1vyf5pw4j7phyffa1aw66ms2j3r983qjj47wlsiyi0sdmwvzy9pi"; - }; - - sourceRoot = "."; - nativeBuildInputs = [ autoPatchelfHook ]; - buildInputs = [ openssl stdenv.cc.cc.lib ]; - dontConfigure = true; - dontBuild = true; - installPhase = '' - runHook preInstall - install -Dm555 pay $out/bin/pay - runHook postInstall - ''; - dontStrip = true; - dontPatchELF = true; - - meta = { - description = "Solana Foundation CLI for x402 / MPP agentic API payments"; - homepage = "https://pay.sh/"; - license = lib.licenses.mit; - mainProgram = "pay"; - }; -}