Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
./nix/packages.nix
./nix/overlays.nix
./nix/nixosModules.nix
./nix/homeManagerModules.nix
./nix/checks.nix
./nix/devShell.nix
];
Expand Down
33 changes: 32 additions & 1 deletion hermes_cli/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,9 @@ def _reject_denylisted_env_var(key: str) -> None:

_MANAGED_TRUE_VALUES = ("true", "1", "yes")
_MANAGED_SYSTEM_NAMES = {
"home-manager": "Home Manager",
"hm": "Home Manager",
"home-manager-nixos": "Home Manager (NixOS)",
"nix": "NixOS",
"nixos": "NixOS",
}
Expand Down Expand Up @@ -367,7 +370,13 @@ def get_managed_system() -> Optional[str]:

managed_marker = get_hermes_home() / ".managed"
if managed_marker.exists():
return "NixOS"
# Read marker content to distinguish NixOS vs home-manager.
# Legacy (empty) markers default to NixOS for backwards compat.
try:
content = managed_marker.read_text().strip().lower()
except (OSError, UnicodeDecodeError):
content = ""
return _MANAGED_SYSTEM_NAMES.get(content, "NixOS")
return None


Expand All @@ -390,6 +399,10 @@ def is_managed() -> bool:
def get_managed_update_command() -> Optional[str]:
"""Return the preferred upgrade command for a managed install."""
managed_system = get_managed_system()
if managed_system == "Home Manager (NixOS)":
return "sudo nixos-rebuild switch"
if managed_system == "Home Manager":
return "home-manager switch"
if managed_system == "NixOS":
return _NIX_UPDATE_MSG
return None
Expand Down Expand Up @@ -634,6 +647,24 @@ def format_managed_message(action: str = "modify this Hermes installation") -> s
" sudo nixos-rebuild switch"
)

if managed_system == "Home Manager (NixOS)":
env_hint = raw or "home-manager-nixos"
return (
f"Cannot {action}: this Hermes installation is managed by Home Manager "
f"(via NixOS module, HERMES_MANAGED={env_hint}).\n"
"Edit programs.hermes-agent.settings in your NixOS configuration and run:\n"
" sudo nixos-rebuild switch"
)

if managed_system == "Home Manager":
env_hint = raw or "home-manager"
return (
f"Cannot {action}: this Hermes installation is managed by Home Manager "
f"(HERMES_MANAGED={env_hint}).\n"
"Edit programs.hermes-agent.settings in your home-manager config and run:\n"
" home-manager switch"
)

return (
f"Cannot {action}: this Hermes installation is managed by {managed_system}.\n"
"Use your package manager to upgrade or reinstall Hermes."
Expand Down
4 changes: 2 additions & 2 deletions hermes_cli/gateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -7511,7 +7511,7 @@ def _gateway_command_inner(args):
# Service management commands
if subcmd == "install":
if is_managed():
managed_error("install gateway service (managed by NixOS)")
managed_error("install gateway service")
return
force = getattr(args, "force", False)
system = getattr(args, "system", False)
Expand Down Expand Up @@ -7623,7 +7623,7 @@ def _gateway_command_inner(args):

elif subcmd == "uninstall":
if is_managed():
managed_error("uninstall gateway service (managed by NixOS)")
managed_error("uninstall gateway service")
return
system = getattr(args, "system", False)
if is_termux():
Expand Down
46 changes: 46 additions & 0 deletions nix/checks.nix
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,52 @@ json.dump(sorted(leaf_paths(DEFAULT_CONFIG)), sys.stdout, indent=2)
${self'.packages.messaging.hermesVenv}/bin/python3 -c \
"import discord; print(discord.__version__)"
echo "PASS: discord.py importable from messaging variant venv"

mkdir -p $out
echo "ok" > $out/result
'';

# Verify HERMES_MANAGED=home-manager guard works on mutation commands
Comment thread
yzx9 marked this conversation as resolved.
home-manager-guard = pkgs.runCommand "hermes-home-manager-guard" { } ''
set -e
export HOME=$(mktemp -d)

check_blocked() {
local label="$1"
shift
OUTPUT=$(HERMES_MANAGED=home-manager "$@" 2>&1 || true)
echo "$OUTPUT" | grep -q "managed by Home Manager" || (echo "FAIL: $label not guarded"; echo "$OUTPUT"; exit 1)
echo "PASS: $label blocked in home-manager managed mode"
}

echo "=== Checking HERMES_MANAGED=home-manager guards ==="
check_blocked "config set" ${hermes-agent}/bin/hermes config set model foo
check_blocked "config edit" ${hermes-agent}/bin/hermes config edit

echo "=== All home-manager guard checks passed ==="
mkdir -p $out
echo "ok" > $out/result
'';

# Verify HERMES_MANAGED=home-manager-nixos guard (NixOS module mode)
home-manager-nixos-guard = pkgs.runCommand "hermes-home-manager-nixos-guard" { } ''
set -e
export HOME=$(mktemp -d)

check_blocked() {
local label="$1"
shift
OUTPUT=$(HERMES_MANAGED=home-manager-nixos "$@" 2>&1 || true)
echo "$OUTPUT" | grep -q "managed by Home Manager" || (echo "FAIL: $label not guarded"; echo "$OUTPUT"; exit 1)
echo "$OUTPUT" | grep -q "sudo nixos-rebuild switch" || (echo "FAIL: $label missing nixos-rebuild hint"; echo "$OUTPUT"; exit 1)
echo "PASS: $label blocked in home-manager-nixos managed mode"
}

echo "=== Checking HERMES_MANAGED=home-manager-nixos guards ==="
check_blocked "config set" ${hermes-agent}/bin/hermes config set model foo
check_blocked "config edit" ${hermes-agent}/bin/hermes config edit

echo "=== All home-manager-nixos guard checks passed ==="
mkdir -p $out
echo "ok" > $out/result
'';
Expand Down
Loading
Loading