feat: add yolo host
New NixOS VM on proxmox, replacing the Ubuntu box. Reuses the existing Hyprland config; remote access is Sunshine/Moonlight rather than xrdp, since xrdp cannot drive a wayland compositor. Two fixes here are not yolo-specific and affect any fresh install: git at system level (nix needs it for the type = "git" hyprland input, but git only came from home-manager, so neither rebuild could run), and dropping the yogurt input, whose private repo made home-manager un-evaluatable without GitHub auth. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Generated
+232
-43
@@ -1,5 +1,26 @@
|
||||
{
|
||||
"nodes": {
|
||||
"agent-of-empires": {
|
||||
"inputs": {
|
||||
"crane": "crane",
|
||||
"flake-parts": "flake-parts",
|
||||
"nixpkgs": "nixpkgs"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1786554876,
|
||||
"narHash": "sha256-akMknOIdX0QsBsM4lgreXSNNym7TNu9iOrDBqrQuTuQ=",
|
||||
"owner": "agent-of-empires",
|
||||
"repo": "agent-of-empires",
|
||||
"rev": "9b0d691a6cdaa6d2451f6eda05e83628c54eb95a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "agent-of-empires",
|
||||
"ref": "v1.14.1",
|
||||
"repo": "agent-of-empires",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"aquamarine": {
|
||||
"inputs": {
|
||||
"hyprutils": [
|
||||
@@ -36,7 +57,7 @@
|
||||
"claude-code": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs"
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1785285785,
|
||||
@@ -82,11 +103,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1785336468,
|
||||
"narHash": "sha256-zVeyr06Ra4+NUhMzkaxLmYGdgKhw9DuMR89jpzws82k=",
|
||||
"lastModified": 1786822283,
|
||||
"narHash": "sha256-RdoFKwNQ2m2zbHnq/QbgLf2lUI9cohsnlMwLfJuaTh0=",
|
||||
"owner": "ilysenko",
|
||||
"repo": "codex-desktop-linux",
|
||||
"rev": "dc479a4caca73b2a29fe2f2945e72bdedde5a12c",
|
||||
"rev": "e6b51d96ac2b9b5d9adafa852241bd0982972557",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -95,9 +116,24 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"crane": {
|
||||
"locked": {
|
||||
"lastModified": 1771796463,
|
||||
"narHash": "sha256-9bCDuUzpwJXcHMQYMS1yNuzYMmKO/CCwCexpjWOl62I=",
|
||||
"owner": "ipetkov",
|
||||
"repo": "crane",
|
||||
"rev": "3d3de3313e263e04894f284ac18177bd26169bad",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "ipetkov",
|
||||
"repo": "crane",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"ethui": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs_2",
|
||||
"nixpkgs": "nixpkgs_3",
|
||||
"rust": "rust",
|
||||
"utils": "utils"
|
||||
},
|
||||
@@ -132,6 +168,42 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-parts": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": "nixpkgs-lib"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1769996383,
|
||||
"narHash": "sha256-AnYjnFWgS49RlqX7LrC4uA+sCCDBj0Ry/WOJ5XWAsa0=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "57928607ea566b5db3ad13af0e57e921e6b12381",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-parts_2": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": "nixpkgs-lib_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1775087534,
|
||||
"narHash": "sha256-91qqW8lhL7TLwgQWijoGBbiD4t7/q75KTi8NxjVmSmA=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "3107b77cd68437b9a76194f0f7f9c55f2329ca5b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
@@ -201,6 +273,24 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils_5": {
|
||||
"inputs": {
|
||||
"systems": "systems_8"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"foundry": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils_4",
|
||||
@@ -353,7 +443,7 @@
|
||||
"hyprutils": "hyprutils",
|
||||
"hyprwayland-scanner": "hyprwayland-scanner",
|
||||
"hyprwire": "hyprwire",
|
||||
"nixpkgs": "nixpkgs_4",
|
||||
"nixpkgs": "nixpkgs_5",
|
||||
"pre-commit-hooks": "pre-commit-hooks",
|
||||
"systems": "systems_5",
|
||||
"xdph": "xdph"
|
||||
@@ -648,6 +738,52 @@
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1781074563,
|
||||
"narHash": "sha256-md8WlXOlfnIeHeOScMTTHFyf2d6iaTwPl2apR5EQ3P4=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "9ae611a455b90cf061d8f332b977e387bda8e1ca",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-lib": {
|
||||
"locked": {
|
||||
"lastModified": 1769909678,
|
||||
"narHash": "sha256-cBEymOf4/o3FD5AZnzC3J9hLbiZ+QDT/KDuyHXVJOpM=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nixpkgs.lib",
|
||||
"rev": "72716169fe93074c333e8d0173151350670b824c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "nixpkgs.lib",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-lib_2": {
|
||||
"locked": {
|
||||
"lastModified": 1774748309,
|
||||
"narHash": "sha256-+U7gF3qxzwD5TZuANzZPeJTZRHS29OFQgkQ2kiTJBIQ=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nixpkgs.lib",
|
||||
"rev": "333c4e0545a6da976206c74db8773a1645b5870a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "nixpkgs.lib",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1784783405,
|
||||
"narHash": "sha256-4IHyyLgLBdKefkljdKod4IMn023pQiDXAWJA187cmdY=",
|
||||
@@ -663,7 +799,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"nixpkgs_3": {
|
||||
"locked": {
|
||||
"lastModified": 1764517877,
|
||||
"narHash": "sha256-pp3uT4hHijIC8JUK5MEqeAWmParJrgBVzHLNfJDZxg4=",
|
||||
@@ -679,7 +815,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_3": {
|
||||
"nixpkgs_4": {
|
||||
"locked": {
|
||||
"lastModified": 1744536153,
|
||||
"narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=",
|
||||
@@ -695,7 +831,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_4": {
|
||||
"nixpkgs_5": {
|
||||
"locked": {
|
||||
"lastModified": 1784356753,
|
||||
"narHash": "sha256-12KrbMiWLcf8m7pCvAtZh1ZrgF85ZXDXvfR/fWTKy84=",
|
||||
@@ -711,7 +847,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_5": {
|
||||
"nixpkgs_6": {
|
||||
"locked": {
|
||||
"lastModified": 1785090369,
|
||||
"narHash": "sha256-m0pDuRJG7EDo9ri+4Ksu83VsI+PlxNC9lNBfydejce4=",
|
||||
@@ -727,18 +863,34 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_6": {
|
||||
"nixpkgs_7": {
|
||||
"locked": {
|
||||
"lastModified": 1751274312,
|
||||
"narHash": "sha256-/bVBlRpECLVzjV19t5KMdMFWSwKLtb5RyXdjz3LJT+g=",
|
||||
"lastModified": 1775036866,
|
||||
"narHash": "sha256-ZojAnPuCdy657PbTq5V0Y+AHKhZAIwSIT2cb8UgAz/U=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "50ab793786d9de88ee30ec4e4c24fb4236fc2674",
|
||||
"rev": "6201e203d09599479a3b3450ed24fa81537ebc4e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-24.11",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_8": {
|
||||
"locked": {
|
||||
"lastModified": 1744536153,
|
||||
"narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "18dd725c29603f582cf1900e0d25f9f1063dbf11",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
@@ -826,6 +978,7 @@
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"agent-of-empires": "agent-of-empires",
|
||||
"claude-code": "claude-code",
|
||||
"codex-cli": "codex-cli",
|
||||
"codex-desktop-linux": "codex-desktop-linux",
|
||||
@@ -835,14 +988,14 @@
|
||||
"home-manager": "home-manager",
|
||||
"hyprland": "hyprland",
|
||||
"nix-index-database": "nix-index-database",
|
||||
"nixpkgs": "nixpkgs_5",
|
||||
"nixpkgs": "nixpkgs_6",
|
||||
"noctalia": "noctalia",
|
||||
"nvchad-starter": "nvchad-starter",
|
||||
"nvchad4nix": "nvchad4nix",
|
||||
"rose-pine-hyprcursor": "rose-pine-hyprcursor",
|
||||
"sem": "sem",
|
||||
"spicetify-nix": "spicetify-nix",
|
||||
"systems": "systems_9",
|
||||
"yogurt": "yogurt",
|
||||
"systems": "systems_10",
|
||||
"zen-browser": "zen-browser"
|
||||
}
|
||||
},
|
||||
@@ -870,7 +1023,7 @@
|
||||
},
|
||||
"rust": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs_3"
|
||||
"nixpkgs": "nixpkgs_4"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1764729618,
|
||||
@@ -886,12 +1039,51 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"rust-overlay": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs_8"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1775445266,
|
||||
"narHash": "sha256-3fgIj85WHQbOamrpIw9WY3ZL1PoEvjPOjmzMYNsEQJo=",
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "61747bc3cf2da179b9af356ae9e70f3b895b0c24",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"sem": {
|
||||
"inputs": {
|
||||
"flake-parts": "flake-parts_2",
|
||||
"flake-utils": "flake-utils_5",
|
||||
"nixpkgs": "nixpkgs_7",
|
||||
"rust-overlay": "rust-overlay"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1786903203,
|
||||
"narHash": "sha256-MaISe6TG4I5zb6hSRsBj5ENe5JSh7MjQ+QIDWDhxTo0=",
|
||||
"owner": "Ataraxy-Labs",
|
||||
"repo": "sem",
|
||||
"rev": "ba2dfbbe75836cfe6f69dc036c9060b7ce5cc158",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "Ataraxy-Labs",
|
||||
"repo": "sem",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"spicetify-nix": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"systems": "systems_8"
|
||||
"systems": "systems_9"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1785048222,
|
||||
@@ -922,6 +1114,21 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"systems_10": {
|
||||
"locked": {
|
||||
"lastModified": 1689347949,
|
||||
"narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default-linux",
|
||||
"rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default-linux",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"systems_2": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
@@ -1029,16 +1236,16 @@
|
||||
},
|
||||
"systems_9": {
|
||||
"locked": {
|
||||
"lastModified": 1689347949,
|
||||
"narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=",
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default-linux",
|
||||
"rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default-linux",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
@@ -1119,24 +1326,6 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"yogurt": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs_6"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1783264766,
|
||||
"narHash": "sha256-1iD8gdvxBYBfffHhNsnZPnPGDDttYVRUhghLbAa1Mho=",
|
||||
"ref": "refs/heads/main",
|
||||
"rev": "515ab16c76fc0779a1c6be93cfa1424a901373cb",
|
||||
"revCount": 67,
|
||||
"type": "git",
|
||||
"url": "https://github.com/ZePedroResende/yogurt"
|
||||
},
|
||||
"original": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ZePedroResende/yogurt"
|
||||
}
|
||||
},
|
||||
"zen-browser": {
|
||||
"inputs": {
|
||||
"home-manager": "home-manager_2",
|
||||
|
||||
@@ -66,7 +66,12 @@
|
||||
url = "github:ilysenko/codex-desktop-linux";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
yogurt.url = "git+https://github.com/ZePedroResende/yogurt";
|
||||
# Pinned to the tag, and pins its own nixpkgs for the same reason ethui does
|
||||
# — it is a verified Rust build. Bump deliberately, not via `flake update`.
|
||||
agent-of-empires.url = "github:agent-of-empires/agent-of-empires/v1.14.1";
|
||||
# Semantic-diff tool rev calls via REV_SEM_BIN. NOT nixpkgs' `sem`, which is
|
||||
# the unrelated Semaphore CI cli.
|
||||
sem.url = "github:Ataraxy-Labs/sem";
|
||||
nix-index-database = {
|
||||
url = "github:nix-community/nix-index-database";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
@@ -124,6 +129,7 @@
|
||||
nixosConfigurations = {
|
||||
arrakis = mkNixOS "arrakis";
|
||||
konishi = mkNixOS "konishi";
|
||||
yolo = mkNixOS "yolo";
|
||||
};
|
||||
|
||||
# Named "<user>@<host>" so `nh home switch` auto-detects them
|
||||
@@ -131,6 +137,7 @@
|
||||
homeConfigurations = {
|
||||
"naps62@arrakis" = mkHome "arrakis" x86;
|
||||
"naps62@konishi" = mkHome "konishi" x86;
|
||||
"naps62@yolo" = mkHome "yolo" x86;
|
||||
};
|
||||
|
||||
devShells =
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
lib,
|
||||
pkgs,
|
||||
config,
|
||||
inputs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
@@ -34,7 +33,6 @@
|
||||
|
||||
packages = with pkgs; [
|
||||
impala
|
||||
inputs.yogurt.packages.${pkgs.system}.default
|
||||
];
|
||||
|
||||
username = lib.mkDefault "naps62";
|
||||
|
||||
@@ -154,7 +154,6 @@ in
|
||||
hl.exec_cmd("hyprctl setcursor Nordzy-cursors ${toString cfg.cursorSize}")
|
||||
hl.exec_cmd("hyprsunset")
|
||||
hl.exec_cmd("noctalia")
|
||||
hl.exec_cmd("yogurt --tray")
|
||||
end)
|
||||
|
||||
-- layer rules
|
||||
|
||||
Executable
+158
@@ -0,0 +1,158 @@
|
||||
#!/usr/bin/env bash
|
||||
# Manage the live list of Claude Code Remote Control projects.
|
||||
# The projects file is the source of truth; sync reconciles systemd to match.
|
||||
set -euo pipefail
|
||||
|
||||
LIST="${CLAUDE_RC_LIST:-$HOME/.config/claude-rc/projects}"
|
||||
UNIT=claude-rc
|
||||
|
||||
die() { echo "claude-rc: $*" >&2; exit 1; }
|
||||
|
||||
# configured paths: strip comments, an optional "| Display Name" suffix,
|
||||
# surrounding space, and any trailing slash.
|
||||
wanted_paths() {
|
||||
[ -f "$LIST" ] || return 0
|
||||
sed -e 's/#.*//' -e 's/|.*//' -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' "$LIST" \
|
||||
| grep -v '^$' \
|
||||
| sed -e 's#/\+$##' \
|
||||
| sort -u
|
||||
}
|
||||
|
||||
# display name for a path, if the list defines one
|
||||
name_for() {
|
||||
[ -f "$LIST" ] || return 0
|
||||
awk -F'|' -v t="$1" '
|
||||
{ line=$0; sub(/#.*/,"",line)
|
||||
p=line; if (index(line,"|")) { p=substr(line,1,index(line,"|")-1) }
|
||||
gsub(/^[[:space:]]+|[[:space:]]+$/,"",p); sub(/\/+$/,"",p)
|
||||
if (p == t && index(line,"|")) {
|
||||
n=substr(line,index(line,"|")+1)
|
||||
gsub(/^[[:space:]]+|[[:space:]]+$/,"",n)
|
||||
if (n != "") { print n; exit }
|
||||
}
|
||||
}' "$LIST" 2>/dev/null
|
||||
}
|
||||
|
||||
# instance names systemd should have enabled
|
||||
wanted_units() {
|
||||
wanted_paths | while read -r p; do
|
||||
printf '%s@%s.service\n' "$UNIT" "$(systemd-escape -p "$p")"
|
||||
done | sort -u
|
||||
}
|
||||
|
||||
# instance names systemd currently has
|
||||
current_units() {
|
||||
systemctl --user list-units --all --no-legend --plain "${UNIT}@*.service" 2>/dev/null \
|
||||
| awk '{print $1}' | sort -u
|
||||
}
|
||||
|
||||
cmd_sync() {
|
||||
local want have add rm
|
||||
want=$(wanted_units); have=$(current_units)
|
||||
add=$(comm -23 <(printf '%s\n' "$want") <(printf '%s\n' "$have") | grep -v '^$' || true)
|
||||
rm=$(comm -13 <(printf '%s\n' "$want") <(printf '%s\n' "$have") | grep -v '^$' || true)
|
||||
|
||||
if [ -n "$rm" ]; then
|
||||
while read -r u; do
|
||||
echo "- stop $u"
|
||||
systemctl --user disable --now "$u" >/dev/null 2>&1 || true
|
||||
done <<<"$rm"
|
||||
fi
|
||||
if [ -n "$add" ]; then
|
||||
while read -r u; do
|
||||
echo "+ start $u"
|
||||
systemctl --user enable --now "$u" >/dev/null 2>&1 \
|
||||
|| echo " FAILED: $u (see: claude-rc log $u)" >&2
|
||||
done <<<"$add"
|
||||
fi
|
||||
[ -z "$add$rm" ] && echo "in sync ($(wanted_paths | grep -c . || true) projects)"
|
||||
return 0
|
||||
}
|
||||
|
||||
cmd_list() {
|
||||
local n=0
|
||||
printf '%-46s %-9s %s\n' PROJECT STATE GIT
|
||||
while read -r p; do
|
||||
n=$((n+1))
|
||||
local u state git
|
||||
u="${UNIT}@$(systemd-escape -p "$p").service"
|
||||
state=$(systemctl --user is-active "$u" 2>/dev/null || true)
|
||||
if [ ! -d "$p" ]; then git="MISSING DIR"
|
||||
elif git -C "$p" rev-parse --git-dir >/dev/null 2>&1; then git="worktree"
|
||||
else git="same-dir (not git)"; fi
|
||||
printf '%-46s %-9s %s\n' "${p/#$HOME/\~}" "$state" "$git"
|
||||
done < <(wanted_paths)
|
||||
[ "$n" = 0 ] && echo "(no projects configured; claude-rc add <path>)"
|
||||
return 0
|
||||
}
|
||||
|
||||
cmd_add() {
|
||||
local p="${1:-$PWD}"
|
||||
p=$(cd "$p" 2>/dev/null && pwd) || die "no such directory: ${1:-$PWD}"
|
||||
if wanted_paths | grep -qxF "$p"; then echo "already listed: $p"; return 0; fi
|
||||
# revive a commented-out entry if present, else append; keeps the file tidy
|
||||
# across add/rm cycles instead of accumulating dead duplicates.
|
||||
if awk -v t="$p" '
|
||||
{ l=$0; sub(/^[[:space:]]*#[[:space:]]*/,"",l); sub(/\/+$/,"",l)
|
||||
gsub(/^[[:space:]]+|[[:space:]]+$/,"",l)
|
||||
if ($0 ~ /^[[:space:]]*#/ && l == t) found=1 }
|
||||
END { exit !found }' "$LIST"; then
|
||||
awk -v t="$p" '
|
||||
{ l=$0; sub(/^[[:space:]]*#[[:space:]]*/,"",l); sub(/\/+$/,"",l)
|
||||
gsub(/^[[:space:]]+|[[:space:]]+$/,"",l)
|
||||
if (!done && $0 ~ /^[[:space:]]*#/ && l == t) { print t; done=1 }
|
||||
else print $0 }
|
||||
' "$LIST" > "$LIST.tmp" && mv "$LIST.tmp" "$LIST"
|
||||
else
|
||||
printf '%s\n' "$p" >> "$LIST"
|
||||
fi
|
||||
echo "added: $p"
|
||||
cmd_sync
|
||||
}
|
||||
|
||||
cmd_rm() {
|
||||
local p="${1:?usage: claude-rc rm <path>}"
|
||||
p=$(cd "$p" 2>/dev/null && pwd) || p="${p%/}"
|
||||
wanted_paths | grep -qxF "$p" || die "not listed: $p"
|
||||
# comment out rather than delete, so the entry is easy to restore.
|
||||
# awk, not sed: the path is data, so no regex metachar/delimiter escaping.
|
||||
awk -v target="$p" '
|
||||
{
|
||||
line = $0
|
||||
sub(/#.*/, "", line)
|
||||
gsub(/^[[:space:]]+|[[:space:]]+$/, "", line)
|
||||
sub(/\/+$/, "", line)
|
||||
if (line != "" && line == target) print "# " $0
|
||||
else print $0
|
||||
}
|
||||
' "$LIST" > "$LIST.tmp" && mv "$LIST.tmp" "$LIST"
|
||||
echo "removed: $p"
|
||||
cmd_sync
|
||||
}
|
||||
|
||||
cmd_edit() { "${EDITOR:-vi}" "$LIST"; cmd_sync; }
|
||||
cmd_log() {
|
||||
local p="${1:?usage: claude-rc log <path>}"
|
||||
p=$(cd "$p" 2>/dev/null && pwd) || die "no such directory: $p"
|
||||
journalctl --user -u "${UNIT}@$(systemd-escape -p "$p").service" -n 40 --no-pager
|
||||
}
|
||||
|
||||
case "${1:-list}" in
|
||||
sync) cmd_sync ;;
|
||||
list|ls|status) cmd_list ;;
|
||||
add) shift; cmd_add "${1:-}" ;;
|
||||
rm|remove|del) shift; cmd_rm "${1:-}" ;;
|
||||
edit) cmd_edit ;;
|
||||
log|logs) shift; cmd_log "${1:-}" ;;
|
||||
*) cat >&2 <<EOF
|
||||
usage: claude-rc <cmd>
|
||||
list projects + running state (default)
|
||||
add [path] add project (default: cwd)
|
||||
rm <path> remove project (comments it out)
|
||||
edit \$EDITOR the list, then sync
|
||||
sync force reconcile
|
||||
log <path> journal for one project
|
||||
list file: $LIST
|
||||
EOF
|
||||
exit 1 ;;
|
||||
esac
|
||||
Executable
+40
@@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env bash
|
||||
# Launch a Claude Code Remote Control server for one project dir.
|
||||
# Invoked by claude-rc@.service; arg is the project path.
|
||||
set -euo pipefail
|
||||
|
||||
dir="${1:?usage: claude-rc-run <project-dir>}"
|
||||
|
||||
if [ ! -d "$dir" ]; then
|
||||
echo "claude-rc-run: no such directory: $dir" >&2
|
||||
exit 78 # EX_CONFIG - systemd won't spin on Restart=on-failure
|
||||
fi
|
||||
|
||||
# --spawn worktree needs a git repo; fall back to same-dir if not one
|
||||
spawn=worktree
|
||||
git -C "$dir" rev-parse --git-dir >/dev/null 2>&1 || {
|
||||
echo "claude-rc-run: $dir is not a git repo, using --spawn same-dir" >&2
|
||||
spawn=same-dir
|
||||
}
|
||||
|
||||
# Optional display name: a projects-file line may read
|
||||
# /path/to/repo | My Display Name
|
||||
# Falls back to the bare directory name.
|
||||
LIST="${CLAUDE_RC_LIST:-$HOME/.config/claude-rc/projects}"
|
||||
name=$(awk -F'|' -v t="$dir" '
|
||||
{ line=$0; sub(/#.*/,"",line)
|
||||
p=line; if (index(line,"|")) { p=substr(line,1,index(line,"|")-1) }
|
||||
gsub(/^[[:space:]]+|[[:space:]]+$/,"",p); sub(/\/+$/,"",p)
|
||||
if (p == t && index(line,"|")) {
|
||||
n=substr(line,index(line,"|")+1)
|
||||
gsub(/^[[:space:]]+|[[:space:]]+$/,"",n)
|
||||
if (n != "") { print n; exit }
|
||||
}
|
||||
}' "$LIST" 2>/dev/null || true)
|
||||
[ -n "$name" ] || name="$(basename "$dir")"
|
||||
|
||||
cd "$dir"
|
||||
exec claude remote-control \
|
||||
--spawn "$spawn" \
|
||||
--permission-mode bypassPermissions \
|
||||
--name "$name"
|
||||
@@ -0,0 +1,36 @@
|
||||
{
|
||||
pkgs,
|
||||
inputs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
imports = [
|
||||
../common/programs/default.nix
|
||||
../common/programs/desktop
|
||||
../common/programs/zen-browser.nix
|
||||
../common/programs/hyprland
|
||||
../common/programs/kitty
|
||||
../common/programs/gpg.nix
|
||||
../common/features/xdg.nix
|
||||
../common/features/downloads-cleanup.nix
|
||||
./monitors.nix
|
||||
./services.nix
|
||||
];
|
||||
|
||||
custom.hyprland.cursorSize = 32;
|
||||
|
||||
# The agent session manager the hourlog/week-review timers drive. Was a
|
||||
# hand-installed binary in ~/.local/bin on the Ubuntu box.
|
||||
home.packages = [ inputs.agent-of-empires.packages.${pkgs.system}.default ];
|
||||
|
||||
# Blur and shadow cost a fullscreen pass per frame, and every frame here is
|
||||
# also x264-encoded for the stream — on a virtio-gpu with no VirGL, in software.
|
||||
wayland.windowManager.hyprland.extraConfig = ''
|
||||
hl.config({
|
||||
decoration = {
|
||||
blur = { enabled = false },
|
||||
shadow = { enabled = false },
|
||||
},
|
||||
})
|
||||
'';
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
_:
|
||||
{
|
||||
# Hyprland 0.55+ is Lua-only (see home/common/programs/hyprland).
|
||||
#
|
||||
# Matches every output rather than naming one: the virtio-gpu connector name
|
||||
# varies by qemu display backend (Virtual-1 vs Virtual-0). Explicit mode, not
|
||||
# `preferred` — this is the resolution Sunshine streams.
|
||||
wayland.windowManager.hyprland.extraConfig = ''
|
||||
hl.monitor({ output = "", mode = "2560x1440@60", position = "0x0", scale = 1 })
|
||||
'';
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
{
|
||||
pkgs,
|
||||
inputs,
|
||||
...
|
||||
}:
|
||||
# The user services this box exists to run, ported from hand-written units in
|
||||
# ~/.config/systemd/user on the Ubuntu machine.
|
||||
#
|
||||
# NOT self-contained: every ExecStart under ~/.bun or ~/.local/bin is an
|
||||
# imperatively-installed binary, and the WorkingDirectories are clones of
|
||||
# separate repos. Nix owns the unit definitions here, nothing more.
|
||||
let
|
||||
# A user unit gets almost no PATH by default; these are the profile dirs the
|
||||
# original units got for free from the system PATH on Ubuntu.
|
||||
toolPath = "%h/.local/bin:%h/.nix-profile/bin:/etc/profiles/per-user/naps62/bin:/run/current-system/sw/bin";
|
||||
|
||||
sem = inputs.sem.packages.${pkgs.system}.default;
|
||||
|
||||
# runtimeInputs is prepended to PATH, not a replacement, so `claude` still
|
||||
# resolves from the unit's own PATH.
|
||||
claude-rc-run = pkgs.writeShellApplication {
|
||||
name = "claude-rc-run";
|
||||
runtimeInputs = with pkgs; [
|
||||
git
|
||||
gawk
|
||||
coreutils
|
||||
];
|
||||
text = builtins.readFile ./bin/claude-rc-run;
|
||||
};
|
||||
|
||||
claude-rc = pkgs.writeShellApplication {
|
||||
name = "claude-rc";
|
||||
runtimeInputs = with pkgs; [
|
||||
git
|
||||
gawk
|
||||
gnused
|
||||
gnugrep
|
||||
coreutils
|
||||
systemd
|
||||
];
|
||||
text = builtins.readFile ./bin/claude-rc;
|
||||
};
|
||||
in
|
||||
{
|
||||
home.packages = [
|
||||
claude-rc
|
||||
sem
|
||||
pkgs.bun
|
||||
];
|
||||
|
||||
systemd.user.services = {
|
||||
rev = {
|
||||
Unit = {
|
||||
Description = "rev — always-on local code review server";
|
||||
After = [ "network.target" ];
|
||||
};
|
||||
Service = {
|
||||
Type = "simple";
|
||||
WorkingDirectory = "%h/tea/yolo/rev";
|
||||
# nodejs_26, not pkgs.nodejs: rev's package.json sets engines >=26 and
|
||||
# the nixpkgs default is 24.
|
||||
ExecStart = "${pkgs.nodejs_26}/bin/node server/index.ts";
|
||||
Environment = [
|
||||
"NODE_ENV=production"
|
||||
"REV_ROOTS=%h"
|
||||
"REV_DEPTH=3"
|
||||
"REV_SEM_BIN=${sem}/bin/sem"
|
||||
"PATH=${toolPath}"
|
||||
];
|
||||
Restart = "always";
|
||||
RestartSec = 2;
|
||||
};
|
||||
Install.WantedBy = [ "default.target" ];
|
||||
};
|
||||
|
||||
rev-deploy = {
|
||||
Unit = {
|
||||
Description = "rev-deploy — Gitea webhook listener that deploys rev on push to main";
|
||||
After = [ "network.target" ];
|
||||
};
|
||||
Service = {
|
||||
Type = "simple";
|
||||
WorkingDirectory = "%h/tea/yolo/rev";
|
||||
ExecStart = "${pkgs.bun}/bin/bun scripts/deploy-webhook.ts";
|
||||
EnvironmentFile = "%h/.config/rev/deploy.env";
|
||||
Environment = [ "PATH=${toolPath}" ];
|
||||
Restart = "always";
|
||||
RestartSec = 2;
|
||||
};
|
||||
Install.WantedBy = [ "default.target" ];
|
||||
};
|
||||
|
||||
"claude-rc@" = {
|
||||
Unit = {
|
||||
Description = "Claude Code Remote Control (/%I)";
|
||||
Documentation = [ "https://code.claude.com/docs/en/remote-control" ];
|
||||
After = [ "network-online.target" ];
|
||||
Wants = [ "network-online.target" ];
|
||||
StopWhenUnneeded = false;
|
||||
};
|
||||
Service = {
|
||||
Type = "simple";
|
||||
# Leading "-": a missing dir must not be fatal, or systemd fails with
|
||||
# 200/CHDIR before claude-rc-run can report the friendlier exit 78.
|
||||
WorkingDirectory = "-/%I";
|
||||
ExecStart = "${claude-rc-run}/bin/claude-rc-run /%I";
|
||||
Environment = [ "PATH=${toolPath}" ];
|
||||
# `always`, not `on-failure`: a >10min outage times the session out and
|
||||
# the process exits 0, which on-failure would not restart.
|
||||
Restart = "always";
|
||||
RestartSec = 15;
|
||||
# 78 = dir gone; 200 = systemd CHDIR failure. Without these, a deleted
|
||||
# project dir restart-loops every 15s forever.
|
||||
RestartPreventExitStatus = "78 200";
|
||||
StandardOutput = "append:%h/.local/state/claude-rc/%i.log";
|
||||
StandardError = "inherit";
|
||||
};
|
||||
Install.WantedBy = [ "default.target" ];
|
||||
};
|
||||
|
||||
claude-rc-sync = {
|
||||
Unit.Description = "Reconcile Claude Remote Control servers with the project list";
|
||||
Service = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${claude-rc}/bin/claude-rc sync";
|
||||
Environment = [ "PATH=${toolPath}" ];
|
||||
};
|
||||
};
|
||||
|
||||
hourlog = {
|
||||
Unit = {
|
||||
Description = "Start the Friday hour log in a tmux session";
|
||||
Documentation = [ "https://git.naps.pt/yolo/agent-skills" ];
|
||||
ConditionPathIsDirectory = "%h/tea/yolo/agent-skills";
|
||||
};
|
||||
Service = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "%h/tea/yolo/agent-skills/bin/hourlog-session.sh";
|
||||
Environment = [ "PATH=${toolPath}" ];
|
||||
# This unit may be what starts the tmux server; the default cgroup kill
|
||||
# would take it back down as soon as ExecStart returns.
|
||||
KillMode = "process";
|
||||
};
|
||||
};
|
||||
|
||||
week-review = {
|
||||
Unit = {
|
||||
Description = "Start the weekly agent-skills review in a tmux session";
|
||||
Documentation = [ "https://git.naps.pt/yolo/agent-skills" ];
|
||||
ConditionPathIsDirectory = "%h/tea/yolo/agent-skills";
|
||||
};
|
||||
Service = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "%h/tea/yolo/agent-skills/bin/week-review-session.sh";
|
||||
Environment = [ "PATH=${toolPath}" ];
|
||||
KillMode = "process";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
systemd.user.timers = {
|
||||
hourlog = {
|
||||
Unit.Description = "Friday hour log, 18:00 Europe/Lisbon";
|
||||
Timer = {
|
||||
# Zone suffix pinned because the machine clock is UTC; keeps it at 18:00
|
||||
# wall time across DST.
|
||||
OnCalendar = "Fri 18:00 Europe/Lisbon";
|
||||
Persistent = true;
|
||||
AccuracySec = "1min";
|
||||
};
|
||||
Install.WantedBy = [ "timers.target" ];
|
||||
};
|
||||
|
||||
week-review = {
|
||||
Unit.Description = "Weekly agent-skills review, Fridays 17:00 Europe/Lisbon";
|
||||
Timer = {
|
||||
OnCalendar = "Fri 17:00 Europe/Lisbon";
|
||||
Persistent = true;
|
||||
AccuracySec = "1min";
|
||||
};
|
||||
Install.WantedBy = [ "timers.target" ];
|
||||
};
|
||||
};
|
||||
|
||||
systemd.user.paths.claude-rc = {
|
||||
Unit.Description = "Watch the Claude Remote Control project list for edits";
|
||||
Path = {
|
||||
PathChanged = "%h/.config/claude-rc/projects";
|
||||
Unit = "claude-rc-sync.service";
|
||||
};
|
||||
Install.WantedBy = [ "default.target" ];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
_:
|
||||
# Sunshine as a remote desktop. Same wlr-screencopy capture as
|
||||
# features/gaming/sunshine.nix, minus its NVIDIA workarounds: no cudaSupport
|
||||
# (virtio-gpu has no NVENC, so this software-encodes) and no uhid rule.
|
||||
#
|
||||
# First run: https://<host>:47990 to set web-UI credentials, then pair Moonlight.
|
||||
{
|
||||
services.sunshine = {
|
||||
enable = true;
|
||||
autoStart = true;
|
||||
openFirewall = true;
|
||||
capSysAdmin = false; # wlr-screencopy needs no CAP_SYS_ADMIN
|
||||
|
||||
settings = {
|
||||
# MUST be set. Auto-probe tries portalgrab first, and
|
||||
# xdg-desktop-portal-hyprland implements no RemoteDesktop interface — the
|
||||
# probe then hangs forever instead of falling back, so sunshine never
|
||||
# binds its ports and the unit sits "active" doing nothing.
|
||||
capture = "wlgrab";
|
||||
|
||||
# The web UI is only reachable over the network here — there is no local
|
||||
# browser — and sunshine CSRF-rejects any origin but localhost unless it
|
||||
# is listed. Both addresses: .250.1 now, .10.2 after the IP handover.
|
||||
#
|
||||
# Bare comma-separated, NOT a JSON array: sunshine splits this on commas
|
||||
# and never strips brackets or quotes, so "[...]" makes every entry fail
|
||||
# its starts_with("https://") check.
|
||||
csrf_allowed_origins = "https://10.7.250.1:47990,https://10.7.10.2:47990";
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
imports = [
|
||||
./hardware-configuration.nix
|
||||
../common/global
|
||||
../common/features/user.nix
|
||||
../common/features/networking.nix
|
||||
../common/features/display
|
||||
../common/features/pipewire.nix
|
||||
../common/features/remote-desktop.nix
|
||||
../common/features/docker.nix
|
||||
../common/features/fonts.nix
|
||||
../common/features/nix-ld.nix
|
||||
../common/features/appimage.nix
|
||||
../common/features/home
|
||||
];
|
||||
|
||||
networking.hostName = "yolo";
|
||||
|
||||
# Lets the Proxmox host drive clean shutdowns/reboots and report the guest's
|
||||
# IP. The qemu-guest profile in hardware-configuration.nix only sets up the
|
||||
# virtio drivers; the agent itself is a separate service.
|
||||
services.qemuGuest.enable = true;
|
||||
|
||||
# Not a security downgrade: naps62 is in `docker`, which is already
|
||||
# root-equivalent, and sshd is key-only — so the prompt guards nothing while
|
||||
# blocking unattended rebuilds (nh shells out to sudo and needs a TTY).
|
||||
security.sudo.wheelNeedsPassword = false;
|
||||
|
||||
# Nix shells out to git for the `type = "git"` flake inputs (hyprland).
|
||||
# Without it at system level, a fresh install cannot build the home config
|
||||
# that would have provided git — so neither rebuild works.
|
||||
environment.systemPackages = [ pkgs.git ];
|
||||
|
||||
# This clone lives under ~/tea, not the ~/projects path global/nix.nix assumes.
|
||||
programs.nh.flake = lib.mkForce "/home/naps62/tea/naps62/nixos-config";
|
||||
|
||||
# No physical seat: Sunshine is a user service and cannot capture until a
|
||||
# graphical session exists, so a cold boot must reach one unattended. No
|
||||
# hyprlock on start (unlike konishi) — nobody could type the password in.
|
||||
services.displayManager = {
|
||||
autoLogin = {
|
||||
enable = true;
|
||||
user = "naps62";
|
||||
};
|
||||
defaultSession = "hyprland";
|
||||
};
|
||||
|
||||
# A Proxmox guest has no emulated sound card, so PipeWire starts with no sink
|
||||
# and Sunshine has nothing to capture — the stream is silent. This sink is the
|
||||
# only one, so it wins the default and Sunshine records its monitor.
|
||||
services.pipewire.extraConfig.pipewire."10-null-sink" = {
|
||||
"context.objects" = [
|
||||
{
|
||||
factory = "adapter";
|
||||
args = {
|
||||
"factory.name" = "support.null-audio-sink";
|
||||
"node.name" = "sunshine-sink";
|
||||
"node.description" = "Sunshine";
|
||||
"media.class" = "Audio/Sink";
|
||||
"audio.position" = "FL,FR";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
# Pinned to 16 to match the cluster being migrated off Ubuntu; restoring that
|
||||
# dump into a newer default would need a pg_upgrade first.
|
||||
services.postgresql = {
|
||||
enable = true;
|
||||
package = pkgs.postgresql_16;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
modulesPath,
|
||||
...
|
||||
}:
|
||||
|
||||
# Proxmox guest (VM 132), q35 + OVMF. Hand-written rather than generated:
|
||||
# filesystems are matched by label, set when the disk is partitioned, so this
|
||||
# stays valid if the VM is ever rebuilt from scratch.
|
||||
{
|
||||
imports = [
|
||||
(modulesPath + "/profiles/qemu-guest.nix")
|
||||
];
|
||||
|
||||
boot = {
|
||||
initrd.availableKernelModules = [
|
||||
"ahci"
|
||||
"xhci_pci"
|
||||
"virtio_pci"
|
||||
"virtio_scsi"
|
||||
"sd_mod"
|
||||
"sr_mod"
|
||||
];
|
||||
# In the initrd, not kernelModules: otherwise there is no DRM device until
|
||||
# late boot and SDDM races it.
|
||||
initrd.kernelModules = [ "virtio_gpu" ];
|
||||
kernelModules = [ "kvm-intel" ];
|
||||
extraModulePackages = [ ];
|
||||
};
|
||||
|
||||
fileSystems."/" = {
|
||||
device = "/dev/disk/by-label/nixos";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
fileSystems."/boot" = {
|
||||
device = "/dev/disk/by-label/BOOT";
|
||||
fsType = "vfat";
|
||||
options = [
|
||||
"fmask=0077"
|
||||
"dmask=0077"
|
||||
];
|
||||
};
|
||||
|
||||
swapDevices = [ { device = "/dev/disk/by-label/swap"; } ];
|
||||
|
||||
networking.useDHCP = lib.mkDefault true;
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
}
|
||||
Reference in New Issue
Block a user