1 Commits
Author SHA1 Message Date
github-actions[bot] 832a71a4a1 flake.lock: Update
Flake lock file updates:

• Updated input 'darwin':
    'github:lnl7/nix-darwin/8df64f819698c1fee0c2969696f54a843b2231e8' (2025-08-22)
  → 'github:lnl7/nix-darwin/830b3f0b50045cf0bcfd4dab65fad05bf882e196' (2025-09-09)
• Updated input 'disko':
    'github:nix-community/disko/bafad29f89e83b2d861b493aa23034ea16595560' (2025-08-25)
  → 'github:nix-community/disko/146f45bee02b8bd88812cfce6ffc0f933788875a' (2025-09-10)
• Updated input 'helix':
    'github:helix-editor/helix/77ff51caa440b1066e0a1920007ab5e148dd4856' (2025-08-29)
  → 'github:helix-editor/helix/c531b7a4faffe727adf78e1d3c2a54c0d85d0c0c' (2025-09-12)
• Updated input 'home-manager':
    'github:nix-community/home-manager/77a71380c38fb2a440b4b5881bbc839f6230e1cb' (2025-08-29)
  → 'github:nix-community/home-manager/a3fcc92180c7462082cd849498369591dfb20855' (2025-09-12)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/dfb2f12e899db4876308eba6d93455ab7da304cd' (2025-08-28)
  → 'github:nixos/nixpkgs/ab0f3607a6c7486ea22229b92ed2d355f1482ee0' (2025-09-10)
• Updated input 'nur':
    'github:nix-community/nur/e82a8b0095f54edb6bbbb1d862f3da502dca1396' (2025-08-30)
  → 'github:nix-community/nur/8a93aa245ea5190634a6eaaa0e6a4faaba850f69' (2025-09-13)
• Updated input 'wsl':
    'github:nix-community/NixOS-WSL/203a7b463f307c60026136dd1191d9001c43457f' (2025-08-15)
  → 'github:nix-community/NixOS-WSL/42666441c3ddf34a8583a77f07a2c7cae32513c3' (2025-09-12)
2025-09-13 03:42:07 +00:00
117 changed files with 751 additions and 2883 deletions
-13
View File
@@ -1,13 +0,0 @@
{
"permissions": {
"allow": [
"WebFetch(domain:github.com)",
"WebFetch(domain:raw.githubusercontent.com)",
"Bash(gh run *)",
"Bash(jj status *)",
"Bash(jj new *)",
"Bash(jj describe *)",
"Bash(nix flake *)"
]
}
}
-16
View File
@@ -1,16 +0,0 @@
# Changelog
## 2026-07-25
- Added jjui config generation to `jujutsu.nix` in Home Manager to include custom GitHub ruleset bypass commands (`ctrl+b` and `ctrl+shift+b`).
- Added `overlays/cheetah3.nix` to disable `pythonMetadataCheckPhase` for `cheetah3`.
This fixes an issue where the NixOS rebuild fails for `sabnzbd` due to `importlib.metadata.PackageNotFoundError: No package metadata was found for cheetah3` during the Python package evaluation in `nixos-unstable`.
## 2026-07-20
- Added `overlays/paho-mqtt.nix` to disable paho-mqtt's flaky, socket-based
test suite. Its `checkPhase` hangs in the Nix sandbox and times out with a
`KeyboardInterrupt` after ~150s, which was breaking the `flame` rebuild
(paho-mqtt is pulled in transitively, e.g. via mealie). The override is
applied through `pythonPackagesExtensions` so it covers every Python
package set.
Generated
+133 -285
View File
@@ -1,18 +1,12 @@
{
"nodes": {
"cl-nix-lite": {
"inputs": {
"flake-parts": "flake-parts",
"nixpkgs": "nixpkgs",
"systems": "systems",
"treefmt-nix": "treefmt-nix"
},
"locked": {
"lastModified": 1782994178,
"narHash": "sha256-VGc3/2fe6hnOmNSLlOygEAbeS69v7A7rjKDKRzAgE2Q=",
"lastModified": 1728174978,
"narHash": "sha256-Grqqg+xuicANB85j0gNEXxi9SBKY7bzGeTuyi95eGcY=",
"owner": "hraban",
"repo": "cl-nix-lite",
"rev": "eb584721e5e799bafe0c6210a8a1a398f90e8ac0",
"rev": "31cfe6275c341eb3120a99f4b1c8516c49a29d87",
"type": "github"
},
"original": {
@@ -28,11 +22,11 @@
]
},
"locked": {
"lastModified": 1784500460,
"narHash": "sha256-UvORnAxTRHax7RG74W8Z2t4GvIkX6AjJ5kk0QlwZomo=",
"lastModified": 1757430124,
"narHash": "sha256-MhDltfXesGH8VkGv3hmJ1QEKl1ChTIj9wmGAFfWj/Wk=",
"owner": "lnl7",
"repo": "nix-darwin",
"rev": "57a3171f94705599a2499248ca5758d5eb47c0e0",
"rev": "830b3f0b50045cf0bcfd4dab65fad05bf882e196",
"type": "github"
},
"original": {
@@ -49,11 +43,11 @@
]
},
"locked": {
"lastModified": 1781152676,
"narHash": "sha256-RxWs5ND31KzTG7wvMM+PMfUjyNpmIEr999lqNARaM5o=",
"lastModified": 1757508292,
"narHash": "sha256-7lVWL5bC6xBIMWWDal41LlGAG+9u2zUorqo3QCUL4p4=",
"owner": "nix-community",
"repo": "disko",
"rev": "ff8702b4de27f72b4c78573dfb89ec74e36abdf1",
"rev": "146f45bee02b8bd88812cfce6ffc0f933788875a",
"type": "github"
},
"original": {
@@ -65,11 +59,11 @@
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1766808011,
"narHash": "sha256-s83BS0abtIj7vzUf8JE0209KphfHA6qRw/92D9k/F+0=",
"lastModified": 1730663653,
"narHash": "sha256-kFCUWettiFHDIqxCWWQ9qY8pVh+Lj+XL0Giyy/kdomg=",
"owner": "hraban",
"repo": "flake-compat",
"rev": "6e0aafdc4c4c2043c66f756d5045374b42184fc5",
"rev": "e5b16676185cb7548581c852f51ce7f3a49bba5e",
"type": "github"
},
"original": {
@@ -82,27 +76,11 @@
"flake-compat_2": {
"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-compat_3": {
"flake": false,
"locked": {
"lastModified": 1767039857,
"narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=",
"lastModified": 1747046372,
"narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab",
"rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885",
"type": "github"
},
"original": {
@@ -112,24 +90,6 @@
}
},
"flake-parts": {
"inputs": {
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1765835352,
"narHash": "sha256-XswHlK/Qtjasvhd1nOa1e8MgZ8GS//jBoTqWtrS1Giw=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "a34fae9c08a15ad73f295041fec82323541400a9",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-parts_2": {
"inputs": {
"nixpkgs-lib": [
"nur",
@@ -172,7 +132,7 @@
},
"flake-utils_2": {
"inputs": {
"systems": "systems_3"
"systems": "systems_2"
},
"locked": {
"lastModified": 1731533236,
@@ -188,6 +148,27 @@
"type": "github"
}
},
"helix": {
"inputs": {
"nixpkgs": [
"nixpkgs"
],
"rust-overlay": "rust-overlay"
},
"locked": {
"lastModified": 1757688164,
"narHash": "sha256-IfSIZM7/4MwzxF769jVSBeB8JF4fHjYqaoan58HHw1E=",
"owner": "helix-editor",
"repo": "helix",
"rev": "c531b7a4faffe727adf78e1d3c2a54c0d85d0c0c",
"type": "github"
},
"original": {
"owner": "helix-editor",
"repo": "helix",
"type": "github"
}
},
"home-manager": {
"inputs": {
"nixpkgs": [
@@ -195,11 +176,11 @@
]
},
"locked": {
"lastModified": 1784913159,
"narHash": "sha256-JWq0BfjO4ktpH5USfQNQzdvHpIDT8fSKD5K7LvdMRFs=",
"lastModified": 1757698511,
"narHash": "sha256-UqHHGydF/q3jfYXCpvYLA0TWtvByOp1NwOKCUjhYmPs=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "079a3b5d1aa6a719920a51316253b7d6dd22738d",
"rev": "a3fcc92180c7462082cd849498369591dfb20855",
"type": "github"
},
"original": {
@@ -214,61 +195,23 @@
"cl-nix-lite": "cl-nix-lite",
"flake-compat": "flake-compat",
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs_3",
"systems": "systems_2",
"treefmt-nix": "treefmt-nix_2"
},
"locked": {
"lastModified": 1783182903,
"narHash": "sha256-7IteXipJZfFepi5zakxe0jQ5i3vRBQguk0+Gtte1Fu4=",
"owner": "hraban",
"repo": "mac-app-util",
"rev": "039f33deef21782d4db97087f426504951239887",
"type": "github"
},
"original": {
"owner": "hraban",
"repo": "mac-app-util",
"type": "github"
}
},
"nix-caddy-withplugins": {
"inputs": {
"flake-compat": "flake-compat_2",
"nixpkgs": "nixpkgs_5"
},
"locked": {
"lastModified": 1784936738,
"narHash": "sha256-X4w9BrFkisfzla3m1WwDJUicUbI7JRdhzq5aS7rrB0k=",
"owner": "MichailiK",
"repo": "nix-caddy-withplugins",
"rev": "70307cfc568e5434cf42067d797b27c38ea69944",
"type": "github"
},
"original": {
"owner": "MichailiK",
"ref": "nixos-unstable",
"repo": "nix-caddy-withplugins",
"type": "github"
}
},
"nix-index-database": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
],
"systems": "systems",
"treefmt-nix": "treefmt-nix"
},
"locked": {
"lastModified": 1785046085,
"narHash": "sha256-UiK+mmZJuLWQVhJ5b2wDzogIYWAesyRm6LA3h3Ulh3Y=",
"owner": "nix-community",
"repo": "nix-index-database",
"rev": "11665045df8b9938ef811a3bfdc65cffb02b4b70",
"lastModified": 1756057867,
"narHash": "sha256-ziR5eQGqRWhW8tf8r0TIplaqNt+HXu1G1X41LUr4IYo=",
"owner": "hraban",
"repo": "mac-app-util",
"rev": "8414fa1e2cb775b17793104a9095aabeeada63ef",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nix-index-database",
"owner": "hraban",
"repo": "mac-app-util",
"type": "github"
}
},
@@ -280,11 +223,11 @@
]
},
"locked": {
"lastModified": 1779563638,
"narHash": "sha256-9CQKxDKDqVYdDhJW+A955AZwpwZjKUgvu0LbfsL6uyI=",
"lastModified": 1755344765,
"narHash": "sha256-k/Cvh/mzb5lSvilKdgwNBCyAyYmD8YPr1nc0sTSgwxI=",
"owner": "gytis-ivaskevicius",
"repo": "nix2vim",
"rev": "6927414f0de10a18fb6bc9977717088777d50d0d",
"rev": "78467c8de07719f92397179844bf75cdf2e58b83",
"type": "github"
},
"original": {
@@ -316,11 +259,11 @@
]
},
"locked": {
"lastModified": 1769813415,
"narHash": "sha256-nnVmNNKBi1YiBNPhKclNYDORoHkuKipoz7EtVnXO50A=",
"lastModified": 1751903740,
"narHash": "sha256-PeSkNMvkpEvts+9DjFiop1iT2JuBpyknmBUs0Un0a4I=",
"owner": "nix-community",
"repo": "nixos-generators",
"rev": "8946737ff703382fda7623b9fab071d037e897d5",
"rev": "032decf9db65efed428afd2fa39d80f7089085eb",
"type": "github"
},
"original": {
@@ -331,138 +274,59 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1779796641,
"narHash": "sha256-ZsIrKmhp4vbBXoXXmR/tBXA/UCsAQiJL9vsgZEduhVY=",
"lastModified": 1754340878,
"narHash": "sha256-lgmUyVQL9tSnvvIvBp7x1euhkkCho7n3TMzgjdvgPoU=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "25f538306313eae3927264466c70d7001dcea1df",
"rev": "cab778239e705082fe97bb4990e0d24c50924c04",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-25.11",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-lib": {
"locked": {
"lastModified": 1765674936,
"narHash": "sha256-k00uTP4JNfmejrCLJOwdObYC9jHRrr/5M/a/8L2EIdo=",
"owner": "nix-community",
"repo": "nixpkgs.lib",
"rev": "2075416fcb47225d9b68ac469a5c4801a9c4dd85",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixpkgs.lib",
"type": "github"
}
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1784707089,
"narHash": "sha256-2V/6imsUgB7mPZlHY54oeVBRDoZbPKnvzwkAHUSSufk=",
"lastModified": 1735563628,
"narHash": "sha256-OnSAY7XDSx7CtDoqNh8jwVwh4xNL/2HaJxGjryLWzX8=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "b3fe9581c9061c749abef42b6d4ee7b7c05c33fa",
"rev": "b134951a4c9f3c995fd7be05f3243f8ecd65d798",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-26.05",
"ref": "nixos-24.05",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1761236834,
"narHash": "sha256-+pthv6hrL5VLW2UqPdISGuLiUZ6SnAXdd2DdUE+fV2Q=",
"lastModified": 1757487488,
"narHash": "sha256-zwE/e7CuPJUWKdvvTCB7iunV4E/+G0lKfv4kk/5Izdg=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "d5faa84122bc0a1fd5d378492efce4e289f8eac1",
"rev": "ab0f3607a6c7486ea22229b92ed2d355f1482ee0",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixpkgs-unstable",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_3": {
"locked": {
"lastModified": 1782999065,
"narHash": "sha256-5Dgj5+pIQYZKrXUGaLCk7CKfN3MmpwIhO94++WVxvng=",
"lastModified": 1728538411,
"narHash": "sha256-f0SBJz1eZ2yOuKUr5CA9BHULGXVSn6miBuUWdTyhUhU=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "80d591ed473cfc46329932c2aadac9b435342c7c",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-26.05",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_4": {
"locked": {
"lastModified": 1770107345,
"narHash": "sha256-tbS0Ebx2PiA1FRW8mt8oejR0qMXmziJmPaU1d4kYY9g=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "4533d9293756b63904b7238acb84ac8fe4c8c2c4",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_5": {
"locked": {
"lastModified": 1781074563,
"narHash": "sha256-md8WlXOlfnIeHeOScMTTHFyf2d6iaTwPl2apR5EQ3P4=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "9ae611a455b90cf061d8f332b977e387bda8e1ca",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_6": {
"locked": {
"lastModified": 1784796856,
"narHash": "sha256-wWFrV5/Qbm+lyt5x20E/bSbfJiGKMo4RCxZV8cl/WZI=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "e2587caef70cea85dd97d7daab492899902dbf5d",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_7": {
"locked": {
"lastModified": 1744536153,
"narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "18dd725c29603f582cf1900e0d25f9f1063dbf11",
"rev": "b69de56fac8c2b6f8fd27f2eca01dcda8e0a4221",
"type": "github"
},
"original": {
@@ -474,17 +338,17 @@
},
"nur": {
"inputs": {
"flake-parts": "flake-parts_2",
"flake-parts": "flake-parts",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1784959021,
"narHash": "sha256-Atc5ydxAmAAD5o8e6F8VVxVCOQb82bqi5TRNRUSBvZU=",
"lastModified": 1757733608,
"narHash": "sha256-k8k4VpFuMMiRGBKaut2YIUCJsu0DR/QDV9058C96/Xw=",
"owner": "nix-community",
"repo": "nur",
"rev": "1166a294990afd245fd72b8d2896075222408399",
"rev": "8a93aa245ea5190634a6eaaa0e6a4faaba850f69",
"type": "github"
},
"original": {
@@ -497,16 +361,14 @@
"inputs": {
"darwin": "darwin",
"disko": "disko",
"helix": "helix",
"home-manager": "home-manager",
"mac-app-util": "mac-app-util",
"nix-caddy-withplugins": "nix-caddy-withplugins",
"nix-index-database": "nix-index-database",
"nix2vim": "nix2vim",
"nixos-generators": "nixos-generators",
"nixpkgs": "nixpkgs_6",
"nixpkgs": "nixpkgs_2",
"nixpkgs-stable": "nixpkgs-stable",
"nur": "nur",
"rust-overlay": "rust-overlay",
"wsl": "wsl",
"zellij-switch": "zellij-switch",
"zenyd-mpv-scripts": "zenyd-mpv-scripts"
@@ -514,14 +376,35 @@
},
"rust-overlay": {
"inputs": {
"nixpkgs": "nixpkgs_7"
"nixpkgs": [
"helix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1784956772,
"narHash": "sha256-5polVWDhgATIQj+RUV2ZlOd5nE6cGJo+C4tOEs5vp6U=",
"lastModified": 1740623427,
"narHash": "sha256-3SdPQrZoa4odlScFDUHd4CUPQ/R1gtH4Mq9u8CBiK8M=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "a163bd01a6e11ac58d4f8d11669da550b5afbbc6",
"rev": "d342e8b5fd88421ff982f383c853f0fc78a847ab",
"type": "github"
},
"original": {
"owner": "oxalica",
"repo": "rust-overlay",
"type": "github"
}
},
"rust-overlay_2": {
"inputs": {
"nixpkgs": "nixpkgs_3"
},
"locked": {
"lastModified": 1736476219,
"narHash": "sha256-+qyv3QqdZCdZ3cSO/cbpEY6tntyYjfe1bB12mdpNFaY=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "de30cc5963da22e9742bbbbb9a3344570ed237b9",
"type": "github"
},
"original": {
@@ -531,21 +414,6 @@
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1689347925,
"narHash": "sha256-ozenz5bFe1UUqOn7f60HRmgc01BgTGIKZ4Xl+HbocGQ=",
@@ -560,6 +428,21 @@
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_3": {
"locked": {
"lastModified": 1681028828,
@@ -575,49 +458,16 @@
"type": "github"
}
},
"systems_4": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"treefmt-nix": {
"inputs": {
"nixpkgs": "nixpkgs_2"
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1766000401,
"narHash": "sha256-+cqN4PJz9y0JQXfAK5J1drd0U05D5fcAGhzhfVrDlsI=",
"lastModified": 1755934250,
"narHash": "sha256-CsDojnMgYsfshQw3t4zjRUkmMmUdZGthl16bXVWgRYU=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "42d96e75aa56a3f70cab7e7dc4a32868db28e8fd",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
}
},
"treefmt-nix_2": {
"inputs": {
"nixpkgs": "nixpkgs_4"
},
"locked": {
"lastModified": 1780220602,
"narHash": "sha256-eynAfOmbmxJnkp7YewvCEbShNnnYJ9gLLqkzsYtBPeM=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "db947814a175b7ca6ded66e21383d938df01c227",
"rev": "74e1a52d5bd9430312f8d1b8b0354c92c17453e5",
"type": "github"
},
"original": {
@@ -628,17 +478,17 @@
},
"wsl": {
"inputs": {
"flake-compat": "flake-compat_3",
"flake-compat": "flake-compat_2",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1784642409,
"narHash": "sha256-hcbDqFuySAJawljt5r0sKBCJKYnbtGD0T/ZIozH1Dq0=",
"lastModified": 1757671225,
"narHash": "sha256-ZzoQXe7GV7QX3B3Iw59BogmrtHSP5Ig7MAPPD0cOFW4=",
"owner": "nix-community",
"repo": "NixOS-WSL",
"rev": "eaeb18da90024448a60eb1ec7132eafa4003404e",
"rev": "42666441c3ddf34a8583a77f07a2c7cae32513c3",
"type": "github"
},
"original": {
@@ -652,17 +502,15 @@
"nixpkgs": [
"nixpkgs"
],
"rust-overlay": [
"rust-overlay"
],
"systems": "systems_4"
"rust-overlay": "rust-overlay_2",
"systems": "systems_3"
},
"locked": {
"lastModified": 1781873766,
"narHash": "sha256-V8baEgRBa2SqtCLbQ4EaphIMKsnAogY2oMdttWYhkEs=",
"lastModified": 1742588229,
"narHash": "sha256-IPg0pBw0ciF+xl6viq3nK+dvZoDZrfBDui7dkPLz258=",
"owner": "mostafaqanbaryan",
"repo": "zellij-switch",
"rev": "ced3c681afe40785b2853e3a976908466786ee79",
"rev": "0e3c303c19890ccb03589230ac5a7c4307e573e4",
"type": "github"
},
"original": {
@@ -674,11 +522,11 @@
"zenyd-mpv-scripts": {
"flake": false,
"locked": {
"lastModified": 1765050776,
"narHash": "sha256-9gO+GkNoGsxAbMRrBWu0FfXEQtyTmHivlaxlYLpV2YM=",
"lastModified": 1707704915,
"narHash": "sha256-9P/8q/OZXfaJMS08acQP4h3/zUA5mKRQee0JmkXcz1w=",
"owner": "zenyd",
"repo": "mpv-scripts",
"rev": "62f4bb313c6cb6366672e78dea940e9da8fec84a",
"rev": "9bdce0050144cb24f92475f7bdd77180e0e4c26b",
"type": "github"
},
"original": {
+31 -51
View File
@@ -8,7 +8,7 @@
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
# Used for specific stable packages
nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-26.05";
nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-24.05";
# Used for MacOS system config
darwin = {
@@ -37,13 +37,7 @@
# Better App install management in macOS
mac-app-util = {
url = "github:hraban/mac-app-util";
# inputs.nixpkgs.follows = "nixpkgs"; # Use system packages list for their inputs
};
# Caddy with decoupled plugin hashes
nix-caddy-withplugins = {
url = "github:MichailiK/nix-caddy-withplugins/nixos-unstable";
# Important: Do not follow nixpkgs here, per the README
inputs.nixpkgs.follows = "nixpkgs"; # Use system packages list for their inputs
};
# Manage disk format and partitioning
@@ -58,11 +52,6 @@
inputs.nixpkgs.follows = "nixpkgs";
};
nix-index-database = {
url = "github:nix-community/nix-index-database";
inputs.nixpkgs.follows = "nixpkgs";
};
# Convert Nix to Neovim config
nix2vim = {
url = "github:gytis-ivaskevicius/nix2vim";
@@ -75,23 +64,17 @@
flake = false;
};
rust-overlay = {
url = "github:oxalica/rust-overlay";
};
# Zellij Switcher
zellij-switch = {
url = "github:mostafaqanbaryan/zellij-switch";
inputs.nixpkgs.follows = "nixpkgs";
inputs.rust-overlay.follows = "rust-overlay";
};
# # Text editor
# helix = {
# url = "github:helix-editor/helix";
# inputs.nixpkgs.follows = "nixpkgs";
# inputs.rust-overlay.follows = "rust-overlay";
# };
# Text editor
helix = {
url = "github:helix-editor/helix";
inputs.nixpkgs.follows = "nixpkgs";
};
# # Nextcloud Apps
# nextcloud-news = {
@@ -131,7 +114,6 @@
bookmarks = "keep.${baseName}";
books = "books.${baseName}";
budget = "money.${baseName}";
contacts = "contacts.${baseName}";
content = "cloud.${baseName}";
download = "download.${baseName}";
files = "files.${baseName}";
@@ -143,7 +125,6 @@
mathesar = "mathesar.${baseName}";
metrics = "metrics.${baseName}";
minecraft = "minecraft.${baseName}";
mumble = "mumble.${baseName}";
n8n = "n8n.${baseName}";
navidrome = "music.${baseName}";
notifications = "ntfy.${baseName}";
@@ -151,7 +132,6 @@
photos = "photos.${baseName}";
postgresql = "pg.${baseName}";
prometheus = "prom.${baseName}";
recipes = "cooking.${baseName}";
secrets = "vault.${baseName}";
smtp = "smtp.purelymail.com";
status = "status.${baseName}";
@@ -266,30 +246,30 @@
default = lib.pkgsBySystem.${system}.nmasur.dotfiles-devshell;
});
# checks = lib.forAllSystems (
# system:
# let
# pkgs = import nixpkgs {
# inherit system;
# overlays = lib.overlays;
# };
# in
# {
# neovim =
# pkgs.runCommand "neovim-check-health" { buildInputs = [ inputs.self.packages.${system}.neovim ]; }
# ''
# mkdir -p $out
# export HOME=$TMPDIR
# nvim -c "checkhealth" -c "write $out/health.log" -c "quitall"
checks = lib.forAllSystems (
system:
let
pkgs = import nixpkgs {
inherit system;
overlays = lib.overlays;
};
in
{
neovim =
pkgs.runCommand "neovim-check-health" { buildInputs = [ inputs.self.packages.${system}.neovim ]; }
''
mkdir -p $out
export HOME=$TMPDIR
nvim -c "checkhealth" -c "write $out/health.log" -c "quitall"
# # Check for errors inside the health log
# if $(grep "ERROR" $out/health.log); then
# cat $out/health.log
# exit 1
# fi
# '';
# }
# );
# Check for errors inside the health log
if $(grep "ERROR" $out/health.log); then
cat $out/health.log
exit 1
fi
'';
}
);
formatter = lib.forAllSystems (
system:
@@ -299,7 +279,7 @@
inherit (lib) overlays;
};
in
pkgs.nixfmt
pkgs.nixfmt-rfc-style
);
# Templates for starting other projects quickly
@@ -12,9 +12,9 @@ rec {
nmasur.profiles = {
base.enable = true;
# work.enable = true;
# extra.enable = true;
# gaming.enable = true;
work.enable = true;
extra.enable = true;
gaming.enable = true;
};
home-manager.users."Noah.Masur" = {
@@ -26,13 +26,10 @@ rec {
nmasur.profiles = {
common.enable = true;
darwin-base.enable = true;
darwin-gaming.enable = true;
llm-development.enable = true;
power-user.enable = true;
work.enable = true;
experimental.enable = true;
};
nmasur.presets.services.mbsync.user = "noah";
nmasur.presets.programs.git-work.work = {
name = "Noah-Masur_1701";
email = "${nmasur.settings.username}@take2games.com";
+2 -3
View File
@@ -28,14 +28,13 @@ rec {
nmasur.profiles = {
common.enable = true;
linux-base.enable = true;
llm-development.enable = true;
power-user.enable = true;
};
nmasur.presets.programs.helix.enable = true;
home.stateVersion = "25.05";
home.stateVersion = "23.05";
};
system.stateVersion = "25.05";
system.stateVersion = "23.05";
# File systems must be declared in order to boot
# # This is the root filesystem containing NixOS
-4
View File
@@ -26,7 +26,6 @@ rec {
nmasur.profiles = {
common.enable = true;
linux-base.enable = true;
llm-development.enable = true;
power-user.enable = true;
};
home.stateVersion = "23.05";
@@ -34,9 +33,6 @@ rec {
system.stateVersion = "23.05";
# Temp: disable while this isn't working
services.automatic-timezoned.enable = false;
# Not sure what's necessary but too afraid to remove anything
boot.initrd.availableKernelModules = [
"xhci_pci"
+11 -12
View File
@@ -30,7 +30,6 @@ rec {
linux-base.enable = true;
linux-gui.enable = true;
linux-gaming.enable = true;
llm-development.enable = true;
power-user.enable = true;
developer.enable = true;
experimental.enable = true;
@@ -52,7 +51,7 @@ rec {
# Graphics and VMs
boot.initrd.kernelModules = [ "amdgpu" ];
boot.kernelModules = [ "kvm-amd" "it87" ];
boot.kernelModules = [ "kvm-amd" ];
services.xserver.videoDrivers = [ "amdgpu" ];
# Required binary blobs to boot on this machine
@@ -69,16 +68,16 @@ rec {
hardware.fancontrol.config = ''
# Configuration file generated by pwmconfig, changes will be lost
INTERVAL=10
DEVPATH=hwmon1=devices/pci0000:00/0000:00:03.1/0000:06:00.0/0000:07:00.0/0000:08:00.0
DEVNAME=hwmon1=amdgpu
FCTEMPS=hwmon1/pwm1=hwmon1/temp1_input
FCFANS= hwmon1/pwm1=hwmon1/fan1_input
MINTEMP=hwmon1/pwm1=50
MAXTEMP=hwmon1/pwm1=70
MINSTART=hwmon1/pwm1=100
MINSTOP=hwmon1/pwm1=10
MINPWM=hwmon1/pwm1=10
MAXPWM=hwmon1/pwm1=240
DEVPATH=hwmon0=devices/pci0000:00/0000:00:03.1/0000:06:00.0/0000:07:00.0/0000:08:00.0
DEVNAME=hwmon0=amdgpu
FCTEMPS=hwmon0/pwm1=hwmon0/temp1_input
FCFANS= hwmon0/pwm1=hwmon0/fan1_input
MINTEMP=hwmon0/pwm1=50
MAXTEMP=hwmon0/pwm1=70
MINSTART=hwmon0/pwm1=100
MINSTOP=hwmon0/pwm1=10
MINPWM=hwmon0/pwm1=10
MAXPWM=hwmon0/pwm1=240
'';
# File systems must be declared in order to boot
+18 -38
View File
@@ -66,12 +66,9 @@ lib
overlays = [
inputs.nur.overlays.default
inputs.nix2vim.overlay
(final: prev: {
zellij-switch = inputs.zellij-switch.packages.${prev.stdenv.hostPlatform.system}.default;
})
# inputs.helix.overlays.default
]
++ (importOverlays ../overlays);
inputs.zellij-switch.overlays.default
inputs.helix.overlays.default
] ++ (importOverlays ../overlays);
# System types to support.
supportedSystems = [
@@ -100,13 +97,7 @@ lib
system:
import inputs.nixpkgs {
inherit system overlays;
config.permittedInsecurePackages = [
"litestream-0.3.13"
"electron-36.9.5"
# Build-time-only dep of karakeep's frontend; CVEs don't reach
# the runtime closure. Remove once nixpkgs bumps it.
"pnpm-9.15.9"
];
config.permittedInsecurePackages = [ "litestream-0.3.13" ];
config.allowUnfree = true;
}
);
@@ -139,8 +130,7 @@ lib
];
extraSpecialArgs = {
inherit colorscheme;
}
// specialArgs;
} // specialArgs;
};
buildNixos =
@@ -154,20 +144,16 @@ lib
pkgs = pkgsBySystem.${system};
modules = [
inputs.home-manager.nixosModules.home-manager
inputs.nix-index-database.nixosModules.default
inputs.disko.nixosModules.disko
inputs.wsl.nixosModules.wsl
{ imports = (nixFiles ../platforms/nixos); }
module
# (builtins.removeAttrs module [ "home-manager" ])
{
home-manager = {
extraSpecialArgs = {
inherit colorscheme;
}
// specialArgs;
}
// homeModule.home-manager;
} // specialArgs;
} // homeModule.home-manager;
}
];
};
@@ -182,21 +168,19 @@ lib
inherit system specialArgs;
modules = [
inputs.home-manager.darwinModules.home-manager
inputs.nix-index-database.darwinModules.nix-index
inputs.mac-app-util.darwinModules.default
{
imports = (nixFiles ../platforms/nix-darwin);
nixpkgs.pkgs = pkgsBySystem.${system};
}
# Home Manager is intentionally NOT activated here. It is managed
# standalone via `nh home switch` (see homeConfigurations, extracted
# from the host module's `home-manager.users`). Strip that attr so
# darwin-rebuild doesn't also activate a second, divergent HM
# generation with different store paths (useUserPackages puts packages
# in /etc/profiles/per-user vs. ~/.nix-profile standalone) -- that
# mismatch broke the prompt after every darwin-rebuild until the next
# `nh home switch`.
(builtins.removeAttrs module [ "home-manager" ])
module
{
home-manager = {
extraSpecialArgs = {
inherit colorscheme;
} // specialArgs;
} // homeModule.home-manager;
}
];
};
@@ -227,7 +211,6 @@ lib
pkgs = pkgsBySystem.${system};
modules = [
inputs.home-manager.nixosModules.home-manager
inputs.nix-index-database.homeModules.default
inputs.disko.nixosModules.disko
inputs.wsl.nixosModules.wsl
{
@@ -239,15 +222,12 @@ lib
home-manager = {
extraSpecialArgs = {
inherit colorscheme;
}
// specialArgs;
}
// homeModule.home-manager;
} // specialArgs;
} // homeModule.home-manager;
}
];
specialArgs = {
}
// specialArgs;
} // specialArgs;
};
}
+67
View File
@@ -0,0 +1,67 @@
{
config,
pkgs,
lib,
...
}:
{
home-manager.users.${config.user} = lib.mkIf pkgs.stdenv.isDarwin {
home.packages =
let
ldap_scheme = "ldaps";
magic_prefix = "take";
ldap_port = 3269;
jq_parse = pkgs.writeShellScriptBin "ljq" ''
jq --slurp \
--raw-input 'split("\n\n")|map(split("\n")|map(select(.[0:1]!="#" and length>0)) |select(length > 0)|map(capture("^(?<key>[^:]*:?): *(?<value>.*)") |if .key[-1:.key|length] == ":" then .key=.key[0:-1]|.value=(.value|@base64d) else . end)| group_by(.key) | map({key:.[0].key,value:(if .|length > 1 then [.[].value] else .[].value end)}) | from_entries)' | jq -r 'del(.[].thumbnailPhoto)'
'';
ldap_script = pkgs.writeShellScriptBin "ldap" ''
if ! [ "$LDAP_HOST" ]; then
echo "No LDAP_HOST specified!"
exit 1
fi
SEARCH_FILTER="$@"
ldapsearch -LLL \
-B -o ldif-wrap=no \
-E pr=5000/prompt \
-H "${ldap_scheme}://''${LDAP_HOST}:${builtins.toString ldap_port}" \
-D "${pkgs.lib.toUpper magic_prefix}2\\${pkgs.lib.toLower config.user}" \
-w "$(${pkgs._1password-cli}/bin/op item get T2 --fields label=password --reveal)" \
-b "dc=''${LDAP_HOST//./,dc=}" \
-s "sub" -x "(cn=''${SEARCH_FILTER})" \
| ${jq_parse}/bin/ljq
'';
ldapm_script = pkgs.writeShellScriptBin "ldapm" ''
if ! [ "$LDAP_HOST" ]; then
echo "No LDAP_HOST specified!"
exit 1
fi
${ldap_script}/bin/ldap "$@" | jq '[ .[].memberOf] | add'
'';
ldapg_script = pkgs.writeShellScriptBin "ldapg" ''
if ! [ "$LDAP_HOST" ]; then
echo "No LDAP_HOST specified!"
exit 1
fi
${ldap_script}/bin/ldap "$@" | jq '[ .[].member] | add'
'';
ldapl_script = pkgs.writeShellScriptBin "ldapl" ''
if ! [ "$LDAP_HOST" ]; then
echo "No LDAP_HOST specified!"
exit 1
fi
${ldap_script}/bin/ldap "*$@*" | jq -r '.[].name'
'';
in
[
ldap_script
ldapm_script
ldapg_script
ldapl_script
jq_parse
];
};
}
+56
View File
@@ -0,0 +1,56 @@
{
config,
pkgs,
lib,
...
}:
{
# Homebrew - Mac-specific packages that aren't in Nix
config = lib.mkIf pkgs.stdenv.isDarwin {
# # Requires Homebrew to be installed
system.activationScripts.preActivation.text = ''
if ! xcode-select --version 2>/dev/null; then
$DRY_RUN_CMD xcode-select --install
fi
if ! /opt/homebrew/bin/brew --version 2>/dev/null; then
$DRY_RUN_CMD /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
fi
'';
# Add homebrew paths to CLI path
home-manager.users.${config.user}.home.sessionPath = [
"/opt/homebrew/bin/"
"/opt/homebrew/opt/trash/bin/"
];
homebrew = {
enable = true;
onActivation = {
autoUpdate = false; # Don't update during rebuild
cleanup = "zap"; # Uninstall all programs not declared
upgrade = true;
};
global = {
brewfile = true; # Run brew bundle from anywhere
lockfiles = false; # Don't save lockfile (since running from anywhere)
};
brews = [
"trash" # Delete files and folders to trash instead of rm
];
casks = [
"1password" # 1Password will not launch from Nix on macOS
# "gitify" # Git notifications in menu bar (downgrade manually from 4.6.1)
"keybase" # GUI on Nix not available for macOS
# "logitech-g-hub" # Mouse and keyboard management
"logitune" # Logitech webcam firmware
"meetingbar" # Show meetings in menu bar
"scroll-reverser" # Different scroll style for mouse vs. trackpad
"notunes" # Don't launch Apple Music with the play button
"steam" # Not packaged for Nixon macOS
"epic-games" # Not packaged for Nix
];
};
};
}
-9
View File
@@ -1,9 +0,0 @@
_inputs: _final: prev: {
pythonPackagesExtensions = prev.pythonPackagesExtensions ++ [
(_pyfinal: pyprev: {
cheetah3 = pyprev.cheetah3.overridePythonAttrs (_old: {
dontCheckPythonMetadata = true;
});
})
];
}
-5
View File
@@ -1,5 +0,0 @@
inputs: final: prev: {
firefox-unwrapped = final.stable.firefox-unwrapped;
}
-7
View File
@@ -1,7 +0,0 @@
_inputs: _final: prev: {
kubernetes-helm = prev.kubernetes-helm.overrideAttrs (_old: {
doCheck = false;
});
}
-1
View File
@@ -1 +0,0 @@
inputs: inputs.nix-caddy-withplugins.overlays.default
-20
View File
@@ -1,20 +0,0 @@
# Disable paho-mqtt's flaky test suite.
#
# paho-mqtt's checkPhase runs socket-based integration tests that hang in
# the Nix sandbox (they eventually time out with a KeyboardInterrupt after
# ~150s, reporting errors and failing the build). This breaks the flame
# rebuild, where paho-mqtt is pulled in transitively (e.g. via mealie).
#
# Applied through pythonPackagesExtensions so it covers every Python
# package set (python3Packages, python314Packages, ...).
_inputs: _final: prev: {
pythonPackagesExtensions = prev.pythonPackagesExtensions ++ [
(_pyfinal: pyprev: {
paho-mqtt = pyprev.paho-mqtt.overridePythonAttrs (_old: {
doCheck = false;
doInstallCheck = false;
});
})
];
}
-3
View File
@@ -21,9 +21,6 @@ let
# [ package1.drv package2.drv ]
(builtins.map (name: prev.callPackage name { }))
# Filter out packages that return null (e.g. platform-specific packages)
(builtins.filter (v: v != null))
# Convert the list to an attrset
# { package1 = package1.drv, package2 = package2.drv }
listToAttrsByPnameOrName
+1 -2
View File
@@ -4,8 +4,7 @@
inputs: _final: prev: {
# Provides `pkgs.stable`.
stable = import inputs.nixpkgs-stable {
system = prev.stdenv.hostPlatform.system;
config = { };
inherit (prev) system config;
overlays = [
# inputs.self.overlays.vim-plugins
];
+1 -2
View File
@@ -4,8 +4,7 @@
inputs: _final: prev: {
# Provides `pkgs.unstable`.
unstable = import inputs.nixpkgs {
system = prev.stdenv.hostPlatform.system;
inherit (prev) config;
inherit (prev) system config;
overlays = [
# inputs.self.overlays.vim-plugins
];
-43
View File
@@ -1,43 +0,0 @@
{
lib,
buildNpmPackage,
fetchFromGitHub,
nodejs,
}:
buildNpmPackage rec {
pname = "actualtap";
version = "1.0.34";
src = fetchFromGitHub {
owner = "MattFaz";
repo = "actualtap";
rev = "v${version}";
hash = "sha256-I2yb3WCOXYx/6RXiKjePlpChrr9G1il44OdON/SeVCw=";
};
npmDepsHash = "sha256-LlTLwUt0Yja4NSBLbaYPV/keawSJKffno/28rtSj/oQ=";
dontNpmBuild = true;
postPatch = ''
substituteInPlace src/server.js \
--replace-fail 'port: 3001' 'port: process.env.PORT || 3001'
'';
postInstall = ''
mkdir -p $out/bin
cat <<EOF > $out/bin/actualtap
#!/bin/sh
exec ${lib.getExe nodejs} $out/lib/node_modules/actualtap/src/server.js "\$@"
EOF
chmod +x $out/bin/actualtap
'';
meta = with lib; {
description = "Automatically create transactions in Actual Budget when you use Tap-to-Pay on a mobile device";
homepage = "https://github.com/MattFaz/actualtap";
license = licenses.gpl3Only;
maintainers = [ ];
};
}
@@ -100,7 +100,7 @@
lua.command = "${pkgs.stylua}/bin/stylua";
black.command = "${pkgs.black}/bin/black";
fish_indent.command = "${pkgs.fish}/bin/fish_indent";
nixfmt.command = "${pkgs.nixfmt}/bin/nixfmt";
nixfmt.command = "${pkgs.nixfmt-rfc-style}/bin/nixfmt";
rustfmt.command = "${pkgs.rustfmt}/bin/rustfmt";
shfmt = {
command = "${pkgs.shfmt}/bin/shfmt";
@@ -3,10 +3,10 @@
plugins = [
(pkgs.vimPlugins.nvim-treesitter.withPlugins (_plugins: [
pkgs.nmasur.tree-sitter-ini
pkgs.nmasur.tree-sitter-puppet
pkgs.nmasur.tree-sitter-rasi
pkgs.nmasur.tree-sitter-vimdoc
pkgs.nmasur.ini-grammar
pkgs.nmasur.puppet-grammar
pkgs.nmasur.rasi-grammar
pkgs.nmasur.vimdoc-grammar
pkgs.tree-sitter-grammars.tree-sitter-bash
pkgs.tree-sitter-grammars.tree-sitter-c
pkgs.tree-sitter-grammars.tree-sitter-fish
@@ -21,6 +21,7 @@
pkgs.tree-sitter-grammars.tree-sitter-yaml
]))
pkgs.vimPlugins.vim-matchup # Better % jumping in languages
pkgs.vimPlugins.playground # Tree-sitter experimenting
pkgs.vimPlugins.nginx-vim
pkgs.vimPlugins.vim-helm
# pkgs.vimPlugins.hmts-nvim # Tree-sitter injections for home-manager
@@ -1,9 +1,6 @@
# Fix: Volnoti error: 'volnoti' has been removed due to lack of maintenance upstream.
{ pkgs, lib, ... }:
if !pkgs.stdenv.isLinux then
null
else
pkgs.stdenv.mkDerivation {
pname = "volnoti";
version = "2013-09-23";
-11
View File
@@ -1,11 +0,0 @@
# Caddy with Cloudflare DNS
{
pkgs,
...
}:
pkgs.caddy.withPlugins {
plugins = [ "github.com/caddy-dns/cloudflare@v0.2.1" ];
hash = "sha256-HuVBmiT3kD6RrDejQ6SnjCN8f7pFdZlGtZFbEf47bks=";
}
@@ -1,41 +0,0 @@
function exportHistory() {
const now = new Date();
const startTime = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0, 0); // Beginning of today
browser.history.search({
text: '',
startTime: startTime,
endTime: now,
maxResults: 10000
}).then(historyItems => {
const historyData = JSON.stringify(historyItems, null, 2);
const blob = new Blob([historyData], {type: 'application/json'});
const url = URL.createObjectURL(blob);
const date = now.toISOString().slice(0, 10); // YYYY-MM-DD
const filename = `firefox-history/history-${date}.json`;
browser.downloads.download({
url: url,
filename: filename,
conflictAction: 'overwrite',
saveAs: false
});
});
}
browser.alarms.create('daily-export', {
periodInMinutes: 60 // every 1 hour
});
browser.alarms.onAlarm.addListener(alarm => {
if (alarm.name === 'daily-export') {
exportHistory();
}
});
browser.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.command === "exportHistory") {
exportHistory();
}
});
@@ -1,25 +0,0 @@
{
"manifest_version": 3,
"name": "History Exporter",
"version": "1.1",
"description": "Automatically exports today's browsing history.",
"permissions": [
"history",
"downloads",
"alarms"
],
"background": {
"scripts": ["background.js"]
},
"action": {
"default_popup": "popup.html"
},
"browser_specific_settings": {
"gecko": {
"id": "[email protected]",
"data_collection_permissions": {
"required": ["none"]
}
}
}
}
-26
View File
@@ -1,26 +0,0 @@
{ pkgs, ... }:
pkgs.stdenv.mkDerivation rec {
pname = "firefox-history-exporter";
version = "1.1";
src = ./.;
nativeBuildInputs = [ pkgs.zip ];
dontUnpack = true;
installPhase = ''
dst="$out/share/mozilla/extensions/{ec8030f7-c20a-464f-9b0e-13a3a9e97384}"
mkdir -p "$dst"
zip -j "$dst/firefox-history-exporter@nmasur.com.xpi" \
"${src}/manifest.json" \
"${src}/background.js" \
"${src}/popup.html" \
"${src}/popup.js"
'';
meta = with pkgs.lib; {
description = "Automatically exports today's browsing history.";
license = licenses.mit;
};
}
-25
View File
@@ -1,25 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>History Exporter</title>
<style>
body {
width: 200px;
text-align: center;
font-family: sans-serif;
}
button {
margin-top: 10px;
padding: 10px;
font-size: 16px;
cursor: pointer;
}
</style>
</head>
<body>
<h1>History Exporter</h1>
<button id="export-button">Export Now</button>
<p id="status"></p>
<script src="popup.js"></script>
</body>
</html>
-9
View File
@@ -1,9 +0,0 @@
document.getElementById('export-button').addEventListener('click', () => {
browser.runtime.sendMessage({command: "exportHistory"});
const statusElement = document.getElementById('status');
statusElement.textContent = 'Exporting...';
setTimeout(() => {
statusElement.textContent = 'Export complete!';
}, 2000);
});
-7
View File
@@ -89,13 +89,6 @@ let
drf-access-policy
# psycopg-binary
;
# clevercsv's test_encoding_chardet is nondeterministic (chardet
# returns None instead of ISO-8859-1/KOI8-R on some platforms),
# breaking the build. Skip its test suite.
clevercsv = pyprev.clevercsv.overridePythonAttrs (_old: {
doCheck = false;
doInstallCheck = false;
});
};
};
+10 -11
View File
@@ -1,10 +1,9 @@
{
lib,
fetchFromGitHub,
nodejs_22,
nodejs_20,
buildNpmPackage,
typescript,
node-gyp,
nodePackages,
python3,
gcc,
gnumake,
@@ -30,10 +29,10 @@ buildNpmPackage (finalAttrs: rec {
npmDepsHash = "sha256-N8xqRYFelolNGTEhG22M7KJ7B5U/uW7o+/XfLF8rHMg=";
nativeBuildInputs = [
nodejs_22
typescript
nodejs_20
nodePackages.typescript
python3
node-gyp
nodePackages.node-gyp
gcc
gnumake
];
@@ -54,8 +53,8 @@ buildNpmPackage (finalAttrs: rec {
# export npm_config_build_from_source=true
# export npm_config_unsafe_perm=true
# export BINARY_SITE=none
# export PATH=${node-gyp}/bin:$PATH
# export npm_config_node_gyp=${node-gyp}/bin/node-gyp
# export PATH=${nodePackages.node-gyp}/bin:$PATH
# export npm_config_node_gyp=${nodePackages.node-gyp}/bin/node-gyp
# npm rebuild better-sqlite3 --build-from-source --verbose
@@ -65,7 +64,7 @@ buildNpmPackage (finalAttrs: rec {
installPhase = ''
mkdir -p $out/{bin,lib}
cp -r . $out/lib/prometheus-actual-exporter
makeWrapper ${lib.getExe nodejs_22} $out/bin/prometheus-actual-exporter \
makeWrapper ${lib.getExe nodejs_20} $out/bin/prometheus-actual-exporter \
--add-flags "$out/lib/prometheus-actual-exporter/dist/app.js"
'';
@@ -75,8 +74,8 @@ buildNpmPackage (finalAttrs: rec {
export npm_config_build_from_source=true
export npm_config_unsafe_perm=true
export BINARY_SITE=none
export PATH=${node-gyp}/bin:$PATH
export npm_config_node_gyp=${node-gyp}/bin/node-gyp
export PATH=${nodePackages.node-gyp}/bin:$PATH
export npm_config_node_gyp=${nodePackages.node-gyp}/bin/node-gyp
sed -i '/"install"/d' node_modules/better-sqlite3/package.json
rm -f node_modules/better-sqlite3/build/Release/better_sqlite3.node || true
+26 -29
View File
@@ -1,42 +1,39 @@
{
lib,
stdenv,
buildDotnetModule,
fetchFromGitHub,
dotnetCorePackages,
}:
if !stdenv.isLinux then
null
else
buildDotnetModule rec {
pname = "slsk-batchdl";
version = "2.4.7";
buildDotnetModule rec {
pname = "slsk-batchdl";
version = "2.4.7";
src = fetchFromGitHub {
owner = "fiso64";
repo = "slsk-batchdl";
rev = "v${version}";
sha256 = "sha256-P7V7YJUA1bkfp13Glb1Q+NJ7iTya/xgO1TM88z1Nddc=";
};
src = fetchFromGitHub {
owner = "fiso64";
repo = "slsk-batchdl";
rev = "v${version}";
sha256 = "sha256-P7V7YJUA1bkfp13Glb1Q+NJ7iTya/xgO1TM88z1Nddc=";
};
projectFile = "slsk-batchdl/slsk-batchdl.csproj";
nugetDeps = ./nuget-deps.nix;
projectFile = "slsk-batchdl/slsk-batchdl.csproj";
nugetDeps = ./nuget-deps.nix;
dotnet-sdk = dotnetCorePackages.sdk_8_0;
dotnet-runtime = dotnetCorePackages.runtime_8_0;
dotnet-sdk = dotnetCorePackages.sdk_8_0;
dotnet-runtime = dotnetCorePackages.runtime_8_0;
postPatch = ''
substituteInPlace slsk-batchdl/slsk-batchdl.csproj \
--replace-fail "net6.0" "net8.0"
'';
# Patch the project file to use .NET 8
postPatch = ''
substituteInPlace slsk-batchdl/slsk-batchdl.csproj \
--replace-fail "net6.0" "net8.0"
'';
doCheck = false;
doCheck = false;
meta = with lib; {
description = "A batch downloader for Soulseek";
homepage = "https://github.com/fiso64/slsk-batchdl";
platforms = platforms.linux;
mainProgram = "slsk-batchdl";
};
}
meta = with lib; {
description = "A batch downloader for Soulseek";
homepage = "https://github.com/fiso64/slsk-batchdl";
platforms = platforms.linux;
mainProgram = "slsk-batchdl";
};
}
+9 -9
View File
@@ -6,17 +6,17 @@
# Specify AWS_PROFILE and AWS_REGION before running this script
aws ec2 describe-instances \
--filters "Name=instance-state-name,Values=running" |
jq -r \
'.Reservations[]
--filters "Name=instance-state-name,Values=running" |
jq -r \
'.Reservations[]
| .Instances[]
| .InstanceId + " - " +
(.PrivateIpAddress // "n/a") + " - " +
(.PublicIpAddress // "n/a") + " - " +
(.Tags // [] | from_entries | .Name // "n/a")' |
fzf \
--height 100% \
--layout reverse \
--header $'Press Enter to start SSM session\nInstance ID - Private IP - Public IP - Name' \
--preview "aws ec2 describe-instances --instance-ids \"\$(echo {} | cut -d' ' -f1)\" | jq -r '.Reservations[].Instances[0]'" \
--bind "enter:become(aws ssm start-session --document-name 'AWS-StartInteractiveCommand' --parameters '{\"command\": [\"bash\"]}' --target \$(echo {} | cut -d' ' -f1))"
fzf \
--height 100% \
--layout reverse \
--header $'Press Enter to start SSM session\nInstance ID - Private IP - Public IP - Name' \
--preview "aws ec2 describe-instances --instance-ids \"\$(echo {} | cut -d' ' -f1)\" | jq -r '.Reservations[].Instances[0]'" \
--bind "enter:become(aws ssm start-session --target \$(echo {} | cut -d' ' -f1))"
@@ -5,7 +5,7 @@ pkgs.mkShell {
buildInputs = with pkgs; [
git
stylua
nixfmt
nixfmt-rfc-style
shfmt
shellcheck
];
+33 -36
View File
@@ -1,47 +1,44 @@
{ pkgs, lib, ... }:
{ pkgs, ... }:
# Inspired by https://github.com/cleverca22/nix-tests/blob/master/kexec/justdoit.nix
# This script will partition and format drives; use at your own risk!
if !pkgs.stdenv.isLinux then
null
else
pkgs.writeShellScriptBin "installer" ''
set -e
pkgs.writeShellScriptBin "installer" ''
set -e
DISK=$1
FLAKE=$2
PARTITION_PREFIX=""
DISK=$1
FLAKE=$2
PARTITION_PREFIX=""
if [ -z "$DISK" ] || [ -z "$FLAKE" ]; then
${pkgs.gum}/bin/gum style --width 50 --margin "1 2" --padding "2 4" \
--foreground "#fb4934" \
"Missing required parameter." \
"Usage: installer -- <disk> <host>" \
"Example: installer -- nvme0n1 tempest" \
"Flake example: nix run github:nmasur/dotfiles#installer -- nvme0n1 tempest"
echo "(exiting)"
exit 1
fi
if [ -z "$DISK" ] || [ -z "$FLAKE" ]; then
${pkgs.gum}/bin/gum style --width 50 --margin "1 2" --padding "2 4" \
--foreground "#fb4934" \
"Missing required parameter." \
"Usage: installer -- <disk> <host>" \
"Example: installer -- nvme0n1 tempest" \
"Flake example: nix run github:nmasur/dotfiles#installer -- nvme0n1 tempest"
echo "(exiting)"
exit 1
fi
case "$DISK" in nvme*)
PARTITION_PREFIX="p"
esac
case "$DISK" in nvme*)
PARTITION_PREFIX="p"
esac
${pkgs.gum}/bin/gum confirm \
"This will ERASE ALL DATA on the disk /dev/''${DISK}. Are you sure you want to continue?" \
--default=false
${pkgs.gum}/bin/gum confirm \
"This will ERASE ALL DATA on the disk /dev/''${DISK}. Are you sure you want to continue?" \
--default=false
${pkgs.parted}/bin/parted /dev/''${DISK} -- mklabel gpt
${pkgs.parted}/bin/parted /dev/''${DISK} -- mkpart primary 512MiB 100%
${pkgs.parted}/bin/parted /dev/''${DISK} -- mkpart ESP fat32 1MiB 512MiB
${pkgs.parted}/bin/parted /dev/''${DISK} -- set 3 esp on
mkfs.ext4 -L nixos /dev/''${DISK}''${PARTITION_PREFIX}1
mkfs.fat -F 32 -n boot /dev/''${DISK}''${PARTITION_PREFIX}2
${pkgs.parted}/bin/parted /dev/''${DISK} -- mklabel gpt
${pkgs.parted}/bin/parted /dev/''${DISK} -- mkpart primary 512MiB 100%
${pkgs.parted}/bin/parted /dev/''${DISK} -- mkpart ESP fat32 1MiB 512MiB
${pkgs.parted}/bin/parted /dev/''${DISK} -- set 3 esp on
mkfs.ext4 -L nixos /dev/''${DISK}''${PARTITION_PREFIX}1
mkfs.fat -F 32 -n boot /dev/''${DISK}''${PARTITION_PREFIX}2
mount /dev/disk/by-label/nixos /mnt
mkdir --parents /mnt/boot
mount /dev/disk/by-label/boot /mnt/boot
mount /dev/disk/by-label/nixos /mnt
mkdir --parents /mnt/boot
mount /dev/disk/by-label/boot /mnt/boot
${pkgs.nixos-install-tools}/bin/nixos-install --flake github:nmasur/dotfiles#''${FLAKE}
''
${pkgs.nixos-install-tools}/bin/nixos-install --flake github:nmasur/dotfiles#''${FLAKE}
''
+1 -1
View File
@@ -1,7 +1,7 @@
{ pkgs, ... }:
pkgs.writeShellScriptBin "rebuild" ''
echo ${pkgs.stdenv.hostPlatform.system}
echo ${pkgs.system}
SYSTEM=${if pkgs.stdenv.isDarwin then "darwin" else "linux"}
if [ "$SYSTEM" == "darwin" ]; then
sudo darwin-rebuild switch --flake ${builtins.toString ../../../../.}
@@ -17,27 +17,23 @@ in
home.packages = [
pkgs.nerd-fonts.victor-mono # Used for Vim and Terminal
pkgs.nerd-fonts.hack # For Polybar, Rofi
# Maple Mono NF (Ligature unhinted)
pkgs.maple-mono.NF-unhinted
];
fonts.fontconfig = {
enable = true;
defaultFonts.monospace = [ "Maple Mono NF" ];
defaultFonts.monospace = [ "Victor Mono" ];
};
xsession.windowManager.i3.config.fonts = {
# names = [ "pango:Victor Mono" ];
names = [ "pango:Maple Mono" ];
names = [ "pango:Victor Mono" ];
# style = "Regular";
# size = 11.0;
};
services.polybar.config."bar/main".font-0 = "Hack Nerd Font:size=10;2";
programs.rofi.font = "Hack Nerd Font 14";
programs.alacritty.settings.font.normal.family = "Maple Mono NF";
programs.kitty.font.name = "Maple Mono NF";
nmasur.presets.programs.wezterm.font = "Maple Mono NF";
programs.ghostty.settings.font-family = "Maple Mono NF";
programs.alacritty.settings.font.normal.family = "VictorMono";
programs.kitty.font.name = "VictorMono Nerd Font Mono";
nmasur.presets.programs.wezterm.font = "VictorMono Nerd Font Mono";
programs.ghostty.settings.font-family = "VictorMono Nerd Font Mono";
services.dunst.settings.global.font = "Hack Nerd Font 14";
};
}
@@ -18,17 +18,16 @@ in
"1password"
"_1password-gui"
"1password-cli"
# "onepassword-password-manager" # Firefox extension
"onepassword-password-manager" # Firefox extension
];
home.packages = [
pkgs._1password-cli
]
++ (if pkgs.stdenv.isLinux then [ pkgs._1password-gui ] else [ ]);
] ++ (if pkgs.stdenv.isLinux then [ pkgs._1password-gui ] else [ ]);
# # Firefox extension
# programs.firefox.profiles.default.extensions.packages = [
# pkgs.nur.repos.rycee.firefox-addons.onepassword-password-manager
# ];
# Firefox extension
programs.firefox.profiles.default.extensions.packages = [
pkgs.nur.repos.rycee.firefox-addons.onepassword-password-manager
];
};
# # https://1password.community/discussion/135462/firefox-extension-does-not-connect-to-linux-app
@@ -174,10 +174,8 @@ in
filters = {
"text/plain" = "${pkgs.aerc}/libexec/aerc/filters/colorize";
"text/calendar" = "${pkgs.gawk}/bin/awk -f ${pkgs.aerc}/libexec/aerc/filters/calendar";
# "text/html" =
# "${pkgs.aerc}/libexec/aerc/filters/html | ${pkgs.aerc}/libexec/aerc/filters/colorize"; # Requires w3m, dante
"text/html" =
"!${pkgs.chawan}/bin/cha --type text/html --opt display.image-mode=kitty --opt display.columns=100 --opt display.force-columns=true";
"${pkgs.aerc}/libexec/aerc/filters/html | ${pkgs.aerc}/libexec/aerc/filters/colorize"; # Requires w3m, dante
# "text/*" =
# ''${pkgs.bat}/bin/bat -fP --file-name="$AERC_FILENAME "'';
"message/delivery-status" = "${pkgs.aerc}/libexec/aerc/filters/colorize";
@@ -202,12 +200,9 @@ in
};
};
# Used for macOS
xdg.enable = lib.mkDefault pkgs.stdenv.isDarwin;
xdg.desktopEntries.aerc = lib.mkIf (pkgs.stdenv.isLinux) {
name = "aerc";
exec = "${lib.getExe config.nmasur.presets.services.i3.terminal} -e aerc %u";
exec = "${lib.getExe config.nmasur.presets.services.i3.terminal} aerc %u";
};
xsession.windowManager.i3.config.keybindings = lib.mkIf pkgs.stdenv.isLinux {
"${config.xsession.windowManager.i3.config.modifier}+Shift+e" =
@@ -217,7 +212,7 @@ in
if terminal == pkgs.wezterm then
"start --class com.noah.aerc -- aerc"
else
"--class=com.noah.aerc -e aerc";
"--class=com.noah.aerc --command=aerc";
in
"exec ${
# Don't name the script `aerc` or it will affect grep
@@ -32,6 +32,7 @@ in
config = lib.mkIf cfg.enable {
accounts.calendar.accounts.default = {
basePath = "other/calendars"; # Where to save calendars in ~ directory
name = "personal";
local.type = "filesystem";
primary = true;
@@ -18,16 +18,15 @@ in
ca = "cargo";
};
home.packages = [
pkgs.gcc
pkgs.rustc
pkgs.cargo
pkgs.stable.cargo-watch
pkgs.clippy
pkgs.rustfmt
pkgs.pkg-config
pkgs.openssl
pkgs.rust-analyzer
home.packages = with pkgs; [
gcc
rustc
cargo
cargo-watch
clippy
rustfmt
pkg-config
openssl
];
};
}
@@ -1,34 +0,0 @@
{
config,
pkgs,
lib,
...
}:
let
cfg = config.nmasur.presets.programs.chawan;
in
{
options.nmasur.presets.programs.chawan.enable = lib.mkEnableOption "chawan TUI web browser";
config = lib.mkIf cfg.enable {
programs.chawan = {
enable = true;
settings = {
external.copy-cmd = if pkgs.stdenv.isLinux then "xclip -selection clipboard -in" else "pbcopy";
};
};
# Set Chawan as the default app for manual pages
home.sessionVariables = {
MANPAGER = "${lib.getExe pkgs.chawan} -T text/x-ansi";
};
programs.fish.shellAbbrs.man = "mancha";
};
}
@@ -29,7 +29,7 @@ in
config = lib.mkIf cfg.enable {
# Always make the dotfiles directory considered safe for git and direnv
programs.git.settings.safe.directory = cfg.path;
programs.git.extraConfig.safe.directory = cfg.path;
programs.direnv.config.whitelist.prefix = [ cfg.path ];
home.activation = {
@@ -46,8 +46,6 @@ in
ublacklist
vimium
wappalyzer # TODO: only for work profile
# pkgs.nmasur.firefox-history-exporter
# copy-as-markdown
# saml-tracer
# text-fragment
];
@@ -63,7 +61,6 @@ in
"trailhead.firstrun.didSeeAboutWelcome" = true; # Disable welcome splash
"dom.forms.autocomplete.formautofill" = false; # Disable autofill
"extensions.formautofill.creditCards.enabled" = false; # Disable credit cards
"extensions.autoDisableScopes" = false; # Enable extensions automatically
"dom.payments.defaults.saveAddress" = false; # Disable address save
"general.autoScroll" = true; # Drag middle-mouse to scroll
"services.sync.prefs.sync.general.autoScroll" = false; # Prevent disabling autoscroll
@@ -190,7 +187,7 @@ in
xsession.windowManager.i3.config.keybindings = lib.mkIf pkgs.stdenv.isLinux {
"${config.xsession.windowManager.i3.config.modifier}+Shift+b" = "exec ${
# Don't name the script `firefox` or it will affect grep
toString (
builtins.toString (
pkgs.writeShellScript "focus-ff.sh" ''
count=$(ps aux | grep -c firefox)
if [ "$count" -eq 1 ]; then
@@ -13,35 +13,13 @@ in
options.nmasur.presets.programs.fish-darwin.enable = lib.mkEnableOption {
description = "Fish macOS options";
default = config.nmasur.presets.programs.fish && pkgs.stdenv.isDarwin;
};
config = lib.mkIf cfg.enable {
# Default shell setting doesn't work
home.sessionVariables = {
SHELL = "${pkgs.fish}/bin/fish";
};
programs.fish = {
shellAbbrs = {
# Shortcut to edit hosts file
hosts = "sudo hx /etc/hosts";
};
shellInit = ''
set -g __nixos_path_original $PATH
function __nixos_path_fix -d "fix PATH value"
set -l result (string split ":" $__nixos_path_original)
for elt in $PATH
if not contains -- $elt $result
set -a result $elt
end
end
set -g PATH $result
end
__nixos_path_fix
'';
# # Speeds up fish launch time on macOS
# useBabelfish = true;
programs.fish.shellAbbrs = {
# Shortcut to edit hosts file
hosts = "sudo nvim /etc/hosts";
};
};
}
@@ -21,7 +21,7 @@ in
programs.ghostty = {
enable = true;
package = if pkgs.stdenv.isDarwin then pkgs.ghostty-bin else pkgs.ghostty;
package = if pkgs.stdenv.isDarwin then pkgs.nur.repos.DimitarNestorov.ghostty else pkgs.ghostty;
enableFishIntegration = true;
enableBashIntegration = true;
@@ -39,19 +39,8 @@ in
config = lib.mkIf cfg.enable {
programs.git = {
settings = {
user = {
name = lib.mkForce cfg.work.name;
email = lib.mkForce cfg.work.email;
signingKey = "~/.ssh/work_github";
};
commit = {
gpgsign = true;
};
tag = {
gpgsign = true;
};
};
userName = lib.mkForce cfg.work.name;
userEmail = lib.mkForce cfg.work.email;
includes = [
{
path = "${config.home.homeDirectory}/${config.xdg.configFile."git/personal".target}";
@@ -61,11 +50,6 @@ in
};
# Add work to signers file
xdg.configFile."git/allowed-signers".text = ''
${cfg.work.email} ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIP7aXbmKHmWUZgwG5HPtwx+nREVeMIRplpAAzxPOFXL
'';
# Personal git config
xdg.configFile."git/personal".text = lib.generators.toGitINI {
user = {
@@ -73,6 +57,12 @@ in
email = cfg.personal.email;
signingkey = "~/.ssh/id_ed25519";
};
commit = {
gpgsign = true;
};
tag = {
gpgsign = true;
};
};
# Personal jj config
@@ -29,11 +29,9 @@ in
programs.git = {
enable = true;
settings = {
user = {
name = cfg.name;
email = cfg.email;
};
userName = cfg.name;
userEmail = cfg.email;
extraConfig = {
core.pager = "${pkgs.git}/share/git/contrib/diff-highlight/diff-highlight | less --no-init";
interactive.difffilter = "${pkgs.git}/share/git/contrib/diff-highlight/diff-highlight";
pager = {
@@ -65,7 +63,7 @@ in
};
xdg.configFile."git/allowed-signers".text = ''
${config.nmasur.presets.programs.git.email} ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB+AbmjGEwITk5CK9y7+Rg27Fokgj9QEjgc9wST6MA3s
7386960+nmasur@users.noreply.github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB+AbmjGEwITk5CK9y7+Rg27Fokgj9QEjgc9wST6MA3s
'';
programs.fish.shellAbbrs = {
@@ -22,6 +22,7 @@ in
extensions = [
pkgs.nmasur.gh-collaborators
pkgs.gh-dash
pkgs.gh-copilot
];
};
@@ -7,62 +7,6 @@
let
cfg = config.nmasur.presets.programs.helix;
blame_file_pretty = pkgs.writeShellScriptBin "blame_file_pretty" ''
# Source: https://gist.github.com/gloaysa/828707f067e3bb20da18d72fa5d4963a
# Utility for Helix: open the patch for the commit that last touched the current line.
# If the line isnt committed yet, it shows the working-tree diff for THIS file only.
# The script writes the diff to /tmp and prints the absolute path to stdout
# Adjust `context` to see more/fewer unchanged lines around the change (default: 3).
#
# usage: git-file_pretty.sh <file> <line> [context_lines]
# Helix mapping example:
# B = ':open %sh{ ~/.config/helix/utils/git-blame-commit.sh "%{buffer_name}" %{cursor_line} 3 }'
file="$1"
line="$2"
ctx="''${3:-3}"
# blame the exact line
porc="$(git blame -L "$line",+1 --porcelain -- "$file")" || exit 1
sha="$(printf '%s\n' "$porc" | awk 'NR==1{print $1}')"
commit_path="$(printf '%s\n' "$porc" | awk '/^filename /{print substr($0,10); exit}')"
out="/tmp/hx-blame_$(basename "$file")_''${sha:-wt}.diff"
if [ -z "$sha" ] || [ "$sha" = 0000000000000000000000000000000000000000 ] || [ "$sha" = "^" ]; then
# uncommitted line working tree diff for this file
git --no-pager diff --no-color -U"$ctx" -- "$file" > "$out"
else
# committed line only this files patch in that commit
git --no-pager show --no-color -M -C -U"$ctx" "$sha" -- "''${commit_path:-$file}" > "$out"
fi
# "return" the path for :open %sh{}
printf '%s' "$out"
'';
blame_line_pretty = pkgs.writeShellScriptBin "blame_line_pretty" ''
# Source: https://gist.github.com/gloaysa/828707f067e3bb20da18d72fa5d4963a
# Utility for Helix: pretty-print blame info for the line under the cursor.
# Quite basic.
#
# usage: blame_line_pretty <file> <line>
# Helix mapping example:
# b = ":run-shell-command ~/.config/helix/utils/blame_line_pretty.sh %{buffer_name} %{cursor_line}"
file="$1"; line="$2"
out="$(git blame -L "$line",+1 --porcelain -- "$file")" || return 1
sha="$(printf '%s\n' "$out" | awk 'NR==1{print $1}')"
author="$(printf '%s\n' "$out" | awk -F'author ' '/^author /{print $2; exit}')"
epoch="$(printf '%s\n' "$out" | awk '/^author-time /{print $2; exit}')"
# dd-mm-yyyy (macOS `date -r`; fallback to gdate if present)
date="$( (date -r "$epoch" +%d-%m-%Y\ %H:%M 2>/dev/null) || (gdate -d "@$epoch" +%d-%m-%Y\ %H:%M 2>/dev/null) || printf '%s' "$epoch")"
summary="$(printf '%s\n' "$out" | awk -F'summary ' '/^summary /{print $2; exit}')"
change="$(printf '%s\n' "$out" | tail -n 1)"
printf "%s\n%s\n%s\n%s\n%s\n" "$sha" "$author" "$date" "$summary" "$change"
'';
in
{
@@ -72,13 +16,13 @@ in
config = lib.mkIf cfg.enable {
# Use Neovim as the editor for git commit messages
programs.git.settings.core.editor = lib.mkForce "${lib.getExe pkgs.helix}";
programs.git.extraConfig.core.editor = lib.mkForce "${lib.getExe pkgs.helix}";
programs.jujutsu.settings.ui.editor = lib.mkForce "${lib.getExe pkgs.helix}";
# Set Neovim as the default app for text editing and manual pages
home.sessionVariables = {
EDITOR = lib.mkForce "${lib.getExe pkgs.helix}";
# MANPAGER = lib.mkForce "sh -c 'col -bx | ${lib.getExe pkgs.helix}'";
MANPAGER = lib.mkForce "sh -c 'col -bx | ${lib.getExe pkgs.helix}'";
MANWIDTH = 87;
MANROFFOPT = "-c";
};
@@ -102,10 +46,6 @@ in
command = "${pkgs.nixd}/bin/nixd";
};
language-server.ty = {
command = "${pkgs.ty}/bin/ty";
};
language-server.fish-lsp = {
command = "${pkgs.fish-lsp}/bin/fish-lsp";
};
@@ -118,14 +58,8 @@ in
command = lib.getExe pkgs.marksman;
};
language-server.rumdl = {
command = lib.getExe pkgs.rumdl;
args = [ "server" ];
};
language-server.terraform-ls = {
command = "${lib.getExe pkgs.terraform-ls}";
args = [ "serve" ];
command = "${lib.getExe pkgs.terraform-ls} serve";
};
language-server.bash-language-server = {
@@ -148,16 +82,10 @@ in
{
name = "markdown";
auto-format = false;
language-servers = [
"marksman"
"rumdl"
];
language-servers = [ "marksman" ];
formatter = {
command = lib.getExe pkgs.rumdl;
args = [
"fmt"
"-"
];
command = lib.getExe pkgs.mdformat;
args = [ "-" ];
};
# Allows return key to continue the token on the next line
comment-tokens = [
@@ -169,18 +97,9 @@ in
];
}
{
name = "hcl";
scope = "source.hcl";
# injection-regex = "terraform";
name = "tfvars";
auto-format = true;
language-servers = [ "terraform-ls" ];
language-id = "terraform";
file-types = [
"tf"
"tfvars"
"terraform"
{ glob = "*.auto.tfvars"; }
];
formatter = {
command = lib.getExe pkgs.terraform;
args = [
@@ -190,15 +109,11 @@ in
};
}
{
name = "hcl-packer";
scope = "source.hcl-packer";
name = "hcl";
auto-format = true;
file-types = [
"hcl"
"pkr.hcl"
];
language-servers = [ "terraform-ls" ];
formatter = {
command = "${pkgs.packer}/bin/packer";
command = lib.getExe pkgs.terraform;
args = [
"fmt"
"-"
@@ -259,9 +174,18 @@ in
];
# Commandline git blame
# space.B = ":echo %sh{git log -n1 --date=short --pretty=format:'%%h %%ad %%s' $(git blame -L %{cursor_line},+1 \"%{buffer_name}\" | cut -d' ' -f1)}";
space.B = '':open %sh{ ${blame_line_pretty}/bin/blame_line_pretty "%{buffer_name}" %{cursor_line} 3 }'';
space.i = '':open %sh{ ${blame_file_pretty}/bin/blame_file_pretty "%{buffer_name}" %{cursor_line} 3 }'';
space.B = ":echo %sh{git log -n1 --date=short --pretty=format:'%%h %%ad %%s' $(git blame -L %{cursor_line},+1 \"%{buffer_name}\" | cut -d' ' -f1)}";
# Open yazi
# https://github.com/sxyazi/yazi/pull/2461
# Won't work until next Helix release
C-y = [
":sh rm -f /tmp/unique-file"
":insert-output ${lib.getExe pkgs.yazi} %{buffer_name} --chooser-file=/tmp/unique-file"
":insert-output echo \\x1b[?1049h\\x1b[?2004h > /dev/tty"
":open %sh{cat /tmp/unique-file}"
":redraw"
];
# Extend selection above
X = "select_line_above";
@@ -327,10 +251,6 @@ in
git-exclude = true; # Skip excluded files
};
completion-replace = true; # Replace whole word with completion
trim-trailing-whitespace = true;
# rainbow-brackets = true; # Make it easier to match parentheses
# Show whitespace visible to the user
# Waiting for trailing whitespace option ideally
whitespace = {
@@ -347,7 +267,7 @@ in
};
themes.base16 = {
themes."${config.programs.helix.settings.theme}" = {
"attributes" = config.theme.colors.base09;
"comment" = {
fg = config.theme.colors.base03;
@@ -527,220 +447,8 @@ in
};
};
themes.alabaster-style = {
"attribute" = config.theme.colors.base05;
"comment" = {
fg = config.theme.colors.base0A;
# modifiers = [ "italic" ];
};
"constant" = config.theme.colors.base0E;
"constant.numeric" = config.theme.colors.base0E;
"constant.builtin" = config.theme.colors.base0E;
"constant.character" = config.theme.colors.base0E;
"constant.character.escape" = config.theme.colors.base0C;
"constructor" = config.theme.colors.base0D;
"debug" = config.theme.colors.base03;
"diagnostic" = {
modifiers = [ "underlined" ];
};
"diff.delta" = config.theme.colors.base09;
"diff.minus" = config.theme.colors.base08;
"diff.plus" = config.theme.colors.base0B;
"error" = config.theme.colors.base08;
"function" = config.theme.colors.base0D;
"hint" = config.theme.colors.base03;
"info" = config.theme.colors.base0D;
"keyword" = config.theme.colors.base05;
"keyword.control" = config.theme.colors.base05;
"keyword.operator" = config.theme.colors.base05;
"label" = config.theme.colors.base0E;
"namespace" = config.theme.colors.base0E;
"operator" = config.theme.colors.base05;
"punctuation" = config.theme.colors.base04;
"punctuation.bracket" = config.theme.colors.base04;
"punctuation.delimiter" = config.theme.colors.base04;
"special" = config.theme.colors.base0D;
"string" = config.theme.colors.base0B;
"string.regexp" = config.theme.colors.base0B;
"string.special" = config.theme.colors.base0C;
"type" = config.theme.colors.base0A;
"variable" = config.theme.colors.base05;
"variable.parameter" = config.theme.colors.base05;
"variable.builtin" = config.theme.colors.base05;
"variable.other.member" = config.theme.colors.base05;
"warning" = config.theme.colors.base09;
"markup.bold" = {
fg = config.theme.colors.base0A;
modifiers = [ "bold" ];
};
"markup.heading" = config.theme.colors.base0D;
"markup.italic" = {
fg = config.theme.colors.base0E;
modifiers = [ "italic" ];
};
"markup.link.text" = config.theme.colors.base08;
"markup.link.url" = {
fg = config.theme.colors.base09;
modifiers = [ "underlined" ];
};
"markup.list" = config.theme.colors.base08;
"markup.quote" = config.theme.colors.base0C;
"markup.raw" = config.theme.colors.base0B;
"markup.strikethrough" = {
modifiers = [ "crossed_out" ];
};
"diagnostic.hint" = {
underline = {
style = "curl";
};
};
"diagnostic.info" = {
underline = {
style = "curl";
};
};
"diagnostic.warning" = {
underline = {
style = "curl";
};
};
"diagnostic.error" = {
underline = {
style = "curl";
};
};
"ui.background" = {
bg = config.theme.colors.base00;
};
"ui.bufferline.active" = {
fg = config.theme.colors.base00;
bg = config.theme.colors.base03;
modifiers = [ "bold" ];
};
"ui.bufferline" = {
fg = config.theme.colors.base04;
bg = config.theme.colors.base00;
};
"ui.cursor" = {
fg = config.theme.colors.base04;
modifiers = [ "reversed" ];
};
"ui.cursor.insert" = {
fg = config.theme.colors.base0A;
modifiers = [ "reversed" ];
};
"ui.cursorline.primary" = {
fg = config.theme.colors.base05;
bg = config.theme.colors.base01;
};
"ui.cursor.match" = {
fg = config.theme.colors.base03;
modifiers = [ "reversed" ];
};
"ui.cursor.select" = {
fg = config.theme.colors.base04;
modifiers = [ "reversed" ];
};
"ui.gutter" = {
bg = config.theme.colors.base00;
};
"ui.help" = {
fg = config.theme.colors.base06;
bg = config.theme.colors.base01;
};
"ui.linenr" = {
fg = config.theme.colors.base03;
bg = config.theme.colors.base00;
};
"ui.linenr.selected" = {
fg = config.theme.colors.base04;
bg = config.theme.colors.base01;
modifiers = [ "bold" ];
};
"ui.menu" = {
fg = config.theme.colors.base05;
bg = config.theme.colors.base01;
};
"ui.menu.scroll" = {
fg = config.theme.colors.base03;
bg = config.theme.colors.base01;
};
"ui.menu.selected" = {
fg = config.theme.colors.base01;
bg = config.theme.colors.base04;
};
"ui.popup" = {
bg = config.theme.colors.base01;
};
"ui.selection" = {
bg = config.theme.colors.base01;
};
"ui.selection.primary" = {
bg = config.theme.colors.base02;
};
"ui.statusline" = {
fg = config.theme.colors.base04;
bg = config.theme.colors.base01;
};
"ui.statusline.inactive" = {
bg = config.theme.colors.base01;
fg = config.theme.colors.base03;
};
"ui.statusline.insert" = {
fg = config.theme.colors.base00;
bg = config.theme.colors.base0B;
};
"ui.statusline.normal" = {
fg = config.theme.colors.base00;
bg = config.theme.colors.base03;
};
"ui.statusline.select" = {
fg = config.theme.colors.base00;
bg = config.theme.colors.base0F;
};
"ui.text" = config.theme.colors.base05;
"ui.text.focus" = config.theme.colors.base05;
"ui.virtual.indent-guide" = {
fg = config.theme.colors.base03;
};
"ui.virtual.inlay-hint" = {
fg = config.theme.colors.base03;
};
"ui.virtual.ruler" = {
bg = config.theme.colors.base01;
};
"ui.virtual.jump-label" = {
fg = config.theme.colors.base0A;
modifiers = [ "bold" ];
};
"ui.window" = {
bg = config.theme.colors.base01;
};
};
};
# Create a desktop option for launching Helix from a file manager
# (Requires launching the terminal and then executing Helix)
xdg.desktopEntries.helix =
lib.mkIf (pkgs.stdenv.isLinux && config.nmasur.presets.services.i3.enable)
{
name = "Helix wrapper";
exec = ''sh -c "${lib.getExe config.nmasur.presets.services.i3.terminal} --command='hx \$1'" _ %F ''; # TODO: change to work for any terminal
mimeType = [
"text/plain"
"text/markdown"
];
};
xdg.mimeApps.defaultApplications = {
"text/plain" = lib.mkBefore [ "Helix.desktop" ];
"text/markdown" = lib.mkBefore [ "Helix.desktop" ];
};
home.packages = [
(pkgs.writers.writeDashBin "xterm" ''${lib.getExe config.nmasur.presets.services.i3.terminal} +new-window --command"$@" '')
];
};
}
@@ -1,83 +0,0 @@
{
config,
lib,
...
}:
let
cfg = config.nmasur.presets.programs.homebrew;
in
{
options.nmasur.presets.programs.homebrew.enable =
lib.mkEnableOption "Homebrew macOS package manager";
config = lib.mkIf cfg.enable {
home.file.".Brewfile".text = /* homebrew */ ''
# Taps
# tap "homebrew/bundle"
# Brews (CLI Apps)
brew "trash" # Delete files and folders to trash instead of rm
# Casks (GUI Apps)
cask "scroll-reverser" # Different scroll style for mouse vs. trackpad
cask "notunes" # Don't launch Apple Music with the play button
cask "topnotch" # Darkens the menu bar to complete black
cask "ghostty" # Terminal application (not buildable on Nix on macOS)
cask "discord" # nixpkgs bundle breaks its notarization seal on macOS 26+
# Mac App Store apps (requires 'mas' CLI, optional)
# mas "Tailscale", id: 1475387142
'';
# Add homebrew paths to CLI path
home.sessionPath = [
"/opt/homebrew/bin/"
"/opt/homebrew/opt/trash/bin"
];
programs.fish.shellAbbrs.t = "trash";
home.activation.backendBrewBundle = /* bash */ ''
# Requires Homebrew to be installed
if ! /usr/bin/xcode-select --version 2>/dev/null; then
$DRY_RUN_CMD /usr/bin/xcode-select --install
fi
if ! /opt/homebrew/bin/brew --version 2>/dev/null; then
$DRY_RUN_CMD /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
fi
verboseEcho "Syncing Homebrew dependencies via Brewfile..."
# Ensure Homebrew is in the PATH for the script (Apple Silicon path)
export PATH="/opt/homebrew/bin:/usr/local/bin:$PATH"
# Keep activation deterministic and non-interactive. Without this, brew
# auto-updates (git-fetches its taps) which can hang forever when there
# is no TTY (network stall, credential prompt, or a leftover brew lock).
export HOMEBREW_NO_AUTO_UPDATE=1
export HOMEBREW_NO_ENV_HINTS=1
# Point brew at the generated Brewfile in the Nix store directly. This
# avoids depending on the ~/.Brewfile symlink being linked first, and
# sidesteps the --global vs. inherited HOMEBREW_BUNDLE_FILE conflict.
unset HOMEBREW_BUNDLE_FILE
brewfile="${config.home.file.".Brewfile".source}"
if command -v brew &> /dev/null; then
# Install/upgrade everything declared in the Brewfile...
$DRY_RUN_CMD brew bundle install --file="$brewfile"
# ...then uninstall anything NOT listed (replaces deprecated --cleanup).
$DRY_RUN_CMD brew bundle cleanup --file="$brewfile" --force
else
verboseEcho "Warning: Homebrew not found. Actions skipped."
fi
'';
};
}
@@ -7,7 +7,6 @@
let
cfg = config.nmasur.presets.programs.jujutsu;
tomlFormat = pkgs.formats.toml { };
in
{
@@ -21,8 +20,8 @@ in
# https://github.com/martinvonz/jj/blob/main/docs/config.md
settings = {
user = {
name = config.programs.git.settings.user.name;
email = config.programs.git.settings.user.email;
name = config.programs.git.userName;
email = config.programs.git.userEmail;
};
ui.paginate = "never";
@@ -32,37 +31,9 @@ in
};
};
xdg.configFile."jjui/config.toml".source = tomlFormat.generate "jjui-config" {
actions = [
{
name = "set-github-bypass";
lua = ''
exec_shell([[gh api --method PATCH -H "Accept: application/vnd.github+json" /repos/$(gh repo view --json nameWithOwner -q .nameWithOwner)/properties/values -f 'properties[][property_name]=Allow-Ruleset-Bypass' -f 'properties[][value]=true']])
flash("Set GitHub rule bypass")
'';
key = "ctrl+b";
scope = "revisions";
desc = "Set GitHub rule bypass";
}
{
name = "remove-github-bypass";
lua = ''
exec_shell([[gh api --method PATCH -H "Accept: application/vnd.github+json" /repos/$(gh repo view --json nameWithOwner -q .nameWithOwner)/properties/values -f 'properties[][property_name]=Allow-Ruleset-Bypass' -f 'properties[][value]=']])
flash("Removed GitHub rule bypass")
'';
key = "ctrl+shift+b";
scope = "revisions";
desc = "Remove GitHub rule bypass";
}
];
};
home.packages = [
# Required for the fsmonitor to auto-snapshot
pkgs.stable.watchman
# Required to be on path to work in Zellij
pkgs.jjui
pkgs.watchman
];
};
@@ -38,13 +38,13 @@ in
);
# Use Neovim as the editor for git commit messages
programs.git.settings.core.editor = "${lib.getExe cfg.package}";
programs.git.extraConfig.core.editor = "${lib.getExe cfg.package}";
programs.jujutsu.settings.ui.editor = "${lib.getExe cfg.package}";
# Set Neovim as the default app for text editing and manual pages
home.sessionVariables = {
EDITOR = "${lib.getExe cfg.package}";
# MANPAGER = "${lib.getExe cfg.package} +Man!";
MANPAGER = "${lib.getExe cfg.package} +Man!";
};
# Create quick aliases for launching Neovim
@@ -66,7 +66,7 @@ in
lib.mkIf (pkgs.stdenv.isLinux && config.nmasur.presets.services.i3.enable)
{
name = "Neovim wrapper";
exec = ''${lib.getExe config.nmasur.presets.services.i3.terminal} --command="nvim %F"''; # TODO: change to generic
exec = "${lib.getExe config.nmasur.presets.services.i3.terminal} nvim %F"; # TODO: change to generic
mimeType = [
"text/plain"
"text/markdown"
@@ -1,6 +1,6 @@
{
config,
# pkgs,
pkgs,
lib,
...
}:
@@ -23,18 +23,17 @@ in
};
# Create nix-index if doesn't exist
# Should not be necessary with the nix-index-database flake
# home.activation.createNixIndex =
# let
# cacheDir = "${config.xdg.cacheHome}/nix-index";
# in
# lib.mkIf config.programs.nix-index.enable (
# config.lib.dag.entryAfter [ "writeBoundary" ] ''
# if [ ! -d ${cacheDir} ]; then
# run ${pkgs.nix-index}/bin/nix-index -f ${pkgs.path}
# fi
# ''
# );
home.activation.createNixIndex =
let
cacheDir = "${config.xdg.cacheHome}/nix-index";
in
lib.mkIf config.programs.nix-index.enable (
config.lib.dag.entryAfter [ "writeBoundary" ] ''
if [ ! -d ${cacheDir} ]; then
run ${pkgs.nix-index}/bin/nix-index -f ${pkgs.path}
fi
''
);
};
@@ -29,18 +29,6 @@ in
doas nixos-rebuild switch --flake ${config.nmasur.presets.programs.dotfiles.path}
'';
};
rebuildNixosAndPause = lib.mkOption {
type = lib.types.package;
default = pkgs.writeShellScriptBin "rebuild-nixos-pause" ''
${lib.getExe cfg.commands.rebuildNixos} || read
'';
};
rebuildHomeAndPause = lib.mkOption {
type = lib.types.package;
default = pkgs.writeShellScriptBin "rebuild-home-pause" ''
${lib.getExe cfg.commands.rebuildHome} || read
'';
};
};
};
@@ -15,21 +15,10 @@ in
config = lib.mkIf (cfg.enable && (pkgs.stdenv.isDarwin || config.services.dunst.enable)) {
home.packages = [ pkgs.noti ];
programs.fish = {
shellAbbrs = {
# Add noti for ghpr in Darwin
ghpr = lib.mkForce "gh pr create && sleep 3 && noti gh run watch";
grw = lib.mkForce "noti gh run watch";
};
functions = {
gh-run = {
body =
lib.mkForce # fish
''
${lib.getExe pkgs.zellij} action new-pane --start-suspended -- noti gh run watch
'';
};
};
programs.fish.shellAbbrs = {
# Add noti for ghpr in Darwin
ghpr = lib.mkForce "gh pr create && sleep 3 && noti gh run watch";
grw = lib.mkForce "noti gh run watch";
};
};
}
@@ -22,6 +22,6 @@ in
# Broken on 2023-12-11
# https://forum.obsidian.md/t/electron-25-is-now-eol-please-upgrade-to-a-newer-version/72878/8
# allowInsecurePackages = [ "electron-36.9.5" ];
# insecurePackages = [ "electron-25.9.0" ];
};
}
@@ -24,7 +24,6 @@ in
.terraform/
.target/
/Library/
.jj/
'';
};
};
@@ -15,8 +15,6 @@ in
config = lib.mkIf cfg.enable {
home.packages = [ pkgs.jj-starship ];
programs.starship = {
enable = true;
enableFishIntegration = true;
@@ -29,7 +27,6 @@ in
"$git_branch"
"$git_commit"
"$git_status"
"\${custom.jj}"
"$hostname"
"$cmd_duration"
"$character"
@@ -41,37 +38,23 @@ in
vicmd_symbol = "[](bold green)";
};
cmd_duration = {
min_time = 5001;
min_time = 5000;
show_notifications = if pkgs.stdenv.isLinux then false else true;
min_time_to_notify = 30000;
format = "[$duration]($style) ";
};
custom = {
jj = {
when = "jj-starship detect";
shell = [
"jj-starship"
"--no-jj-prefix"
"--no-git-prefix"
];
format = "$output ";
};
};
directory = {
truncate_to_repo = true;
truncation_length = 100;
};
git_branch = {
disabled = true;
format = "[$symbol$branch]($style)";
};
git_commit = {
disabled = true;
format = "( @ [$hash]($style) )";
only_detached = false;
};
git_status = {
disabled = true;
format = "([$all_status$ahead_behind]($style) )";
conflicted = "=";
ahead = "";
@@ -1,17 +0,0 @@
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IE1nSGFPdyBTYTRy
elYzTGpSNDQ3UEcwTXlVeGJleUJmWWhaeDdDQTFRcGpmNlNrQlNVCjA5L2JrS3Vx
Q0cyRkk5dTBLOHJXa0xJSG9MTDFnNjV1M0F5L3F5RUlVbW8KLT4gc3NoLWVkMjU1
MTkgWXlTVU1RIG5vNm1Xem9lN2pkS25WRi9xSlpZUjhuYmdUVDUvc2o4M0xqYURR
UmY0VGcKWVVQc2wyV0Jqbk9JR3N4bW5HOXFTZHpCa25EMC85eThQY05MdHdaeXZy
VQotPiBzc2gtZWQyNTUxOSBuanZYNUEgWXRVa3c4STZ3WmFaNThSdE1QdVpiMVR1
cm5hYXJsckZiRGtXLzN5RzJEawpkVHBscFd2c0R1SGxnZ3lKUnNnMEZtTUxoQlB4
dVBEbTkvUzBJSVRiV1hBCi0+IHNzaC1lZDI1NTE5IENxSU9VQSAvQjhVam1heHNU
elVrVGtvaUx1elFCeTdNTkRnN3c5NEc5MWg4dDU3NUhzCm5sUlhHclJrNldnVDhF
MTV2cGd3ZFhFdm1rM2ExWVFXbkNJYWlWY0VnUmsKLT4gc3NoLWVkMjU1MTkgejFP
Y1p3IGc1QUdkZEp0Z0xEekFjcHd4WVFVam9BZTBEQm9NR3QzQmxNS09VVXpHV2sK
c2tYSElVK2prRlF3VlFqKzlVUFRHUWU3TmFXcEdsV2FKWVhKT3pWZkxVNAotLS0g
c1cxdk5sL1c3dDZuVGp5VWJrTlBGZTByNjRxMGxTdHd0NFNHV1pyN2k5Ywr7SW9q
/FaTTUHB5QiCihA+385sNogq7Q1RvgT2Dwn9NdmMRd/ObESbokJXVSiDDEt6d39s
D/uoDY20p3PCk4julNn1
-----END AGE ENCRYPTED FILE-----
@@ -1,106 +0,0 @@
{
config,
pkgs,
lib,
...
}:
let
inherit (config.nmasur.settings) hostnames;
cfg = config.nmasur.presets.programs.thunderbird;
in
{
options.nmasur.presets.programs.thunderbird = {
enable = lib.mkEnableOption "Thunderbird email client";
calendar = {
username = lib.mkOption {
type = lib.types.str;
description = "Username for the calendar service backend";
default = config.nmasur.settings.username;
};
passwordCommand = lib.mkOption {
type = lib.types.str;
description = "Password for the calendar service backend";
default = config.accounts.email.accounts.home.passwordCommand;
};
hostname = lib.mkOption {
type = lib.types.str;
description = "Hostname for the calendar service backend";
default = hostnames.content;
};
url = lib.mkOption {
type = lib.types.str;
description = "URL for the calendar service backend";
default = "https://${cfg.calendar.hostname}/remote.php/dav";
};
};
tasks = {
username = lib.mkOption {
type = lib.types.str;
description = "Username for the tasks service backend";
default = config.nmasur.settings.username;
};
passwordCommand = lib.mkOption {
type = lib.types.str;
description = "Password for the tasks service backend";
default = "${lib.getExe pkgs.age} --decrypt --identity ~/.ssh/id_ed25519 ${pkgs.writeText "taskspass.age" (builtins.readFile ./taskspass.age)}";
};
hostname = lib.mkOption {
type = lib.types.str;
description = "Hostname for the tasks service backend";
default = hostnames.content;
};
url = lib.mkOption {
type = lib.types.str;
description = "URL for the tasks service backend";
default = "https://${cfg.tasks.hostname}/remote.php/dav";
};
};
};
config = lib.mkIf cfg.enable {
programs.thunderbird = {
enable = true;
profiles.default = {
isDefault = true;
};
};
accounts.email.accounts.home.thunderbird = {
enable = true;
profiles = [ "default" ];
};
accounts.calendar.basePath = "other/calendars"; # Where to save calendars in ~ directory
# accounts.calendar.accounts.home = {
# local.type = "filesystem";
# primary = true;
# remote = {
# passwordCommand = [ cfg.calendar.passwordCommand ];
# type = "caldav";
# url = cfg.calendar.url;
# userName = cfg.calendar.username;
# };
# thunderbird = {
# enable = true;
# profiles = [ "default" ];
# };
# };
# accounts.calendar.accounts.tasks = {
# local.type = "filesystem";
# primary = false;
# remote = {
# passwordCommand = [ cfg.tasks.passwordCommand ];
# type = "caldav";
# url = cfg.tasks.url;
# userName = cfg.tasks.username;
# };
# thunderbird = {
# enable = true;
# profiles = [ "default" ];
# };
# };
};
}
@@ -16,7 +16,6 @@ in
config = lib.mkIf cfg.enable {
programs.zed-editor = {
enable = true;
package = pkgs.stable.zed-editor;
extensions = [
"nix"
@@ -6,7 +6,6 @@
}:
let
inherit (config.nmasur.settings) username;
cfg = config.nmasur.presets.programs.zellij;
zellij-switch-to-last = pkgs.writeShellScriptBin "zellij-switch-to-last" ''
@@ -15,7 +14,7 @@ let
return 1
fi
echo "$ZELLIJ_SESSION_NAME" > ~/.local/state/zellij-last-session
${lib.getExe pkgs.zellij} action switch-session $TARGET_SESSION
zellij pipe --plugin file:$(which zellij-switch.wasm) -- "--session $TARGET_SESSION"
'';
in
@@ -34,24 +33,7 @@ in
# description = "Open a session in Zellij";
body = # fish
''
set TARGET_DIR $( \
zoxide query --list --score | \
fzf --filter="$query" --no-sort | \
fzf \
--prompt="zoxide > " \
--nth=2.. \
--ansi \
--height=60% \
--info=inline \
--border=rounded \
--layout=reverse \
--preview-window=down:40%:wrap \
--preview='ls -F -C --color=always {2..}' \
--bind 'ctrl-z:ignore,btab:up,tab:down,enter:become:echo {2..}' \
--cycle \
--keep-right \
--tabstop=1 \
)
set TARGET_DIR $(zoxide query --interactive)
if test -z $TARGET_DIR
return 0
end
@@ -59,20 +41,18 @@ in
return 1
end
echo "$ZELLIJ_SESSION_NAME" > ~/.local/state/zellij-last-session
${lib.getExe pkgs.zellij} action switch-session $(basename $TARGET_DIR) --cwd $TARGET_DIR --layout default
zellij pipe --plugin file:$(which zellij-switch.wasm) -- "--cwd $TARGET_DIR --layout default --session $(basename $TARGET_DIR)"
'';
};
gh-run = {
body = # fish
''
${lib.getExe pkgs.zellij} action new-pane --start-suspended -- gh run watch
zellij action new-pane --start-suspended -- gh run watch
'';
};
};
};
programs.ghostty.settings.initial-command = lib.getExe pkgs.zellij;
xdg.configFile."zellij/layouts/compact-top.kdl".text = # kdl
''
layout {
@@ -105,14 +85,10 @@ in
enableFishIntegration = true;
enableZshIntegration = true;
attachExistingSession = true;
exitShellOnExit = true;
exitShellOnExit = false;
settings = {
default_mode = "locked";
# Spawn fish directly instead of trusting $SHELL, which inherits the
# macOS login shell. On darwin that login shell is no longer managed by
# nix-darwin, so $SHELL can point at a stale /run/current-system path.
default_shell = lib.getExe pkgs.fish;
# default_layout = "compact-top";
# Remove border
pane_frames = false;
@@ -122,22 +98,6 @@ in
show_startup_tips = false;
keybinds = {
locked = lib.mkIf (pkgs.stdenv.isLinux && !config.programs.ghostty.enable) {
# For servers that I SSH into, use c-a-G to unlock
"bind \"Ctrl Alt G\"" = lib.mkIf (pkgs.stdenv.isLinux && !config.programs.ghostty.enable) {
SwitchToMode = {
_args = [ "normal" ];
};
};
};
normal = lib.mkIf (pkgs.stdenv.isLinux && !config.programs.ghostty.enable) {
# For servers that I SSH into, use c-a-G to lock
"bind \"Ctrl Alt G\"" = lib.mkIf (pkgs.stdenv.isLinux && !config.programs.ghostty.enable) {
SwitchToMode = {
_args = [ "locked" ];
};
};
};
session = {
"bind \"w\"" = {
LaunchOrFocusPlugin = {
@@ -161,15 +121,9 @@ in
shared = {
"bind \"Alt Shift s\"" = {
Run = {
_args =
if pkgs.stdenv.isDarwin then
[
# "env"
# "PATH=/nix/var/nix/profiles/default/bin:/run/current-system/sw/bin:/usr/bin:/bin"
(lib.getExe zellij-switch-to-last)
]
else
[ (lib.getExe zellij-switch-to-last) ];
_args = [
(lib.getExe zellij-switch-to-last)
];
close_on_exit = true;
};
};
@@ -232,28 +186,9 @@ in
};
};
"bind \"Alt Shift j\"" = {
Run = {
_args =
if pkgs.stdenv.isDarwin then
[
"env"
"PATH=${config.home.homeDirectory}/.nix-profile/bin:/etc/profiles/per-user/${username}/bin:/usr/bin"
(lib.getExe pkgs.jjui)
]
else
[ (lib.getExe pkgs.jjui) ];
close_on_exit = true;
floating = true;
x = "1%";
y = "1%";
width = "99%";
height = "99%";
};
};
"bind \"Alt Shift y\"" = {
Run = {
_args = [
(lib.getExe pkgs.yazi)
(lib.getExe pkgs.lazyjj)
];
close_on_exit = true;
floating = true;
@@ -308,16 +243,6 @@ in
_args = [ "Left" ];
};
};
"bind \"Alt j\"" = {
MoveFocus = {
_args = [ "Down" ];
};
};
"bind \"Alt k\"" = {
MoveFocus = {
_args = [ "Up" ];
};
};
};
};
@@ -1,93 +0,0 @@
{
config,
lib,
...
}:
let
cfg = config.nmasur.presets.services.darwin-settings;
in
{
options.nmasur.presets.services.darwin-settings.enable = lib.mkEnableOption "macOS settings";
config = lib.mkIf cfg.enable {
targets.darwin.defaults = {
NSGlobalDomain = {
# Set to dark mode
AppleInterfaceStyle = "Dark";
# Don't change from dark to light automatically
# AppleInterfaceSwitchesAutomatically = false;
# Enable full keyboard access for all controls (e.g. enable Tab in modal dialogs)
AppleKeyboardUIMode = 3;
# Expand save panel by default
NSNavPanelExpandedStateForSaveMode = true;
# Expand print panel by default
PMPrintingExpandedStateForPrint = true;
# Replace press-and-hold with key repeat
ApplePressAndHoldEnabled = false;
# Set a fast key repeat rate
KeyRepeat = 2;
# Shorten delay before key repeat begins
InitialKeyRepeat = 12;
# Disable autocorrect capitalization
NSAutomaticCapitalizationEnabled = false;
# Disable autocorrect smart dashes
NSAutomaticDashSubstitutionEnabled = false;
# Disable autocorrect adding periods
NSAutomaticPeriodSubstitutionEnabled = false;
# Disable autocorrect smart quotation marks
NSAutomaticQuoteSubstitutionEnabled = false;
# Disable autocorrect spellcheck
NSAutomaticSpellingCorrectionEnabled = false;
};
"com.apple.LaunchServices" = {
# Disable "Are you sure you want to open" dialog
LSQuarantine = false;
};
# Where to save screenshots
"com.apple.screencapture" = {
location = "~/Downloads";
};
# Disable disk image verification
"com.apple.frameworks.diskimages" = {
skip-verify = true;
skip-verify-locked = true;
skip-verify-remote = true;
};
# Require password immediately after screen saver begins
"com.apple.screensaver" = {
askForPassword = 1;
askForPasswordDelay = 0;
};
};
targets.darwin.currentHostDefaults = {
"com.apple.mouse.tapBehavior" = {
# Disable trackpad tap to click
Clicking = false;
};
};
};
}
@@ -1,81 +0,0 @@
{
config,
pkgs,
lib,
...
}:
let
cfg = config.nmasur.presets.services.dock;
# macOS stores persistent-apps as an array of dicts, not strings.
# nix-darwin's dock module did this transform for us; targets.darwin.defaults
# writes values verbatim, so we build the tile dicts ourselves.
mkDockApp = path: {
tile-data.file-data = {
_CFURLString = path;
_CFURLStringType = 0;
};
};
in
{
options.nmasur.presets.services.dock.enable = lib.mkEnableOption "macOS Dock";
config = lib.mkIf cfg.enable {
targets.darwin.defaults = {
"com.apple.dock" = {
magnification = true;
largesize = 48;
# Automatically show and hide the dock
autohide = true;
# Add translucency in dock for hidden applications
showhidden = true;
# Enable spring loading on all dock items
enable-spring-load-actions-on-all-items = true;
# Highlight hover effect in dock stack grid view
mouse-over-hilite-stack = true;
mineffect = "genie";
orientation = "bottom";
show-recents = false;
tilesize = 44;
persistent-apps = map mkDockApp [
"/Applications/1Password.app"
"${pkgs.thunderbird}/Applications/Thunderbird.app"
"${pkgs.slack}/Applications/Slack.app"
"/System/Applications/Reminders.app"
"/System/Applications/Calendar.app"
"/Applications/Claude.app"
"${pkgs.firefox-unwrapped}/Applications/Firefox.app"
"/System/Applications/Messages.app"
"/System/Applications/Preview.app"
"/System/Applications/Mail.app"
"/Applications/zoom.us.app"
"${config.programs.ghostty.package}/Applications/Ghostty.app"
# Discord comes from Homebrew on macOS: the nixpkgs bundle is
# modified in place, breaking its notarization seal, so macOS 26+
# refuses to launch it ("damaged"). See presets/programs/homebrew.nix.
"/Applications/Discord.app"
"${pkgs.obsidian}/Applications/Obsidian.app"
];
};
};
# Automatically reload the Dock and Finder when Home Manager switches
home.activation = {
reloadMacSettings = config.lib.dag.entryAfter [ "writeBoundary" ] ''
verboseEcho "Restarting macOS desktop services..."
run /usr/bin/killall Dock Finder || true
'';
};
};
}
@@ -1,50 +0,0 @@
{
config,
lib,
...
}:
let
cfg = config.nmasur.presets.services.finder;
in
{
options.nmasur.presets.services.finder.enable = lib.mkEnableOption "macOS Finder options";
config = lib.mkIf cfg.enable {
targets.darwin.defaults = {
"com.apple.finder" = {
# Default Finder window set to column view
FXPreferredViewStyle = "clmv";
# Finder search in current folder by default
FXDefaultSearchScope = "SCcf";
# Disable warning when changing file extension
FXEnableExtensionChangeWarning = false;
# Allow quitting of Finder application
QuitMenuItem = true;
# Disable the warning before emptying the Trash
WarnOnEmptyTrash = false;
};
NSGlobalDomain = {
# Save to local disk by default, not iCloud
NSDocumentSaveNewDocumentsToCloud = false;
};
# Avoid creating .DS_Store files on network or USB volumes
"com.apple.desktopservices" = {
DSDontWriteNetworkStores = true;
DSDontWriteUSBStores = true;
};
};
};
}
@@ -1,45 +0,0 @@
--- === Hide Zoom Window ===
-- Credit: https://news.ycombinator.com/item?id=47369091
local obj = {}
obj.__index = obj
-- Metadata
obj.name = "HideZoomWindow"
obj.version = "0.1"
function obj:init()
-- Hide Zoom's "share" windows so it doesn't come back on ESC keypress
local zoomWindow = nil
local originalFrame = nil
hs.hotkey.bind({"cmd", "ctrl", "alt"}, "H", function()
print("> trying to hide zoom")
if not zoomWindow then
print("> looking for window")
zoomWindow = hs.window.find("zoom share statusbar window")
end
if zoomWindow then
print("> found window")
if originalFrame then
print("> restoring")
zoomWindow:setFrame(originalFrame)
originalFrame = nil
zoomWindow = nil
else
print("> hiding")
originalFrame = zoomWindow:frame()
local screen = zoomWindow:screen()
local frame = zoomWindow:frame()
frame.x = screen:frame().w + 99000
frame.y = screen:frame().h + 99000
zoomWindow:setFrame(frame)
end
else
print("> window not found")
end
end)
end
return obj
@@ -7,7 +7,6 @@
let
cfg = config.nmasur.presets.services.hammerspoon;
# inherit (config.nmasur.settings) username;
in
{
@@ -16,47 +15,26 @@ in
lib.mkEnableOption "Hammerspoon macOS automation";
config = lib.mkIf cfg.enable {
home.file.".Brewfile".text = /* homebrew */ ''
cask "hammerspoon" # Different scroll style for mouse vs. trackpad
'';
targets.darwin.defaults = {
"org.hammerspoon.Hammerspoon" = {
MJConfigFile = "${config.xdg.configHome}/hammerspoon/init.lua";
};
};
xdg.configFile."hammerspoon/init.lua".source = ./init.lua;
xdg.configFile."hammerspoon/Spoons/ControlEscape.spoon".source = ./Spoons/ControlEscape.spoon;
xdg.configFile."hammerspoon/Spoons/DismissAlerts.spoon".source = ./Spoons/DismissAlerts.spoon;
xdg.configFile."hammerspoon/Spoons/Launcher.spoon/init.lua".source =
pkgs.replaceVars ./Spoons/Launcher.spoon/init.lua
{
discord = "Discord.app";
discord = "${pkgs.discord}/Applications/Discord.app";
firefox = "${pkgs.firefox-unwrapped}/Applications/Firefox.app";
ghostty = "${pkgs.ghostty-bin}/Applications/Ghostty.app";
ghostty = "${config.programs.ghostty.package}/Applications/Ghostty.app";
obsidian = "${pkgs.obsidian}/Applications/Obsidian.app";
slack = "${pkgs.slack}/Applications/Slack.app";
wezterm = "${pkgs.wezterm}/Applications/WezTerm.app";
zed = "${config.programs.zed-editor.package}/Applications/Zed.app";
zed = "${pkgs.zed-editor}/Applications/Zed.app";
};
xdg.configFile."hammerspoon/Spoons/MoveWindow.spoon".source = ./Spoons/MoveWindow.spoon;
xdg.configFile."hammerspoon/Spoons/HideZoomWindow.spoon".source = ./Spoons/HideZoomWindow.spoon;
home.activation.reloadHammerspoon = config.lib.dag.entryAfter [ "writeBoundary" ] ''
# The `hs` CLI blocks forever on Hammerspoon's IPC message port when the
# app isn't running (|| true can't help it never returns). Only reload
# when the app is actually up, and wrap each call in `timeout` as a hard
# backstop so activation can never hang even if IPC is unresponsive.
hs=/Applications/Hammerspoon.app/Contents/Frameworks/hs/hs
if /usr/bin/pgrep -x Hammerspoon > /dev/null 2>&1; then
$DRY_RUN_CMD ${pkgs.coreutils}/bin/timeout 10 "$hs" -c "hs.reload()" || true
$DRY_RUN_CMD sleep 1
$DRY_RUN_CMD ${pkgs.coreutils}/bin/timeout 10 "$hs" -c "hs.console.clearConsole()" || true
else
verboseEcho "Hammerspoon not running; skipping reload."
fi
$DRY_RUN_CMD /Applications/Hammerspoon.app/Contents/Frameworks/hs/hs -c "hs.reload()"
$DRY_RUN_CMD sleep 1
$DRY_RUN_CMD /Applications/Hammerspoon.app/Contents/Frameworks/hs/hs -c "hs.console.clearConsole()"
'';
};
@@ -3,4 +3,3 @@ hs.loadSpoon("ControlEscape"):start() -- Load Hammerspoon bits from https://gith
hs.loadSpoon("Launcher"):init()
hs.loadSpoon("DismissAlerts"):init()
hs.loadSpoon("MoveWindow"):init()
hs.loadSpoon("HideZoomWindow"):init()
@@ -214,9 +214,9 @@ in
cfg.commands.lockScreen != null
) "exec ${cfg.commands.lockScreen}";
"${modifier}+Mod1+h" =
''exec --no-startup-id ${lib.getExe cfg.terminal} -e "${lib.getExe config.nmasur.presets.programs.nixpkgs.commands.rebuildHome} '';
''exec --no-startup-id ${lib.getExe cfg.terminal} --command="${pkgs.home-manager}/bin/home-manager switch --flake ${config.nmasur.presets.programs.dotfiles.path}#''${hostname} || read" '';
"${modifier}+Mod1+r" =
"exec --no-startup-id ${lib.getExe cfg.terminal} -e ${lib.getExe config.nmasur.presets.programs.nixpkgs.commands.rebuildNixos}";
"exec --no-startup-id ${lib.getExe cfg.terminal} --command='doas nixos-rebuild switch --flake ${config.nmasur.presets.programs.dotfiles.path} || read'";
# Window options
"${modifier}+q" = "kill";
@@ -1,53 +0,0 @@
{
config,
pkgs,
lib,
...
}:
let
cfg = config.nmasur.presets.services.menubar;
in
{
options.nmasur.presets.services.menubar.enable = lib.mkEnableOption "macOS menubar settings";
config = lib.mkIf cfg.enable {
home.packages = [
pkgs.ice-bar # Menu bar hiding
];
targets.darwin.defaults = {
NSGlobalDomain = {
# Only hide menu bar in fullscreen
_HIHideMenuBar = false;
NSStatusItemSelectionPadding = 6;
NSStatusItemSpacing = 6;
};
"com.apple.menuextra.clock" = {
# Show seconds on the clock
ShowSeconds = true;
FlashDateSeparator = false;
};
"leits.MeetingBar" = {
eventTimeFormat = ''"show"'';
eventTitleFormat = ''"none"'';
eventTitleIconFormat = ''"iconCalendar"'';
slackBrowser = ''{"deletable":true,"arguments":"","name":"Slack","path":""}'';
zoomBrowser = ''{"deletable":true,"arguments":"","name":"Zoom","path":""}'';
teamsBrowser = ''{"deletable":true,"arguments":"","name":"Teams","path":""}'';
KeyboardShortcuts_joinEventShortcut = ''{"carbonModifiers":6400,"carbonKeyCode":38}'';
timeFormat = ''"12-hour"'';
};
};
};
}
@@ -33,7 +33,6 @@ in
nmasur.presets = {
programs = {
bat.enable = lib.mkDefault true;
chawan.enable = lib.mkDefault true;
fd.enable = lib.mkDefault true;
ripgrep.enable = lib.mkDefault true;
starship.enable = lib.mkDefault true;
@@ -17,23 +17,33 @@ in
nmasur.presets = {
fonts.enable = lib.mkDefault true;
services = {
darwin-settings.enable = lib.mkDefault true;
dock.enable = lib.mkDefault true;
finder.enable = lib.mkDefault true;
hammerspoon.enable = lib.mkDefault true;
menubar.enable = lib.mkDefault true;
};
programs = {
fish-darwin.enable = lib.mkDefault true;
homebrew.enable = lib.mkDefault true;
nixpkgs-darwin.enable = lib.mkDefault true;
mpv.enable = lib.mkDefault true;
noti.enable = lib.mkDefault true;
};
services.hammerspoon.enable = lib.mkDefault true;
programs.nixpkgs-darwin.enable = lib.mkDefault true;
programs.mpv.enable = lib.mkDefault true;
};
home.homeDirectory = lib.mkForce "/Users/${config.home.username}";
# Default shell setting doesn't work
home.sessionVariables = {
SHELL = "${pkgs.fish}/bin/fish";
};
# Used for aerc
xdg.enable = lib.mkDefault pkgs.stdenv.isDarwin;
programs.fish.shellAbbrs.t = "trash";
# Add homebrew paths to CLI path
home.sessionPath = [
"/opt/homebrew/bin/"
"/opt/homebrew/opt/trash/bin"
];
home.packages = [
pkgs.noti # Create notifications programmatically
pkgs.ice-bar # Menu bar hiding
];
};
# Fix for: 'Error: HOME is set to "/var/root" but we expect "/var/empty"'
@@ -1,24 +0,0 @@
{
config,
lib,
...
}:
let
cfg = config.nmasur.profiles.darwin-gaming;
in
{
options.nmasur.profiles.darwin-gaming.enable = lib.mkEnableOption "gaming config for macOS";
config = lib.mkIf cfg.enable {
home.file.".Brewfile".text = /* homebrew */ ''
# Casks (GUI Apps)
cask "steam" # Not packaged for Nix on macOS
cask "epic-games" # Not packaged for Nix
'';
};
}
@@ -19,10 +19,6 @@ in
pkgs.pgcli # Postgres client with autocomplete
];
nmasur.presets = {
programs.cargo.enable = lib.mkDefault true;
};
};
}
@@ -17,27 +17,17 @@ in
nmasur.presets.programs = {
zed-editor.enable = lib.mkDefault true;
jujutsu.enable = lib.mkDefault true;
};
home.packages = [
pkgs.nmasur.ren-find # Rename files
pkgs.nmasur.rep-grep # Replace text in files
# Charm tools
pkgs.glow # Markdown previews
pkgs.skate # Key-value store
pkgs.charm # Manage account and filesystem
pkgs.pop # Send emails from a TUI
pkgs.snitch # Network
pkgs.comma # Nix-index auto-launch
pkgs.nix-inspect # TUI for browsing Nix configs
# pkgs.crush # AI LLM Agent
pkgs.gemini-cli # AI LLM Agent
pkgs.antigravity-cli # AI LLM Agent
pkgs.pi-coding-agent # AI LLM Agent
];
@@ -32,7 +32,6 @@ in
nsxiv.enable = lib.mkDefault true;
obsidian.enable = lib.mkDefault true;
rofi.enable = lib.mkDefault true;
thunderbird.enable = lib.mkDefault true;
xclip.enable = lib.mkDefault true;
zathura.enable = lib.mkDefault true;
};
@@ -1,26 +0,0 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.nmasur.profiles.llm-development;
in
{
options.nmasur.profiles.llm-development.enable = lib.mkEnableOption "LLM coding tools";
config = lib.mkIf cfg.enable {
home.packages = [
pkgs.pi-coding-agent # AI LLM Agent
];
};
}
@@ -16,23 +16,24 @@ in
pkgs.age # Encryption
pkgs.bc # Calculator
pkgs.bottom # System monitor (top)
pkgs.csvlens # CSV viewer (easier than visidata)
pkgs.delta # Fancy diffs
pkgs.difftastic # Other fancy diffs
pkgs.doggo # DNS client (dig)
pkgs.dust # Disk usage tree (ncdu)
pkgs.du-dust # Disk usage tree (ncdu)
pkgs.dua # File sizes (du)
pkgs.duf # Basic disk information (df)
pkgs.jless # JSON viewer
pkgs.jo # JSON output
pkgs.stable.mpd # TUI slideshows
pkgs.nixfmt # Format Nix code
pkgs.mpd # TUI slideshows
pkgs.nixfmt-rfc-style # Format Nix code
pkgs.nmasur.jqr # FZF fq JSON tool
pkgs.nmasur.osc # Clipboard over SSH
pkgs.nmasur.ren-find # Rename files
pkgs.nmasur.rep-grep # Replace text in files
pkgs.pandoc # Convert text documents
pkgs.qrencode # Generate qr codes
pkgs.spacer # Output lines in terminal
pkgs.stable.tealdeer # Cheatsheets
pkgs.tealdeer # Cheatsheets
pkgs.tree # Print tree in terminal
pkgs.vimv-rs # Batch rename files
pkgs.yazi # TUI file explorer
@@ -41,7 +42,7 @@ in
programs.fish.shellAliases = {
"du" = lib.mkDefault (lib.getExe pkgs.dua);
"ncdu" = lib.mkDefault (lib.getExe pkgs.dust);
"ncdu" = lib.mkDefault (lib.getExe pkgs.du-dust);
"df" = lib.mkDefault (lib.getExe pkgs.duf);
# Use eza (exa) instead of ls for fancier output
@@ -62,9 +63,8 @@ in
ghostty.enable = lib.mkDefault true;
git.enable = lib.mkDefault true;
helix.enable = lib.mkDefault true;
jujutsu.enable = lib.mkDefault true;
lazygit.enable = lib.mkDefault true;
# neovim.enable = lib.mkDefault true;
neovim.enable = lib.mkDefault true;
nix-index.enable = lib.mkDefault true;
nixpkgs.enable = lib.mkDefault true;
notes.enable = lib.mkDefault true;
@@ -21,9 +21,7 @@ in
];
home.packages = [
pkgs.actionlint # Lint for GitHub Actions Workflows
pkgs.claude-code # AI LLM Agent
pkgs.stable.visidata # CSV inspector
pkgs.visidata # CSV inspector
pkgs.dos2unix # Convert Windows text files
pkgs.inetutils # Includes telnet
pkgs.gnupg # Encryption
@@ -31,7 +29,6 @@ in
pkgs.ssm-session-manager-plugin
pkgs.awslogs
pkgs.stu # TUI for AWS S3
pkgs.pre-commit
pkgs.google-cloud-sdk
pkgs.vault-bin
pkgs.ipcalc # Make IP network calculations
@@ -40,28 +37,18 @@ in
pkgs.nmasur.ocr # Converts images to text
pkgs.nmasur.aws-ec2 # Browse EC2 instances
pkgs.nmasur.terraform-init # Quick shortcut for initializing Terraform backend
pkgs.uv # Python packaging
];
home.file.".Brewfile".text = /* homebrew */ ''
# cask "1password" # 1Password will not launch from Nix on macOS
# cask "gitify" # Git notifications in menu bar (downgrade manually from 4.6.1)
# cask "logitech-g-hub" # Mouse and keyboard management
cask "logitune" # Logitech webcam firmware
cask "meetingbar" # Show meetings in menu bar
'';
programs.fish.shellAliases.ec2 = "aws-ec2";
nmasur.presets = {
fonts.enable = lib.mkDefault true;
programs = {
# _1password.enable = lib.mkDefault true;
_1password.enable = lib.mkDefault true;
atuin.enable = lib.mkDefault true;
aws-ssh.enable = lib.mkDefault true;
bash.enable = lib.mkDefault true;
bat.enable = lib.mkDefault true;
cargo.enable = lib.mkDefault true;
direnv.enable = lib.mkDefault true;
dotfiles.enable = lib.mkDefault true;
fd.enable = lib.mkDefault true;
@@ -80,12 +67,8 @@ in
ripgrep.enable = lib.mkDefault true;
starship.enable = lib.mkDefault true;
terraform.enable = lib.mkDefault true;
thunderbird.enable = lib.mkDefault true;
weather.enable = lib.mkDefault true;
};
services = {
mbsync.enable = lib.mkDefault true;
};
};
};
@@ -1,26 +0,0 @@
{
config,
lib,
...
}:
let
cfg = config.nmasur.presets.programs._1password;
in
{
options.nmasur.presets.programs._1password.enable = lib.mkEnableOption "1Password password manager";
config = lib.mkIf cfg.enable {
# Unfree packages are already permitted via the shared nixpkgs instance
# created in lib/default.nix (config.allowUnfree = true). Setting
# nixpkgs.config here would conflict with nixpkgs.pkgs being set externally.
programs._1password.enable = true;
programs._1password-gui = {
enable = true;
# Certain features, including CLI integration and system authentication support,
# require enabling PolKit integration on some desktop environments (e.g. Plasma).
# polkitPolicyOwners = [ "yourUsernameHere" ];
};
};
}
@@ -23,19 +23,5 @@ in
# Speeds up fish launch time on macOS
programs.fish.useBabelfish = true;
programs.fish.shellInit = ''
set -g __nixos_path_original $PATH
function __nixos_path_fix -d "fix PATH value"
set -l result (string split ":" $__nixos_path_original)
for elt in $PATH
if not contains -- $elt $result
set -a result $elt
end
end
set -g PATH $result
end
__nixos_path_fix
'';
};
}
@@ -33,6 +33,7 @@ in
};
global = {
brewfile = true; # Run brew bundle from anywhere
lockfiles = false; # Don't save lockfile (since running from anywhere)
};
};
@@ -1,70 +0,0 @@
{
config,
pkgs,
lib,
...
}:
let
inherit (config.nmasur.settings) username;
cfg = config.nmasur.presets.services.daily-summary;
# Remove process urls in favor of using extention
# process_urls = pkgs.writers.writePython3Bin "process-urls" {
# libraries = [
# pkgs.python3Packages.requests
# pkgs.python3Packages.beautifulsoup4
# ];
# } (builtins.readFile ./process-urls.py);
# prompt = "Based on my browser usage for today from the markdown file located in /Users/${username}/Downloads/Sidebery/todays_urls.md, create or update a daily summary markdown file in the generated notes directory located in /Users/${username}/dev/personal/notes/generated/ with the filename format 'YYYY-MM-DD Daily Summary.md'. The resulting markdown file should use /Users/${username}/dev/personal/notes/templates/generated-summary.md as a format template, and it should summarize where I have spent my time today and highlight any notable links that I have visited. Please create markdown links to other relevant notes in /Users/${username}/dev/personal/notes/. If there is an existing markdown file for today, update it to include the newest information.";
prompt = "Based on my browser usage for today from the JSON file located in /Users/${username}/Downloads/firefox-history/history-YYYY-MM-DD.json, create or update a daily summary markdown file in the generated notes directory located in /Users/${username}/dev/personal/notes/generated/ with the filename format 'YYYY-MM-DD Daily Summary.md'. If the JSON file for today doesn't exist, exit. The resulting markdown file should use /Users/${username}/dev/personal/notes/templates/generated-summary.md as a format template, and it should summarize where I have spent my time today and highlight any notable pages that I have visited, using the titles of each URL in the JSON file for markdown links. Please create markdown links to other relevant notes in /Users/${username}/dev/personal/notes/ and explain why they are being referenced. If there is an existing markdown file for today, update it to include the newest information.";
in
{
options.nmasur.presets.services.daily-summary.enable = lib.mkEnableOption "Daily work summary";
config = lib.mkIf cfg.enable {
launchd.user.agents.daily-summary = {
# This replaces program and args entirely
# script = ''
# ${process_urls}/bin/process-urls /Users/${username}/Downloads/Sidebery/
# GEMINI_API_KEY=$(cat /Users/${username}/.config/gemini/.gemini_api_key) ${pkgs.gemini-cli}/bin/gemini --allowed-tools all --yolo --include-directories /Users/${username}/Downloads/Sidebery/ --include-directories /Users/${username}/dev/personal/notes/ "${prompt}"
# '';
script = ''
GEMINI_API_KEY=$(cat /Users/${username}/.config/gemini/.gemini_api_key) ${pkgs.gemini-cli}/bin/gemini --allowed-tools all --yolo --include-directories "/Users/${username}/Downloads/firefox-history/,/Users/${username}/dev/personal/notes/" "${prompt} | tee -a /Users/${username}/dev/personal/gemini-archive/daily-summary-logs/$(date +"%Y-%m-%d").log"
'';
path = [
pkgs.bash
pkgs.coreutils
];
serviceConfig = {
Label = "com.example.daily-summary";
# Runs the script through /bin/sh automatically
# RunAtLoad = true;
StartCalendarInterval = [
{
Hour = 4;
Minute = 45;
}
{
Hour = 6;
Minute = 0;
}
{
Hour = 9;
Minute = 0;
}
{
Hour = 11;
Minute = 0;
}
];
};
};
};
}
@@ -1,115 +0,0 @@
# Temporarily disabled in favor of using an extension to save history
import requests
from bs4 import BeautifulSoup
import json
import os
import sys
from datetime import datetime
from urllib.parse import urlparse
def find_urls(data):
urls = []
if isinstance(data, dict):
for key, value in data.items():
if key == 'url' and isinstance(value, str):
urls.append(value)
else:
urls.extend(find_urls(value))
elif isinstance(data, list):
for item in data:
urls.extend(find_urls(item))
return urls
def main():
if len(sys.argv) > 1:
base_dir = sys.argv[1]
if not os.path.isdir(base_dir):
print(f"Error: Directory '{base_dir}' not found.")
sys.exit(1)
else:
base_dir = '.'
today = datetime.now().strftime('%Y.%m.%d')
output_filename = 'todays_urls.md'
output_filepath = os.path.join(base_dir, output_filename)
url_titles = {}
print(f"Searching for files in '{base_dir}' "
f"starting with 'snapshot-{today}-'")
with open(output_filepath, 'w') as md_file:
md_file.write(f'# URLs from Sidebery Snapshots for '
f'{today.replace(".", "-")}\n\n')
files_processed = 0
for filename in sorted(os.listdir(base_dir)):
# Debugging print removed
if (filename.startswith(f'snapshot-{today}-')
and filename.endswith('.json')):
files_processed += 1
print(f"Processing file: "
f"{os.path.join(base_dir, filename)}")
# Extract and format date and time from filename
# Example: snapshot-2026.01.25-13.19.29.json
clean_filename = (filename.replace('snapshot-', '')
.replace('.json', ''))
date_time_parts = clean_filename.split('-', 1)
formatted_date = date_time_parts[0].replace('.', '-')
formatted_time = date_time_parts[1].replace('.', ':')
datetime_str = f"{formatted_date} {formatted_time}"
md_file.write(f'## {datetime_str}\n\n')
with open(os.path.join(base_dir, filename), 'r') as json_file:
try:
data = json.load(json_file)
urls = find_urls(data)
print(f" Found {len(urls)} URLs")
for url in urls:
if url not in url_titles:
try:
# Get title of URL
res = requests.get(
url,
timeout=10,
allow_redirects=True
)
soup = BeautifulSoup(
res.text,
'html.parser'
)
if soup.title and soup.title.string:
title = soup.title.string.strip()
else:
domain = urlparse(url).netloc
title = domain if domain else url
url_titles[url] = title
except requests.exceptions.InvalidSchema:
continue
except Exception:
domain = urlparse(url).netloc
title = domain if domain else url
url_titles[url] = title
if url in url_titles:
title = url_titles[url]
md_file.write(f'- [{title}]({url})\n')
md_file.write('\n')
except json.JSONDecodeError:
print(f" Error decoding JSON in {filename}")
md_file.write('- Error decoding JSON\n\n')
if files_processed == 0:
print("No files found for today.")
print(f"Processing complete. Output written to {output_filepath}")
if __name__ == '__main__':
main()
@@ -6,6 +6,7 @@
}:
let
inherit (config.nmasur.settings) username;
cfg = config.nmasur.presets.services.dock;
in
@@ -49,13 +50,9 @@ in
"/System/Applications/Messages.app"
"/System/Applications/Mail.app"
"/Applications/zoom.us.app"
"/Applications/Ghostty.app"
# Discord comes from Homebrew on macOS: the nixpkgs bundle is modified
# in place, breaking its notarization seal, so macOS 26+ refuses to
# launch it ("damaged").
"/Applications/Discord.app"
"${config.home-manager.users.${username}.programs.ghostty.package}/Applications/Ghostty.app"
"${pkgs.discord}/Applications/Discord.app"
"${pkgs.obsidian}/Applications/Obsidian.app"
"${pkgs.thunderbird}/Applications/Thunderbird.app"
];
};
};
@@ -25,85 +25,85 @@ in
enableKeyMapping = true; # Allows for skhd
};
# defaults = {
# NSGlobalDomain = {
defaults = {
NSGlobalDomain = {
# # Set to dark mode
# AppleInterfaceStyle = "Dark";
# Set to dark mode
AppleInterfaceStyle = "Dark";
# # Don't change from dark to light automatically
# # AppleInterfaceSwitchesAutomatically = false;
# Don't change from dark to light automatically
# AppleInterfaceSwitchesAutomatically = false;
# # Enable full keyboard access for all controls (e.g. enable Tab in modal dialogs)
# AppleKeyboardUIMode = 3;
# Enable full keyboard access for all controls (e.g. enable Tab in modal dialogs)
AppleKeyboardUIMode = 3;
# # Expand save panel by default
# NSNavPanelExpandedStateForSaveMode = true;
# Expand save panel by default
NSNavPanelExpandedStateForSaveMode = true;
# # Expand print panel by default
# PMPrintingExpandedStateForPrint = true;
# Expand print panel by default
PMPrintingExpandedStateForPrint = true;
# # Replace press-and-hold with key repeat
# ApplePressAndHoldEnabled = false;
# Replace press-and-hold with key repeat
ApplePressAndHoldEnabled = false;
# # Set a fast key repeat rate
# KeyRepeat = 2;
# Set a fast key repeat rate
KeyRepeat = 2;
# # Shorten delay before key repeat begins
# InitialKeyRepeat = 12;
# Shorten delay before key repeat begins
InitialKeyRepeat = 12;
# # Disable autocorrect capitalization
# NSAutomaticCapitalizationEnabled = false;
# Disable autocorrect capitalization
NSAutomaticCapitalizationEnabled = false;
# # Disable autocorrect smart dashes
# NSAutomaticDashSubstitutionEnabled = false;
# Disable autocorrect smart dashes
NSAutomaticDashSubstitutionEnabled = false;
# # Disable autocorrect adding periods
# NSAutomaticPeriodSubstitutionEnabled = false;
# Disable autocorrect adding periods
NSAutomaticPeriodSubstitutionEnabled = false;
# # Disable autocorrect smart quotation marks
# NSAutomaticQuoteSubstitutionEnabled = false;
# Disable autocorrect smart quotation marks
NSAutomaticQuoteSubstitutionEnabled = false;
# # Disable autocorrect spellcheck
# NSAutomaticSpellingCorrectionEnabled = false;
# };
# Disable autocorrect spellcheck
NSAutomaticSpellingCorrectionEnabled = false;
};
# # Disable "Are you sure you want to open" dialog
# LaunchServices.LSQuarantine = false;
# Disable "Are you sure you want to open" dialog
LaunchServices.LSQuarantine = false;
# # Disable trackpad tap to click
# trackpad.Clicking = false;
# Disable trackpad tap to click
trackpad.Clicking = false;
# # Where to save screenshots
# screencapture.location = "~/Downloads";
# Where to save screenshots
screencapture.location = "~/Downloads";
# CustomUserPreferences = {
# # Disable disk image verification
# "com.apple.frameworks.diskimages" = {
# skip-verify = true;
# skip-verify-locked = true;
# skip-verify-remote = true;
# };
# # Require password immediately after screen saver begins
# "com.apple.screensaver" = {
# askForPassword = 1;
# askForPasswordDelay = 0;
# };
# };
CustomUserPreferences = {
# Disable disk image verification
"com.apple.frameworks.diskimages" = {
skip-verify = true;
skip-verify-locked = true;
skip-verify-remote = true;
};
# Require password immediately after screen saver begins
"com.apple.screensaver" = {
askForPassword = 1;
askForPasswordDelay = 0;
};
};
# CustomSystemPreferences = {
CustomSystemPreferences = {
# };
# };
};
};
# # Settings that don't have an option in nix-darwin
# activationScripts.postActivation.text = ''
# echo "Allow apps from anywhere"
# SPCTL=$(spctl --status)
# if ! [ "$SPCTL" = "assessments disabled" ]; then
# spctl --master-disable
# fi
# '';
# Settings that don't have an option in nix-darwin
activationScripts.postActivation.text = ''
echo "Allow apps from anywhere"
SPCTL=$(spctl --status)
if ! [ "$SPCTL" = "assessments disabled" ]; then
sudo spctl --master-disable
fi
'';
};
@@ -18,31 +18,28 @@ in
nmasur.presets = {
programs = {
_1password.enable = lib.mkDefault true;
fish.enable = lib.mkDefault true;
# homebrew.enable = lib.mkDefault true;
homebrew.enable = lib.mkDefault true;
};
services = {
# daily-summary.enable = lib.mkDefault false;
# dock.enable = lib.mkDefault true;
# finder.enable = lib.mkDefault true;
# hammerspoon.enable = lib.mkDefault true;
# menubar.enable = lib.mkDefault true;
dock.enable = lib.mkDefault true;
finder.enable = lib.mkDefault true;
hammerspoon.enable = lib.mkDefault true;
menubar.enable = lib.mkDefault true;
nix.enable = lib.mkDefault true;
settings.enable = lib.mkDefault true;
user.enable = lib.mkDefault true;
};
};
# homebrew.brews = [
# "trash" # Delete files and folders to trash instead of rm
# ];
# homebrew.casks = [
# "scroll-reverser" # Different scroll style for mouse vs. trackpad
# "notunes" # Don't launch Apple Music with the play button
# "topnotch" # Darkens the menu bar to complete black
# "ghostty" # Terminal application (not buildable on Nix on macOS)
# ];
homebrew.brews = [
"trash" # Delete files and folders to trash instead of rm
];
homebrew.casks = [
"scroll-reverser" # Different scroll style for mouse vs. trackpad
"notunes" # Don't launch Apple Music with the play button
"topnotch" # Darkens the menu bar to complete black
];
};
}
@@ -16,12 +16,12 @@ in
nmasur.profiles.base.enable = lib.mkDefault true;
# homebrew.casks = [
# "1password" # 1Password will not launch from Nix on macOS
# # "gitify" # Git notifications in menu bar (downgrade manually from 4.6.1)
# # "logitech-g-hub" # Mouse and keyboard management
# "logitune" # Logitech webcam firmware
# "meetingbar" # Show meetings in menu bar
# ];
homebrew.casks = [
"1password" # 1Password will not launch from Nix on macOS
# "gitify" # Git notifications in menu bar (downgrade manually from 4.6.1)
# "logitech-g-hub" # Mouse and keyboard management
"logitune" # Logitech webcam firmware
"meetingbar" # Show meetings in menu bar
];
};
}
@@ -109,9 +109,8 @@ in
};
# Allow web traffic to Caddy
nmasur.presets.services.caddy.routes = lib.mkAfter [
nmasur.presets.services.caddy.routes = [
{
group = "actual";
match = [ { host = [ hostnames.budget ]; } ];
handle = [
{
@@ -126,7 +125,7 @@ in
services.cloudflare-dyndns.domains = [ hostnames.budget ];
# Backups
services.restic.backups.default.paths = [ "/var/lib/private/actual" ];
services.restic.backups.default.paths = [ "/var/lib/actual" ];
};
@@ -1,122 +0,0 @@
{
config,
pkgs,
lib,
...
}:
let
inherit (config.nmasur.settings) hostnames;
cfg = config.nmasur.presets.services.actualtap;
actualtapConfigType = lib.types.submodule {
options = {
port = lib.mkOption {
type = lib.types.port;
description = "Port to use for the actualtap instance localhost";
};
path = lib.mkOption {
type = lib.types.str;
description = "Path prefix for this actualtap instance on the reverse proxy";
};
budgetIdFile = lib.mkOption {
type = lib.types.path;
description = "Path to the age encrypted file containing the budget ID";
};
apiKeyFile = lib.mkOption {
type = lib.types.path;
description = "Path to the age encrypted file containing the API key";
};
};
};
in
{
options.nmasur.presets.services.actualtap = {
enable = lib.mkEnableOption "ActualTap instances";
instances = lib.mkOption {
type = lib.types.attrsOf actualtapConfigType;
default = { };
description = "Attribute set of ActualTap instances.";
};
};
config = lib.mkIf cfg.enable {
users.users.actualtap = {
isSystemUser = true;
group = "shared";
uid = 981;
};
systemd.services = lib.mapAttrs' (
name: instance:
lib.nameValuePair "actualtap-${name}" {
enable = true;
description = "ActualTap - ${name}";
after = [
"network.target"
"actual.service"
];
wantedBy = [ "multi-user.target" ];
environment = {
PORT = builtins.toString instance.port;
ACTUAL_URL = "http://127.0.0.1:${builtins.toString config.nmasur.presets.services.actualbudget.port}";
};
serviceConfig = {
User = config.users.users.actualtap.name;
Group = config.users.users.actualtap.group;
EnvironmentFile = [
config.secrets."actualbudget-password".dest
config.secrets."actualtap-${name}-budget-id".dest
config.secrets."actualtap-${name}-api-key".dest
];
ExecStart = lib.getExe pkgs.nmasur.actualtap;
Restart = "on-failure";
WorkingDirectory = "/var/lib/actualtap-${name}";
StateDirectory = "actualtap-${name}";
};
}
) cfg.instances;
secrets = lib.mkMerge (
lib.mapAttrsToList (name: instance: {
"actualtap-${name}-budget-id" = {
source = instance.budgetIdFile;
dest = "${config.secretsDirectory}/actualtap-${name}-budget-id";
owner = config.users.users.actualtap.name;
group = config.users.users.actualtap.group;
};
"actualtap-${name}-api-key" = {
source = instance.apiKeyFile;
dest = "${config.secretsDirectory}/actualtap-${name}-api-key";
owner = config.users.users.actualtap.name;
group = config.users.users.actualtap.group;
};
}) cfg.instances
);
nmasur.presets.services.caddy.routes = lib.mapAttrsToList (name: instance: {
group = "actual";
match = [
{
host = [ hostnames.budget ];
path = [ "${instance.path}*" ];
}
];
handle = [
{
handler = "rewrite";
strip_path_prefix = instance.path;
}
{
handler = "reverse_proxy";
upstreams = [ { dial = "localhost:${builtins.toString instance.port}"; } ];
}
];
}) cfg.instances;
};
}
@@ -1,17 +0,0 @@
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IE1nSGFPdyBIUkxs
RmFmNmo3L2MwVVhmeTdUVGdXOWRIVDd5c21EVnhtWWUwTVpWbW5zCnNSS1luUHNW
YlIwbmVrbTJTUUdOQkpCbGpNQm1tYlRrbDhaWEhJUDRHaDQKLT4gc3NoLWVkMjU1
MTkgWXlTVU1RIHJIYTd4eFo3aklGQ1Evb0JPOGZSWDh1Q1pXU3ExZ1pmR29qT2lP
bFcwREkKTWFXMlZCeXpoMi92OXdtN3plekE2dFlCbk44YncxLzJYZzE2amNIVnEz
QQotPiBzc2gtZWQyNTUxOSBuanZYNUEgWi8rNnV4VWtwUEEzbys4Skl1Z0p0Ly9r
ZS82dzFJeEhHVHpSNU04WU5CVQpIMWhQcDdNeU45dVpkVyswQW1RK2Q0aXpkZXMz
MXAraG9KUFBDUVdFcTRVCi0+IHNzaC1lZDI1NTE5IENxSU9VQSBUQWQvU0JwdTlX
UkJYakdYTjU1YlBzWHEzY3FQa1dhMmp6UjE0RTJYN1ZBCmk0SWc0Ym1mUTdVL1NJ
ZXJFVkNmckRaVnlkSmUxL0dSUlo5VER0b2x3WVUKLT4gc3NoLWVkMjU1MTkgejFP
Y1p3IHBIQllKcmczOVJvSzRMZW9mVjZjTFo1ZjVJNDRvUG9pSnlRZDBUWEtoV2sK
aGhPeUpkVEZ0QWxDM1VJZzlDWEZ2VnFuTFRCVDkzY2JLVWNQTUE2STMyRQotLS0g
cXhWR2lQWnkxOUZhRzhOTS96UDJWVmZEQVpZTkF1MmlpNCtEbDZzRGZaYwof4Y/t
N5osO/bY+ojbarYoCBq12NSaKKlL6MNy1OQZOuOF0IP1CZ0fLY+R9DgJcNol3I73
q4JyXbfohWtG/2NdIwhRXumQ/OnY1maVvg==
-----END AGE ENCRYPTED FILE-----
@@ -1,17 +0,0 @@
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IE1nSGFPdyAyRTF0
L3Y3ZVJ0YlJSbzR6cnNWeVNRd2czNUVKWmtQNFA3VFRlb053d1dRCmxmTGRGSFhL
UmlSdUVQNzVPcktIdE0yVWFhVGpGYVRPMEpNQll6Z0owNFEKLT4gc3NoLWVkMjU1
MTkgWXlTVU1RIHE5L09YNWFaT0JLT0o0YjdQY01GRDByeFVXeE9LMXNFNGFCWkFO
ZStBd28KamhUYzd1VXhlL3RqY3hlMG5UeGFJemY2ajRhVGZ2ZDJNb1hSRHkrUFNt
NAotPiBzc2gtZWQyNTUxOSBuanZYNUEgbDdMVzNTT1Y2VmVsZyt2WTh0RWdUVEpY
c0RoRWE2S2ZyZXFuTllFU1FVWQpmeDF0MEp2NEYxS2k1ZlJaTVNWMWdRRlJ1UWh2
Wm0xbHhGYXhoWGtDbVkwCi0+IHNzaC1lZDI1NTE5IENxSU9VQSBJeERSTUpPbzhu
NGQrZXRoWGJEalBlMHdQUmlsVkF2TEZBOStOZ3ExN2lzClRZeE5yZG1uY3ZRRDNy
am5uTjRiTnpLSkhURWZTNzgyVVdOVDA2WlpqZmsKLT4gc3NoLWVkMjU1MTkgejFP
Y1p3IGticUNqWDJ0RTJTZmdXdzVWM0xsejBvYUJ3MXZvNWw1OWE3aUJMTCtSQ2MK
KzMyZW5jZUNIV1puVFlLMEdyeUdoUUt3MjlzTUgvWlFob0QwME9ZZ1VVNAotLS0g
VU5nOFA0Nzd3ckhnRHdSNkVSNG9tZks5VmVoZnlmU1R6bzl4ZVdMcGlLTQqZWLkP
VdZPvgCJ8A9UcKWl+5f8Jjlc79d6ib8wwfMRl0zK4SNQJGgcXr6sFuieY3H4DzRb
MuqKZQBBIKtPAmrvmzcKgNSeiJoZjG801Jqd3lpkJEA=
-----END AGE ENCRYPTED FILE-----
@@ -1,17 +0,0 @@
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IE1nSGFPdyBSR2tx
b2FyZ2t0d2xONGIvYjJrcVU1VTNHT3RVbjlWT1IyUW1CM1BkNVNzCmJmNFFFbUR6
WG9ncmhuakFzVHhSVEtZUlR4dWg3cWRzUXc2ZmVpZ3NqZ1EKLT4gc3NoLWVkMjU1
MTkgWXlTVU1RIGFFRmFsVjdkTkFZY29XdWo4akVDaEZHMTdXRDY4N2U5WE13a1JD
QWdXMkUKbnVXazZpSzZqTHJqamFUdDJMMUpiTEhLeTJqcVNmV2dncjVvZlNNT09M
WQotPiBzc2gtZWQyNTUxOSBuanZYNUEgTzV0eGpSU2plaTFCTXZTbFB2R1VOQnFn
d01EUXcza3JuR3RFUzE3N2MzawpqT0ZRQ1hPTFcvZ2ZOQjNGcThYL1lSdURXbWlv
NkRSRERJQ1IvSHdMa2M4Ci0+IHNzaC1lZDI1NTE5IENxSU9VQSBvQjZkYVJjYy9H
L3BSVWRPczlOOGV2RkRBSGlIakF1cG1yQk9tbXNWdWlZCnZGaGxvdkZVWXp2THhK
RnRBQ2VSNkErU0VnOWlYbkY2U1JCZTlBSFFUK0UKLT4gc3NoLWVkMjU1MTkgejFP
Y1p3IFQrdUtDdENRK2dnN2t3dVBsN0oxYkNRSm43aDREa3ZJQjhvTWpxM0FWVEkK
OTNCVFRTclFFckFkQXBzWnBybWxKRm92TEFqRU5ZWkprdytJQm5RT2tOYwotLS0g
Nk5WZXhZM0VXaHpVK2EzeGFqNS9hZUlLQjlJRU9EMnVLL3VRV3RKTkVRcwpA8GqA
24oLFT1VIE5eNl/Ltd102W4J6jafmiizCEu3/7EULI/X5oh2LvjSjOuivW6y+Gbu
rXITu245mDM6ZqE2LikYR6134QSC2lmNvw==
-----END AGE ENCRYPTED FILE-----
@@ -1,17 +0,0 @@
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IE1nSGFPdyAyakVC
ZGZqMitTVVc0KzJSV0c3V3Ryc2JSWXp0V2I4YURmektyVGh5a2hBCjlCaGQ4SmxQ
VzhBRWw4SW9QamdVZDVvK3laVkNuWTRhMW1hR1ZmS1lqOWsKLT4gc3NoLWVkMjU1
MTkgWXlTVU1RIE5oVVdMWHZlSEJ2akc1UVcrdnNNOWgzaGFhb2VWNlNxQU5yQzM0
dGk3eGsKaE1Ba3BneC9yQTBpcXo3YWhqcDZheUJnbE5vS0Z0WUNzYnQ1a2o5OVN4
YwotPiBzc2gtZWQyNTUxOSBuanZYNUEgcitOTmNKS04xc01LNTZKbE9QblVKRUVr
ZHdyY0Q2VWtUQ1VOQnFZTjNpbwp0RmNTV2RwR2RlcG5odE81VEFxNGhJOVFYd3Zk
TU9IanIzMFkxVU1GUlQwCi0+IHNzaC1lZDI1NTE5IENxSU9VQSBmRC92WjRkTVFz
eGlFa1VhcEk1NVpkVnFVVkpZRTdzMGR1aWNuWW9ZTFFVCkFRaVM5a1hjcjV3dU1m
WHNnSWhSN1l4ZVEwUkhXZVg3UFRZQStSVllFcEEKLT4gc3NoLWVkMjU1MTkgejFP
Y1p3IFUreGtraXo5aXM2OTFKcjZkL2p0ZEVwaEFXL3B5R2M1Q1J2elZYVityRUkK
bk80bnp1UzgzdmFqV0RJaVFhaytPWnJpQ0Y4Wmg1M2xLbGJyUzZzazlMUQotLS0g
dlZiRzZVSkYwbEVDaEVzZUhoRUkwMUpTM3pyOWJBaHUzZG8vejdmVklBYwpirejN
5cR1roLwVsunUkn+gnaMCYk+tDlaZABGXAC94k9RQVF06KquxeK0S17KOeQNn9Gb
N70JDklLLfuDsWbry6rIDYqsiEmTKi0WXhn44E1PaXQ=
-----END AGE ENCRYPTED FILE-----
@@ -71,7 +71,7 @@ in
bazarr = {
enable = true;
};
seerr.enable = true;
jellyseerr.enable = true;
prowlarr.enable = true;
sabnzbd = {
enable = true;
@@ -244,7 +244,7 @@ in
handle = [
{
handler = "reverse_proxy";
upstreams = [ { dial = "localhost:${builtins.toString config.services.seerr.port}"; } ];
upstreams = [ { dial = "localhost:${builtins.toString config.services.jellyseerr.port}"; } ];
}
];
}
@@ -24,7 +24,6 @@ let
hostnames.download
hostnames.photos
hostnames.audiobooks
hostnames.paperless
];
mkRecord = service: "${service} A ${localIp}";
localRecords = lib.concatLines (map mkRecord localServices);
@@ -58,7 +58,6 @@ in
{
handler = "static_response";
status_code = "403";
body = "IP not allowed";
}
];
}
@@ -110,95 +109,96 @@ in
apps.tls.automation.policies = cfg.tlsPolicies;
# Setup logging to journal and files
logging.logs = {
# System logs and catch-all
# Must be called `default` to override Caddy's built-in default logger
default = {
level = "INFO";
encoder.format = "console";
writer = {
output = "stderr";
logging.logs =
{
# System logs and catch-all
# Must be called `default` to override Caddy's built-in default logger
default = {
level = "INFO";
encoder.format = "console";
writer = {
output = "stderr";
};
exclude = (map (hostname: "http.log.access.${hostname}") (builtins.attrNames hostname_map)) ++ [
"http.log.access.${default_logger_name}"
];
};
exclude = (map (hostname: "http.log.access.${hostname}") (builtins.attrNames hostname_map)) ++ [
"http.log.access.${default_logger_name}"
];
};
# This is for the default access logs (anything not captured by hostname)
other = {
# This is for the default access logs (anything not captured by hostname)
other = {
level = "INFO";
encoder.format = "json";
writer = {
output = "file";
filename = "${config.services.caddy.logDir}/other.log";
roll = true;
inherit roll_size_mb;
};
include = [ "http.log.access.${default_logger_name}" ];
};
# This is for using the Caddy API, which will probably never happen
admin = {
level = "INFO";
encoder.format = "json";
writer = {
output = "file";
filename = "${config.services.caddy.logDir}/admin.log";
roll = true;
inherit roll_size_mb;
};
include = [ "admin" ];
};
# This is for TLS cert management tracking
tls = {
level = "INFO";
encoder.format = "json";
writer = {
output = "file";
filename = "${config.services.caddy.logDir}/tls.log";
roll = true;
inherit roll_size_mb;
};
include = [ "tls" ];
};
# This is for debugging
debug = {
level = "DEBUG";
encoder.format = "json";
writer = {
output = "file";
filename = "${config.services.caddy.logDir}/debug.log";
roll = true;
roll_keep = 1;
inherit roll_size_mb;
};
};
}
# These are the access logs for individual hostnames
// (lib.mapAttrs (name: value: {
level = "INFO";
encoder.format = "json";
writer = {
output = "file";
filename = "${config.services.caddy.logDir}/other.log";
roll = true;
inherit roll_size_mb;
};
include = [ "http.log.access.${default_logger_name}" ];
};
# This is for using the Caddy API, which will probably never happen
admin = {
level = "INFO";
encoder.format = "json";
writer = {
output = "file";
filename = "${config.services.caddy.logDir}/admin.log";
roll = true;
inherit roll_size_mb;
};
include = [ "admin" ];
};
# This is for TLS cert management tracking
tls = {
level = "INFO";
encoder.format = "json";
writer = {
output = "file";
filename = "${config.services.caddy.logDir}/tls.log";
roll = true;
inherit roll_size_mb;
};
include = [ "tls" ];
};
# This is for debugging
debug = {
level = "DEBUG";
encoder.format = "json";
writer = {
output = "file";
filename = "${config.services.caddy.logDir}/debug.log";
roll = true;
roll_keep = 1;
inherit roll_size_mb;
};
};
}
# These are the access logs for individual hostnames
// (lib.mapAttrs (name: value: {
level = "INFO";
encoder.format = "json";
writer = {
output = "file";
filename = "${config.services.caddy.logDir}/${name}-access.log";
roll = true;
inherit roll_size_mb;
};
include = [ "http.log.access.${name}" ];
}) hostname_map)
# We also capture just the errors separately for easy debugging
// (lib.mapAttrs' (name: value: {
name = "${name}-error";
value = {
level = "ERROR";
encoder.format = "json";
writer = {
output = "file";
filename = "${config.services.caddy.logDir}/${name}-error.log";
filename = "${config.services.caddy.logDir}/${name}-access.log";
roll = true;
inherit roll_size_mb;
};
include = [ "http.log.access.${name}" ];
};
}) hostname_map);
}) hostname_map)
# We also capture just the errors separately for easy debugging
// (lib.mapAttrs' (name: value: {
name = "${name}-error";
value = {
level = "ERROR";
encoder.format = "json";
writer = {
output = "file";
filename = "${config.services.caddy.logDir}/${name}-error.log";
roll = true;
inherit roll_size_mb;
};
include = [ "http.log.access.${name}" ];
};
}) hostname_map);
}
);
};
@@ -32,7 +32,6 @@ in
reverseProxyAuth.enable = false;
enableBookConversion = true;
enableBookUploading = true;
# Point this directly to the folder containing your 'metadata.db' file
calibreLibrary = libraryPath;
};
};
@@ -61,13 +60,6 @@ in
# Grant user access to Calibre directories
users.users.${username}.extraGroups = [ "calibre-web" ];
# Ensure the service has explicit filesystem read/write access to the library path
# This fixes the "sqlite3.OperationalError: unable to open database file" bug
systemd.services.calibre-web.serviceConfig.ReadWritePaths = [
libraryPath
"/var/lib/calibre-web-db"
];
# Run a backup on a schedule
systemd.timers.calibre-backup = lib.mkIf config.nmasur.presets.services.litestream.enable {
timerConfig = {
@@ -66,7 +66,10 @@ in
nmasur.presets.services.caddy.cidrAllowlist = cloudflareIpRanges;
# Tell Caddy to use Cloudflare DNS for ACME challenge validation
services.caddy.package = pkgs.nmasur.caddy;
services.caddy.package = pkgs.caddy.withPlugins {
plugins = [ "github.com/caddy-dns/cloudflare@v0.2.1" ];
hash = "sha256-S1JN7brvH2KIu7DaDOH1zij3j8hWLLc0HdnUc+L89uU=";
};
nmasur.presets.services.caddy.tlsPolicies = [
{
issuers = [
@@ -173,16 +176,5 @@ in
# Enable the home-made service that we created for non-proxied records
services.cloudflare-dyndns-noproxy.enable = true;
# Create certs when not using proxy
secrets.cloudflare-dns-api-prefixed = {
source = ./cloudflare-api.age;
dest = "${config.secretsDirectory}/cloudflare-dns-api-prefixed";
prefix = "CLOUDFLARE_DNS_API_TOKEN=";
};
security.acme = {
acceptTerms = true;
defaults.email = "acme@${config.nmasur.presets.programs.msmtp.domain}";
};
};
}

Some files were not shown because too many files have changed in this diff Show More