diff --git a/Justfile b/Justfile index 36714f40..b56fb13f 100644 --- a/Justfile +++ b/Justfile @@ -20,7 +20,7 @@ deploy-rrv-sh: deploy-mercury: nix build --accept-flake-config .#nixosConfigurations.mercury.config.system.build.toplevel nix copy --no-check-sigs --to ssh-ng://rafiq@mercury ./result - ssh rafiq@mercury "sudo $(readlink -f result)/bin/switch-to-configuration switch" + ssh rafiq@mercury "sudo nix-env --profile /nix/var/nix/profiles/system --set $(readlink -f result) && sudo $(readlink -f result)/bin/switch-to-configuration switch" register-aenyrathia-deploy-key: #!/usr/bin/env bash diff --git a/fish/zmx.fish b/fish/zmx.fish index fae9bd54..bd553340 100644 --- a/fish/zmx.fish +++ b/fish/zmx.fish @@ -379,7 +379,7 @@ function zmx-select end set -l current_host (hostname -s) - set -l hosts alpha kikir nemesis + set -l hosts alpha kikir mercury nemesis if not contains -- "$current_host" $hosts set -p hosts "$current_host" end diff --git a/flake.lock b/flake.lock index 2bd80228..7c3b229d 100644 --- a/flake.lock +++ b/flake.lock @@ -113,7 +113,7 @@ }, "cl-nix-lite": { "inputs": { - "flake-parts": "flake-parts_5", + "flake-parts": "flake-parts_4", "nixpkgs": "nixpkgs_5", "systems": "systems_2", "treefmt-nix": "treefmt-nix" @@ -243,27 +243,6 @@ } }, "flake-parts_4": { - "inputs": { - "nixpkgs-lib": [ - "hermes-agent", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1782949081, - "narHash": "sha256-vp6Y/Grm98ESt6ceOkWiHWyZRDV3J1RID4w+6NWK9yA=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "17c9d6cdfc60c64f4ee8d306f9bc0b4ccb51481e", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "flake-parts", - "type": "github" - } - }, - "flake-parts_5": { "inputs": { "nixpkgs-lib": "nixpkgs-lib" }, @@ -281,7 +260,7 @@ "type": "github" } }, - "flake-parts_6": { + "flake-parts_5": { "inputs": { "nixpkgs-lib": [ "pi", @@ -302,7 +281,7 @@ "type": "github" } }, - "flake-parts_7": { + "flake-parts_6": { "inputs": { "nixpkgs-lib": [ "pi-claude-bridge", @@ -323,7 +302,7 @@ "type": "github" } }, - "flake-parts_8": { + "flake-parts_7": { "inputs": { "nixpkgs-lib": "nixpkgs-lib_2" }, @@ -341,7 +320,7 @@ "type": "github" } }, - "flake-parts_9": { + "flake-parts_8": { "inputs": { "nixpkgs-lib": "nixpkgs-lib_3" }, @@ -379,35 +358,6 @@ "type": "indirect" } }, - "hermes-agent": { - "inputs": { - "flake-parts": "flake-parts_4", - "home-manager": [ - "home-manager" - ], - "nixpkgs": [ - "nixpkgs" - ], - "npm-lockfile-fix": "npm-lockfile-fix", - "pyproject-build-systems": "pyproject-build-systems", - "pyproject-nix": "pyproject-nix", - "uv2nix": "uv2nix" - }, - "locked": { - "lastModified": 1788819404, - "narHash": "sha256-2NuDx7rjsoBDO4I/iMoZsJ+5IaAbiNrDc+sFuzOe08w=", - "owner": "NousResearch", - "repo": "hermes-agent", - "rev": "2237be355906fbe6065ce1815711eee52b2d646e", - "type": "github" - }, - "original": { - "owner": "NousResearch", - "repo": "hermes-agent", - "rev": "2237be355906fbe6065ce1815711eee52b2d646e", - "type": "github" - } - }, "home-manager": { "inputs": { "nixpkgs": [ @@ -1188,30 +1138,9 @@ "type": "github" } }, - "npm-lockfile-fix": { - "inputs": { - "nixpkgs": [ - "hermes-agent", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1775903712, - "narHash": "sha256-2GV79U6iVH4gKAPWYrxUReB0S41ty/Y3dBLquU8AlaA=", - "owner": "jeslie0", - "repo": "npm-lockfile-fix", - "rev": "c6093acb0c0548e0f9b8b3d82918823721930fe8", - "type": "github" - }, - "original": { - "owner": "jeslie0", - "repo": "npm-lockfile-fix", - "type": "github" - } - }, "pi": { "inputs": { - "flake-parts": "flake-parts_6", + "flake-parts": "flake-parts_5", "import-tree": "import-tree_3", "nixpkgs": "nixpkgs_10" }, @@ -1231,7 +1160,7 @@ }, "pi-claude-bridge": { "inputs": { - "flake-parts": "flake-parts_7", + "flake-parts": "flake-parts_6", "import-tree": "import-tree_4", "nixpkgs": [ "nixpkgs" @@ -1276,7 +1205,7 @@ }, "pi-session-drain": { "inputs": { - "flake-parts": "flake-parts_8", + "flake-parts": "flake-parts_7", "nixpkgs": [ "nixpkgs" ] @@ -1298,7 +1227,7 @@ }, "pi-slopchop": { "inputs": { - "flake-parts": "flake-parts_9", + "flake-parts": "flake-parts_8", "nixpkgs": [ "nixpkgs" ] @@ -1339,63 +1268,12 @@ "type": "github" } }, - "pyproject-build-systems": { - "inputs": { - "nixpkgs": [ - "hermes-agent", - "nixpkgs" - ], - "pyproject-nix": [ - "hermes-agent", - "pyproject-nix" - ], - "uv2nix": [ - "hermes-agent", - "uv2nix" - ] - }, - "locked": { - "lastModified": 1785115949, - "narHash": "sha256-8AM37BfyGaL2v/SZyg4PupRxJ01Y4htvM+WrTjWrPpo=", - "owner": "pyproject-nix", - "repo": "build-system-pkgs", - "rev": "62c0d86027edb1c4f39a5facc09876348144f7c9", - "type": "github" - }, - "original": { - "owner": "pyproject-nix", - "repo": "build-system-pkgs", - "type": "github" - } - }, - "pyproject-nix": { - "inputs": { - "nixpkgs": [ - "hermes-agent", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1784591072, - "narHash": "sha256-zP/WaDxrRu8GANZM61+V2LT/7ycEEdoyLWn7M6WzU7M=", - "owner": "pyproject-nix", - "repo": "pyproject.nix", - "rev": "e3b599ca2e7fcf93d4edf65d7f19bbf6491724f3", - "type": "github" - }, - "original": { - "owner": "pyproject-nix", - "repo": "pyproject.nix", - "type": "github" - } - }, "root": { "inputs": { "aenyrathia": "aenyrathia", "agent-browser": "agent-browser", "beads": "beads", "flake-parts": "flake-parts_3", - "hermes-agent": "hermes-agent", "home-manager": "home-manager", "homebrew-cask": "homebrew-cask", "homebrew-core": "homebrew-core", @@ -1562,31 +1440,6 @@ "type": "github" } }, - "uv2nix": { - "inputs": { - "nixpkgs": [ - "hermes-agent", - "nixpkgs" - ], - "pyproject-nix": [ - "hermes-agent", - "pyproject-nix" - ] - }, - "locked": { - "lastModified": 1785277507, - "narHash": "sha256-9Tq3UDX2hD/aveW/HvkBlAmEwJTOlY5HQXJM+L5BGmE=", - "owner": "pyproject-nix", - "repo": "uv2nix", - "rev": "5a836d395cbf5fc22670eb98dd4aa4fc4d406977", - "type": "github" - }, - "original": { - "owner": "pyproject-nix", - "repo": "uv2nix", - "type": "github" - } - }, "xdph": { "inputs": { "hyprland-protocols": [ diff --git a/flake.nix b/flake.nix index 0af7ee1d..f361ead5 100644 --- a/flake.nix +++ b/flake.nix @@ -37,11 +37,6 @@ flake-parts.url = "github:hercules-ci/flake-parts"; home-manager.inputs.nixpkgs.follows = "nixpkgs"; home-manager.url = "github:nix-community/home-manager"; - hermes-agent = { - url = "github:NousResearch/hermes-agent/2237be355906fbe6065ce1815711eee52b2d646e"; - inputs.home-manager.follows = "home-manager"; - inputs.nixpkgs.follows = "nixpkgs"; - }; hyprland.url = "github:hyprwm/Hyprland"; # Pin this hypr-dynamic-cursors to Hyprland input - it will break on mismatched revs. hypr-dynamic-cursors = { diff --git a/nix/hosts.nix b/nix/hosts.nix index 4eabcb81..72eb7ae2 100644 --- a/nix/hosts.nix +++ b/nix/hosts.nix @@ -226,7 +226,6 @@ in modules = [ cfg.modules.nixos.user-primary cfg.modules.nixos.vultr-vps - cfg.modules.nixos.hermes-agent ( { lib, ... }: { diff --git a/nix/modules/hermes-agent.nix b/nix/modules/hermes-agent.nix deleted file mode 100644 index 943c0155..00000000 --- a/nix/modules/hermes-agent.nix +++ /dev/null @@ -1,190 +0,0 @@ -{ config, inputs, ... }: -let - cfg = config.flake; - inherit (cfg.paths) root; -in -{ - config.flake.modules.nixos.hermes-agent = - { - config, - hostName, - lib, - pkgs, - ... - }: - let - cheapModel = { - model = "deepseek/deepseek-v4-flash-0731"; - provider = "openrouter"; - }; - delegationModel = { - model = "gpt-5.6-luna"; - provider = "openai-codex"; - }; - beadsPackage = inputs.beads.packages.${pkgs.stdenv.hostPlatform.system}.default; - hardening = { - AmbientCapabilities = ""; - CapabilityBoundingSet = ""; - LockPersonality = true; - MemoryMax = "3G"; - PrivateDevices = true; - ProtectControlGroups = true; - ProtectHome = false; - ProtectKernelModules = true; - ProtectKernelTunables = true; - RestrictAddressFamilies = [ - "AF_INET" - "AF_INET6" - "AF_UNIX" - ]; - RestrictSUIDSGID = true; - SystemCallArchitectures = "native"; - TasksMax = 512; - }; - in - { - imports = [ inputs.hermes-agent.nixosModules.default ]; - services.hermes-agent = { - enable = true; - hermesHomeFiles."skills/issue-ticket-pr-writing/SKILL.md" = - root + "/agents/skills/issue-ticket-pr-writing/SKILL.md"; - addToSystemPackages = true; - package = inputs.hermes-agent.packages.${pkgs.stdenv.hostPlatform.system}.minimal; - extraDependencyGroups = [ "messaging" ]; - backend.mode = "none"; - user = "rafiq"; - group = "users"; - createUser = false; - environmentFiles = [ config.sops.secrets."hermes/env".path ]; - extraPackages = [ - beadsPackage - pkgs.curl - pkgs.jq - pkgs.openssh - pkgs.ripgrep - ]; - settings = { - model = { - default = "gpt-5.6-sol"; - provider = "openai-codex"; - }; - fallback_providers = [ cheapModel ]; - auxiliary = - lib.genAttrs [ - "approval" - "compression" - "curator" - "goal_judge" - "kanban_decomposer" - "mcp" - "memory_query_rewrite" - "moa_aggregator" - "moa_reference" - "monitor" - "profile_describer" - "skills_hub" - "title_generation" - "triage_specifier" - "tts_audio_tags" - "web_extract" - ] (_: cheapModel) - // { - background_review = cheapModel // { - enabled = true; - }; - vision = { - model = "qwen/qwen3.7-flash"; - provider = "openrouter"; - }; - }; - delegation = delegationModel; - mcp_servers = { - atlassian = { - url = "https://mcp.atlassian.com/v2/mcp"; - auth = "oauth"; - connect_timeout = 3660; - oauth = { - flow = "browser"; - timeout = 3600; - }; - sampling.enabled = false; - }; - linear = { - url = "https://mcp.linear.app/mcp"; - auth = "oauth"; - sampling.enabled = false; - }; - }; - memory.write_approval = true; - skills.write_approval = true; - cron = { - model = "gpt-5.6-sol"; - model_provider = "openai-codex"; - }; - }; - }; - sops.secrets."hermes/env" = { - sopsFile = root + "/sops/hermes.yaml"; - owner = "rafiq"; - group = "users"; - mode = "0400"; - }; - systemd = { - services = { - hermes-agent = { - environment = { - BD_DISABLE_EVENT_FLUSH = "1"; - BD_DISABLE_METRICS = "1"; - BEADS_ACTOR = hostName; - HOME = lib.mkForce "/home/rafiq"; - }; - serviceConfig = hardening // { - ReadWritePaths = lib.mkForce [ - "/var/lib/hermes" - "/home/rafiq" - ]; - }; - }; - hermes-agent-daily-maintenance = { - description = "Clean Hermes build outputs and restart Hermes Agent"; - path = [ pkgs.systemd ]; - script = '' - trap 'systemctl start hermes-agent.service' EXIT - systemctl stop hermes-agent.service - ${ - cfg.packages.${pkgs.stdenv.hostPlatform.system}.hermes-workspace-cleanup - }/bin/hermes-workspace-cleanup \ - /var/lib/hermes/workspace \ - /run/hermes-agent-daily-maintenance - systemctl start hermes-agent.service - trap - EXIT - ''; - serviceConfig = hardening // { - CapabilityBoundingSet = [ - "CAP_DAC_OVERRIDE" - "CAP_FOWNER" - ]; - ExecStopPost = "${pkgs.systemd}/bin/systemctl start hermes-agent.service"; - PrivateTmp = true; - ProtectHome = true; - ProtectSystem = "strict"; - ReadWritePaths = [ "/var/lib/hermes/workspace" ]; - RestrictAddressFamilies = [ "AF_UNIX" ]; - RuntimeDirectory = "hermes-agent-daily-maintenance"; - RuntimeDirectoryMode = "0700"; - Type = "oneshot"; - UMask = "0077"; - }; - }; - }; - timers.hermes-agent-daily-maintenance = { - description = "Run daily Hermes maintenance at 02:00 Asia/Singapore"; - wantedBy = [ "timers.target" ]; - timerConfig = { - OnCalendar = "*-*-* 02:00:00 Asia/Singapore"; - Persistent = true; - }; - }; - }; - }; -} diff --git a/nix/packages/hermes-workspace-cleanup.nix b/nix/packages/hermes-workspace-cleanup.nix deleted file mode 100644 index b194ea38..00000000 --- a/nix/packages/hermes-workspace-cleanup.nix +++ /dev/null @@ -1,22 +0,0 @@ -{ config, ... }: -let - inherit (config.flake.paths) root; -in -{ - perSystem = - { lib, pkgs, ... }: - { - packages = lib.optionalAttrs pkgs.stdenv.isLinux { - hermes-workspace-cleanup = pkgs.writeShellApplication { - name = "hermes-workspace-cleanup"; - runtimeInputs = with pkgs; [ - coreutils - findutils - jq - util-linux - ]; - text = builtins.readFile (root + /nix/scripts/hermes-workspace-cleanup.sh); - }; - }; - }; -} diff --git a/nix/profiles/development.nix b/nix/profiles/development.nix index 21385d81..0c7f3489 100644 --- a/nix/profiles/development.nix +++ b/nix/profiles/development.nix @@ -129,6 +129,7 @@ in agentsIgnorePatterns = [ "/.session-drain/" "/.session-drain/**" + "/worktrees" "**/.cargo-home/" "**/.cargo-home/**" "**/.venv/" diff --git a/nix/scripts/hermes-workspace-cleanup.sh b/nix/scripts/hermes-workspace-cleanup.sh deleted file mode 100644 index 09a9dc63..00000000 --- a/nix/scripts/hermes-workspace-cleanup.sh +++ /dev/null @@ -1,84 +0,0 @@ -if (( $# != 2 )); then - echo "usage: hermes-workspace-cleanup WORKSPACE SNAPSHOT_DIRECTORY" >&2 - exit 64 -fi - -workspace=$(readlink -e -- "$1") -snapshot=$2 -if [[ ! -d "$workspace" || "$workspace" != /* || "$snapshot" != /* ]]; then - echo "workspace and snapshot directory must be existing absolute directories" >&2 - exit 64 -fi - -findmnt --task 1 --json --output TARGET >"$snapshot/findmnt.json" -jq --raw-output0 -e \ - '.filesystems[] | recurse(.children[]?) | .target' \ - "$snapshot/findmnt.json" >"$snapshot/targets" -[[ -s "$snapshot/targets" ]] - -find "$workspace" -xdev -type d \ - \( -name target -o -name node_modules -o -name .venv -o -name .cargo-home \) \ - -prune -print0 >"$snapshot/candidates" -while IFS= read -r -d "" path; do - generated="" - case "${path##*/}" in - target) - [[ -f "$path/CACHEDIR.TAG" || -f "$path/.rustc_info.json" ]] && generated=1 - ;; - node_modules) - [[ -d "$path/.bin" || -f "$path/.package-lock.json" ]] && generated=1 - ;; - .venv) - [[ -f "$path/pyvenv.cfg" ]] && generated=1 - ;; - .cargo-home) - [[ -d "$path/registry" || -d "$path/git" ]] && generated=1 - ;; - esac - if [[ -z "$generated" ]]; then - echo "Skipping unrecognized build directory: $path" >&2 - continue - fi - - has_mount="" - while IFS= read -r -d "" mount; do - if - [[ "$mount" == "$path" || "$mount" == "$path/"* ]] \ - || [[ "$mount" != "/" && "$path" == "$mount/"* ]] - then - has_mount=1 - break - fi - done <"$snapshot/targets" - if [[ -n "$has_mount" ]]; then - echo "Skipping build directory with a mount: $path" >&2 - continue - fi - - find "$path" -xdev -mmin -60 -print0 -quit >"$snapshot/recent" - if [[ -s "$snapshot/recent" ]]; then - echo "Skipping recently active build directory: $path" >&2 - continue - fi - - referenced="" - for reference in \ - /proc/[0-9]*/cwd \ - /proc/[0-9]*/root \ - /proc/[0-9]*/exe \ - /proc/[0-9]*/fd/* \ - /proc/[0-9]*/map_files/* - do - resolved=$(readlink -f -- "$reference" 2>/dev/null) || continue - if [[ "$resolved" == "$path" || "$resolved" == "$path/"* ]]; then - referenced=1 - break - fi - done - if [[ -n "$referenced" ]]; then - echo "Skipping process-referenced build directory: $path" >&2 - continue - fi - - rm -rf --one-file-system -- "$path" -done <"$snapshot/candidates" diff --git a/sops/hermes.yaml b/sops/hermes.yaml deleted file mode 100644 index f0fbc88a..00000000 --- a/sops/hermes.yaml +++ /dev/null @@ -1,17 +0,0 @@ -hermes: - env: ENC[AES256_GCM,data:5Jg+IMsKQi+PAUMw0Uj1JXDMvvLl0tSLsW3AwaOJhb2L3KtE6qUTJaeSONlAiXG4qHeK02Jxc5CTUfsDsr0g914RjqSDbRbqi1vK6jK+JHAQSqQEL4y6DCFQJhTW/l+wuESP28PmR9/CQSr5ymJpw6EZQ5TwZeWG4BIg99P9tAYSBa+GpeTWddrXUzknMb3bZJvpugWHpc8E1ck6j3sNXhj1zACjJCL5FpryDLBmcXw9kBgXaFoHjPX4z9RY6Ulk,iv:O97FTVb3V2hQ5KYxn9b9eL7p0MHcjEwsi74ZcW+y1n4=,tag:Gef+c9M55v+QxaPfvLB1pA==,type:str] -sops: - age: - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBPcmNTNnRnZWpUOG10bDJO - MXRMdFB0dTAydS8rVnNHSjhaVEsrNFdsQkZrCks2RGw2ZUlEUHZjWVBYdU8xUWlm - NjZvdTVYT2RGdUdHSldGbDlZWDVoZlEKLS0tIG5hd042WHhIclJUakFuQ0tMU3R1 - QlcySFNyUHpiTWtOWTNaT3cyNDF2VG8Kfx4WzYcR/Z3lN+cRImt7+mygCnSoutpq - QDhWkOIiyEGO+k6Vg3g0X4va5lKWErlYifuweqoH0plc7RDHyRrumw== - -----END AGE ENCRYPTED FILE----- - recipient: age12l33pas8eptwjc7ewux3d8snyzfzwz0tn9qg5kw8le79fswmjgjqdjgyy6 - lastmodified: "2026-08-20T01:47:45Z" - mac: ENC[AES256_GCM,data:ezvro1OIRsFaKGWZm0iUwXBBHWuSs4tI2oWCzqz3MDzGF/SCT1GCj3iBD1T94d28tq3whd6LeOgbFXeSlwuYAbcHiNkXr5/z3f7ioTo0QpixKeVHkmfOf0jy1ufHpfHr28ROeaS/0HBeKy0NosozmAWFSlm7ItLSF0G9z6SNUwY=,iv:n/1cD7iCXzi4FopdbLppTOspo1KO2n7YgqcrLI+PzfU=,tag:ocfES6ElnlQwJSVucJz8Tw==,type:str] - unencrypted_suffix: _unencrypted - version: 3.13.3