Skip to content

feat(nix): add home-manager module for per-user hermes-agent service - #9087

Closed
yzx9 wants to merge 2 commits into
NousResearch:mainfrom
yzx9:feat/home-manager
Closed

feat(nix): add home-manager module for per-user hermes-agent service#9087
yzx9 wants to merge 2 commits into
NousResearch:mainfrom
yzx9:feat/home-manager

Conversation

@yzx9

@yzx9 yzx9 commented Apr 13, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Adds homeManagerModules.default exposing programs.hermes-agent with the same declarative config, MCP servers, documents, and settings as the NixOS module, but adapted for home-manager's user-scoped architecture.

Related Issue

Fixes #9056

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

  • systemd.user.services / launchd.agents instead of system-level services
  • State dir defaults to ~/.local/share/hermes (XDG convention)
  • home.activation for setup, no user/group creation needed

secret management:

sops-nix compatibility: sops-nix decrypts secrets during home.activation, which completes before any services start. No explicit service dependency is needed — ExecStartPre (Linux) and the launchd wrapper (Darwin) find the decrypted files already in place.

agenix compatibility: environmentFiles are appended to .env via ExecStartPre (runs after agenix decrypts secrets), not in the activation script. The service unit adds After/Wants on agenix.service when environmentFiles is non-empty.

A potential issue is that the secret may have been appended multiple times to the .env file. This could be resolved after #10139 is merged.

How to Test

  1. Add the flake input (point at the feature branch for testing):
    inputs.hermes-agent.url = "github:yzx9/hermes-agent/feat/home-manager";
  2. Import the module in your home-manager config:
    imports = [ hermes-agent.homeManagerModules.default ];
    programs.hermes-agent = {
      enable = true;                                                                                                                 
      settings.model = "anthropic/claude-sonnet-4";                                                                                  
      environmentFiles = [ config.sops.secrets.hermes-env.path ]; # optional                                                         
    };
  3. Build and switch:
    # as nixos module
    sudo nixos-rebuild switch --flake .#your-profile
    # standalone
    home-manager switch --flake .#your-profile
  4. Verify directory structure and config were generated:
    ls ~/.local/share/hermes/.hermes/config.yaml
    ls ~/.local/share/hermes/.hermes/.managed
  5. Verify the service is running:
    # Linux
    systemctl --user status hermes-agent
    # macOS
    launchctl list | grep hermes
    
  6. Verify secrets were injected (if using environmentFiles):
    cat ~/.local/share/hermes/.hermes/.env
  7. Verify the gateway is healthy, say hello in the configured message platform

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: NixOS with latest nixpkgs-unstable and latest home-manager

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — or N/A
  • I've updated cli-config.yaml.example if I added/changed config keys — or N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — or N/A
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — or N/A
  • I've updated tool descriptions/schemas if I changed tool behavior — or N/A

For New Skills

  • This skill is broadly useful to most users (if bundled) — see Contributing Guide
  • SKILL.md follows the standard format (frontmatter, trigger conditions, steps, pitfalls)
  • No external dependencies that aren't already available (prefer stdlib, curl, existing Hermes tools)
  • I've tested the skill end-to-end: hermes --toolsets skills -q "Use the X skill to do Y"

Screenshots / Logs

@yzx9
yzx9 force-pushed the feat/home-manager branch 2 times, most recently from d3464f7 to d45391d Compare April 14, 2026 01:55
@yzx9
yzx9 marked this pull request as ready for review April 14, 2026 01:55
@yzx9
yzx9 force-pushed the feat/home-manager branch 2 times, most recently from 6779977 to 3d5f208 Compare April 14, 2026 03:52
@yzx9
yzx9 force-pushed the feat/home-manager branch from 3d5f208 to 4180013 Compare April 17, 2026 04:07
# Runs hermes-agent as a per-user service under home-manager.
# Linux: systemd.user.services
# macOS: launchd.agents
# Container mode is not supported (requires system-level docker/podman).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if it solves this problem, but Home Manager has options for setting up the colima runtime which might be leveraged for container mode.

@yzx9 yzx9 Apr 21, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I notices that services.podman might also work. I can proceed with it if this PR can be merged

@sunny-g

sunny-g commented Apr 19, 2026

Copy link
Copy Markdown

@yzx9 can you rebase with the changes made in #12208 🙏

@yzx9
yzx9 force-pushed the feat/home-manager branch from 4180013 to 1212d89 Compare April 19, 2026 15:38
@yzx9

yzx9 commented Apr 19, 2026

Copy link
Copy Markdown
Contributor Author

@sunny-g done

@sunny-g

sunny-g commented Apr 24, 2026

Copy link
Copy Markdown

@yzx9 any chance you can rebase with the latest version v2026.4.23 (0.11.0)? :) :)

@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have area/nix Nix flake, NixOS module, container packaging labels Apr 24, 2026
@yzx9
yzx9 force-pushed the feat/home-manager branch from 1212d89 to 0cf372a Compare April 25, 2026 07:04
@yzx9

yzx9 commented Apr 25, 2026

Copy link
Copy Markdown
Contributor Author

@sunny-g sure

@yzx9
yzx9 force-pushed the feat/home-manager branch from 3ff4694 to 8759840 Compare May 1, 2026 06:56
Comment thread nix/checks.nix
@sunny-g

sunny-g commented May 1, 2026

Copy link
Copy Markdown

@yzx9 are you running hermes on a mac? I'm getting errors Executing pythonImportsCheckPhase (#16080) that was allegedly fixed in #15953.

@yzx9

yzx9 commented May 2, 2026

Copy link
Copy Markdown
Contributor Author

@sunny-g Hi, I’m not using it on Darwin at the moment, but I’m planning to give it a try next week. I regularly rebase to the latest release tag, though since the project is moving quickly, the releases may not always be up to date. I’ll rebase to the main branch as well. In the meantime, I’d suggest copying the first commit into your config, which enables you to integrate Home Manager with the latest Hermes agent. You can refer to yzx9/nix-config as an example.

@yzx9
yzx9 force-pushed the feat/home-manager branch from 8759840 to 470ddc1 Compare May 2, 2026 01:02
@sunny-g

sunny-g commented May 2, 2026

Copy link
Copy Markdown

@yzx9 way ahead of you and appreciate it :), think im just blocked by the python/av installation issues

@yzx9

yzx9 commented May 2, 2026

Copy link
Copy Markdown
Contributor Author

FYI, I’ve also run into the FFmpeg signing issue on aarch64-darwin with the latest nixpkgs-unstable. It might be related to NixOS/nixpkgs#513225.
I had to roll back to a previous commit since this affects many packages.
For this flake using uv2nix, switching to the prebuilt PyPI wheel might be a possible workaround

@yzx9
yzx9 force-pushed the feat/home-manager branch from 470ddc1 to 5d40829 Compare May 8, 2026 19:22
@yzx9
yzx9 force-pushed the feat/home-manager branch from 5d40829 to f1aa34b Compare May 16, 2026 19:22
@yzx9
yzx9 force-pushed the feat/home-manager branch 2 times, most recently from 66a52d3 to d135c7f Compare May 29, 2026 19:22
@yzx9
yzx9 requested a review from a team May 29, 2026 19:22

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for carrying the Home Manager implementation; current main still lacks this module, so the feature request in #9056 remains valid.

Problems

  • nix/homeManagerModules.nix:516-524 appends every secret file to persistent .env on every service start. That duplicates entries and copies secret-manager output into Hermes state.
  • nix/homeManagerModules.nix:536 and :617 export deprecated MESSAGING_CWD. Gateway startup calls warn_deprecated_cwd_env_vars() at gateway/run.py:1702-1703; hermes_cli/config.py:5402-5439 requires terminal.cwd instead.
  • website/docs/getting-started/nix-setup.md:296 overstates parity: the Home Manager module lacks NixOS options declared at nix/nixosModules.nix:481, :502, and :527.
  • The added checks cover managed-message text only; they do not evaluate homeManagerModules.default.

Suggested changes

  • Use a non-duplicating secret-file design, migrate the working directory to settings.terminal.cwd, correct or complete the option-parity claim, and add Home Manager module evaluation coverage.

Automated hermes-sweeper review.

map (f: ''
if [ -f "${f}" ]; then
echo "" >> "$ENV_FILE"
cat "${f}" >> "$ENV_FILE"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This runs on every service start, so each restart appends the same secret file again to persistent .env. Please use a non-duplicating secret-file mechanism that also avoids copying secret-manager output into Hermes state.

if cfg.managedMode == "nixos" then "home-manager-nixos" else "home-manager"
}"
"MESSAGING_CWD=${cfg.workingDirectory}"
("PATH=" + servicePath + "\${PATH:+:$PATH}")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MESSAGING_CWD is deprecated: current gateway startup warns on it and requires terminal.cwd in config instead (gateway/run.py:1702-1703, hermes_cli/config.py:5402-5439). Configure the module's generated settings.terminal.cwd rather than exporting this environment variable.

}
```

The `programs.hermes-agent` options are the same as the NixOS module's `services.hermes-agent` options, minus `user`, `group`, `createUser`, `addToSystemPackages`, and `container.*`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This parity claim is inaccurate: the Home Manager module does not define NixOS options extraPlugins, extraPythonPackages, or extraDependencyGroups (nix/nixosModules.nix:481, :502, :527). Please either implement them or document the supported subset.

@teknium1 teknium1 added sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 12, 2026
@alt-glitch alt-glitch added comp/cli CLI entry point, hermes_cli/, setup wizard and removed sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data comp/cli CLI entry point, hermes_cli/, setup wizard sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades labels Jul 12, 2026
@yzx9
yzx9 force-pushed the feat/home-manager branch from 1449aac to f51d16a Compare July 20, 2026 21:58
@alt-glitch alt-glitch added area/config Config system, migrations, profiles comp/cli CLI entry point, hermes_cli/, setup wizard sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades labels Jul 20, 2026
@yzx9
yzx9 force-pushed the feat/home-manager branch from f51d16a to 720846d Compare August 3, 2026 22:06
@yzx9
yzx9 force-pushed the feat/home-manager branch 2 times, most recently from 187197e to 622a28c Compare August 16, 2026 22:01
@alt-glitch alt-glitch added the sweeper:risk-automation Sweeper risk: may affect CI, automerge, label sync, or maintainer automation label Aug 16, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Related: #84178 implements the same Home Manager capability via a shared NixOS/Home Manager module refactor. These are competing approaches; maintainer review should choose the preferred design.

@alt-glitch alt-glitch added needs-decision Awaiting maintainer decision before any implementation and removed sweeper:risk-automation Sweeper risk: may affect CI, automerge, label sync, or maintainer automation labels Aug 16, 2026
@yzx9
yzx9 force-pushed the feat/home-manager branch from 622a28c to d05602c Compare August 17, 2026 21:59
yzx9 added 2 commits August 19, 2026 05:59
Adds homeManagerModules.default exposing programs.hermes-agent with the
same declarative config, MCP servers, documents, and settings as the
NixOS module, but adapted for home-manager's user-scoped architecture:

- systemd.user.services or launchd.agents instead of system-level services
- State dir defaults to ~/.local/share/hermes (XDG convention)
- home.activation for setup, no user/group creation needed

sops-nix compatibility: sops-nix decrypts secrets during
home.activation, which completes before any services start.
No explicit service dependency is needed — ExecStartPre (Linux)
and the launchd wrapper (Darwin) find the decrypted files
already in place.

agenix compatibility: environmentFiles are appended to .env via
ExecStartPre (runs after agenix decrypts secrets), not in the
activation script. The service unit adds After/Wants on agenix.service
when environmentFiles is non-empty.
The home-manager module used HERMES_MANAGED=true identically to the
NixOS module, causing incorrect error messages directing users to edit
services.hermes-agent.settings and run nixos-rebuild switch.

Add managedMode option (home-manager/nixos) to the home-manager module
so HERMES_MANAGED now carries the manager identity:
- home-manager: standalone (update via home-manager switch)
- home-manager-nixos: used as NixOS module (update via nixos-rebuild switch)

Also read .managed marker file content for interactive shell detection
and add nix flake checks for both modes.
@yzx9
yzx9 force-pushed the feat/home-manager branch from d05602c to d38dc34 Compare August 18, 2026 21:59
@yzx9

yzx9 commented Aug 19, 2026

Copy link
Copy Markdown
Contributor Author

closed as #84178 got merged

@yzx9 yzx9 closed this Aug 19, 2026
@yzx9
yzx9 deleted the feat/home-manager branch August 19, 2026 01:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/config Config system, migrations, profiles area/nix Nix flake, NixOS module, container packaging comp/cli CLI entry point, hermes_cli/, setup wizard needs-decision Awaiting maintainer decision before any implementation P3 Low — cosmetic, nice to have sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Add a Nix Home Manager module for user-level installation

7 participants