Author SHA1 Message Date
m3ta-chiron 78d1fa262c fix(hyprland): float+pin vibetyper Recording Indicator
Since vibetyper 1.5.x the indicator is a small bottom-center panel,
not a fullscreen overlay. Without an explicit float rule dwindle
tiles it and clips the panel to tile size (magic formatter preview,
language confirm etc. appeared cut off).
2026-09-17 06:51:12 +02:00
m3tam3re 601eae6362 fix(gaming): emulators.nix declared gamescope's option by mistake
Copy-paste slip from 7064bbe: emulators.nix declared
profiles.gaming.gamescope.enable (already declared in gamescope.nix)
while reading profiles.gaming.emulators, which was never declared.
Declare the emulators option instead.
2026-09-12 14:00:38 +02:00
m3tam3re 2de49b5204 fix(desktop): build hermes-desktop with corrected Electron 43.6.0 headers hash
Upstream hermes-agent v2026.8.31 pins sha256-f8bSb… for the
artifacts.electronjs.org v43.6.0 headers tarball. The CDN swapped
that artifact, breaking every desktop build with a fixed-output
derivation hash mismatch (specified f8bSb… vs got xDgc5…).

Local copy of upstream nix/desktop.nix with:
- verified hash for electron 43.6.0 (nix store prefetch-file)
- per-version hash map with a loud throw for unknown versions
- icon/desktop-entry paths resolved against the flake input checkout

Remove once upstream ships the corrected hash and the hermes-agent
input is bumped past that release.
2026-09-12 13:58:56 +02:00
m3tam3re 7064bbebe3 feat: emulators 2026-09-12 13:50:34 +02:00
m3tam3re 9c94b70c93 feat: emulators 2026-09-12 13:49:46 +02:00
m3tam3re afc5bc3aa6 chore: some updates 2026-09-11 17:39:29 +02:00
m3tam3re ff5fef0596 chore: hyprland keybindings 2026-09-05 09:36:29 +02:00
m3tam3re 207b794431 chore: hyprland keybindings 2026-09-05 09:28:05 +02:00
m3ta-chiron fb3e39f0ce fix: libreoffice-fresh -> libreoffice-stable (deprecated alias) 2026-08-31 11:44:58 +02:00
m3ta-chiron 9b1be8eca4 refactor(agents): consume llm-agents packages via pkgs.llm-agents namespace
numtide/llm-agents.nix's shared-nixpkgs overlay exposes everything under
pkgs.llm-agents.* — no flattening to top-level attrs anymore. Namespaced
refs fail loudly when the overlay is missing instead of silently falling
back to outdated nixpkgs attributes (opencode 0.3.x) or disappearing.

Requires the consumer's nixos-config to apply
inputs.llm-agents.overlays.shared-nixpkgs (see nixos-config
hosts/common/default.nix).
2026-08-31 11:44:22 +02:00
m3tam3re 890dc4cb2c mcp changes 2026-08-25 20:09:58 +02:00
m3ta-chiron 31d47b00e5 feat: add ansible to base cli-tools
Adds ansible + ansible-lint as an always-on base module so it is
available in both identities (private/work) and all contexts.
Disable per host via base.cliTools.ansible.enable = false.
2026-08-21 09:06:49 +02:00
m3tam3re 6a311045a4 chore: ssh changes 2026-08-16 13:44:59 +02:00
m3tam3re 808b6628c8 chore: flake update 2026-08-15 14:06:47 +02:00
m3tam3re b58b7e84d1 chore: opencode config updates 2026-08-15 13:53:22 +02:00
m3ta-chiron fbba78e358 chore: fix local repo paths 2026-08-12 10:25:49 +02:00
m3ta-chiron 38fa16eda6 chore: TC01 addr change 2026-08-12 10:24:00 +02:00
m3tam3re 33d0c85ef4 chore: ssh changes 2026-08-11 17:06:01 +02:00
m3tam3re f2cc6b59ef chore: update hyrpland/dms config 2026-08-09 09:50:45 +02:00
m3tam3re f0e98a2ac7 feat: buzz 2026-08-08 17:46:57 +02:00
m3ta-chiron 6a67324c6d fix: litelllm models 2026-08-03 11:49:56 +02:00
m3ta-chiron c90f5a5857 fix: litelllm models 2026-08-03 11:49:23 +02:00
m3ta-chiron 69082a07f2 fix: litelllm models 2026-08-03 11:34:59 +02:00
m3ta-chiron d2b39a3f2d AZ-TC-01 2026-08-03 09:12:37 +02:00
m3ta-chiron de16245929 AZ-TC-01 2026-08-03 08:44:48 +02:00
m3ta-chiron b01084482f Merge branch 'master' of code.m3ta.dev:m3tam3re/m3ta-home 2026-08-03 06:31:55 +02:00
m3ta-chiron 66b1dc72f5 fix: agent-lib-legacy repo url 2026-08-03 06:31:43 +02:00
m3tam3re 0db970c161 feat: docker-sbx 2026-08-02 16:34:20 +02:00
m3tam3re 516f9d74e0 chore: -aionui 2026-08-02 13:41:01 +02:00
m3tam3re 7926491466 feat: migrate Hyprland configuration to Lua 2026-08-01 10:53:09 +02:00
m3tam3re a9cf13abd4 feat: add some mcp servers 2026-07-30 14:50:43 +02:00
m3tam3re 4dec87ebc7 feat: okf skills 2026-07-30 14:22:13 +02:00
m3tam3re 53de70bf4f feat: okf skills 2026-07-30 14:16:33 +02:00
m3tam3re 206ee46d4f fix: basecamp rollback as new rc version does not have a source hash 2026-07-30 09:33:31 +02:00
m3tam3re 4ac8d6fb9a chore: flake update 2026-07-30 08:26:14 +02:00
m3tam3re a22ff06004 chore: flake update 2026-07-30 07:21:22 +02:00
m3tam3re acbf02c3e1 +opencode-desktop 2026-07-30 07:03:27 +02:00
m3ta-chiron 128391afb2 -zellij-ps 2026-07-28 06:49:42 +02:00
m3ta-chiron 92244b5f02 -zellij-ps 2026-07-28 06:35:01 +02:00
m3tam3re 7b3ef4a2c3 Merge branch 'master' of code.m3ta.dev:m3tam3re/m3ta-home 2026-07-25 11:45:38 +02:00
m3tam3re 2aac223e77 chore: flake update 2026-07-25 11:45:26 +02:00
m3ta-chiron 5e26e13aa7 chore: model changes for opencode 2026-07-17 07:21:35 +02:00
m3tam3re 017bf5002e fix: gstreamer 2026-07-16 18:56:09 +02:00
m3tam3re c85600a3b0 chore: skill issue 2026-07-10 15:18:06 +02:00
m3tam3re 32fdaddf7c Merge branch 'master' of code.m3ta.dev:m3tam3re/m3ta-home 2026-07-08 20:41:14 +02:00
m3tam3re 99753e18df feat: +aionui 2026-07-08 20:41:03 +02:00
m3tam3re 10876be5e6 fix: resolve eval warnings and npm prefix 2026-07-07 19:39:43 +02:00
m3tam3re 93cecb1a53 feat: herdr 2026-07-07 18:52:04 +02:00
m3ta-chiron 192b5df938 chore: gitea npm registry 2026-07-07 07:19:28 +02:00
m3ta-chiron 47fbdaaa37 chore: gitea npm registry 2026-07-07 06:51:56 +02:00
m3tam3re ed976b0e9e chore: remove hermes-desktop 2026-07-05 18:37:34 +02:00
m3ta-chiron 671ad7bb8f feat: new skills 2026-07-02 21:13:02 +02:00
m3tam3re 013f031a56 feat: talk crunch 2026-07-02 20:26:03 +02:00
m3tam3re 9f44404d94 feat: talk crunch 2026-07-02 20:24:21 +02:00
m3tam3re 2f4c5c8cba Merge pull request 'refactor: dynamic nushell secrets path via config.home.username' (#2) from feat/dynamic-secrets into master
Reviewed-on: #2
2026-07-02 19:08:43 +02:00
m3ta-chiron 7febc62f50 refactor: resolve nushell secrets path dynamically via config.home.username
Replace hardcoded 'm3tam3re-secrets' with '${config.home.username}-secrets'
so the agenix secret file resolves automatically for any user
(m3tam3re, sascha.koenig, bob, etc.).
2026-07-02 19:07:29 +02:00
m3ta-chiron 6c9d082e41 Merge branch 'master' of code.m3ta.dev:m3tam3re/m3ta-home 2026-06-30 07:22:37 +02:00
m3ta-chiron a42c196840 chore: update agent sources 2026-06-30 07:22:27 +02:00
m3tam3re 9cd60383f8 fix: vibetyper hyprland setting 2026-06-20 10:58:22 +02:00
m3tam3re 6be0ad4ea0 fix: remove deprecated matchBlocks from work profile 2026-06-20 10:51:46 +02:00
m3tam3re 0ae4996d97 chore: vibetyper rec indicator 2026-06-20 08:34:18 +02:00
m3tam3re aa249c1f31 chore: moonlander keyboard layout 2026-06-19 11:29:02 +02:00
m3tam3re 413a7d123e chore: moonlander keyboard layout 2026-06-19 06:56:48 +02:00
m3ta-chiron 57c467ef11 chore: fix opus 4.8 thinking 2026-06-15 13:01:07 +02:00
m3ta-chiron fbcf8f65e6 chore: fix opus 4.8 thinking 2026-06-15 12:59:17 +02:00
m3ta-chiron ef78590a6a chore: opus 4.8 2026-06-15 12:46:09 +02:00
m3ta-chiron 39cc27fd72 chore: hyprland monitor config import from dms 2026-06-15 11:00:32 +02:00
m3ta-chiron fe88684d9d chore: move openwork into agent context 2026-06-15 07:39:27 +02:00
m3ta-chiron 4b4221da30 fix: resolve flake lock conflict markers 2026-06-15 07:22:07 +02:00
m3ta-chiron 9be26d79cc feat: openwork 2026-06-15 07:13:29 +02:00
m3ta-chiron 2821f4b6f4 feat: openwork 2026-06-15 07:13:04 +02:00
m3tam3re d1494476b8 flake update 2026-06-13 13:05:16 +02:00
m3tam3re eea29e9877 skills update 2026-06-13 09:41:14 +02:00
m3tam3re 2ab870db8c feat: re-export Hermes skills renderer 2026-06-13 09:25:40 +02:00
m3tam3re 66127c05ea fix(hyprland): set vibe typer keyboard layout to de 2026-06-13 08:17:16 +02:00
m3tam3re 4a9d24fe08 fix: nix eval warnings 2026-06-11 17:33:32 +02:00
m3tam3re 1265dea16a chore: vibetyper keyboard locale 2026-06-11 07:20:07 +02:00
m3tam3re 222c1becf4 chore: vibetyper keyboard locale 2026-06-11 07:14:35 +02:00
m3tam3re 365b6016f1 chore: vibetyper keyboard locale 2026-06-11 07:14:21 +02:00
m3tam3re 9566724015 chore: updates 2026-06-11 07:00:33 +02:00
m3ta-chiron cd80ded6c0 fix(nushell): guard optional agenix secrets source 2026-06-10 08:18:01 +02:00
m3ta-chiron 4fe9f3e306 +chrome 2026-06-08 06:52:56 +02:00
m3ta-chiron d26a40f4ee +chromium 2026-06-08 06:46:40 +02:00
m3ta-chiron 74566375f9 +playwright mcp 2026-06-08 06:38:43 +02:00
m3tam3re add002e05c fix: make inputs self-contained 2026-06-06 13:13:58 +02:00
m3tam3re 5c92a9f1c6 fix(nushell): source agenix secret env 2026-06-06 10:41:44 +02:00
m3tam3re b67922ca60 feat: add agent secrets and packages 2026-06-06 10:31:38 +02:00
m3tam3re 19dea8277e +nier wallpaper 2026-06-02 19:22:00 +02:00
m3tam3re 8bbfc64b84 +nier wallpaper 2026-06-02 19:21:50 +02:00
m3tam3re f5e2b50082 +nier wallpaper 2026-06-02 18:59:39 +02:00
m3ta-chiron 6286921cd1 fix system dark settings 2026-06-01 20:10:12 +02:00
m3ta-chiron a053c9a50e fix: use dark GTK theme variant 2026-06-01 20:01:21 +02:00
m3ta-chiron 7f80fd8a75 feat: add DankMaterialShell home module 2026-06-01 19:50:33 +02:00
m3ta-chiron 4e1b39f443 +dms draft 2026-06-01 19:34:00 +02:00
m3ta-chiron b2ca12f86c fix(agents): stop legacy agent rendering 2026-06-01 08:36:13 +02:00
m3tam3re 6c6164043b +agents-lib 2026-05-31 14:38:02 +02:00
m3tam3re e02a0a29ea flake update 2026-05-31 14:12:26 +02:00
m3tam3re 831698b766 +babysitter 2026-05-29 18:34:46 +02:00
m3tam3re 336a174a17 +worktrunk +babysitter 2026-05-29 17:37:09 +02:00
m3tam3re 70562ceef2 chore: temp fix invalid Hyprland dispatchers 2026-05-18 20:15:25 +02:00
m3tm3re ef5b67c3e9 chore: +hyprland configType 2026-05-18 20:09:28 +02:00
35 changed files with 3577 additions and 640 deletions
+7 -3
View File
@@ -161,6 +161,7 @@ Every module in m3ta-home has an `enable` option. Base modules default to `true`
### Available Flags
```
base.cliTools.ansible.enable # Ansible (config rollout to servers)
base.shell.fish.enable # Fish shell
base.shell.nushell.enable # Nushell
base.shell.starship.enable # Starship prompt
@@ -177,6 +178,7 @@ base.secrets.enable # pass-wayland, pinentry
desktop.wm.hyprland.enable # Hyprland window manager
desktop.wm.rofi.enable # Rofi launcher
desktop.wm.wayland.enable # Wayland tools (grim, slurp, etc.)
desktop.wm.dms.enable # DankMaterialShell desktop shell
desktop.apps.obsidian.enable # Obsidian
desktop.apps.office.enable # LibreOffice
desktop.apps.crypto.enable # Bisq2, Monero, Trezor
@@ -244,9 +246,11 @@ source = "${config."m3ta-home".paths.srcRoot}/assets/wallpapers";
| `nixpkgs` | Package set (follows nixos-config's nixpkgs) |
| `home-manager` | Home-Manager modules |
| `nix-colors` | Dracula theme palette (used everywhere) |
| `m3ta-nixpkgs` | Custom packages (zellij-ps, rofi-project-opener) and HM modules |
| `agenix` | Secret management |
| `NUR` | Additional packages |
| `m3ta-nixpkgs` | Custom packages (zellij-ps, rofi-project-opener) and HM modules |
| `dms` | DankMaterialShell Home-Manager module and package |
| `dms-plugin-registry` | DankMaterialShell plugin sources |
| `agenix` | Secret management |
| `NUR` | Additional packages |
## Important Notes
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 MiB

Generated
+425 -44
View File
@@ -21,14 +21,52 @@
"type": "github"
}
},
"agent-lib": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1781348569,
"narHash": "sha256-1BJtmKSqtD0CD753ZE37RgxvCJK6Iw3iKLDDaS8trY4=",
"ref": "refs/heads/master",
"rev": "75a2ed2533b4d6d8e4a34acd37e83d98d81a5fb0",
"revCount": 30,
"type": "git",
"url": "ssh://gitea@code.m3ta.dev/m3tam3re/agent-lib-legacy"
},
"original": {
"type": "git",
"url": "ssh://gitea@code.m3ta.dev/m3tam3re/agent-lib-legacy"
}
},
"agents": {
"inputs": {
"nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 1783016143,
"narHash": "sha256-3qejDAo4g2XfzTyWCaX8RVKH17JXnw/fujsbXQA+Mzc=",
"ref": "refs/heads/master",
"rev": "83284d752d2ac325d4bf3ab7b38acad1c2fffe3a",
"revCount": 98,
"type": "git",
"url": "ssh://gitea@code.m3ta.dev/m3tam3re/AGENTS"
},
"original": {
"type": "git",
"url": "ssh://gitea@code.m3ta.dev/m3tam3re/AGENTS"
}
},
"agents_2": {
"flake": false,
"locked": {
"lastModified": 1777399938,
"narHash": "sha256-xXPqUQezDdDtF8MbpZnwD1HkybOYwF92evx8rJ6OXCU=",
"lastModified": 1783016143,
"narHash": "sha256-3qejDAo4g2XfzTyWCaX8RVKH17JXnw/fujsbXQA+Mzc=",
"ref": "refs/heads/master",
"rev": "9a91f1ee0cf011a7eaf1f16a9e17610b0457e055",
"revCount": 85,
"rev": "83284d752d2ac325d4bf3ab7b38acad1c2fffe3a",
"revCount": 98,
"type": "git",
"url": "https://code.m3ta.dev/m3tam3re/AGENTS"
},
@@ -61,20 +99,59 @@
]
},
"locked": {
"lastModified": 1774505501,
"narHash": "sha256-7UiRrDptj7yuEFwToOfdunUMz/i3jRLR7CmMoYQjq6k=",
"lastModified": 1785979955,
"narHash": "sha256-OP96Ak4OBydR98keoNYKdGY8j+wrIys0LafSZgwS20g=",
"owner": "basecamp",
"repo": "basecamp-cli",
"rev": "f087e6ef84002503d0dbc75ea1c8c928a8928d9e",
"rev": "61a5591de1da9bc99c56b8072a4d6bad2c9b9e47",
"type": "github"
},
"original": {
"owner": "basecamp",
"ref": "v0.7.2",
"ref": "v0.9.0",
"repo": "basecamp-cli",
"type": "github"
}
},
"buzz": {
"inputs": {
"nixpkgs": [
"m3ta-nixpkgs",
"nixpkgs"
],
"rust-overlay": "rust-overlay",
"treefmt-nix": "treefmt-nix"
},
"locked": {
"lastModified": 1788856318,
"narHash": "sha256-bOLED82KPrzIXTWELw30y3PVI6MBmlY4Y2F2lwrdOnM=",
"owner": "mulatta",
"repo": "buzz.nix",
"rev": "fdd0152c12c6be339fe01d91887122bb10823aaf",
"type": "github"
},
"original": {
"owner": "mulatta",
"repo": "buzz.nix",
"type": "github"
}
},
"dank-qml-common": {
"flake": false,
"locked": {
"lastModified": 1788376015,
"narHash": "sha256-/tT8rTznLADndTwLBzdgzzgfJH1ZhYQibYo5v/F8U+U=",
"owner": "AvengeMedia",
"repo": "dank-qml-common",
"rev": "26396ce432d6c71c3f5367438f96f4a8d667e160",
"type": "github"
},
"original": {
"owner": "AvengeMedia",
"repo": "dank-qml-common",
"type": "github"
}
},
"darwin": {
"inputs": {
"nixpkgs": [
@@ -97,7 +174,87 @@
"type": "github"
}
},
"dms": {
"inputs": {
"dank-qml-common": "dank-qml-common",
"flake-compat": "flake-compat",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1788959433,
"narHash": "sha256-MAbxGEomcpGomFfw+WYurNkSKBIh7PKEc1U5OV0X6oU=",
"owner": "AvengeMedia",
"repo": "DankMaterialShell",
"rev": "fe293b7379a51f62a4db7043fc09df71f78e72ef",
"type": "github"
},
"original": {
"owner": "AvengeMedia",
"ref": "stable",
"repo": "DankMaterialShell",
"type": "github"
}
},
"dms-plugin-registry": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1789138529,
"narHash": "sha256-46RwWSOzklur59Plvo8N0YBZYun4M4cwK04+8owhJeo=",
"owner": "AvengeMedia",
"repo": "dms-plugin-registry",
"rev": "5e5d72f980f5f16503b8fd0b8b66c4a3441eecdc",
"type": "github"
},
"original": {
"owner": "AvengeMedia",
"repo": "dms-plugin-registry",
"type": "github"
}
},
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1767039857,
"narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=",
"owner": "NixOS",
"repo": "flake-compat",
"rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "flake-compat",
"type": "github"
}
},
"flake-parts": {
"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_2": {
"inputs": {
"nixpkgs-lib": [
"nur",
@@ -118,6 +275,33 @@
"type": "github"
}
},
"hermes-agent": {
"inputs": {
"flake-parts": "flake-parts",
"home-manager": "home-manager_2",
"nixpkgs": [
"nixpkgs"
],
"npm-lockfile-fix": "npm-lockfile-fix",
"pyproject-build-systems": "pyproject-build-systems",
"pyproject-nix": "pyproject-nix",
"uv2nix": "uv2nix"
},
"locked": {
"lastModified": 1788204567,
"narHash": "sha256-Ii9xP2fKUpvCcwWZuxJ0g3CZ+IL2UZH14pUNvBfdclc=",
"owner": "NousResearch",
"repo": "hermes-agent",
"rev": "29112bef099274229cadff79cdff7bf7b99c4b77",
"type": "github"
},
"original": {
"owner": "NousResearch",
"ref": "v2026.8.31",
"repo": "hermes-agent",
"type": "github"
}
},
"home-manager": {
"inputs": {
"nixpkgs": [
@@ -142,15 +326,36 @@
"home-manager_2": {
"inputs": {
"nixpkgs": [
"hermes-agent",
"nixpkgs"
]
},
"locked": {
"lastModified": 1779113444,
"narHash": "sha256-/L61sT1PIKmGWIQpIh0uJGH/ANvcsf6y4alxtb9kelg=",
"lastModified": 1786487128,
"narHash": "sha256-ad60hrRVhH/bo3Jl1YLzO+QcS3mUNZr9LNJdzhMO2P4=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "74f170c62d57f90e656841f1f699e6bdf40f0a24",
"rev": "f404edbfa4117810c96b97048299242fc50e5362",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "home-manager",
"type": "github"
}
},
"home-manager_3": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1789136855,
"narHash": "sha256-82D7ADWE8erhfALj3dqxAOeQaoa+Bwlsdcp9v2m/ExM=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "d0fd95e15e0c3baf565a9fd4bc352321e2564ea3",
"type": "github"
},
"original": {
@@ -161,20 +366,21 @@
},
"m3ta-nixpkgs": {
"inputs": {
"agents": "agents",
"agents": "agents_2",
"basecamp": "basecamp",
"buzz": "buzz",
"nixpkgs": [
"nixpkgs"
],
"nixpkgs-master": "nixpkgs-master",
"openspec": "openspec"
"opencode": "opencode"
},
"locked": {
"lastModified": 1778508052,
"narHash": "sha256-kxzZvJv757TGfHReR21aX6N/jkGMWzGSy9GQEclYD4Y=",
"lastModified": 1789141095,
"narHash": "sha256-f5NLbwOwSQL+tDDelxps1VFh84obOMyw+ox9gcvE7TU=",
"ref": "refs/heads/master",
"rev": "8113723a48c4afa016881ccd5bc4be3fad2c7d5f",
"revCount": 294,
"rev": "1e0db37c579935b9916c1fcb3d3ed733b4cb3114",
"revCount": 389,
"type": "git",
"url": "ssh://gitea@code.m3ta.dev/m3tam3re/nixpkgs"
},
@@ -235,11 +441,11 @@
},
"nixpkgs-master": {
"locked": {
"lastModified": 1778507606,
"narHash": "sha256-6Yc2dIhijc8G+dbMNocyclxF19dUrjaT+EeXGrXmXlg=",
"lastModified": 1789139724,
"narHash": "sha256-QEoQ8xoSO3H2tmwHNBYFL/5Y8Gt10U+bg5ETMsWXiIM=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "39a7b8d815fcc8b689d56fc4a3fa8de4ef93d169",
"rev": "e27e37949736566430ed2f6157bebcdade8860c5",
"type": "github"
},
"original": {
@@ -251,27 +457,59 @@
},
"nixpkgs_2": {
"locked": {
"lastModified": 1777954456,
"narHash": "sha256-hGdgeU2Nk87RAuZyYjyDjFL6LK7dAZN5RE9+hrDTkDU=",
"lastModified": 1772479524,
"narHash": "sha256-u7nCaNiMjqvKpE+uZz9hE7pgXXTmm5yvdtFaqzSzUQI=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "549bd84d6279f9852cae6225e372cc67fb91a4c1",
"rev": "4215e62dc2cd3bc705b0a423b9719ff6be378a43",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_3": {
"locked": {
"lastModified": 1777954456,
"narHash": "sha256-hGdgeU2Nk87RAuZyYjyDjFL6LK7dAZN5RE9+hrDTkDU=",
"lastModified": 1776683584,
"narHash": "sha256-NuTLMrr10Tng72hurYG8jYQ4XKK8wnpJmOGcPiis96g=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "9dd5558b06dbdacbf635a3dd36dce1b1a7ee3a89",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_4": {
"locked": {
"lastModified": 1789006805,
"narHash": "sha256-xB8mKMOx1IA9vTDNLmJZ6n4wCMq/cuWBBOzGCRnqxrU=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "8ce4ef6cb6f871616146b9fe26d2a5ae594e94fe",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_5": {
"locked": {
"lastModified": 1789006805,
"narHash": "sha256-xB8mKMOx1IA9vTDNLmJZ6n4wCMq/cuWBBOzGCRnqxrU=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "549bd84d6279f9852cae6225e372cc67fb91a4c1",
"rev": "8ce4ef6cb6f871616146b9fe26d2a5ae594e94fe",
"type": "github"
},
"original": {
@@ -281,17 +519,38 @@
"type": "github"
}
},
"nur": {
"npm-lockfile-fix": {
"inputs": {
"flake-parts": "flake-parts",
"nixpkgs": "nixpkgs_3"
"nixpkgs": [
"hermes-agent",
"nixpkgs"
]
},
"locked": {
"lastModified": 1778506944,
"narHash": "sha256-lU0Bleh0reE+WU7j8Uiqsu6ekPav50L8sXsgOvEQS+0=",
"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"
}
},
"nur": {
"inputs": {
"flake-parts": "flake-parts_2",
"nixpkgs": "nixpkgs_5"
},
"locked": {
"lastModified": 1789141061,
"narHash": "sha256-T2+uq8rR7zvUFh7/R8DQgsf2AGrUO3EPpr1iv7Jby8Y=",
"owner": "nix-community",
"repo": "NUR",
"rev": "0166493cfe4e0e9927435c1cfbf5505cfb0d10d1",
"rev": "4250406d791dcb1db2b1ce7bd223ac3ee120cfe3",
"type": "github"
},
"original": {
@@ -300,37 +559,112 @@
"type": "github"
}
},
"openspec": {
"opencode": {
"inputs": {
"nixpkgs": "nixpkgs_3"
},
"locked": {
"lastModified": 1789132601,
"narHash": "sha256-2+j5RuHoqrsnjssZ4VfIfSKzGdrPNFT4nazJ2QxNdu0=",
"owner": "anomalyco",
"repo": "opencode",
"rev": "95daf90670b7c039c436c85537da5fbfe2205b41",
"type": "github"
},
"original": {
"owner": "anomalyco",
"ref": "dev",
"repo": "opencode",
"type": "github"
}
},
"pyproject-build-systems": {
"inputs": {
"nixpkgs": [
"m3ta-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": 1778120451,
"narHash": "sha256-MUSPD16+hoFBfQWYahtNLN2BIFEAlFFo2KNofrc947g=",
"owner": "Fission-AI",
"repo": "OpenSpec",
"rev": "053d8a59d587f3c027a06ad80503a6b43d4f2a92",
"lastModified": 1784591072,
"narHash": "sha256-zP/WaDxrRu8GANZM61+V2LT/7ycEEdoyLWn7M6WzU7M=",
"owner": "pyproject-nix",
"repo": "pyproject.nix",
"rev": "e3b599ca2e7fcf93d4edf65d7f19bbf6491724f3",
"type": "github"
},
"original": {
"owner": "Fission-AI",
"repo": "OpenSpec",
"owner": "pyproject-nix",
"repo": "pyproject.nix",
"type": "github"
}
},
"root": {
"inputs": {
"agenix": "agenix",
"home-manager": "home-manager_2",
"agent-lib": "agent-lib",
"agents": "agents",
"dms": "dms",
"dms-plugin-registry": "dms-plugin-registry",
"hermes-agent": "hermes-agent",
"home-manager": "home-manager_3",
"m3ta-nixpkgs": "m3ta-nixpkgs",
"nix-colors": "nix-colors",
"nixpkgs": "nixpkgs_2",
"nixpkgs": "nixpkgs_4",
"nur": "nur"
}
},
"rust-overlay": {
"inputs": {
"nixpkgs": [
"m3ta-nixpkgs",
"buzz",
"nixpkgs"
]
},
"locked": {
"lastModified": 1788591095,
"narHash": "sha256-Vh+BeLWfbTT9AecazIsQ/Tkg/RzJeX3lEduANf256WA=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "c361047d3a538f547f1617bb6b410411929ac9cc",
"type": "github"
},
"original": {
"owner": "oxalica",
"repo": "rust-overlay",
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
@@ -345,6 +679,53 @@
"repo": "default",
"type": "github"
}
},
"treefmt-nix": {
"inputs": {
"nixpkgs": [
"m3ta-nixpkgs",
"buzz",
"nixpkgs"
]
},
"locked": {
"lastModified": 1786901030,
"narHash": "sha256-WSFCsDSE5ffgD2MqzkM2CYjeFiKhRF/dJUN8uedb6YE=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "27b3b12a8e6375f28ebe122f07d230ca5459bbfa",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"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"
}
}
},
"root": "root",
+36 -9
View File
@@ -13,6 +13,33 @@
m3ta-nixpkgs = {
url = "git+ssh://gitea@code.m3ta.dev/m3tam3re/nixpkgs";
# url = "path:/home/m3tam3re/p/NIX/nixpkgs";
inputs.nixpkgs.follows = "nixpkgs";
};
agents = {
# url = "path:/home/m3tam3re/p/AI/AGENTS";
url = "git+ssh://gitea@code.m3ta.dev/m3tam3re/AGENTS";
};
agent-lib = {
# url = "path:/home/m3tam3re/p/agent-lib-legacy";
url = "git+ssh://gitea@code.m3ta.dev/m3tam3re/agent-lib-legacy";
inputs.nixpkgs.follows = "nixpkgs";
};
hermes-agent = {
url = "github:NousResearch/hermes-agent/v2026.8.31";
inputs.nixpkgs.follows = "nixpkgs";
};
dms = {
url = "github:AvengeMedia/DankMaterialShell/stable";
inputs.nixpkgs.follows = "nixpkgs";
};
dms-plugin-registry = {
url = "github:AvengeMedia/dms-plugin-registry";
inputs.nixpkgs.follows = "nixpkgs";
};
@@ -21,21 +48,21 @@
nur.url = "github:nix-community/NUR";
};
outputs = {
self,
nixpkgs,
...
} @ inputs: let
lib = nixpkgs.lib;
in {
outputs = {self, ...} @ inputs: {
# Home-Manager modules — import in nixos-config via:
# imports = [ inputs.m3ta-home.homeManagerModules.default ];
homeManagerModules = import ./modules { inherit inputs; selfPath = self.outPath; };
homeManagerModules = import ./modules {
inherit inputs;
selfPath = self.outPath;
};
# Library functions — use in nixos-config via:
# m3ta-lib = inputs.m3ta-home.lib;
# imports = [ (m3ta-lib.mkHome { ... }) ];
lib = import ./lib {inherit inputs; selfPath = self.outPath;};
lib = import ./lib {
inherit inputs;
selfPath = self.outPath;
};
# Overlays (re-exports from m3ta-nixpkgs)
overlays = inputs.m3ta-nixpkgs.overlays;
+13 -2
View File
@@ -1,5 +1,16 @@
# lib/default.nix — Entry point for m3ta-home library functions.
#
# Called by flake.nix: import ./lib { inherit inputs; selfPath = self.outPath; }
# Re-exports mkHome and future library functions.
{inputs, selfPath}: import ./mkHome.nix {inherit inputs selfPath;}
# Re-exports mkHome and focused helpers for consumers that should not depend on
# m3ta-home's implementation inputs directly.
{
inputs,
selfPath,
}: let
mkHomeLib = import ./mkHome.nix {inherit inputs selfPath;};
in
mkHomeLib
// {
mkHermesSkillsDir = {system, ...} @ args:
inputs.agent-lib.lib.${system}.mkHermesSkillsDir (builtins.removeAttrs args ["system"]);
}
+13 -1
View File
@@ -19,7 +19,10 @@
# m3ta.home.sets.coding.languages.python.extra = true;
# wayland.windowManager.hyprland.settings.monitor = [ ... ];
#
{inputs, selfPath}: let
{
inputs,
selfPath,
}: let
lib = inputs.nixpkgs.lib;
in {
mkHome = {
@@ -80,6 +83,13 @@ in {
in {
imports =
[
# External Home Manager modules required by selectable profiles
inputs.agent-lib.homeManagerModules.default
inputs.dms.homeModules.default
inputs.dms-plugin-registry.homeModules.default
inputs.nix-colors.homeManagerModules.default
inputs.m3ta-nixpkgs.homeManagerModules.default
# Paths module — must be first, provides m3taHome.paths.srcRoot
../modules/paths.nix
baseModule
@@ -89,6 +99,8 @@ in {
++ contextImport
++ setImports;
_module.args.m3taHomeInputs = inputs;
# Set the flake source root for asset path resolution
"m3ta-home".paths.srcRoot = selfPath;
+9 -3
View File
@@ -8,11 +8,15 @@
{
inputs,
selfPath,
}: let
lib = inputs.nixpkgs.lib;
in {
}: {
default = {
imports = [
# External modules
inputs.agent-lib.homeManagerModules.default
inputs.dms.homeModules.default
inputs.dms-plugin-registry.homeModules.default
inputs.nix-colors.homeManagerModules.default
inputs.m3ta-nixpkgs.homeManagerModules.default
# Paths — must be first, provides "m3ta-home".paths.srcRoot
./paths.nix
@@ -30,6 +34,8 @@ in {
./../users/m3tam3re/identities/work.nix
];
_module.args.m3taHomeInputs = inputs;
# Set the source root for asset path resolution
"m3ta-home".paths.srcRoot = selfPath;
};
+21
View File
@@ -0,0 +1,21 @@
# Ansible — configuration management for rolling out configurations to servers.
# Lives in base so it is available in every identity (private/work) and context.
{
config,
lib,
pkgs,
...
}:
with lib; let
cfg = config.base.cliTools.ansible;
in {
# Enabled by default — base modules are always-on.
options.base.cliTools.ansible.enable = (mkEnableOption "enable Ansible configuration management") // {default = true;};
config = mkIf cfg.enable {
home.packages = with pkgs; [
ansible
ansible-lint
];
};
}
+1 -1
View File
@@ -1,6 +1,7 @@
# CLI tools aggregator — imports all base command-line utilities.
{...}: {
imports = [
./ansible.nix
./bat.nix
./carapace.nix
./direnv.nix
@@ -13,7 +14,6 @@
./packages.nix
./television.nix
./zellij.nix
./zellij-ps.nix
./zoxide.nix
];
}
+33 -26
View File
@@ -2,40 +2,47 @@
{
config,
lib,
options,
...
}:
with lib; let
cfg = config.base.cliTools.fzf;
changeDirWidgetCommand = "fd --type d --exclude .git --follow --hidden";
in {
# Enabled by default — base modules are always-on.
options.base.cliTools.fzf.enable = (mkEnableOption "enable fuzzy finder") // {default = true;};
config = mkIf cfg.enable {
programs.fzf = {
enable = true;
enableFishIntegration = true;
colors = {
"fg" = "#${config.colorScheme.palette.base05}";
"bg" = "#${config.colorScheme.palette.base00}";
"hl" = "#${config.colorScheme.palette.base0E}";
"fg+" = "#${config.colorScheme.palette.base05}";
"bg+" = "#${config.colorScheme.palette.base02}";
"hl+" = "#${config.colorScheme.palette.base0E}";
"info" = "#${config.colorScheme.palette.base09}";
"prompt" = "#${config.colorScheme.palette.base0B}";
"pointer" = "#${config.colorScheme.palette.base08}";
"marker" = "#${config.colorScheme.palette.base08}";
"spinner" = "#${config.colorScheme.palette.base09}";
"header" = "#${config.colorScheme.palette.base03}";
};
defaultOptions = [
"--preview='bat --color=always -n {}'"
"--bind 'ctrl-/:toggle-preview'"
"--header 'Press CTRL-Y to copy command into clipboard'"
"--bind 'ctrl-y:execute-silent(echo -n {2..} | wl-copy)+abort'"
];
defaultCommand = "fd --type f --exclude .git --follow --hidden";
changeDirWidgetCommand = "fd --type d --exclude .git --follow --hidden";
};
programs.fzf =
{
enable = true;
enableFishIntegration = true;
colors = {
"fg" = "#${config.colorScheme.palette.base05}";
"bg" = "#${config.colorScheme.palette.base00}";
"hl" = "#${config.colorScheme.palette.base0E}";
"fg+" = "#${config.colorScheme.palette.base05}";
"bg+" = "#${config.colorScheme.palette.base02}";
"hl+" = "#${config.colorScheme.palette.base0E}";
"info" = "#${config.colorScheme.palette.base09}";
"prompt" = "#${config.colorScheme.palette.base0B}";
"pointer" = "#${config.colorScheme.palette.base08}";
"marker" = "#${config.colorScheme.palette.base08}";
"spinner" = "#${config.colorScheme.palette.base09}";
"header" = "#${config.colorScheme.palette.base03}";
};
defaultOptions = [
"--preview='bat --color=always -n {}'"
"--bind 'ctrl-/:toggle-preview'"
"--header 'Press CTRL-Y to copy command into clipboard'"
"--bind 'ctrl-y:execute-silent(echo -n {2..} | wl-copy)+abort'"
];
defaultCommand = "fd --type f --exclude .git --follow --hidden";
}
// (
if options.programs.fzf ? changeDirWidget
then {changeDirWidget.command = changeDirWidgetCommand;}
else {inherit changeDirWidgetCommand;}
);
};
}
-30
View File
@@ -1,30 +0,0 @@
# Zellij-ps — project-aware Zellij session manager from m3ta-nixpkgs.
# Delegates to `cli.zellij-ps` — the home-manager module namespace provided by
# m3ta-nixpkgs. Requires m3ta-nixpkgs overlays to be applied to pkgs
# (via home-manager.useGlobalPkgs = true in NixOS, or overlays in standalone).
{
config,
lib,
...
}:
with lib; let
cfg = config.base.cliTools.zellijPs;
in {
options.base.cliTools.zellijPs = {
# Enabled by default — base modules are always-on.
enable = (mkEnableOption "enable zellij-ps project session manager") // {default = true;};
projectFolders = mkOption {
type = types.listOf types.path;
description = "Project root folders scanned by zellij-ps.";
default = ["${config.home.homeDirectory}/p"];
};
};
config = mkIf cfg.enable {
cli.zellij-ps = {
enable = true;
projectFolders = cfg.projectFolders;
};
};
}
+5 -8
View File
@@ -1,7 +1,6 @@
# profiles/base/default.nix — Always loaded on every host.
#
# Provides:
# - nix-colors and m3ta-nixpkgs HM module imports
# - Shell (nushell, fish, starship) with enable options
# - CLI tools (bat, carapace, direnv, eza, fzf, lf, nitch, television, zellij, zoxide)
# - Secrets management (pass-wayland)
@@ -9,21 +8,19 @@
# - Base packages
#
# NOTE: Overlays are NOT set here. The consuming flake (nixos-config) handles
# overlays at the NixOS level via nixpkgs.overlays. This module only imports
# HM modules and sets user-level preferences.
# overlays at the NixOS level via nixpkgs.overlays. External HM modules are
# imported by mkHome/modules/default.nix. This module only imports base profile
# submodules and sets user-level preferences.
#
# When used standalone (not through NixOS), overlays should be set by the
# standalone HM configuration or by the consuming flake.
{
inputs,
lib,
m3taHomeInputs,
pkgs,
...
}: {
imports = [
inputs.nix-colors.homeManagerModules.default
inputs.m3ta-nixpkgs.homeManagerModules.default
./shell
./cli-tools
./secrets
@@ -44,7 +41,7 @@
};
# ── Color scheme ──
colorScheme = inputs.nix-colors.colorSchemes.dracula;
colorScheme = m3taHomeInputs.nix-colors.colorSchemes.dracula;
# ── Base packages ──
home.packages = with pkgs; [
+13
View File
@@ -6,6 +6,8 @@
}:
with lib; let
cfg = config.base.shell.nushell;
# User-specific secrets file from agenix, resolved at build time.
secretsFile = "/run/agenix/${config.home.username}-secrets";
in {
# Enabled by default — base modules are always-on.
options.base.shell.nushell.enable = (mkEnableOption "enable nushell") // {default = true;};
@@ -41,6 +43,17 @@ in {
| transpose -r -d
| load-env
}
# Load user-specific secrets from agenix. The secret file is Nushell code
# containing a `load-env { ... }` block, not KEY=VALUE lines.
# `source` resolves literal paths at parse time, so use `null` when absent.
# Path is resolved at Nix build time via config.home.username.
const user_secrets_file = if ("${secretsFile}" | path exists) {
"${secretsFile}"
} else {
null
}
source $user_secrets_file
'';
configFile.text = ''
+3 -1
View File
@@ -11,6 +11,8 @@ in {
options.desktop.apps.office.enable = mkEnableOption "install office and paperwork apps";
config = mkIf cfg.enable {
home.packages = [pkgs.libreoffice-fresh];
# libreoffice-fresh warns: upstream changed versioning; -stable is the
# supported attr now.
home.packages = [pkgs.libreoffice-stable];
};
}
+89 -70
View File
@@ -1,10 +1,23 @@
# Desktop environment aggregator — only loaded when context=desktop.
# Includes window manager, applications, theming, and desktop session config.
{
config,
m3taHomeInputs,
pkgs,
...
}: {
}: let
# WORKAROUND (2026-09-12): hermes-agent v2026.8.31 pins a stale hash for
# the Electron 43.6.0 headers artifact (the CDN swapped the file). Build
# the desktop app from a local copy of upstream's nix/desktop.nix with
# the verified hash. Remove when upstream fixes it and the input is bumped.
hermesDesktopFixed = let
hermesAgent = m3taHomeInputs.hermes-agent.packages.${pkgs.stdenv.hostPlatform.system}.default;
in
pkgs.callPackage ./hermes-desktop.nix {
inherit hermesAgent;
hermesNpmLib = hermesAgent.hermesNpmLib;
hermesSrc = m3taHomeInputs.hermes-agent.outPath;
};
in {
imports = [
./wm
./apps
@@ -38,22 +51,57 @@
};
};
home.sessionVariables = {
WEBKIT_DISABLE_COMPOSITING_MODE = "1";
NIXOS_OZONE_WL = "1";
TERMINAL = "ghostty";
QT_QPA_PLATFORM = "wayland";
XDG_CURRENT_DESKTOP = "Hyprland";
XDG_SESSION_TYPE = "wayland";
XDG_SESSION_DESKTOP = "Hyprland";
};
home = {
sessionVariables = {
WEBKIT_DISABLE_COMPOSITING_MODE = "1";
NIXOS_OZONE_WL = "1";
TERMINAL = "ghostty";
QT_QPA_PLATFORM = "wayland";
XDG_CURRENT_DESKTOP = "Hyprland";
XDG_SESSION_TYPE = "wayland";
XDG_SESSION_DESKTOP = "Hyprland";
};
home.sessionPath = [
"\${XDG_BIN_HOME}"
"\${HOME}/.cargo/bin"
"$HOME/.npm-global/bin"
"$HOME/.cache/.bun/bin"
];
sessionPath = [
"\${XDG_BIN_HOME}"
"\${HOME}/.cargo/bin"
"$HOME/.npm-global/bin"
"$HOME/.cache/.bun/bin"
];
pointerCursor = {
enable = true;
gtk.enable = true;
package = pkgs.bibata-cursors;
name = "Bibata-Modern-Ice";
size = 20;
};
packages = with pkgs; [
appimage-run
bemoji
google-chrome
dconf
(element-desktop.override {
commandLineArgs = "--password-store=gnome-libsecret";
})
hermesDesktopFixed
launch-webapp
file-roller
gsettings-desktop-schemas
seahorse
sushi
ksnip
nwg-look
qt6Packages.qt6ct
rose-pine-hyprcursor
remmina
slack
vivaldi
vivaldi-ffmpeg-codecs
vibetyper
];
};
fonts.fontconfig.enable = true;
@@ -64,59 +112,30 @@
settings = {
font-family = "Fira Code";
copy-on-select = "clipboard";
foreground = "#${config.colorScheme.palette.base05}";
background = "#${config.colorScheme.palette.base00}";
selection-foreground = "#${config.colorScheme.palette.base07}";
selection-background = "#${config.colorScheme.palette.base02}";
cursor-color = "#${config.colorScheme.palette.base05}";
palette = [
"0=#${config.colorScheme.palette.base01}"
"1=#${config.colorScheme.palette.base08}"
"2=#${config.colorScheme.palette.base0B}"
"3=#${config.colorScheme.palette.base0A}"
"4=#${config.colorScheme.palette.base0D}"
"5=#${config.colorScheme.palette.base0E}"
"6=#${config.colorScheme.palette.base0C}"
"7=#${config.colorScheme.palette.base05}"
"8=#${config.colorScheme.palette.base03}"
"9=#${config.colorScheme.palette.base08}"
"10=#${config.colorScheme.palette.base0B}"
"11=#${config.colorScheme.palette.base0A}"
"12=#${config.colorScheme.palette.base0D}"
"13=#${config.colorScheme.palette.base0E}"
"14=#${config.colorScheme.palette.base0C}"
"15=#${config.colorScheme.palette.base07}"
];
theme = "dankcolors";
# foreground = "#${config.colorScheme.palette.base05}";
# background = "#${config.colorScheme.palette.base00}";
# selection-foreground = "#${config.colorScheme.palette.base07}";
# selection-background = "#${config.colorScheme.palette.base02}";
# cursor-color = "#${config.colorScheme.palette.base05}";
# palette = [
# "0=#${config.colorScheme.palette.base01}"
# "1=#${config.colorScheme.palette.base08}"
# "2=#${config.colorScheme.palette.base0B}"
# "3=#${config.colorScheme.palette.base0A}"
# "4=#${config.colorScheme.palette.base0D}"
# "5=#${config.colorScheme.palette.base0E}"
# "6=#${config.colorScheme.palette.base0C}"
# "7=#${config.colorScheme.palette.base05}"
# "8=#${config.colorScheme.palette.base03}"
# "9=#${config.colorScheme.palette.base08}"
# "10=#${config.colorScheme.palette.base0B}"
# "11=#${config.colorScheme.palette.base0A}"
# "12=#${config.colorScheme.palette.base0D}"
# "13=#${config.colorScheme.palette.base0E}"
# "14=#${config.colorScheme.palette.base0C}"
# "15=#${config.colorScheme.palette.base07}"
# ];
};
};
home.pointerCursor = {
gtk.enable = true;
package = pkgs.bibata-cursors;
name = "Bibata-Modern-Ice";
size = 20;
};
home.packages = with pkgs; [
appimage-run
bemoji
eigent
(element-desktop.override {
commandLineArgs = "--password-store=gnome-libsecret";
})
launch-webapp
file-roller
hyprpanel
hyprpaper-random
seahorse
sushi
ksnip
nwg-look
rose-pine-hyprcursor
remmina
slack
vivaldi
vivaldi-ffmpeg-codecs
vibetyper
];
}
@@ -0,0 +1,244 @@
# hermes-desktop.nix — local copy of hermes-agent's nix/desktop.nix
#
# WORKAROUND for an upstream build failure (hermes-agent v2026.8.31):
#
# Upstream pins sha256-f8bSbLRmtbP93CJAvEBs+sHWDZ1xP2bcpLhC1EnOmZU=
# for https://artifacts.electronjs.org/headers/dist/v43.6.0/node-v43.6.0-headers.tar.gz
# The Electron CDN swapped that artifact, so the pinned hash no longer
# matches what the server serves today (verified 2026-09-12 via
# `nix store prefetch-file`). Upstream has fixed this class of breakage
# repeatedly ("fix electron headers sha" commits); main is not fixed yet.
#
# Differences from upstream nix/desktop.nix:
# 1. electron headers sha256 per electron version, with a clear throw
# for unknown versions (upstream hardcodes one hash).
# 2. icon.png / linux_desktop_entry.py resolve against `hermesSrc`
# (the flake input checkout) instead of relative repo paths.
#
# REMOVE THIS FILE and the hermesDesktopFixed let-binding in default.nix
# once upstream ships the corrected hash and the hermes-agent input is
# bumped past that release.
{
pkgs,
lib,
stdenv,
makeWrapper,
hermesNpmLib,
electron,
hermesAgent,
python3,
# Checkout of the hermes-agent flake input (outPath), used for files
# that upstream references with relative paths inside its own repo.
hermesSrc,
# Environment to bake into the launcher. A GUI launcher reads none of the
# shell profile, so a variable that an interactive shell exports does not
# reach an app that the desktop menu starts. The Home Manager module passes
# HERMES_HOME and HERMES_MANAGED here, which gives the app the same state
# directory as the services.
extraEnv ? {},
# Shell lines to run before the app starts. A secret belongs here and never
# in extraEnv: makeWrapper writes a --set value into the Nix store, which
# all users can read. A --run line reads the value from a runtime path at
# each start instead.
extraRun ? [],
...
}: let
# Each flag goes on its own continued line, and the leading backslash is
# inside the generated string. An empty attribute set then adds no text
# at all, and cannot leave a backslash above a blank line. That fault ends the
# makeWrapper command early, and the next flag runs as a shell command.
extraEnvFlags = lib.concatMapStrings (
name: " \\\n --set ${name} ${lib.escapeShellArg (toString extraEnv.${name})}"
) (lib.attrNames extraEnv);
extraRunFlags = lib.concatMapStrings (line: " \\\n --run ${lib.escapeShellArg line}") extraRun;
# Electron's CDN has re-uploaded header artifacts for the same version
# before, which silently changes their hash. Keep one verified hash per
# electron version and fail loudly (instead of with a cryptic FOD
# mismatch) whenever a bump needs a new one.
electronHeaderHashes = {
"43.6.0" = "sha256-xDgc5PpkcLpWHnlqVcjBD3SxJKtkUoSGLnJaSSrxJtI=";
};
electronHeaders = pkgs.fetchurl {
url = "https://artifacts.electronjs.org/headers/dist/v${electron.version}/node-v${electron.version}-headers.tar.gz";
sha256 =
electronHeaderHashes.${
electron.version
}
or (throw ''
hermes-desktop workaround: no verified Electron headers hash for version ${electron.version}.
Run: nix store prefetch-file https://artifacts.electronjs.org/headers/dist/v${electron.version}/node-v${electron.version}-headers.tar.gz
and add it to electronHeaderHashes in profiles/contexts/desktop/hermes-desktop.nix (m3ta-home).
'');
};
# node-pty ships no Electron-tagged prebuild we can trust to match this
# exact nixpkgs electron version, so it's always compiled from source
# against Electron's own headers (not whatever Node ran `npm`).
targetPlatform =
if stdenv.hostPlatform.isDarwin
then "darwin"
else if stdenv.hostPlatform.isLinux
then "linux"
else throw "hermes-desktop: unsupported host platform for node-pty staging";
targetArch =
if stdenv.hostPlatform.isAarch64
then "arm64"
else if stdenv.hostPlatform.isx86_64
then "x64"
else throw "hermes-desktop: unsupported host arch for node-pty staging";
# Build the renderer (dist/ + electron/ + package.json).
renderer = hermesNpmLib.buildNpmPackage {
dirs = [
"apps/desktop"
"apps/shared"
];
pname = "hermes-desktop-renderer";
doCheck = true;
buildPhase = ''
runHook preBuild
mkdir -p apps/desktop/build
patchShebangs .
pushd apps/desktop
# typecheck :3
npm exec -- tsc -b
# build the renderer bundle
# vite's emptyOutDir wipes dist/ on every run
# so it has to be first
npm exec -- vite build
# build the electron bundle
node scripts/bundle-electron-main.mjs
# Compile node-pty against Electron's actual ABI (the nixpkgs
# `electron` we ship). Headers come from a pinned fetchurl input
# since the sandbox has no network here, so node-gyp's
# normal --disturl download path can't run.
mkdir -p "$TMPDIR/electron-headers"
tar -xzf ${electronHeaders} -C "$TMPDIR/electron-headers" --strip-components=1
${lib.getExe hermesNpmLib.node-gyp} rebuild \
--directory=../../node_modules/node-pty \
--build-from-source \
--runtime=electron \
--target=${electron.version} \
--nodedir="$TMPDIR/electron-headers" \
--disturl="" \
--offline
# Target platform/arch come from stdenv.hostPlatform, not the
# build host's own process.platform/arch.
node scripts/stage-native-deps.mjs ${targetPlatform} ${targetArch}
popd
runHook postBuild
'';
checkPhase = ''
runHook preCheck
pushd apps/desktop
npm run postbuild
# validate staged node-pty native binary is present.
STAGED_PTY_NODE="./dist/node_modules/node-pty/build/Release/pty.node"
if [ ! -f "$STAGED_PTY_NODE" ]; then
echo "FATAL: Missing staged node-pty native binary at $STAGED_PTY_NODE"
echo "node-pty must be compiled natively"
exit 1
fi
popd
runHook postCheck
'';
installPhase = ''
runHook preInstall
mkdir -p $out
# vite writes to apps/desktop/dist/ (we cd'd there in buildPhase).
# stage-native-deps.mjs stages node-pty into dist/node_modules/node-pty,
# so copying dist/ wholesale carries the native dep along with the
# esbuild bundle that require()s it. apps/desktop/build was created
# before the cd.
cp -rn apps/desktop/dist $out/
echo '{"schemaVersion":1,"commit":"nix-dummy-commit","branch":"nix","dirty":false,"source":"nix"}' > $out/install-stamp.json
cp -n apps/desktop/package.json $out/
runHook postInstall
'';
};
in
# Electron wrapper: nixpkgs' electron binary pointed at the renderer dir.
stdenv.mkDerivation {
pname = "hermes-desktop";
inherit (renderer) version;
dontUnpack = true;
dontBuild = true;
nativeBuildInputs = [
makeWrapper
python3
];
installPhase = ''
runHook preInstall
mkdir -p $out/share/hermes-desktop $out/bin
cp -r ${renderer}/* $out/share/hermes-desktop/
# Standard nixpkgs pattern for electron-builder apps: patch process.resourcesPath
# to point to the app's directory. In Nix, unpackaged electron defaults this
# to the electron distribution's resources path, breaking extraResources lookups.
substituteInPlace $out/share/hermes-desktop/dist/electron-main.mjs \
--replace-fail "process.resourcesPath" "'$out/share/hermes-desktop'"
# Wrap the nixpkgs electron binary to launch our app. Set
# HERMES_DESKTOP_HERMES to the absolute path of the nix-built `hermes`
# binary so the desktop's resolver step 4 ("existing Hermes CLI on
# PATH") uses our fully wrapped binary venv with all deps,
# bundled skills/plugins, runtime PATH (ripgrep/git/ffmpeg/etc).
# No reimplementation of the agent resolver in the wrapper.
makeWrapper ${lib.getExe electron} $out/bin/hermes-desktop \
--add-flags "$out/share/hermes-desktop" \
--set HERMES_DESKTOP_HERMES "${lib.getExe hermesAgent}" \
--set ELECTRON_IS_DEV 0${extraEnvFlags}${extraRunFlags}
# XDG launcher entry
mkdir -p $out/share/applications $out/share/icons/hicolor/1024x1024/apps
install -m 0644 ${hermesSrc}/apps/desktop/assets/icon.png \
$out/share/icons/hicolor/1024x1024/apps/hermes.png
export PYTHONPATH=$(mktemp -d)
cp ${hermesSrc}/hermes_cli/linux_desktop_entry.py "$PYTHONPATH/linux_desktop_entry.py"
export DESKTOP_EXEC="$out/bin/hermes-desktop"
export DESKTOP_ICON="$out/share/icons/hicolor/1024x1024/apps/hermes.png"
python3 -c 'import os; from linux_desktop_entry import render_desktop_entry; print(render_desktop_entry(os.environ["DESKTOP_EXEC"], os.environ["DESKTOP_ICON"]))' > $out/share/applications/hermes.desktop
runHook postInstall
'';
passthru = {
inherit (renderer.passthru) packageJsonPath;
};
meta = with lib; {
description = "Native Electron desktop shell for Hermes Agent";
homepage = "https://github.com/NousResearch/hermes-agent";
license = licenses.mit;
platforms = platforms.unix;
mainProgram = "hermes-desktop";
};
}
+7 -6
View File
@@ -1,4 +1,4 @@
# GTK and Qt theming — Dracula theme with matching icons and cursor.
# GTK and Qt theming — system-wide dark Adwaita/libadwaita-compatible theme.
{
pkgs,
config,
@@ -6,18 +6,19 @@
}: {
qt = {
enable = true;
platformTheme.name = "gtk";
platformTheme.name = "gtk3";
};
gtk = {
enable = true;
colorScheme = "dark";
theme = {
name = "Dracula";
package = pkgs.dracula-theme;
name = "adw-gtk3-dark";
package = pkgs.adw-gtk3;
};
iconTheme = {
name = "Dracula";
package = pkgs.dracula-icon-theme;
name = "Papirus-Dark";
package = pkgs.papirus-icon-theme;
};
gtk4.theme = config.gtk.theme;
};
+1
View File
@@ -4,5 +4,6 @@
./hyprland.nix
./wayland.nix
./rofi.nix
./dms.nix
];
}
+29
View File
@@ -0,0 +1,29 @@
# DankMaterialShell user-session configuration.
# External DMS Home-Manager modules are imported by mkHome/modules/default.nix
# so this file only owns the m3ta-home feature flag and desired defaults.
{
config,
lib,
...
}:
with lib; let
cfg = config.desktop.wm.dms;
in {
options.desktop.wm.dms.enable = mkEnableOption "DankMaterialShell desktop shell";
config = mkIf cfg.enable {
programs.dank-material-shell = {
enable = true;
systemd.enable = true;
enableDynamicTheming = true;
enableClipboardPaste = true;
plugins = {
dankBatteryAlerts.enable = true;
emojiLauncher.enable = true;
dankPomodoroTimer.enable = true;
dankVault.enable = true;
};
};
};
}
+543 -247
View File
@@ -1,6 +1,4 @@
# Hyprland window manager — Lua config for Hyprland 0.55+
# Home-Manager configType = "lua" generates hyprland.lua using hl.* API.
# API reference: https://wiki.hypr.land/Configuring/Start/
# Hyprland window manager with keybindings, window rules, idle/lock, and hyprpaper.
{
config,
lib,
@@ -8,49 +6,109 @@
}:
with lib; let
cfg = config.desktop.wm.hyprland;
p = config.colorScheme.palette;
lua = lib.generators.mkLuaInline;
luaString = builtins.toJSON;
mkEnvVar = name: value: {
_args = [
name
value
];
};
modKey = key: lua ''mainMod .. " + ${key}"'';
mkDispatcher = expression: lua expression;
execCmd = command: "hl.dsp.exec_cmd(${luaString command})";
execExpr = expression: "hl.dsp.exec_cmd(${expression})";
mkBinding = keys: dispatcher: {
_args = [
keys
(mkDispatcher dispatcher)
];
};
mkBindingWithOptions = keys: dispatcher: options: {
_args = [
keys
(mkDispatcher dispatcher)
options
];
};
startupCommand = command: {
_args = [
"hyprland.start"
(lua ''
function()
hl.exec_cmd(${luaString command})
end
'')
];
};
focusWorkspace = workspace: "hl.dsp.focus({ workspace = ${luaString workspace} })";
moveToWorkspace = workspace: "hl.dsp.window.move({ workspace = ${luaString workspace} })";
in {
options.desktop.wm.hyprland.enable = mkEnableOption "Hyprland window manager";
config = mkIf cfg.enable {
wayland.windowManager.hyprland = {
configType = "lua";
extraLuaFiles."00-dms" = {
autoLoad = true;
content = ''
-- DMS setup/runtime owns these modules. Load only the Lua equivalents
-- of the pre-migration active sources, before local Home Manager
-- settings, preserving the old source-first order without enabling new
-- DMS default binds or rules.
--
-- Keep fresh Home Manager generations usable before DMS has written
-- ~/.config/hypr/dms/*.lua.
local function require_if_present(module)
if package.searchpath(module, package.path) ~= nil then
require(module)
end
end
require_if_present("dms.colors")
require_if_present("dms.layout")
require_if_present("dms.outputs")
require_if_present("dms.binds-user")
'';
};
settings = {
# ── Lua local variables (rendered as: local mainMod = "SUPER") ──
mainMod = {_var = "SUPER";};
terminal = {_var = "ghostty";};
mainMod = {
_var = "SUPER";
};
terminal = {
_var = "ghostty";
};
# ── Config sections (rendered as: hl.config({...})) ──
config = {
xwayland = {force_zero_scaling = true;};
xwayland = {
force_zero_scaling = true;
};
input = {
kb_layout = "de,us";
kb_layout = "us,de";
kb_variant = "";
kb_model = "";
kb_rules = "";
kb_options = "ctrl:nocaps";
follow_mouse = 1;
};
general = {
gaps_in = 5;
gaps_out = 5;
border_size = 1;
col = {
active_border = {colors = ["rgba(9742b5ee)" "rgba(9742b5ee)"]; angle = 45;};
inactive_border = "rgba(${p.base03}aa)";
};
layout = "dwindle";
};
decoration = {
shadow = {
enabled = true;
range = 60;
render_power = 3;
color = "rgba(${p.base00}66)";
# color = "rgba(${config.colorScheme.palette.base00}66)";
offset = "1 2";
scale = 0.97;
};
rounding = 8;
@@ -62,258 +120,496 @@ in {
active_opacity = 0.9;
inactive_opacity = 0.5;
};
animations = {enabled = true;};
animations = {
enabled = true;
};
dwindle = {
pseudotile = true;
# pseudotile = true; # TODO
preserve_split = true;
};
master = {new_status = "master";};
master = {
new_status = "master";
};
};
# ── Environment variables (rendered as: hl.env("KEY", "VALUE")) ──
env = [
{ _args = ["XCURSOR_SIZE" "32"]; }
{ _args = ["HYPRCURSOR_THEME" "Bibata-Modern-Ice"]; }
{ _args = ["WLR_NO_HARDWARE_CURSORS" "1"]; }
{ _args = ["GTK_THEME" "Dracula"]; }
{ _args = ["XDG_CURRENT_DESKTOP" "Hyprland"]; }
{ _args = ["XDG_SESSION_TYPE" "wayland"]; }
{ _args = ["XDG_SESSION_DESKTOP" "Hyprland"]; }
{ _args = ["XKB_DEFAULT_LAYOUT" "de"]; }
{ _args = ["NIXOS_OZONE_WL" "1"]; }
on = [
(startupCommand "vibetyper")
];
"env" = [
(mkEnvVar "XCURSOR_SIZE" "32")
(mkEnvVar "HYPRCURSOR_THEME" "Bibata-Modern-Ice")
(mkEnvVar "WLR_NO_HARDWARE_CURSORS" "1")
(mkEnvVar "XDG_CURRENT_DESKTOP" "Hyprland")
(mkEnvVar "XDG_SESSION_TYPE" "wayland")
(mkEnvVar "XDG_SESSION_DESKTOP" "Hyprland")
(mkEnvVar "XKB_DEFAULT_LAYOUT" "de")
(mkEnvVar "NIXOS_OZONE_WL" "1")
(mkEnvVar "QT_QPA_PLATFORM" "wayland;xcb")
(mkEnvVar "QT_QPA_PLATFORMTHEME" "gtk3")
(mkEnvVar "QT_QPA_PLATFORMTHEME_QT6" "gtk3")
];
# ── Per-device config (rendered as: hl.device({...})) ──
device = [
{name = "epic-mouse-v1"; sensitivity = -0.5;}
{name = "zsa-technology-labs-moonlander-mark-i"; kb_layout = "us";}
{name = "keychron-keychron-k7"; kb_layout = "us";}
{
name = "video-bus";
kb_layout = "de,us";
kb_options = "ctrl:nocaps";
}
{
name = "razer-razer-pro-click-v2-vertical-edition-keyboard";
kb_layout = "de,us";
kb_options = "ctrl:nocaps";
}
{
name = "razer-razer-pro-click-v2-vertical-edition-1";
kb_layout = "de,us";
kb_options = "ctrl:nocaps";
}
{
name = "vibe-typer-virtual-keyboard";
kb_layout = "de";
kb_options = "ctrl:nocaps";
}
{
name = "keychron-keychron-k7";
kb_layout = "us,de";
kb_options = "ctrl:nocaps";
}
# Moonlander Sub-Devices bleiben us zuerst (de als zweites Layout):
{
name = "zsa-technology-labs-moonlander-mark-i-consumer-control";
kb_layout = "us,de";
kb_options = "ctrl:nocaps";
}
{
name = "zsa-technology-labs-moonlander-mark-i-keyboard";
kb_layout = "us,de";
kb_options = "ctrl:nocaps";
}
{
name = "zsa-technology-labs-moonlander-mark-i-system-control";
kb_layout = "us,de";
kb_options = "ctrl:nocaps";
}
{
name = "asustek-computer-inc.-gz302ea-keyboard";
kb_layout = "de,us";
kb_options = "ctrl:nocaps";
}
{
name = "asustek-computer-inc.-gz302ea-keyboard-2";
kb_layout = "de,us";
kb_options = "ctrl:nocaps";
}
];
};
# ── Complex Lua: curves, animations, binds, window rules, startup ──
extraConfig = ''
-- Bezier curves
hl.curve("myBezier", { type = "bezier", points = { {0.05, 0.9}, {0.1, 1.05} } })
-- Animations
hl.animation({ leaf = "windows", enabled = true, speed = 7, bezier = "myBezier" })
hl.animation({ leaf = "windowsOut", enabled = true, speed = 7, bezier = "default", style = "popin 80%" })
hl.animation({ leaf = "border", enabled = true, speed = 10, bezier = "default" })
hl.animation({ leaf = "borderangle", enabled = true, speed = 8, bezier = "default" })
hl.animation({ leaf = "fade", enabled = true, speed = 7, bezier = "default" })
hl.animation({ leaf = "workspaces", enabled = true, speed = 6, bezier = "default" })
-- Keybinds: terminals & editors
hl.bind(mainMod .. " + Return", hl.dsp.exec_cmd(terminal .. " nu -c zellij-ps"))
hl.bind(mainMod .. " + T", hl.dsp.exec_cmd(terminal .. " -e nu -c 'nitch; exec nu'"))
hl.bind(mainMod .. " + Shift + T", hl.dsp.exec_cmd("launch-timer"))
hl.bind(mainMod .. " + N", hl.dsp.exec_cmd(terminal .. " -e nvim"))
hl.bind(mainMod .. " + Z", hl.dsp.exec_cmd("uwsm app -- zeditor"))
-- Keybinds: misc
hl.bind(mainMod .. " + O", hl.dsp.exec_cmd("hyprctl dispatch setprop activewindow opaque toggle"))
hl.bind(mainMod .. " + B", hl.dsp.exec_cmd("uwsm app -- thunar"))
hl.bind(mainMod .. " + Shift + B", hl.dsp.exec_cmd("uwsm app -- vivaldi"))
hl.bind(mainMod .. " + Escape", hl.dsp.exec_cmd("uwsm app -- wlogout -p layer-shell"))
-- Keybinds: window management
hl.bind(mainMod .. " + Space", hl.dsp.window.float({ action = "toggle" }))
hl.bind(mainMod .. " + Q", hl.dsp.window.close())
hl.bind(mainMod .. " + M", hl.dsp.exit())
hl.bind(mainMod .. " + F", hl.dsp.window.fullscreen())
hl.bind(mainMod .. " + Shift + V", hl.dsp.window.float({ action = "toggle" }))
-- Keybinds: launchers
hl.bind(mainMod .. " + D", hl.dsp.exec_cmd('uwsm app -- rofi -show drun -run-command "uwsm app -- {cmd}"'))
hl.bind(mainMod .. " + V", hl.dsp.exec_cmd("uwsm app -- cliphist list | rofi -dmenu | cliphist decode | wl-copy"))
hl.bind(mainMod .. " + C", hl.dsp.exec_cmd("bash -c 'FILE=/tmp/screenshot_$(date +%s).png; grim -g \"$(slurp)\" \"$FILE\" && ksnip \"$FILE\"'"))
hl.bind(mainMod .. " + Shift + S", hl.dsp.exec_cmd("uwsm app -- rofi -show emoji"))
hl.bind(mainMod .. " + P", hl.dsp.exec_cmd("uwsm app -- rofi-pass"))
hl.bind(mainMod .. " + Shift + P", hl.dsp.window.pseudo())
-- Keybinds: STT push-to-talk
hl.bind(mainMod .. " + R", hl.dsp.exec_cmd("stt-ptt start"))
hl.bind(mainMod .. " + R", hl.dsp.exec_cmd("stt-ptt stop"), { release = true })
hl.bind(mainMod .. " + S", hl.dsp.exec_cmd("stt-ptt start"))
hl.bind(mainMod .. " + S", hl.dsp.exec_cmd("stt-ptt format-stop"), { release = true })
-- Keybinds: focus
hl.bind(mainMod .. " + H", hl.dsp.focus({ direction = "left" }))
hl.bind(mainMod .. " + L", hl.dsp.focus({ direction = "right" }))
hl.bind(mainMod .. " + K", hl.dsp.focus({ direction = "up" }))
hl.bind(mainMod .. " + J", hl.dsp.focus({ direction = "down" }))
-- Keybinds: workspaces (1-10)
for i = 1, 10 do
local key = i % 10
hl.bind(mainMod .. " + " .. key, hl.dsp.focus({ workspace = i }))
hl.bind(mainMod .. " + Shift + " .. key, hl.dsp.window.move({ workspace = i }))
end
hl.bind(mainMod .. " + mouse_down", hl.dsp.focus({ workspace = "e+1" }))
hl.bind(mainMod .. " + mouse_up", hl.dsp.focus({ workspace = "e-1" }))
-- Keybinds: mouse (drag & resize)
hl.bind(mainMod .. " + mouse:272", hl.dsp.window.drag(), { mouse = true })
hl.bind(mainMod .. " + mouse:273", hl.dsp.window.resize(), { mouse = true })
-- Window rules: floating dialogs
for _, cls in ipairs({
"file_progress", "confirm", "dialog", "download",
"notification", "error", "splash", "confirmreset",
}) do
hl.window_rule({ match = { class = cls }, float = true })
end
-- Window rules: title-based floating
hl.window_rule({ match = { title = "Open File" }, float = true })
hl.window_rule({ match = { title = "branchdialog" }, float = true })
-- Window rules: audio/video
hl.window_rule({ match = { class = "pavucontrol-qt" }, float = true })
hl.window_rule({ match = { class = "pavucontrol" }, float = true })
hl.window_rule({ match = { class = "^espanso$" }, float = true })
-- Window rules: wlogout
hl.window_rule({ match = { class = "wlogout" }, fullscreen = true })
hl.window_rule({ match = { title = "wlogout" }, float = true, fullscreen = true })
-- Window rules: mpv
hl.window_rule({ match = { class = "mpv" }, float = true, idle_inhibit = "focus", opacity = 1.0 })
-- Window rules: misc floating
hl.window_rule({ match = { title = "^Media viewer$" }, float = true })
hl.window_rule({ match = { title = "^Volume Control$" }, float = true })
hl.window_rule({ match = { title = "^Picture-in-Picture$" }, float = true })
-- Window rules: pomodoro (consolidated)
hl.window_rule({
match = { title = "^floating-pomodoro$" },
float = true, size = { 250, 50 }, move = { 12, "monitor_h-150" }, pin = true,
})
-- Window rules: streamlabs (consolidated)
hl.window_rule({
match = { initial_title = ".*streamlabs.com.*" },
float = true, pin = true, size = { 800, 400 }, opacity = 0.5,
idle_inhibit = "focus", no_anim = true, decorate = false, no_shadow = true, no_blur = true,
})
hl.window_rule({ match = { initial_title = ".*alert-box.*" }, move = { "100%-820", 102 } })
hl.window_rule({ match = { initial_title = ".*chat-box.*" }, move = { "100%-820", 512 } })
-- Window rules: vibe-typer
hl.window_rule({ match = { class = "^vibe-typer$", title = "^Recording Indicator$" }, no_blur = true })
-- Window rules: xwayland border
hl.window_rule({ match = { xwayland = true }, border_color = "rgb(ffffff)" })
-- Startup commands
hl.on("hyprland.start", function()
hl.exec_cmd("hyprpanel")
hl.exec_cmd("while ! hyprpaper-random; do sleep 0.5; done")
hl.exec_cmd("wl-paste --type text --watch cliphist store")
hl.exec_cmd("wl-paste --type image --watch cliphist store")
hl.exec_cmd("vibetyper")
end)
'';
};
services.hypridle = {
enable = true;
settings = {
general = {
before_sleep_cmd = "hyprlock";
after_sleep_cmd = "hyprctl dispatch dpms on";
inhibit_sleep = 3;
curve = {
_args = [
"myBezier"
(lua ''{ type = "bezier", points = { { 0.05, 0.9 }, { 0.1, 1.05 } } }'')
];
};
listener = [
animation = [
{
timeout = 300;
on-timeout = "hyprlock";
leaf = "windows";
enabled = true;
speed = 7;
bezier = "myBezier";
}
{
timeout = 420;
on-timeout = "hyprctl dispatch dpms off";
on-resume = "hyprctl dispatch dpms on";
leaf = "windowsOut";
enabled = true;
speed = 7;
bezier = "default";
style = "popin 80%";
}
{
leaf = "border";
enabled = true;
speed = 10;
bezier = "default";
}
{
leaf = "borderangle";
enabled = true;
speed = 8;
bezier = "default";
}
{
leaf = "fade";
enabled = true;
speed = 7;
bezier = "default";
}
{
leaf = "workspaces";
enabled = true;
speed = 6;
bezier = "default";
}
];
window_rule = [
{
match.class = "file_progress";
float = true;
}
{
match.class = "confirm";
float = true;
}
{
match.class = "dialog";
float = true;
}
{
match.class = "download";
float = true;
}
{
match.class = "notification";
float = true;
}
{
match.class = "error";
float = true;
}
{
match.class = "splash";
float = true;
}
{
match.class = "confirmreset";
float = true;
}
{
match.title = "Open File";
float = true;
}
{
match.title = "branchdialog";
float = true;
}
{
match.class = "pavucontrol-qt";
float = true;
}
{
match.class = "pavucontrol";
float = true;
}
{
match.class = "class:^(espanso)$";
float = true;
}
{
match.class = "wlogout";
fullscreen = true;
}
{
match.title = "wlogout";
float = true;
}
{
match.title = "wlogout";
fullscreen = true;
}
{
match.class = "mpv";
float = true;
}
{
match.class = "mpv";
idle_inhibit = "focus";
}
{
match.class = "mpv";
opacity = "1.0 override";
}
{
match.title = "^(Media viewer)$";
float = true;
}
{
match.title = "^(Volume Control)$";
float = true;
}
{
match.title = "^(Picture-in-Picture)$";
float = true;
}
{
match.title = "^(floating-pomodoro)$";
float = true;
}
{
match.title = "^(floating-pomodoro)$";
size = "250 50";
}
{
match.title = "^(floating-pomodoro)$";
move = "12 (monitor_h-150)";
}
{
match.title = "^(floating-pomodoro)$";
pin = true;
}
{
match.initial_title = ".*streamlabs.com.*";
float = true;
}
{
match.initial_title = ".*streamlabs.com.*";
pin = true;
}
{
match.initial_title = ".*streamlabs.com.*";
size = "800 400";
}
{
match.initial_title = ".*alert-box.*";
move = "100%-820 102";
}
{
match.initial_title = ".*chat-box.*";
move = "100%-820 512";
}
{
match.initial_title = ".*streamlabs.com.*";
opacity = "0.5 override";
}
{
match.initial_title = ".*streamlabs.com.*";
idle_inhibit = "focus";
}
{
match.initial_title = ".*streamlabs.com.*";
no_anim = true;
}
{
match.initial_title = ".*streamlabs.com.*";
decorate = false;
}
{
match.initial_title = ".*streamlabs.com.*";
no_shadow = true;
}
{
match.initial_title = ".*streamlabs.com.*";
no_blur = true;
}
{
match = {
class = "^vibe-typer$";
title = "^Recording Indicator$";
};
# 1.5.x renders a small bottom-center panel, not a fullscreen overlay.
# Without float it gets tiled by dwindle and clipped to tile size.
float = true;
}
{
match = {
class = "^vibe-typer$";
title = "^Recording Indicator$";
};
pin = true;
}
{
match = {
class = "^vibe-typer$";
title = "^Recording Indicator$";
};
no_blur = true;
}
{
match = {
class = "^vibe-typer$";
title = "^Recording Indicator$";
};
no_shadow = true;
}
{
match = {
class = "^vibe-typer$";
title = "^Recording Indicator$";
};
no_anim = true;
}
{
match = {
class = "^vibe-typer$";
title = "^Recording Indicator$";
};
border_size = 0;
}
{
match = {
class = "^vibe-typer$";
title = "^Recording Indicator$";
};
no_focus = true;
}
{
match.xwayland = true;
border_color = "rgb(ffffff)";
}
];
"bind" = [
# mainMod + return intentionally remains disabled from the previous config.
(mkBinding (modKey "t") (execExpr ''terminal .. " -e nu -c 'nitch; exec nu'"''))
(mkBinding (modKey "SHIFT + t") (execCmd "launch-timer"))
(mkBinding (modKey "n") (execExpr ''terminal .. " -e nvim"''))
(mkBinding (modKey "z") (execCmd "uwsm app -- zeditor"))
(mkBinding (modKey "o") ''hl.dsp.window.set_prop({ prop = "opaque", value = "toggle" })'')
(mkBinding (modKey "r") (
execCmd ''hyprctl dispatch focuswindow "initialtitle:.*alert-box.*" && hyprctl dispatch moveactive exact 4300 102 && hyprctl dispatch focuswindow "initialtitle:.*chat-box.*" && hyprctl dispatch moveactive exact 4300 512''
))
(mkBinding (modKey "b") (execCmd "uwsm app -- thunar"))
(mkBinding (modKey "SHIFT + B") (execCmd "uwsm app -- vivaldi"))
(mkBinding (modKey "Escape") (execCmd "uwsm app -- dms ipc call powermenu toggle"))
(mkBinding (modKey "q") "hl.dsp.window.close()")
(mkBinding (modKey "M") "hl.dsp.exit()")
(mkBinding (modKey "F") "hl.dsp.window.fullscreen({})")
(mkBinding (modKey "SHIFT + V") ''hl.dsp.window.float({ action = "toggle" })'')
(mkBinding (modKey "D") (execCmd "uwsm app -- dms ipc call spotlight toggle"))
(mkBinding (modKey "V") (execCmd "uwsm app -- dms ipc call clipboard toggle"))
(mkBinding (modKey "C") (
execCmd "bash -c 'FILE=/tmp/screenshot_$(date +%s).png; grim -g \"$(slurp)\" \"$FILE\" && ksnip \"$FILE\"'"
))
(mkBinding (modKey "SHIFT + S") (execCmd "uwsm app -- rofi -show emoji"))
(mkBinding (modKey "P") (execCmd "uwsm app -- rofi-pass"))
(mkBinding (modKey "SHIFT + P") "hl.dsp.window.pseudo({})")
(mkBinding (modKey "R") (execCmd "stt-ptt start"))
(mkBinding (modKey "S") (execCmd "stt-ptt start"))
(mkBinding (modKey "h") ''hl.dsp.focus({ direction = "l" })'')
(mkBinding (modKey "l") ''hl.dsp.focus({ direction = "r" })'')
(mkBinding (modKey "k") ''hl.dsp.focus({ direction = "u" })'')
(mkBinding (modKey "j") ''hl.dsp.focus({ direction = "d" })'')
(mkBinding (modKey "1") (focusWorkspace "1"))
(mkBinding (modKey "2") (focusWorkspace "2"))
(mkBinding (modKey "3") (focusWorkspace "3"))
(mkBinding (modKey "4") (focusWorkspace "4"))
(mkBinding (modKey "5") (focusWorkspace "5"))
(mkBinding (modKey "6") (focusWorkspace "6"))
(mkBinding (modKey "7") (focusWorkspace "7"))
(mkBinding (modKey "8") (focusWorkspace "8"))
(mkBinding (modKey "9") (focusWorkspace "9"))
(mkBinding (modKey "0") (focusWorkspace "10"))
(mkBinding (modKey "SHIFT + 1") (moveToWorkspace "1"))
(mkBinding (modKey "SHIFT + 2") (moveToWorkspace "2"))
(mkBinding (modKey "SHIFT + 3") (moveToWorkspace "3"))
(mkBinding (modKey "SHIFT + 4") (moveToWorkspace "4"))
(mkBinding (modKey "SHIFT + 5") (moveToWorkspace "5"))
(mkBinding (modKey "SHIFT + 6") (moveToWorkspace "6"))
(mkBinding (modKey "SHIFT + 7") (moveToWorkspace "7"))
(mkBinding (modKey "SHIFT + 8") (moveToWorkspace "8"))
(mkBinding (modKey "SHIFT + 9") (moveToWorkspace "9"))
(mkBinding (modKey "SHIFT + 0") (moveToWorkspace "10"))
(mkBinding (modKey "mouse_down") (focusWorkspace "e+1"))
(mkBinding (modKey "mouse_up") (focusWorkspace "e-1"))
(mkBindingWithOptions (modKey "mouse:272") "hl.dsp.window.drag()" {mouse = true;})
(mkBindingWithOptions (modKey "mouse:273") "hl.dsp.window.resize()" {mouse = true;})
(mkBinding (modKey "SPACE") (execCmd "hyprctl switchxkblayout current next"))
];
};
};
services.hyprpaper.enable = true;
# services.hypridle = {
# enable = true;
# settings = {
# general = {
# before_sleep_cmd = "hyprlock";
# after_sleep_cmd = "hyprctl dispatch dpms on";
# inhibit_sleep = 3;
# };
# listener = [
# {
# timeout = 300;
# on-timeout = "hyprlock";
# }
# {
# timeout = 420;
# on-timeout = "hyprctl dispatch dpms off";
# on-resume = "hyprctl dispatch dpms on";
# }
# ];
# };
# };
programs.hyprlock = {
enable = true;
settings = {
"$font" = "JetBrainsMono Nerd Font";
"$base" = "rgb(${p.base00})";
"$text" = "rgb(${p.base05})";
"$textAlpha" = "${p.base05}";
"$accentAlpha" = "${p.base0D}";
"$red" = "rgb(${p.base08})";
"$yellow" = "rgb(${p.base0A})";
# services.hyprpaper.enable = true;
general = {
hide_cursor = true;
};
# programs.hyprlock = {
# enable = true;
# settings = {
# "$font" = "JetBrainsMono Nerd Font";
# "$base" = "rgb(${config.colorScheme.palette.base00})";
# "$text" = "rgb(${config.colorScheme.palette.base05})";
# "$textAlpha" = "${config.colorScheme.palette.base05}";
# "$accentAlpha" = "${config.colorScheme.palette.base0D}";
# "$red" = "rgb(${config.colorScheme.palette.base08})";
# "$yellow" = "rgb(${config.colorScheme.palette.base0A})";
background = {
monitor = "";
path = "${config.home.homeDirectory}/.config/hypr/wallpapers/wallhaven-lmmo8r.jpg";
blur_passes = 0;
color = "rgb(${p.base00})";
};
# general = {
# hide_cursor = true;
# };
label = [
{
monitor = "";
text = "$TIME";
color = "$text";
font_size = 90;
font_family = "$font";
position = "30, 0";
halign = "left";
valign = "top";
}
{
monitor = "";
text = ''cmd[update:43200000] echo "$(date +"%A, %d %B %Y")"'';
color = "$text";
font_size = 25;
font_family = "$font";
position = "30, -150";
halign = "left";
valign = "top";
}
];
# background = {
# monitor = "";
# path = "${config.home.homeDirectory}/.config/hypr/wallpapers/wallhaven-lmmo8r.jpg";
# blur_passes = 0;
# color = "rgb(${config.colorScheme.palette.base00})";
# };
input-field = [
{
monitor = "";
size = "300, 60";
outline_thickness = 4;
dots_size = 0.2;
dots_spacing = 0.2;
dots_center = true;
outer_color = "rgb(${p.base0D})";
inner_color = "rgb(${p.base00})";
font_color = "rgb(${p.base05})";
fade_on_empty = false;
placeholder_text = ''<span foreground="##${p.base05}">󰌾 Logged in as <span foreground="##${p.base0D}">$USER</span></span>'';
hide_input = false;
check_color = "rgb(${p.base0D})";
fail_color = "rgb(${p.base08})";
fail_text = ''<i>$FAIL <b>($ATTEMPTS)</b></i>'';
capslock_color = "rgb(${p.base0A})";
position = "0, -35";
halign = "center";
valign = "center";
}
];
};
};
# label = [
# {
# monitor = "";
# text = "$TIME";
# color = "$text";
# font_size = 90;
# font_family = "$font";
# position = "30, 0";
# halign = "left";
# valign = "top";
# }
# {
# monitor = "";
# text = ''cmd[update:43200000] echo "$(date +"%A, %d %B %Y")"'';
# color = "$text";
# font_size = 25;
# font_family = "$font";
# position = "30, -150";
# halign = "left";
# valign = "top";
# }
# ];
# input-field = [
# {
# monitor = "";
# size = "300, 60";
# outline_thickness = 4;
# dots_size = 0.2;
# dots_spacing = 0.2;
# dots_center = true;
# outer_color = "rgb(${config.colorScheme.palette.base0D})";
# inner_color = "rgb(${config.colorScheme.palette.base00})";
# font_color = "rgb(${config.colorScheme.palette.base05})";
# fade_on_empty = false;
# placeholder_text = ''<span foreground="##${config.colorScheme.palette.base05}">󰌾 Logged in as <span foreground="##${config.colorScheme.palette.base0D}">$USER</span></span>'';
# hide_input = false;
# check_color = "rgb(${config.colorScheme.palette.base0D})";
# fail_color = "rgb(${config.colorScheme.palette.base08})";
# fail_text = ''<i>$FAIL <b>($ATTEMPTS)</b></i>'';
# capslock_color = "rgb(${config.colorScheme.palette.base0A})";
# position = "0, -35";
# halign = "center";
# valign = "center";
# }
# ];
# };
# };
};
}
@@ -0,0 +1,39 @@
{config, ...}: {
programs.agent-lib = {
enable = true;
lockFile = config."m3ta-home".paths.srcRoot + "/agent-sources.lock.json";
targets.pi.enable = true;
targets.opencode.enable = true;
profiles.default = {
sources = {
m3ta-agents = {
agents = {
all = true;
};
skills = {
all = true;
exclude = ["brainstorming" "pdf" "systematic-debugging" "xlsx"];
};
};
anthropic.skills = {
all = true;
exclude = ["skill-creator"];
};
basecamp.skills.all = true;
kestra.skills.all = true;
mattpocock.skills = {
all = true;
};
okf.skills = {
all = true;
};
superpowers.skills = {
all = true;
};
vercel.skills.all = true;
};
};
};
}
+38 -34
View File
@@ -1,10 +1,8 @@
# AI agent system — OpenCode, Pi, and MCP server configuration.
# Relies on coding.agents options provided by home/common/default.nix
# (inputs.m3ta-nixpkgs.homeManagerModules.default).
# (m3taHomeInputs.m3ta-nixpkgs.homeManagerModules.default).
{
config,
inputs,
lib,
m3taHomeInputs,
pkgs,
videoDrivers ? [],
...
@@ -19,67 +17,73 @@
};
imports = [
# OpenCode and Pi agent configurations
# OpenCode, Pi, and Babysitter agent configurations
./agents-lib.nix
./babysitter.nix
./opencode.nix
./pi.nix
];
coding.agents.skills = {
agentsInput = inputs.agents;
externalSkills = [
{
src = inputs.skills-anthropic;
selectSkills = ["pdf" "docx" "frontend-design"];
}
{src = inputs.skills-superpowers;}
{src = inputs.skills-vercel;}
{src = inputs.skills-basecamp;}
{src = inputs.skills-kestra;}
];
};
coding.agents.babysitter.enable = true;
programs.mcp = {
enable = true;
servers = {
ContextMode = {
command = "bash";
args = ["-c" "exec bunx context-mode@latest"];
};
DeepWiki = {
url = "https://mcp.deepwiki.com/mcp";
};
Ref = {
command = "bash";
args = ["-c" "REF_API_KEY=$(cat /run/agenix/ref-key) exec bunx ref-tools-mcp@latest"];
};
Exa = {
command = "bash";
args = ["-c" "EXA_API_KEY=$(cat /run/agenix/exa-key) exec bunx exa-mcp-server@latest tools=web_search_exa"];
};
SallyAI = {
url = "https://app.sally.io/api/v1/McpExternal";
};
Outline = {
url = "https://wiki.az-gruppe.com/mcp";
};
ContextMode = {
Playwright = {
command = "bash";
args = ["-c" "exec bunx context-mode@latest"];
args = ["-c" "exec bunx @playwright/mcp@latest"];
};
Honcho = {
Ref = {
command = "bash";
args = [
"-c"
''exec bunx mcp-remote@latest https://mcp.honcho.dev --header "Authorization:Bearer $(cat /run/agenix/honcho-key)" --header "X-Honcho-User-Name:m3tam3re"''
];
args = ["-c" "REF_API_KEY=$(cat /run/agenix/ref-key) exec bunx ref-tools-mcp@latest"];
};
Teams = {
command = "bunx";
args = ["-y" "@floriscornel/teams-mcp@latest"];
};
};
};
# NOTE: llm-agent packages are consumed via the `llm-agents` namespace
# (pkgs.llm-agents.*), provided by numtide/llm-agents.nix's
# `overlays.shared-nixpkgs`. The consumer's nixos-config MUST apply that
# overlay — namespaced refs fail loudly if it is missing, instead of
# silently falling back to (outdated) nixpkgs attributes.
home.packages = with pkgs; [
agenix-cli
agent-browser
beads
llm-agents.agent-browser
m3taHomeInputs.agent-lib.packages.${pkgs.stdenv.hostPlatform.system}.agent-lib-cli
llm-agents.beads
buzz
crunch
docker-sbx
llm-agents.herdr
pi-coding-agent
(qmd.override {
(llm-agents.qmd.override {
vulkanSupport = videoDrivers == ["amdgpu"];
cudaSupport = videoDrivers == ["nvidia"];
})
# opencode-desktop
opencode-desktop
openshell
openspec
llm-agents.openspec
openwork
talk
];
}
+142
View File
@@ -0,0 +1,142 @@
# Babysitter user profile for Pi/agent workflows.
{
config,
lib,
...
}: let
cfg = config.coding.agents.babysitter;
defaultTimestamp = "2026-05-29T00:00:00.000Z";
defaultUserProfile = {
name = config.home.username;
specialties = [
{
domain = "declarative-system-configuration";
subdomains = ["nix" "home-manager" "agents"];
}
];
expertiseLevels = {};
goals = [
{
id = "goal-agents-declarative-profile";
description = "Keep Babysitter user preferences declarative and reproducible across systems.";
category = "agents";
priority = "medium";
status = "active";
}
];
preferences = {
verbosity = "concise";
autonomyLevel = "semi-autonomous";
riskTolerance = "conservative";
};
toolPreferences = {
packageManagers = ["nix"];
languages = ["nix"];
operatingSystem = "nixos";
};
breakpointTolerance = {
global = "moderate";
skipBreakpointsForKnownPatterns = false;
alwaysBreakOn = ["destructive-operations" "secrets" "external-publication"];
};
communicationStyle = {
tone = "technical";
language = "en";
useEmojis = false;
explanationDepth = "brief";
preferredResponseFormat = "markdown";
};
experience = {};
installedPlugins = ["babysitter-pi"];
installedSkills = ["babysit" "call" "plan" "resume" "doctor" "yolo"];
installedAgents = [];
createdAt = defaultTimestamp;
updatedAt = defaultTimestamp;
version = 1;
};
effectiveProfile = lib.recursiveUpdate cfg.profile cfg.profileOverrides;
profileJsonTarget = "${cfg.profileDirectory}/user-profile.json";
profileMarkdownTarget = "${cfg.profileDirectory}/user-profile.md";
profilePreferences = effectiveProfile.preferences or {};
profileBreakpointTolerance = effectiveProfile.breakpointTolerance or {};
listMarkdown = values:
lib.concatMapStringsSep "\n" (value: "- ${toString value}") values;
specialtyDomains = map (specialty: specialty.domain or "unspecified") (effectiveProfile.specialties or []);
profileMarkdown = ''
# Babysitter User Profile
This file is generated by Home Manager from `coding.agents.babysitter`.
- Name: ${effectiveProfile.name or "unspecified"}
- Breakpoint tolerance: ${profileBreakpointTolerance.global or "unspecified"}
- Autonomy level: ${profilePreferences.autonomyLevel or "unspecified"}
- Risk tolerance: ${profilePreferences.riskTolerance or "unspecified"}
## Specialties
${listMarkdown specialtyDomains}
## Installed Babysitter Pi Skills
${listMarkdown (effectiveProfile.installedSkills or [])}
'';
in {
options.coding.agents.babysitter = {
enable = lib.mkEnableOption "Babysitter user profile for Pi/agent workflows";
profileDirectory = lib.mkOption {
type = lib.types.str;
default = ".a5c";
description = ''
Home-relative directory where Babysitter reads the user profile.
Babysitter Pi documents the user profile at ~/.a5c/user-profile.json.
'';
};
profile = lib.mkOption {
type = lib.types.attrsOf lib.types.anything;
default = defaultUserProfile;
description = "Complete non-secret Babysitter user profile JSON.";
};
profileOverrides = lib.mkOption {
type = lib.types.attrsOf lib.types.anything;
default = {};
description = ''
Recursive overrides merged into the default Babysitter user profile.
Keep this non-secret; the result is written into the Nix store.
'';
};
};
config = lib.mkIf cfg.enable {
assertions = [
{
assertion = cfg.profileDirectory != "" && !lib.hasPrefix "/" cfg.profileDirectory;
message = "coding.agents.babysitter.profileDirectory must be a non-empty home-relative path.";
}
{
assertion = effectiveProfile ? name && builtins.isString effectiveProfile.name;
message = "coding.agents.babysitter profile must include a string name.";
}
{
assertion = effectiveProfile ? specialties && builtins.isList effectiveProfile.specialties;
message = "coding.agents.babysitter profile must include a specialties list.";
}
{
assertion = effectiveProfile ? breakpointTolerance && effectiveProfile.breakpointTolerance ? global;
message = "coding.agents.babysitter profile must include breakpointTolerance.global.";
}
];
home.file = {
"${profileJsonTarget}".text = builtins.toJSON effectiveProfile + "\n";
"${profileMarkdownTarget}".text = profileMarkdown;
};
};
}
+39 -34
View File
@@ -1,37 +1,37 @@
{
inputs,
lib,
...
}: {
coding.agents.opencode = {
enable = true;
agentsInput = inputs.agents;
};
{lib, ...}: {
coding.opencode = {
enable = true;
ohMyOpencodeSettings = {
agents = {
sisyphus.model = "litellm/claude-opus-4-6";
oracle.model = "litellm/claude-sonnet-4-6";
librarian.model = "litellm/claude-sonnet-4-6";
explore.model = "litellm/claude-haiku-4-5";
multimodal-looker.model = "litellm/gpt-5.3-codex";
prometheus.model = "litellm/claude-opus-4-6";
metis.model = "litellm/claude-opus-4-6";
momus.model = "litellm/claude-opus-4-6";
atlas.model = "litellm/claude-sonnet-4-6";
# Primary worker: GLM-5.3 (1M ctx, beats Opus 4.8 on token efficiency).
sisyphus.model = "zai-coding-plan/glm-5.3";
# Planning + deep analysis: strongest reasoning tier.
prometheus.model = "litellm/claude-opus-4-8";
metis.model = "litellm/claude-opus-4-8";
# Verification + docs research: best tool-use quality.
oracle.model = "litellm/claude-sonnet-5";
librarian.model = "litellm/claude-sonnet-5";
# High-volume parallel codebase scans: speed-tuned GLM on flat rate.
explore.model = "zai-coding-plan/glm-5-turbo";
# Vision: GLM-5.3 is text-only -> cheap capable Claude Haiku.
multimodal-looker.model = "litellm/claude-haiku-4-5";
# Critic + navigator: flagship GLM on flat rate.
momus.model = "zai-coding-plan/glm-5.3";
atlas.model = "zai-coding-plan/glm-5.3";
};
categories = {
visual-engineering.model = "zai-coding-plan/glm-5.1";
ultrabrain.model = "litellm/claude-opus-4-6";
deep.model = "litellm/claude-sonnet-4-6";
artistry.model = "zai-coding-plan/glm-5.1";
# Volume categories -> flat-rate GLM-5.3 (1M ctx).
visual-engineering.model = "zai-coding-plan/glm-5.3";
artistry.model = "zai-coding-plan/glm-5.3";
writing.model = "zai-coding-plan/glm-5.3";
# Long deep-work sessions -> GLM-5.3 1M ctx beats Sonnet 200k.
deep.model = "zai-coding-plan/glm-5.3";
# Deliberately pay-per-token for top quality:
ultrabrain.model = "litellm/claude-opus-4-8";
unspecified-high.model = "litellm/claude-opus-4-8";
unspecified-low.model = "litellm/claude-sonnet-5";
quick.model = "litellm/claude-haiku-4-5";
unspecified-low.model = "litellm/claude-sonnet-4-6";
unspecified-high.model = "litellm/claude-opus-4-6";
writing.model = "zai-coding-plan/glm-5.1";
};
};
};
@@ -203,6 +203,13 @@
output = 128000;
};
};
"gpt-5.6-sol" = {
name = "GPT-5.6 Sol";
limit = {
context = 400000;
output = 128000;
};
};
"gpt-5.3-codex" = {
name = "GPT-5.3 Codex";
limit = {
@@ -223,12 +230,11 @@
output = 64000;
};
};
"claude-sonnet-4-6" = {
name = "Claude Sonnet 4.6";
"claude-sonnet-5" = {
name = "Claude Sonnet 5";
options = {
thinking = {
type = "enabled";
budget_tokens = 16000;
type = "adaptive";
};
};
limit = {
@@ -236,12 +242,11 @@
output = 64000;
};
};
"claude-opus-4-6" = {
name = "Claude Opus 4.6";
"claude-opus-4-8" = {
name = "Claude Opus 4.8";
options = {
thinking = {
type = "enabled";
budget_tokens = 16000;
type = "adaptive";
};
};
limit = {
+5 -35
View File
@@ -1,41 +1,12 @@
{inputs, ...}: {
{...}: {
coding.agents.pi = {
enable = true;
agentsInput = inputs.agents;
modelOverrides = {
chiron = "minimax/MiniMax-M2.7";
chiron-forge = "minimax/MiniMax-M2.7";
};
# Coding rules for Pi agent
# Rules sourced from AGENTS repo
codingRules = {
# Language-specific rules
languages = [
"nix" # Nix language conventions
];
# Standard concerns from AGENTS repo
concerns = [
"coding-style" # General coding principles
"naming" # Naming conventions (camelCase, snake_case, etc.)
"documentation" # Documentation standards
"testing" # Testing guidelines (Arrange-Act-Assert)
"git-workflow" # Conventional commits, branch naming
"git-identity" # Git identity configuration for agents
"project-structure" # Project layout conventions
];
# No framework-specific rules for NixOS config
frameworks = [];
};
settings = {
packages = [
"npm:@dreadedzombie/pi-init"
"git:github.com/a5c-ai/babysitter-pi"
"npm:@plannotator/pi-extension"
"npm:@thesethrose/pi-zai-provider"
"npm:pi-agent-browser-native"
"npm:pi-beads-extension"
"npm:pi-lens"
@@ -46,11 +17,10 @@
"npm:pi-subagents"
"npm:pi-tool-display"
"npm:pi-web-access"
"git:github.com/hk-vk/pi-connect"
];
defaultProvider = "minimax";
defaultModel = "MiniMax-M2.7";
defaultProvider = "openai-codex";
defaultModel = "gpt-5.5";
defaultThinkingLevel = "high";
};
@@ -59,7 +29,7 @@
# NOTE: Local project .pi/extensions/guardrails.json can override same rule IDs.
# For immutable global policies, consider a wrapper or upstream patch.
guardrails = {
enable = true;
enable = false;
config = {
enabled = true;
applyBuiltinDefaults = true;
+1
View File
@@ -9,5 +9,6 @@
jq
ripgrep
tree
worktrunk
];
}
@@ -17,9 +17,6 @@ in {
bun
];
home.file.".npmrc".text = ''
prefix=${npmGlobalPrefix}
'';
home.sessionVariables.NPM_CONFIG_PREFIX = npmGlobalPrefix;
};
}
+1
View File
@@ -1,6 +1,7 @@
# Gaming profile aggregator — Steam platform, Gamescope session, and AMD GPU tools.
{...}: {
imports = [
./emulators.nix
./steam.nix
./gamescope.nix
./gpu.nix
+18
View File
@@ -0,0 +1,18 @@
{
config,
lib,
pkgs,
...
}:
with lib; let
cfg = config.profiles.gaming.emulators;
in {
options.profiles.gaming.emulators.enable = mkEnableOption "Emulators";
config = mkIf cfg.enable {
home.packages = with pkgs; [
shadps4
shadps4-qtlauncher
];
};
}
+1 -1
View File
@@ -15,7 +15,7 @@ in {
amf
ffmpeg_6-full
gst_all_1.gstreamer
gst_all_1.gst-vaapi
gst_all_1.gst-plugins-bad
pamixer
pavucontrol
qpwgraph
+65 -65
View File
@@ -44,107 +44,107 @@
programs.ssh = {
enable = true;
enableDefaultConfig = false;
matchBlocks = {
settings = {
"github.com" = {
hostname = "github.com";
user = "m3tam3re";
port = 22;
identityFile = "~/.ssh/github";
HostName = "github.com";
User = "m3tam3re";
Port = 22;
IdentityFile = "~/.ssh/github";
};
"code.m3ta.dev" = {
hostname = "code.m3ta.dev";
user = "m3tam3re";
identityFile = "~/.ssh/gitea";
HostName = "code.m3ta.dev";
User = "m3tam3re";
IdentityFile = "~/.ssh/gitea";
};
"lkk-nix-1" = {
hostname = "89.58.10.189";
user = "lkk-admin";
identityFile = "~/.ssh/lkk-admin";
HostName = "89.58.10.189";
User = "lkk-admin";
IdentityFile = "~/.ssh/lkk-admin";
};
"m3-r1" = {
hostname = "202.61.226.110";
user = "m3tam3re";
identityFile = "~/.ssh/m3tam3re";
HostName = "202.61.226.110";
User = "m3tam3re";
IdentityFile = "~/.ssh/m3tam3re";
};
"m3-deck" = {
hostname = "192.168.178.193";
user = "m3tam3re";
identityFile = "~/.ssh/m3tam3re";
HostName = "192.168.178.193";
User = "m3tam3re";
IdentityFile = "~/.ssh/m3tam3re";
};
"m3-kratos-vm" = {
hostname = "192.168.122.43";
user = "m3tam3re";
identityFile = "~/.ssh/m3tam3re";
HostName = "192.168.122.43";
User = "m3tam3re";
IdentityFile = "~/.ssh/m3tam3re";
};
"m3-helios" = {
hostname = "192.168.178.210";
user = "m3tam3re";
identityFile = "~/.ssh/m3tam3re";
HostName = "192.168.178.210";
User = "m3tam3re";
IdentityFile = "~/.ssh/m3tam3re";
};
"m3-ares" = {
hostname = "192.168.1.30";
user = "m3tam3re";
identityFile = "~/.ssh/m3tam3re";
HostName = "192.168.1.30";
User = "m3tam3re";
IdentityFile = "~/.ssh/m3tam3re";
};
"m3-atlas" = {
hostname = "152.53.85.162";
user = "m3tam3re";
identityFile = "~/.ssh/m3tam3re";
HostName = "152.53.85.162";
User = "m3tam3re";
IdentityFile = "~/.ssh/m3ta-adm";
};
"m3-hermes" = {
hostname = "204.168.229.93";
user = "m3tam3re";
identityFile = "~/.ssh/m3tam3re";
HostName = "204.168.229.93";
User = "m3tam3re";
IdentityFile = "~/.ssh/m3ta-adm";
};
"hermes" = {
hostname = "46.224.0.92";
user = "admin";
identityFile = "~/.ssh/m3tam3re";
"hermes-agent" = {
HostName = "204.168.229.93";
User = "hermes";
IdentityFile = "~/.ssh/hermes";
};
"m3-zelda" = {
hostname = "95.217.189.186";
user = "m3tam3re";
identityFile = "~/.ssh/m3tam3re";
HostName = "95.217.189.186";
User = "m3tam3re";
IdentityFile = "~/.ssh/m3tam3re";
};
"m3-skynet" = {
hostname = "m3-skynet";
user = "admin";
identityFile = "~/.ssh/m3tam3re";
HostName = "m3-skynet";
User = "admin";
IdentityFile = "~/.ssh/m3tam3re";
};
"m3-prox-1" = {
hostname = "192.168.1.110";
user = "root";
identityFile = "~/.ssh/m3tam3re";
HostName = "192.168.1.110";
User = "root";
IdentityFile = "~/.ssh/m3tam3re";
};
"shp-old" = {
hostname = "95.217.3.250";
port = 2222;
user = "m3tam3re";
identityFile = "~/.ssh/self-host-playbook";
HostName = "95.217.3.250";
Port = 2222;
User = "m3tam3re";
IdentityFile = "~/.ssh/self-host-playbook";
};
"shp-1" = {
hostname = "95.217.189.186";
port = 2222;
user = "m3tam3re";
identityFile = "~/.ssh/self-host-playbook";
HostName = "95.217.189.186";
Port = 2222;
User = "m3tam3re";
IdentityFile = "~/.ssh/self-host-playbook";
};
"AZ-CLD-1" = {
hostname = "152.53.186.119";
user = "sascha.koenig";
port = 2022;
identityFile = "~/.ssh/sascha.koenig";
HostName = "152.53.186.119";
User = "sascha.koenig";
Port = 2022;
IdentityFile = "~/.ssh/sascha.koenig";
};
"AZ-PRM-1" = {
hostname = "192.168.152.76";
user = "sascha.koenig";
port = 2022;
identityFile = "~/.ssh/sascha.koenig";
HostName = "192.168.152.76";
User = "sascha.koenig";
Port = 2022;
IdentityFile = "~/.ssh/sascha.koenig";
};
"git.az-gruppe.com" = {
hostname = "git.az-gruppe.com";
port = 2022;
user = "sascha.koenig";
identityFile = "~/.ssh/sascha.koenig";
HostName = "git.az-gruppe.com";
Port = 2022;
User = "sascha.koenig";
IdentityFile = "~/.ssh/sascha.koenig";
};
};
};
+27 -16
View File
@@ -44,29 +44,40 @@
programs.ssh = {
enable = true;
enableDefaultConfig = false;
matchBlocks = {
settings = {
"AZ-CLD-1" = {
hostname = "152.53.186.119";
user = "sascha.koenig";
port = 2022;
identityFile = "~/.ssh/sascha.koenig";
HostName = "152.53.186.119";
User = "sascha.koenig";
Port = 2022;
IdentityFile = "~/.ssh/sascha.koenig";
};
"AZ-PRM-1" = {
hostname = "192.168.152.76";
user = "sascha.koenig";
port = 2022;
identityFile = "~/.ssh/sascha.koenig";
HostName = "192.168.152.76";
User = "sascha.koenig";
Port = 2022;
IdentityFile = "~/.ssh/sascha.koenig";
};
"AZ-TC-01" = {
HostName = "192.168.153.172";
User = "sascha.koenig";
Port = 22;
IdentityFile = "~/.ssh/sascha.koenig";
};
"git.az-gruppe.com" = {
hostname = "git.az-gruppe.com";
port = 2022;
user = "sascha.koenig";
identityFile = "~/.ssh/sascha.koenig";
HostName = "git.az-gruppe.com";
Port = 2022;
User = "sascha.koenig";
IdentityFile = "~/.ssh/sascha.koenig";
};
"code.m3ta.dev" = {
hostname = "code.m3ta.dev";
user = "m3tam3re";
identityFile = "~/.ssh/sascha.koenig";
HostName = "code.m3ta.dev";
User = "m3tam3re";
IdentityFile = "~/.ssh/sascha.koenig";
};
"hermes-agent" = {
HostName = "204.168.229.93";
User = "hermes";
IdentityFile = "~/.ssh/hermes";
};
};
};
+9 -1
View File
@@ -11,7 +11,9 @@
pkgs,
lib,
...
}: {
}: let
npmGlobalPrefix = "${config.home.homeDirectory}/.npm-global";
in {
# ── Clipboard ──
services.cliphist = {
enable = true;
@@ -25,4 +27,10 @@
# These are overridden by the identity module, but provide safe defaults.
home.username = lib.mkDefault "m3tam3re";
home.homeDirectory = lib.mkDefault "/home/${config.home.username}";
home.file.".npmrc".text = ''
prefix=${npmGlobalPrefix}
@m3ta:registry=https://code.m3ta.dev/api/packages/m3tam3re/npm/
//code.m3ta.dev/api/packages/m3tam3re/npm/:_authToken=''${GITEA_TOKEN}
'';
}