Skip to content

peon-ping: add module#8750

Draft
workflow wants to merge 1 commit intonix-community:masterfrom
workflow:peon-ping
Draft

peon-ping: add module#8750
workflow wants to merge 1 commit intonix-community:masterfrom
workflow:peon-ping

Conversation

@workflow
Copy link
Contributor

@workflow workflow commented Feb 15, 2026

Description

Adds a programs.peon-ping home-manager module for peon-ping, a notification sound player for AI coding agents (Claude Code, Cursor, Codex, etc.).

Features:

  • programs.peon-ping.enable — installs peon-ping
  • programs.peon-ping.settings — declarative config (immutable nix store symlink) or mutable seeded config when left empty
  • programs.peon-ping.packs — sound packs from og-packs (defaults to ["peon"])
  • programs.peon-ping.enableClaudeCodeIntegration — auto-configures Claude Code hooks and skills

Design note — sound packs via fetchFromGitHub:

The ogPacksSource option defaults to a fetchFromGitHub of PeonPing/og-packs v1.1.0, which contains ~40 sound packs (~35 MB) including localized variants (German, Czech, Spanish, French, Polish, Russian). The packs option selects which subdirectories to install, defaulting to ["peon"].

This keeps sound packs out of nixpkgs (they're audio assets, not software) while still being declaratively managed. The tradeoff is a fetchFromGitHub at eval time pinned to a specific tag. Users can override ogPacksSource to point at their own source. Open to feedback on whether this approach is appropriate or if there's a preferred pattern for managing non-software assets.

Dependency: This module depends on the peon-ping package being available in nixpkgs. Pending PR: NixOS/nixpkgs#490742. Tests use stubs in the meantime.

Checklist

  • Change is backwards compatible.

  • Code formatted with nix fmt or
    nix-shell -p treefmt nixfmt deadnix keep-sorted nixf-diagnose --run treefmt.

  • Code tested through nix run .#tests -- test-all or
    nix-shell --pure tests -A run.all.

  • Test cases updated/added. See example.

  • Commit messages are formatted like

    {component}: {description}
    
    {long description}
    

    See CONTRIBUTING for more information and recent commit messages for examples.

  • If this PR adds a new module

    • Added myself as module maintainer. See example.
    • Generate a news entry. See News
    • Basic tests added. See Tests

time = "2026-02-15T12:00:00+00:00";
condition = true;
message = ''

Copy link
Member

Choose a reason for hiding this comment

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

Why start the entry with an empty line?

lib.hm.dag.entryAfter [ "linkGeneration" ] ''
peonConfigDir="''${CLAUDE_CONFIG_DIR:-$HOME/.claude}/hooks/peon-ping"
peonConfigFile="$peonConfigDir/config.json"
if [ ! -f "$peonConfigFile" ]; then
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if [ ! -f "$peonConfigFile" ]; then
if [[ ! -f $peonConfigFile ]]; then

Comment on lines +181 to +182
peonConfigDir="''${CLAUDE_CONFIG_DIR:-$HOME/.claude}/hooks/peon-ping"
peonConfigFile="$peonConfigDir/config.json"
Copy link
Member

Choose a reason for hiding this comment

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

Need to unset these variables at the end of the code block

Comment on lines +184 to +186
run mkdir -p "$peonConfigDir"
run cp "${cfg.package}/lib/peon-ping/config.json" "$peonConfigFile"
run chmod u+w "$peonConfigFile"
Copy link
Member

Choose a reason for hiding this comment

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

Can use the VERBOSE_ARG variable to add --verbose on verbose runs:

Suggested change
run mkdir -p "$peonConfigDir"
run cp "${cfg.package}/lib/peon-ping/config.json" "$peonConfigFile"
run chmod u+w "$peonConfigFile"
run mkdir $VERBOSE_ARG -p "$peonConfigDir"
run cp $VERBOSE_ARG "${cfg.package}/lib/peon-ping/config.json" "$peonConfigFile"
run chmod $VERBOSE_ARG u+w "$peonConfigFile"

Comment on lines +11 to +17
defaultOgPacksSource = pkgs.fetchFromGitHub {
owner = "PeonPing";
repo = "og-packs";
rev = "v1.1.0";
hash = "sha256-spao/GTIhH4c5HOmVc0umMvrwOaMRa4s5Pem1AWyUOw=";
};

Copy link
Member

Choose a reason for hiding this comment

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

We don't want to manage packages in Home Manager. Can either remove altogether or add it to Nixpkgs and refer to it there.

);

claudeCodeHooks = lib.listToAttrs (
map (event: lib.nameValuePair event [ (hookEntry event) ]) cfg.claudeCodeHookEvents
Copy link
Member

Choose a reason for hiding this comment

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

The hookEntry function is only used here but defined further up. Could put it in a let binding inside this definition instead.

(
{
type = "command";
command = hookCommand;
Copy link
Member

Choose a reason for hiding this comment

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

The hookCommand variable seems unnecessary, it only seems to be used here.

@rycee
Copy link
Member

rycee commented Feb 15, 2026

Thanks for the contribution! I added some comments.

@workflow
Copy link
Contributor Author

workflow commented Feb 15, 2026

Thanks a lot for the light-speed review @rycee! Will see that I get peon-ping (and maybe og-packs) into nixpkgs first, then cycle back to address your comments.

jonpulsifer added a commit to jonpulsifer/dotfiles that referenced this pull request Feb 21, 2026
Vendor peon-ping v2.8.1 package and an adapted home-manager module
(from nix-community/home-manager#8750) so it can be used before the
upstream PRs are merged.

Package (pkgs/peon-ping.nix):
- Cross-platform support (macOS + Linux) — libnotify conditional on Linux
- Installs adapters, scripts, and skills alongside the main peon.sh
- Shell completions for bash and fish

Module (home/modules/peon-ping.nix):
- programs.peon-ping.enable installs package and sound packs
- Copies packs as real files (not symlinks) to avoid peon's realpath
  path-traversal check rejecting nix store paths
- Symlinks peon.sh and adapters/ into hooks dir for IDE detection
- enableClaudeCodeIntegration merges hooks into settings.json
- enableGeminiIntegration merges adapter hooks into ~/.gemini/settings.json
- Seeds mutable default config on first activation

Also fixes pre-existing syntax error in gcloud.nix (stray 'w' prefix).

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Signed-off-by: Jonathan Pulsifer <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants