Author SHA1 Message Date
Noah Masur e00560c42c post-TUI lag: two-phase autosuggestion toggle; Ctrl-b was never activated
Root cause of 'Ctrl-b does nothing': home-manager was not switched, so the
binding built into the flake was never deployed (~/.config/fish lacked
heal-autosuggest and \cb; the built config had both). Activation needs the
home rebuild, not a system rebuild.

heal-autosuggest is now two-phase (set 0; repaint; set 1; repaint) to give
the reader a disabled-state repaint, which is what clears the wedged
in_flight_autosuggest_request per reader.rs update_autosuggestion. Matches
the manual cure (which had prompt cycles between off and on); the old
back-to-back toggle and the postexec hook did not. User chose the
session-preserving toggle over exec fish.
2026-09-07 11:17:44 -04:00
Noah Masur d4e56dd190 post-TUI lag: autosuggestion culprit confirmed; add self-heal hook
A/B in a live lagging shell: disabling fish_autosuggestion_enabled cures
the lag instantly, and re-enabling does NOT bring it back — the toggle
resets the wedged reader state. __autosuggestion_unwedge (fish_postexec)
now applies that reset after every command, at the moment TUIs exit.
Builtins only, invisible, respects a deliberate manual disable. Flight
recorder stays armed until the hook is proven in real use.

Also from this investigation: wedged-thread evidence (sampler attach
cures), lag-sample tool, flight recorder in the zellij fish wrapper.
2026-09-07 11:17:44 -04:00
Noah Masur db49e746b8 remove zellij-switch 2026-09-07 11:17:39 -04:00
Noah Masur 7f8400ff58 feat(immich): configure oidc authentication 2026-09-07 15:03:27 +00:00
Noah Masur d3914768c8 allow keybase gui 2026-09-06 18:00:20 -04:00
Noah Masur fd9cae9c40 fix(ssh): use openssh.authorizedPrincipals for cloudflare certificates 2026-09-06 19:34:37 +00:00
Noah Masur f593fdb81f feat(mealie): configure oidc authentication 2026-09-06 18:56:48 +00:00
Noah Masur 01ee98155a feat(actualbudget): configure oidc authentication 2026-09-06 18:18:57 +00:00
Noah Masur 2a3cbfb5f5 fix(grafana): allow oauth email lookup to match existing user 2026-09-06 18:04:46 +00:00
Noah Masur ca1343f593 configure grafana for oidc 2026-09-06 17:55:33 +00:00
Noah Masur a053a9ab0f define setup for oidc services 2026-09-06 15:02:21 +00:00
Noah Masur 90dc80f7b4 add pocket-id for auth 2026-09-06 12:18:17 +00:00
Noah Masur aff596aa64 add hister 2026-09-05 21:15:02 +00:00
github-actions[bot] 6e0f4e2000 flake.lock: Update
Flake lock file updates:

• Updated input 'home-manager':
    'github:nix-community/home-manager/99c9ec63390f1d8c14d95d9e8b17cc29cfbd4e11' (2026-08-27)
  → 'github:nix-community/home-manager/693e8ce0fb240a73c116a03cfd7b19269c87af88' (2026-09-04)
• Updated input 'nix-index-database':
    'github:nix-community/nix-index-database/c51d5c2ba69c907a34e90c9b6b80cd2b93811745' (2026-08-23)
  → 'github:nix-community/nix-index-database/dbb978fa87faf13398e90ccbc52c343d21c7dd6d' (2026-08-30)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/9fbb54b33e91ee4ca368e35a78e0613c720600b3' (2026-08-26)
  → 'github:nixos/nixpkgs/801bef6abd86b91e51083066b83fb354a11fc640' (2026-09-04)
• Updated input 'nixpkgs-stable':
    'github:nixos/nixpkgs/d57af924f160a5084293c71c2043f058bd1cdb60' (2026-08-27)
  → 'github:nixos/nixpkgs/a5cc6f2c37bf518436dc8d1c288ccd0c43c2f4c4' (2026-09-03)
• Updated input 'nur':
    'github:nix-community/nur/5b6adc26a9ef1bc45c09fcc845e7d08258c7e0ca' (2026-08-29)
  → 'github:nix-community/nur/82ca52a282cd5f90afabcf7c9acd27571b253523' (2026-09-05)
• Updated input 'rust-overlay':
    'github:oxalica/rust-overlay/996e9b0b019a4a9eb9e9a5641aefa06d801b5895' (2026-08-29)
  → 'github:oxalica/rust-overlay/c361047d3a538f547f1617bb6b410411929ac9cc' (2026-09-05)
2026-09-05 07:54:54 +00:00
Noah Masur 72c4f4823b fix nix-autoupgrade email notification to use system msmtp config 2026-08-30 14:46:53 -06:00
Noah Masur a93fa75779 fix invalid url in autoupgrade 2026-08-30 14:46:51 -06:00
Noah Masur a50d2c01a9 remove empty file 2026-08-30 13:24:35 -06:00
Noah Masur a72e81fcce fix post-TUI typing lag: latch fish query-term off in zellij pane shells
Root cause (proven via live lag-triage capture + deterministic PTY repro):
fish latches feature flags from its startup env before config.fish runs, so
the existing no-query-term settings never applied to zellij-spawned shells.
With query-term on, fish queries the terminal after every command; one reply
zellij fails to relay permanently degrades that fish process's reader.
Subshells were immune (inherited the exported var), which is why the lag
always 'disappeared' when tested in a new shell.

Also adds the lag-triage/unlag/term-probe diagnostic toolkit used to find
this, and upstream_repro.py for filing the fish-shell bug.
2026-08-29 17:48:23 -06:00
Noah Masur fe2843ead6 add lag-triage diagnostic toolkit for post-TUI typing lag 2026-08-29 14:04:44 -06:00
Noah Masur 68320577ae troubleshoot zellij alt-shift-p latency 2026-08-29 10:18:58 -06:00
github-actions[bot] 38ba019c3d flake.lock: Update
Flake lock file updates:

• Updated input 'home-manager':
    'github:nix-community/home-manager/c53d643b3737e2fcd04e6cb3b3580ef50b2087a0' (2026-08-19)
  → 'github:nix-community/home-manager/99c9ec63390f1d8c14d95d9e8b17cc29cfbd4e11' (2026-08-27)
• Updated input 'nix-index-database':
    'github:nix-community/nix-index-database/c7962dc97b45129df8d751bedaf37beb5a17706e' (2026-08-16)
  → 'github:nix-community/nix-index-database/c51d5c2ba69c907a34e90c9b6b80cd2b93811745' (2026-08-23)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/ffb3c9b700e759be2ef13237c9d8f953b32a1e46' (2026-08-19)
  → 'github:nixos/nixpkgs/9fbb54b33e91ee4ca368e35a78e0613c720600b3' (2026-08-26)
• Updated input 'nixpkgs-stable':
    'github:nixos/nixpkgs/5880666fd9eb563038431edb35c2d0aa595884e6' (2026-08-20)
  → 'github:nixos/nixpkgs/d57af924f160a5084293c71c2043f058bd1cdb60' (2026-08-27)
• Updated input 'nur':
    'github:nix-community/nur/aca4ff4662f393ef7f3ca88c8805c082cfc11b08' (2026-08-22)
  → 'github:nix-community/nur/5b6adc26a9ef1bc45c09fcc845e7d08258c7e0ca' (2026-08-29)
• Updated input 'rust-overlay':
    'github:oxalica/rust-overlay/fd2ebb9cc4323d0c5a1336138dab5c3c5a5d8bd9' (2026-08-22)
  → 'github:oxalica/rust-overlay/996e9b0b019a4a9eb9e9a5641aefa06d801b5895' (2026-08-29)
2026-08-29 10:27:49 +00:00
Noah Masur e339a4969f add back keybindings for zellij 2026-08-27 15:15:12 -06:00
Noah Masur 44f2ca803e fix(ghostty/zellij): translate mac super and ctrl shortcuts to alt sequences for zellij 2026-08-27 11:26:37 -06:00
Noah Masur 239b56c1b1 fix(zellij): disable kitty keyboard protocol to fix post-TUI typing lag 2026-08-26 17:27:01 -06:00
Noah Masur 4ba1ed807c fix(nix): resolve stdenv deprecation warnings and gemini-cli deprecation 2026-08-24 20:22:43 -06:00
Noah Masur 32989f1758 fix(fish): fix TUI exit hang and typing latency in Zellij and Ghostty 2026-08-24 20:14:53 -06:00
Noah Masur b0b08d2475 fix(zellij): fix CWD tracking in fish for zellij tabs 2026-08-24 19:52:22 -06:00
Noah Masur 5ecefd4589 fix: firefox profile cannot be loaded error on macOS 2026-08-22 09:25:04 -04:00
Noah Masur fffb9d547c switch 1password in ldap to homebrew version 2026-08-22 09:25:04 -04:00
Noah Masur 3c303ccd19 switch to claude desktop with launcher l command 2026-08-22 09:25:04 -04:00
github-actions[bot] d222fef02e flake.lock: Update
Flake lock file updates:

• Updated input 'darwin':
    'github:lnl7/nix-darwin/15abb8c98f336cd8bd840d71059adebabe60bf04' (2026-07-30)
  → 'github:lnl7/nix-darwin/4cff07de74b50e64bdd68cd4e722ab5b6b35ee48' (2026-08-16)
• Updated input 'home-manager':
    'github:nix-community/home-manager/83b7606dcf44abe3a94b86e8bb2b3355d22e8797' (2026-08-14)
  → 'github:nix-community/home-manager/c53d643b3737e2fcd04e6cb3b3580ef50b2087a0' (2026-08-19)
• Updated input 'nix-index-database':
    'github:nix-community/nix-index-database/14d55b8069119e3b88da7aa2f6c97f86a2cd3cd6' (2026-08-09)
  → 'github:nix-community/nix-index-database/c7962dc97b45129df8d751bedaf37beb5a17706e' (2026-08-16)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/0e251e24a4f24e036a084b6b4b2d2491af4167f4' (2026-08-13)
  → 'github:nixos/nixpkgs/ffb3c9b700e759be2ef13237c9d8f953b32a1e46' (2026-08-19)
• Updated input 'nixpkgs-stable':
    'github:nixos/nixpkgs/02e08985a27c65ffd33d434eeb2e660a2e4dc84d' (2026-08-14)
  → 'github:nixos/nixpkgs/5880666fd9eb563038431edb35c2d0aa595884e6' (2026-08-20)
• Updated input 'nur':
    'github:nix-community/nur/507d1d8fed0d7cf923d986f6c2aec3cbd5002bcd' (2026-08-15)
  → 'github:nix-community/nur/aca4ff4662f393ef7f3ca88c8805c082cfc11b08' (2026-08-22)
• Updated input 'rust-overlay':
    'github:oxalica/rust-overlay/ad8ebb59d84bcf3780c46f107e1d99eb4ca2fe7f' (2026-08-15)
  → 'github:oxalica/rust-overlay/fd2ebb9cc4323d0c5a1336138dab5c3c5a5d8bd9' (2026-08-22)
2026-08-22 04:11:59 +00:00
github-actions[bot] 71ce9689ce flake.lock: Update
Flake lock file updates:

• Updated input 'home-manager':
    'github:nix-community/home-manager/7834e82588860aaf780cec1366524456a70898d7' (2026-08-06)
  → 'github:nix-community/home-manager/83b7606dcf44abe3a94b86e8bb2b3355d22e8797' (2026-08-14)
• Updated input 'nix-index-database':
    'github:nix-community/nix-index-database/dbc756c9d7287de19b3e0e38c928c47510d42c3e' (2026-08-02)
  → 'github:nix-community/nix-index-database/14d55b8069119e3b88da7aa2f6c97f86a2cd3cd6' (2026-08-09)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/b7c2ada94fe99c15b0dbcf4d11fd7850b957a436' (2026-08-05)
  → 'github:nixos/nixpkgs/0e251e24a4f24e036a084b6b4b2d2491af4167f4' (2026-08-13)
• Updated input 'nixpkgs-stable':
    'github:nixos/nixpkgs/445d861c6d31b4af0c79d8d4be2331f762a361d7' (2026-08-06)
  → 'github:nixos/nixpkgs/02e08985a27c65ffd33d434eeb2e660a2e4dc84d' (2026-08-14)
• Updated input 'nur':
    'github:nix-community/nur/b94fbbbf2878ef877830cbfafc2070faf49a1ddd' (2026-08-08)
  → 'github:nix-community/nur/507d1d8fed0d7cf923d986f6c2aec3cbd5002bcd' (2026-08-15)
• Updated input 'rust-overlay':
    'github:oxalica/rust-overlay/4e1c940c96560ceab7c547f89642231371a66646' (2026-08-08)
  → 'github:oxalica/rust-overlay/ad8ebb59d84bcf3780c46f107e1d99eb4ca2fe7f' (2026-08-15)
2026-08-15 04:10:20 +00:00
Noah Masur 4047cae211 enable calibre on macos through homebrew
broken build from nix on macos
2026-08-10 09:29:44 -04:00
Noah Masur e70661a623 attempt to fix shell lagging after exiting tuis 2026-08-09 09:53:44 -04:00
Noah Masur a979036462 fix: firefox not using profile and preferences 2026-08-08 10:51:10 -04:00
Noah Masur 8ae7fd435e fix: switch firefox and watchman to unstable to pull from cache
also remove some unnecessary packages
2026-08-08 10:21:03 -04:00
Noah Masur 2d5de254e4 add noti to gh runs for zellij 2026-08-08 10:20:24 -04:00
github-actions[bot] d90b45d194 flake.lock: Update
Flake lock file updates:

• Updated input 'darwin':
    'github:lnl7/nix-darwin/57a3171f94705599a2499248ca5758d5eb47c0e0' (2026-07-19)
  → 'github:lnl7/nix-darwin/15abb8c98f336cd8bd840d71059adebabe60bf04' (2026-07-30)
• Updated input 'home-manager':
    'github:nix-community/home-manager/079a3b5d1aa6a719920a51316253b7d6dd22738d' (2026-07-24)
  → 'github:nix-community/home-manager/7834e82588860aaf780cec1366524456a70898d7' (2026-08-06)
• Updated input 'nix-index-database':
    'github:nix-community/nix-index-database/11665045df8b9938ef811a3bfdc65cffb02b4b70' (2026-07-26)
  → 'github:nix-community/nix-index-database/dbc756c9d7287de19b3e0e38c928c47510d42c3e' (2026-08-02)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/e2587caef70cea85dd97d7daab492899902dbf5d' (2026-07-23)
  → 'github:nixos/nixpkgs/b7c2ada94fe99c15b0dbcf4d11fd7850b957a436' (2026-08-05)
• Updated input 'nixpkgs-stable':
    'github:nixos/nixpkgs/b3fe9581c9061c749abef42b6d4ee7b7c05c33fa' (2026-07-22)
  → 'github:nixos/nixpkgs/445d861c6d31b4af0c79d8d4be2331f762a361d7' (2026-08-06)
• Updated input 'nur':
    'github:nix-community/nur/1166a294990afd245fd72b8d2896075222408399' (2026-07-25)
  → 'github:nix-community/nur/b94fbbbf2878ef877830cbfafc2070faf49a1ddd' (2026-08-08)
• Updated input 'rust-overlay':
    'github:oxalica/rust-overlay/a163bd01a6e11ac58d4f8d11669da550b5afbbc6' (2026-07-25)
  → 'github:oxalica/rust-overlay/4e1c940c96560ceab7c547f89642231371a66646' (2026-08-08)
2026-08-08 04:40:55 +00:00
Noah Masur d8a29f0267 fix warnings on linux home-manager 2026-08-04 20:24:03 -04:00
Noah Masur f3a8d45722 trust corporate MITM root CA on lookingglass for TLS-intercepting proxy 2026-08-03 15:58:12 -04:00
Noah Masur df38163999 fix: cap zellij session name length to avoid socket path overflow crash 2026-08-03 15:54:52 -04:00
Noah Masur 31cecf05cc try to fix nix warnings 2026-08-01 08:54:13 -04:00
Noah Masur 59685bf023 add actualtap for working with actual api 2026-07-29 00:46:26 +00:00
Noah Masur a3a5c516ce fix: pwmconfig hardware ids chnaged 2026-07-28 20:10:59 -04:00
Noah Masur 033026bff8 add nix-index-database flake input 2026-07-28 18:34:12 -04:00
Noah Masur 5929b3201d fix calibre-web write issue 2026-07-28 22:04:29 +00:00
Noah Masur 373beb6daf move ren and rep to experimental
i don't like having to build them
2026-07-28 16:58:10 -04:00
Noah Masur 8cef9bfb59 feat(jjui): add custom github ruleset bypass commands 2026-07-28 11:34:48 -04:00
Noah Masur 98d426ce89 more dock cleanup 2026-07-28 11:34:42 -04:00
Noah Masur e107431fa9 fix(python): disable python metadata check for cheetah3 to fix sabnzbd build 2026-07-28 11:34:39 -04:00
Noah Masur 1960d84e7a re-arrange dock with preview and thunderbird 2026-07-25 14:35:26 -04:00
Noah Masur 671a17af76 fix discord and 1pass dock link 2026-07-25 09:29:58 -04:00
github-actions[bot] 71709776f9 flake.lock: Update
Flake lock file updates:

• Updated input 'darwin':
    'github:lnl7/nix-darwin/a4cf1d10853b0d2be19b9eca35d749e201d70b55' (2026-07-15)
  → 'github:lnl7/nix-darwin/57a3171f94705599a2499248ca5758d5eb47c0e0' (2026-07-19)
• Updated input 'home-manager':
    'github:nix-community/home-manager/460108009ca1ff69ca2ff19079ca2c838d6e3080' (2026-07-18)
  → 'github:nix-community/home-manager/079a3b5d1aa6a719920a51316253b7d6dd22738d' (2026-07-24)
• Updated input 'nix-caddy-withplugins':
    'github:MichailiK/nix-caddy-withplugins/79db67d97207b6e32eaba69d5c3e6d7e63144154' (2026-06-14)
  → 'github:MichailiK/nix-caddy-withplugins/70307cfc568e5434cf42067d797b27c38ea69944' (2026-07-24)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/753cc8a3a87467296ddd1fa93f0cc3e81120ee46' (2026-07-15)
  → 'github:nixos/nixpkgs/e2587caef70cea85dd97d7daab492899902dbf5d' (2026-07-23)
• Updated input 'nixpkgs-stable':
    'github:nixos/nixpkgs/293d6abedf0478e681a4dfcfcb35b30fc796a32f' (2026-07-17)
  → 'github:nixos/nixpkgs/b3fe9581c9061c749abef42b6d4ee7b7c05c33fa' (2026-07-22)
• Updated input 'nur':
    'github:nix-community/nur/697f13fd230047493989b03576419792273c3a9e' (2026-07-18)
  → 'github:nix-community/nur/1166a294990afd245fd72b8d2896075222408399' (2026-07-25)
• Updated input 'rust-overlay':
    'github:oxalica/rust-overlay/3c38e1e1ba9c8d7030f7b5a801398ea7d8a6fdc0' (2026-07-18)
  → 'github:oxalica/rust-overlay/a163bd01a6e11ac58d4f8d11669da550b5afbbc6' (2026-07-25)
• Updated input 'wsl':
    'github:nix-community/NixOS-WSL/24c8dc8e0f2170e1a377be24dfadc7d9d21dc1ad' (2026-07-14)
  → 'github:nix-community/NixOS-WSL/eaeb18da90024448a60eb1ec7132eafa4003404e' (2026-07-21)
2026-07-25 06:05:57 +00:00
Noah Masur 829af86dd8 switch to nix caddy plugin module
in order to prevent frequent need to re-hash
2026-07-21 15:08:29 +00:00
Noah Masur e7fd5eb770 update caddy hash 2026-07-20 23:12:23 +00:00
Noah Masur f0b400d134 set base url for mealie 2026-07-20 22:32:03 +00:00
Noah Masur 573c0acd33 disable flaky paho-mqtt test suite breaking flame rebuild 2026-07-20 18:28:57 -04:00
Noah Masur eec777c0c1 fix mathesar has a flaky test 2026-07-20 17:50:56 -04:00
Noah Masur 638b112db9 fix Discord on macOS: use Homebrew cask instead of broken nixpkgs bundle 2026-07-20 17:50:54 -04:00
Noah Masur 27917ffede remove home-manager module from nix-darwin
this fixes the starship errors when rebuilding nix-darwin
2026-07-20 14:33:48 -04:00
Noah Masur 73b62e0907 fix broken rebuilds 2026-07-20 14:25:58 -04:00
Noah Masur b25cfe6877 add llm-development profile 2026-07-20 14:25:58 -04:00
Noah Masur d162df2515 use noti for gh run watch in zellij pane 2026-07-20 09:00:59 -04:00
github-actions[bot] 396337f74d flake.lock: Update
Flake lock file updates:

• Updated input 'darwin':
    'github:lnl7/nix-darwin/d5bd9cd77aea4c0a8f49e7fd85545671a208ed15' (2026-07-07)
  → 'github:lnl7/nix-darwin/a4cf1d10853b0d2be19b9eca35d749e201d70b55' (2026-07-15)
• Updated input 'home-manager':
    'github:nix-community/home-manager/2afec152df4e284d264f8489d16004c264aebf4c' (2026-07-11)
  → 'github:nix-community/home-manager/460108009ca1ff69ca2ff19079ca2c838d6e3080' (2026-07-18)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/0bb7ec54c8483066ec9d7720e780a5caa71f8612' (2026-07-08)
  → 'github:nixos/nixpkgs/753cc8a3a87467296ddd1fa93f0cc3e81120ee46' (2026-07-15)
• Updated input 'nixpkgs-stable':
    'github:nixos/nixpkgs/8f0500b9660505dc3cb647775fe9a978a74b5283' (2026-07-10)
  → 'github:nixos/nixpkgs/293d6abedf0478e681a4dfcfcb35b30fc796a32f' (2026-07-17)
• Updated input 'nur':
    'github:nix-community/nur/29c4c5612e67bce09ee3f2f988bebe51ff9e6b81' (2026-07-11)
  → 'github:nix-community/nur/697f13fd230047493989b03576419792273c3a9e' (2026-07-18)
• Updated input 'rust-overlay':
    'github:oxalica/rust-overlay/e598b37857b895b81020a65a802ef55f5bbed72f' (2026-07-11)
  → 'github:oxalica/rust-overlay/3c38e1e1ba9c8d7030f7b5a801398ea7d8a6fdc0' (2026-07-18)
• Updated input 'wsl':
    'github:nix-community/NixOS-WSL/a9620cfa43f0c1c30a46c31ae3c6e58cdb124a14' (2026-07-06)
  → 'github:nix-community/NixOS-WSL/24c8dc8e0f2170e1a377be24dfadc7d9d21dc1ad' (2026-07-14)
2026-07-18 05:53:01 +00:00
Noah Masur 76b50920de update and fix karakeep transitive dependency error 2026-07-11 09:28:07 -06:00
Noah Masur e04cdab409 switch 1password on darwin to nix module 2026-07-08 11:20:22 -06:00
Noah Masur d238b7a81a remove modules directory no longer used 2026-07-08 11:10:11 -06:00
Noah Masur f3e24c3730 add noti preset to darwin profile 2026-07-07 14:34:04 -06:00
Noah Masur 5862c7cb29 add back staeam for macos 2026-07-06 18:19:16 -06:00
Noah Masur a175acd0ad fix: ghostty breaking zellij and hammerspoon launching 2026-07-05 18:33:38 -06:00
Noah Masur 3f3cf65c77 fix: system renamed warning 2026-07-05 18:06:13 -06:00
Noah Masur 35d40ca346 switch from nix-darwin control to more home-manager darwin settings 2026-07-05 17:59:27 -06:00
github-actions[bot] e0fb590314 flake.lock: Update
Flake lock file updates:

• Updated input 'home-manager':
    'github:nix-community/home-manager/8d8a6cc50ddc60748791a14ee1163c865ec57635' (2026-06-27)
  → 'github:nix-community/home-manager/b885baad531fa3d3beae2ba9a0712d22974d8016' (2026-07-04)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/e73de5be04e0eff4190a1432b946d469c794e7b4' (2026-06-26)
  → 'github:nixos/nixpkgs/65179426c83bb3f6bc14898b42ea1c6f01d374b0' (2026-07-02)
• Updated input 'nixpkgs-stable':
    'github:nixos/nixpkgs/4062d36ebeae843c750011eef6b61ec9a9dbc9a9' (2026-06-25)
  → 'github:nixos/nixpkgs/95ca1e203c0750115fd4a6f17d5a245dfe6b1edd' (2026-06-30)
• Updated input 'nur':
    'github:nix-community/nur/e0abe20203566414fc15f8c1006ada8a0fb0b8af' (2026-06-27)
  → 'github:nix-community/nur/c50af1cc06115c76b81c0bbe079248193003e707' (2026-07-04)
• Updated input 'rust-overlay':
    'github:oxalica/rust-overlay/06ba695dfefc4afc513b49dfc41c4bf0dd2eaeb1' (2026-06-27)
  → 'github:oxalica/rust-overlay/fe5aee0952e8e1525533d61defd9e36513db811b' (2026-07-04)
2026-07-04 06:39:14 +00:00
github-actions[bot] 2f107ad207 flake.lock: Update
Flake lock file updates:

• Updated input 'home-manager':
    'github:nix-community/home-manager/37f21dfa5d27e71b75bacd9418b156f9265e312e' (2026-06-19)
  → 'github:nix-community/home-manager/8d8a6cc50ddc60748791a14ee1163c865ec57635' (2026-06-27)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/567a49d1913ce81ac6e9582e3553dd90a955875f' (2026-06-16)
  → 'github:nixos/nixpkgs/e73de5be04e0eff4190a1432b946d469c794e7b4' (2026-06-26)
• Updated input 'nixpkgs-stable':
    'github:nixos/nixpkgs/a0374025a863d007d98e3297f6aa46cc3141c2f0' (2026-06-11)
  → 'github:nixos/nixpkgs/4062d36ebeae843c750011eef6b61ec9a9dbc9a9' (2026-06-25)
• Updated input 'nur':
    'github:nix-community/nur/16d79cbdb047a88b69d7dbd5a111e00ea733905d' (2026-06-20)
  → 'github:nix-community/nur/e0abe20203566414fc15f8c1006ada8a0fb0b8af' (2026-06-27)
• Updated input 'rust-overlay':
    'github:oxalica/rust-overlay/e8e2021ee8cf3b58b000953ed3bee0d16b5e98e0' (2026-06-20)
  → 'github:oxalica/rust-overlay/06ba695dfefc4afc513b49dfc41c4bf0dd2eaeb1' (2026-06-27)
2026-06-27 06:46:54 +00:00
Noah Masur b6b0a29a78 add antigravity cli 2026-06-21 17:13:07 -04:00
github-actions[bot] fd6da7e68d flake.lock: Update
Flake lock file updates:

• Updated input 'darwin':
    'github:lnl7/nix-darwin/aabb2037edfc0f210723b72cd5f528aab5dd3f0b' (2026-06-12)
  → 'github:lnl7/nix-darwin/a1fa429e945becaf60468600daf649be4ba0350c' (2026-06-18)
• Updated input 'home-manager':
    'github:nix-community/home-manager/c87a39aa979acc4848016d2220c6238390d84779' (2026-06-12)
  → 'github:nix-community/home-manager/37f21dfa5d27e71b75bacd9418b156f9265e312e' (2026-06-19)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/9ae611a455b90cf061d8f332b977e387bda8e1ca' (2026-06-10)
  → 'github:nixos/nixpkgs/567a49d1913ce81ac6e9582e3553dd90a955875f' (2026-06-16)
• Updated input 'nixpkgs-stable':
    'github:nixos/nixpkgs/bd0ff2d3eac24699c3664d5966b9ef36f388e2ca' (2026-06-08)
  → 'github:nixos/nixpkgs/a0374025a863d007d98e3297f6aa46cc3141c2f0' (2026-06-11)
• Updated input 'nur':
    'github:nix-community/nur/d093785742fb74b13a61ca54060206da54f782d0' (2026-06-13)
  → 'github:nix-community/nur/16d79cbdb047a88b69d7dbd5a111e00ea733905d' (2026-06-20)
• Updated input 'rust-overlay':
    'github:oxalica/rust-overlay/5b929d8c854149d926d05ea0cd6469bf4e54db27' (2026-06-13)
  → 'github:oxalica/rust-overlay/e8e2021ee8cf3b58b000953ed3bee0d16b5e98e0' (2026-06-20)
• Updated input 'zellij-switch':
    'github:mostafaqanbaryan/zellij-switch/0e3c303c19890ccb03589230ac5a7c4307e573e4' (2025-03-21)
  → 'github:mostafaqanbaryan/zellij-switch/ced3c681afe40785b2853e3a976908466786ee79' (2026-06-19)
2026-06-20 07:40:39 +00:00
Noah Masur 28049e9c30 fix: skip broken checkPhase for kubernetes-helm 4.2.0 2026-06-14 09:54:40 -04:00
Noah Masur d95cdb1385 sign git commits with work acct 2026-06-14 09:54:40 -04:00
Noah Masur cf8f1fa221 fix: allow calibre-web to write through metadata.db symlink 2026-06-13 09:45:34 -04:00
Noah Masur 8b098f0589 fix: zoxide fuzzy search for session switching 2026-06-13 09:45:34 -04:00
github-actions[bot] 12961b19c0 flake.lock: Update
Flake lock file updates:

• Updated input 'darwin':
    'github:lnl7/nix-darwin/56c666e108467d87d13508936aade6d567f2a501' (2026-05-17)
  → 'github:lnl7/nix-darwin/aabb2037edfc0f210723b72cd5f528aab5dd3f0b' (2026-06-12)
• Updated input 'disko':
    'github:nix-community/disko/115e5211780054d8a890b41f0b7734cafad54dfe' (2026-06-01)
  → 'github:nix-community/disko/ff8702b4de27f72b4c78573dfb89ec74e36abdf1' (2026-06-11)
• Updated input 'home-manager':
    'github:nix-community/home-manager/b2b7db486e06e098711dc291bb25db82850e1d16' (2026-06-05)
  → 'github:nix-community/home-manager/c87a39aa979acc4848016d2220c6238390d84779' (2026-06-12)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/331800de5053fcebacf6813adb5db9c9dca22a0c' (2026-05-31)
  → 'github:nixos/nixpkgs/9ae611a455b90cf061d8f332b977e387bda8e1ca' (2026-06-10)
• Updated input 'nixpkgs-stable':
    'github:nixos/nixpkgs/6b316287bae2ee04c9b93c8c858d930fd07d7338' (2026-06-03)
  → 'github:nixos/nixpkgs/bd0ff2d3eac24699c3664d5966b9ef36f388e2ca' (2026-06-08)
• Updated input 'nur':
    'github:nix-community/nur/b4f1d49eba34ce60c2e5d0e7246da64be7904fd3' (2026-06-06)
  → 'github:nix-community/nur/d093785742fb74b13a61ca54060206da54f782d0' (2026-06-13)
• Updated input 'rust-overlay':
    'github:oxalica/rust-overlay/27b7e78c6935293ee868469cc4172e9b8b17823b' (2026-06-06)
  → 'github:oxalica/rust-overlay/5b929d8c854149d926d05ea0cd6469bf4e54db27' (2026-06-13)
• Updated input 'wsl':
    'github:nix-community/NixOS-WSL/ad4c358ded144d26da517b999ddb51295770c419' (2026-06-06)
  → 'github:nix-community/NixOS-WSL/5675822ba756e6e56f8f6a5a76e90e0da2ece94d' (2026-06-11)
2026-06-13 07:14:35 +00:00
github-actions[bot] 455c047607 flake.lock: Update
Flake lock file updates:

• Updated input 'disko':
    'github:nix-community/disko/caa775cf67bfdc47f940edd96c975b5016df9059' (2026-05-29)
  → 'github:nix-community/disko/115e5211780054d8a890b41f0b7734cafad54dfe' (2026-06-01)
• Updated input 'home-manager':
    'github:nix-community/home-manager/7d8127d308c3fb9664f7e643eec944be74ebb37d' (2026-05-30)
  → 'github:nix-community/home-manager/b2b7db486e06e098711dc291bb25db82850e1d16' (2026-06-05)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/64c08a7ca051951c8eae34e3e3cb1e202fe36786' (2026-05-23)
  → 'github:nixos/nixpkgs/331800de5053fcebacf6813adb5db9c9dca22a0c' (2026-05-31)
• Updated input 'nixpkgs-stable':
    'github:nixos/nixpkgs/ec942ba042dad5ef097e2ef3a3effc034241f011' (2026-05-28)
  → 'github:nixos/nixpkgs/6b316287bae2ee04c9b93c8c858d930fd07d7338' (2026-06-03)
• Updated input 'nur':
    'github:nix-community/nur/0014c5be6969541b8ae4c6f64f59f14ce1b09503' (2026-05-30)
  → 'github:nix-community/nur/b4f1d49eba34ce60c2e5d0e7246da64be7904fd3' (2026-06-06)
• Updated input 'rust-overlay':
    'github:oxalica/rust-overlay/85570ef134d92a8702de6afd1f6f0209c863fa91' (2026-05-30)
  → 'github:oxalica/rust-overlay/27b7e78c6935293ee868469cc4172e9b8b17823b' (2026-06-06)
• Updated input 'wsl':
    'github:nix-community/NixOS-WSL/5482f113fd31ebac131d1ebeb2ae90bf0d5e41f5' (2026-05-02)
  → 'github:nix-community/NixOS-WSL/ad4c358ded144d26da517b999ddb51295770c419' (2026-06-06)
2026-06-06 06:47:25 +00:00
Noah Masur fa307c0f4b updates for swan 2026-05-30 22:36:02 +00:00
Noah Masur 07a980e937 fix: grafana secrets systemd 2026-05-30 22:22:14 +00:00
Noah Masur 0a4a28d06a increase mealie login session 2026-05-30 18:54:42 +00:00
Noah Masur 5fd6593a92 fix: replace enableAllTerminfo with specific terminfo packages 2026-05-30 13:56:15 -04:00
Noah Masur 8af595b62b update to 26.05 for stable 2026-05-30 13:02:48 -04:00
Noah Masur 1e723db068 use jj-starship from nixpkgs instead of separate flake 2026-05-30 12:54:20 -04:00
Noah Masur 16e42c2021 fix: upgrade prometheus-actual-exporter to nodejs_22 2026-05-30 10:36:00 -04:00
github-actions[bot] 38edf0a1a6 flake.lock: Update
Flake lock file updates:

• Updated input 'darwin':
    'github:lnl7/nix-darwin/8c62fba0854ba15c8917aed18894dbccb48a3777' (2026-05-03)
  → 'github:lnl7/nix-darwin/56c666e108467d87d13508936aade6d567f2a501' (2026-05-17)
• Updated input 'disko':
    'github:nix-community/disko/63b4e7e6cf75307c1d26ac3762b886b5b0247267' (2026-05-02)
  → 'github:nix-community/disko/65fb947964bd44fc0008faf77d1fcb7a9f40bb32' (2026-05-19)
• Updated input 'home-manager':
    'github:nix-community/home-manager/a89686d115e970e200eb2caa7603f3673050e00c' (2026-05-04)
  → 'github:nix-community/home-manager/509ed3c603349a9d43de9e2ae6613baea6bd5b34' (2026-05-23)
• Updated input 'jj-starship':
    'github:dmmulroy/jj-starship/76cf00619b0cce5bd08a1b9a49b310ed928794d5' (2026-01-25)
  → 'github:dmmulroy/jj-starship/292224a93d5490332f32cc26d77676ccaeec0bfa' (2026-05-13)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/15f4ee454b1dce334612fa6843b3e05cf546efab' (2026-04-30)
  → 'github:nixos/nixpkgs/f83fc3c307e74bc5fd5adb7eb6b8b13ffd2a36e1' (2026-05-21)
• Updated input 'nur':
    'github:nix-community/nur/3a67c1ca739171f7196584bc250d195736e524b4' (2026-05-04)
  → 'github:nix-community/nur/7233bc9ba561a4a40166d72f489c76592354e5e4' (2026-05-23)
• Updated input 'rust-overlay':
    'github:oxalica/rust-overlay/669151bbc7f2416b622af2f48e9136e2c9da5530' (2026-05-04)
  → 'github:oxalica/rust-overlay/d9973e2ab49747fada06ebbe26cda27eb0220cf1' (2026-05-23)
2026-05-23 06:27:33 +00:00
Noah Masur 15f70dce2c fix nodePackages references in prometheus-actual-exporter 2026-05-16 10:38:18 -04:00
Noah Masur 1a7633fe8c disable daily summary 2026-05-16 08:38:08 -04:00
Noah Masur 40025b1211 enable thunderbird on mac 2026-05-11 11:12:03 -04:00
Noah Masur f5d9664caf try changing murmur credentials files, and disable murmur 2026-05-09 14:03:30 -04:00
Noah Masur 7010d6cea3 update system 2026-05-05 08:59:00 -04:00
Noah Masur a2a429d286 update nixpkgs and add pi 2026-04-08 10:58:51 -04:00
Noah Masur 7f5b5eb809 fix session switching (using cli actions) 2026-04-04 10:50:07 -04:00
Noah Masur f5f3a8336e switch font to maple mono 2026-04-04 10:50:07 -04:00
Noah Masur 4444a479d4 add actionlint 2026-04-04 10:50:07 -04:00
github-actions[bot] 395c4b4348 flake.lock: Update
Flake lock file updates:

• Updated input 'darwin':
    'github:lnl7/nix-darwin/da529ac9e46f25ed5616fd634079a5f3c579135f' (2026-03-08)
  → 'github:lnl7/nix-darwin/06648f4902343228ce2de79f291dd5a58ee12146' (2026-04-01)
• Updated input 'home-manager':
    'github:nix-community/home-manager/02371c05a04a2876cf92e2d67a259e8f87399068' (2026-03-27)
  → 'github:nix-community/home-manager/9dc93220c1c9a410ef6277d6dc55c571d9e592d0' (2026-04-04)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/46db2e09e1d3f113a13c0d7b81e2f221c63b8ce9' (2026-03-24)
  → 'github:nixos/nixpkgs/6201e203d09599479a3b3450ed24fa81537ebc4e' (2026-04-01)
• Updated input 'nur':
    'github:nix-community/nur/6298c3410e4000a9e91c344ac5f163b043534e03' (2026-03-28)
  → 'github:nix-community/nur/274b289253048dec21259c12a16508fb1e30e0f6' (2026-04-04)
• Updated input 'rust-overlay':
    'github:oxalica/rust-overlay/98caaa8cd1fbcc45913d1bb2b7fbabcf3e8d967a' (2026-03-28)
  → 'github:oxalica/rust-overlay/740fb0203b2852917b909a72b948d34d0b171ec0' (2026-04-04)
• Updated input 'wsl':
    'github:nix-community/NixOS-WSL/fd0eae98d1ecee31024271f8d64676250a386ee7' (2026-03-19)
  → 'github:nix-community/NixOS-WSL/d97e078f4788cddb8d11c3c99f72a4bb9ddec221' (2026-03-31)
2026-04-04 05:14:31 +00:00
github-actions[bot] 8dbec5f6ab flake.lock: Update
Flake lock file updates:

• Updated input 'home-manager':
    'github:nix-community/home-manager/9670de2921812bc4e0452f6e3efd8c859696c183' (2026-03-20)
  → 'github:nix-community/home-manager/02371c05a04a2876cf92e2d67a259e8f87399068' (2026-03-27)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/b40629efe5d6ec48dd1efba650c797ddbd39ace0' (2026-03-18)
  → 'github:nixos/nixpkgs/46db2e09e1d3f113a13c0d7b81e2f221c63b8ce9' (2026-03-24)
• Updated input 'nur':
    'github:nix-community/nur/08e7d1fc8fc15731a4d6a664207e18828fe028cb' (2026-03-21)
  → 'github:nix-community/nur/6298c3410e4000a9e91c344ac5f163b043534e03' (2026-03-28)
• Updated input 'rust-overlay':
    'github:oxalica/rust-overlay/c807e83cc2e32adc35f51138b3bdef722c0812ab' (2026-03-21)
  → 'github:oxalica/rust-overlay/98caaa8cd1fbcc45913d1bb2b7fbabcf3e8d967a' (2026-03-28)
2026-03-28 05:14:58 +00:00
Noah Masur f8d79cdf3a add claude code 2026-03-23 10:16:19 -04:00
Noah Masur 280082acfe zoom window hiding functionality
fix hammerspoon
2026-03-23 10:16:19 -04:00
github-actions[bot] 1edf9da155 flake.lock: Update
Flake lock file updates:

• Updated input 'disko':
    'github:nix-community/disko/7b9f7f88ab3b339f8142dc246445abb3c370d3d3' (2026-03-09)
  → 'github:nix-community/disko/5ad85c82cc52264f4beddc934ba57f3789f28347' (2026-03-19)
• Updated input 'home-manager':
    'github:nix-community/home-manager/ef12a9a2b0f77c8fa3dda1e7e494fca668909056' (2026-03-13)
  → 'github:nix-community/home-manager/9670de2921812bc4e0452f6e3efd8c859696c183' (2026-03-20)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/fe416aaedd397cacb33a610b33d60ff2b431b127' (2026-03-12)
  → 'github:nixos/nixpkgs/b40629efe5d6ec48dd1efba650c797ddbd39ace0' (2026-03-18)
• Updated input 'nur':
    'github:nix-community/nur/a8b4f501a52ac4a789acb4ae022ce27bb2cf3c99' (2026-03-14)
  → 'github:nix-community/nur/08e7d1fc8fc15731a4d6a664207e18828fe028cb' (2026-03-21)
• Updated input 'rust-overlay':
    'github:oxalica/rust-overlay/055977c30249484010750e03074c744dcdaa0d23' (2026-03-14)
  → 'github:oxalica/rust-overlay/c807e83cc2e32adc35f51138b3bdef722c0812ab' (2026-03-21)
• Updated input 'wsl':
    'github:nix-community/NixOS-WSL/d2fd7da4565797cf7e18b9b0a8b1044fbada8ff8' (2026-03-13)
  → 'github:nix-community/NixOS-WSL/fd0eae98d1ecee31024271f8d64676250a386ee7' (2026-03-19)
2026-03-21 04:57:33 +00:00
github-actions[bot] 8d970103e1 flake.lock: Update
Flake lock file updates:

• Updated input 'darwin':
    'github:lnl7/nix-darwin/6a7fdcd5839ec8b135821179eea3b58092171bcf' (2026-02-19)
  → 'github:lnl7/nix-darwin/da529ac9e46f25ed5616fd634079a5f3c579135f' (2026-03-08)
• Updated input 'disko':
    'github:nix-community/disko/4707eec8d1d2db5182ea06ed48c820a86a42dc13' (2026-02-19)
  → 'github:nix-community/disko/7b9f7f88ab3b339f8142dc246445abb3c370d3d3' (2026-03-09)
• Updated input 'home-manager':
    'github:nix-community/home-manager/436b27742c996b75e2baf8e835e3b3eae0c9fbd4' (2026-02-21)
  → 'github:nix-community/home-manager/ef12a9a2b0f77c8fa3dda1e7e494fca668909056' (2026-03-13)
• Updated input 'nix2vim':
    'github:gytis-ivaskevicius/nix2vim/78467c8de07719f92397179844bf75cdf2e58b83' (2025-08-16)
  → 'github:gytis-ivaskevicius/nix2vim/71acbf5f97545b01778df03a8f2194e918103eba' (2026-03-07)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/0182a361324364ae3f436a63005877674cf45efb' (2026-02-17)
  → 'github:nixos/nixpkgs/fe416aaedd397cacb33a610b33d60ff2b431b127' (2026-03-12)
• Updated input 'nur':
    'github:nix-community/nur/1bedc7cb7cfbb0c29970ce26f61718c9b2dac4c3' (2026-02-21)
  → 'github:nix-community/nur/a8b4f501a52ac4a789acb4ae022ce27bb2cf3c99' (2026-03-14)
• Updated input 'rust-overlay':
    'github:oxalica/rust-overlay/85078369717bdbe1f266c9eaad5e66956fb6feea' (2026-02-21)
  → 'github:oxalica/rust-overlay/055977c30249484010750e03074c744dcdaa0d23' (2026-03-14)
• Updated input 'wsl':
    'github:nix-community/NixOS-WSL/379d20c55f552e91fb9f3f0382e4a97d3f452943' (2026-02-20)
  → 'github:nix-community/NixOS-WSL/d2fd7da4565797cf7e18b9b0a8b1044fbada8ff8' (2026-03-13)
2026-03-14 05:02:26 +00:00
Noah Masur d9137ad738 add jj to gitignore 2026-03-12 20:29:24 -04:00
Noah Masur 4eacca970e add required secret key for grafana 2026-03-07 12:33:21 -05:00
Noah Masur d09ee3337b update jj starship to remove git prompt 2026-03-06 20:18:20 -05:00
Noah Masur 22e1c9b8eb keep uv installed as an available program 2026-03-06 20:18:00 -05:00
Noah Masur acd71623e4 remove my own extension from ff because it's not signed 2026-03-06 20:17:29 -05:00
Noah Masur 9a97d94ffa add jj-starship and fix zellij lockout 2026-02-28 09:49:11 -05:00
Noah Masur 84bffd13e8 remove deprecated brew line 2026-02-26 09:46:25 -05:00
Noah Masur 774b323837 add pre-commit to work packages 2026-02-24 14:43:39 -05:00
Noah Masur 2f2d2c0145 add zellij keybinds for nested zellij 2026-02-24 14:17:51 -05:00
github-actions[bot] 6b17248804 flake.lock: Update
Flake lock file updates:

• Updated input 'darwin':
    'github:lnl7/nix-darwin/6c5a56295d2a24e43bcd8af838def1b9a95746b2' (2026-02-12)
  → 'github:lnl7/nix-darwin/6a7fdcd5839ec8b135821179eea3b58092171bcf' (2026-02-19)
• Updated input 'disko':
    'github:nix-community/disko/71a3fc97d80881e91710fe721f1158d3b96ae14d' (2026-01-27)
  → 'github:nix-community/disko/4707eec8d1d2db5182ea06ed48c820a86a42dc13' (2026-02-19)
• Updated input 'home-manager':
    'github:nix-community/home-manager/05e6dc0f6ed936f918cb6f0f21f1dad1e4c53150' (2026-02-14)
  → 'github:nix-community/home-manager/436b27742c996b75e2baf8e835e3b3eae0c9fbd4' (2026-02-21)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/ec7c70d12ce2fc37cb92aff673dcdca89d187bae' (2026-02-11)
  → 'github:nixos/nixpkgs/0182a361324364ae3f436a63005877674cf45efb' (2026-02-17)
• Updated input 'nur':
    'github:nix-community/nur/40fb292376611e388cb14329c96853966f57763a' (2026-02-14)
  → 'github:nix-community/nur/1bedc7cb7cfbb0c29970ce26f61718c9b2dac4c3' (2026-02-21)
• Updated input 'rust-overlay':
    'github:oxalica/rust-overlay/d7a86c8a4df49002446737603a3e0d7ef91a9637' (2026-02-14)
  → 'github:oxalica/rust-overlay/85078369717bdbe1f266c9eaad5e66956fb6feea' (2026-02-21)
• Updated input 'wsl':
    'github:nix-community/NixOS-WSL/5b50ea1aaa14945d4794c80fcc99c4aa1db84d2d' (2026-02-09)
  → 'github:nix-community/NixOS-WSL/379d20c55f552e91fb9f3f0382e4a97d3f452943' (2026-02-20)
2026-02-21 04:56:29 +00:00
Noah Masur a7dacb7edf murmur (mumble server) and non-caddy acme client 2026-02-14 20:11:52 +00:00
github-actions[bot] dfd3b955c0 flake.lock: Update
Flake lock file updates:

• Updated input 'darwin':
    'github:lnl7/nix-darwin/0d7874ef7e3ba02d58bebb871e6e29da36fa1b37' (2026-02-04)
  → 'github:lnl7/nix-darwin/6c5a56295d2a24e43bcd8af838def1b9a95746b2' (2026-02-12)
• Updated input 'home-manager':
    'github:nix-community/home-manager/471e6a065f9efed51488d7c51a9abbd387df91b8' (2026-02-05)
  → 'github:nix-community/home-manager/05e6dc0f6ed936f918cb6f0f21f1dad1e4c53150' (2026-02-14)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/00c21e4c93d963c50d4c0c89bfa84ed6e0694df2' (2026-02-04)
  → 'github:nixos/nixpkgs/ec7c70d12ce2fc37cb92aff673dcdca89d187bae' (2026-02-11)
• Updated input 'nur':
    'github:nix-community/nur/227b931ac44365853d7a0026360878cb990b426e' (2026-02-07)
  → 'github:nix-community/nur/40fb292376611e388cb14329c96853966f57763a' (2026-02-14)
• Updated input 'rust-overlay':
    'github:oxalica/rust-overlay/9922ff9f99a6436756cbe6f5d11f9c3630e58cf0' (2026-02-07)
  → 'github:oxalica/rust-overlay/d7a86c8a4df49002446737603a3e0d7ef91a9637' (2026-02-14)
• Updated input 'wsl':
    'github:nix-community/NixOS-WSL/38a5250e57f583662eac3b944830e4b9e169e965' (2026-01-24)
  → 'github:nix-community/NixOS-WSL/5b50ea1aaa14945d4794c80fcc99c4aa1db84d2d' (2026-02-09)
2026-02-14 05:01:07 +00:00
Noah Masur fd7ddf71f3 update to fix builds on macos 2026-02-10 17:20:00 -05:00
github-actions[bot] bba66e3e6a flake.lock: Update
Flake lock file updates:

• Updated input 'darwin':
    'github:lnl7/nix-darwin/0fc4e7ac670a0ed874abacf73c4b072a6a58064b' (2026-01-18)
  → 'github:lnl7/nix-darwin/0d7874ef7e3ba02d58bebb871e6e29da36fa1b37' (2026-02-04)
• Updated input 'home-manager':
    'github:nix-community/home-manager/475921375def3eb930e1f8883f619ff8609accb6' (2026-01-30)
  → 'github:nix-community/home-manager/471e6a065f9efed51488d7c51a9abbd387df91b8' (2026-02-05)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/bfc1b8a4574108ceef22f02bafcf6611380c100d' (2026-01-26)
  → 'github:nixos/nixpkgs/00c21e4c93d963c50d4c0c89bfa84ed6e0694df2' (2026-02-04)
• Updated input 'nur':
    'github:nix-community/nur/2db81de33100ef4d86ebc80dc4bc30df1fe97c5d' (2026-01-31)
  → 'github:nix-community/nur/227b931ac44365853d7a0026360878cb990b426e' (2026-02-07)
• Updated input 'rust-overlay':
    'github:oxalica/rust-overlay/a1d32c90c8a4ea43e9586b7e5894c179d5747425' (2026-01-31)
  → 'github:oxalica/rust-overlay/9922ff9f99a6436756cbe6f5d11f9c3630e58cf0' (2026-02-07)
2026-02-07 04:56:30 +00:00
Noah Masur be6d6b0d35 fix add-on manifest 2026-01-31 11:53:43 -05:00
Noah Masur 0239a9925c try to prevent unnecessary firefox rebuidl 2026-01-31 11:53:43 -05:00
Noah Masur 49e35403b6 adjust daily summary to use browser extension for history 2026-01-31 11:53:43 -05:00
Noah Masur 430b522c61 enable daily browser summary on darwin 2026-01-31 11:53:43 -05:00
Noah Masur a64488093c fix current build on darwin 2026-01-31 11:53:43 -05:00
Noah Masur 54d2376437 add alabaster theme to helix 2026-01-31 11:53:43 -05:00
Noah Masur cd0a5d5de0 fix vertical pane navigation in zellij 2026-01-31 11:53:30 -05:00
github-actions[bot] 10eecfa136 flake.lock: Update
Flake lock file updates:

• Updated input 'disko':
    'github:nix-community/disko/00395d188e3594a1507f214a2f15d4ce5c07cb28' (2026-01-20)
  → 'github:nix-community/disko/71a3fc97d80881e91710fe721f1158d3b96ae14d' (2026-01-27)
• Updated input 'home-manager':
    'github:nix-community/home-manager/082a4cd87c6089d1d9c58ebe52655f9e07245fcb' (2026-01-23)
  → 'github:nix-community/home-manager/475921375def3eb930e1f8883f619ff8609accb6' (2026-01-30)
• Updated input 'nixos-generators':
    'github:nix-community/nixos-generators/032a1878682fafe829edfcf5fdfad635a2efe748' (2025-11-27)
  → 'github:nix-community/nixos-generators/8946737ff703382fda7623b9fab071d037e897d5' (2026-01-30)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/88d3861acdd3d2f0e361767018218e51810df8a1' (2026-01-21)
  → 'github:nixos/nixpkgs/bfc1b8a4574108ceef22f02bafcf6611380c100d' (2026-01-26)
• Updated input 'nur':
    'github:nix-community/nur/4d20ca56620171b095fc4b51d55b155395c86506' (2026-01-24)
  → 'github:nix-community/nur/2db81de33100ef4d86ebc80dc4bc30df1fe97c5d' (2026-01-31)
• Updated input 'rust-overlay':
    'github:oxalica/rust-overlay/22da29e7f3d8cff75009cbbcf992c7cb66920cfd' (2026-01-24)
  → 'github:oxalica/rust-overlay/a1d32c90c8a4ea43e9586b7e5894c179d5747425' (2026-01-31)
2026-01-31 04:53:01 +00:00
Noah Masur b5b3f6cb6a fix: n8n can't write to disk 2026-01-25 15:00:01 +00:00
Noah Masur 810c92a7b8 update restic path for actual and fix build 2026-01-24 20:25:03 +00:00
github-actions[bot] fcb28c8151 flake.lock: Update
Flake lock file updates:

• Updated input 'darwin':
    'github:lnl7/nix-darwin/9f48ffaca1f44b3e590976b4da8666a9e86e6eb1' (2026-01-06)
  → 'github:lnl7/nix-darwin/0fc4e7ac670a0ed874abacf73c4b072a6a58064b' (2026-01-18)
• Updated input 'disko':
    'github:nix-community/disko/916506443ecd0d0b4a0f4cf9d40a3c22ce39b378' (2025-12-19)
  → 'github:nix-community/disko/00395d188e3594a1507f214a2f15d4ce5c07cb28' (2026-01-20)
• Updated input 'home-manager':
    'github:nix-community/home-manager/d0aefc169fa9a0bd2b1239aeb98899c77d6da5b2' (2026-01-10)
  → 'github:nix-community/home-manager/082a4cd87c6089d1d9c58ebe52655f9e07245fcb' (2026-01-23)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/3497aa5c9457a9d88d71fa93a4a8368816fbeeba' (2026-01-08)
  → 'github:nixos/nixpkgs/88d3861acdd3d2f0e361767018218e51810df8a1' (2026-01-21)
• Updated input 'nur':
    'github:nix-community/nur/a4f7c05a5f80044f9dcf3dfeb55a16b5a2713caf' (2026-01-10)
  → 'github:nix-community/nur/4d20ca56620171b095fc4b51d55b155395c86506' (2026-01-24)
• Updated input 'rust-overlay':
    'github:oxalica/rust-overlay/312b4371e72f644ffcff25b23615195e3b390643' (2026-01-10)
  → 'github:oxalica/rust-overlay/22da29e7f3d8cff75009cbbcf992c7cb66920cfd' (2026-01-24)
• Updated input 'wsl':
    'github:nix-community/NixOS-WSL/be4af8042e7a61fa12fda58fe9a3b3babdefe17b' (2025-12-15)
  → 'github:nix-community/NixOS-WSL/38a5250e57f583662eac3b944830e4b9e169e965' (2026-01-24)
• Updated input 'wsl/flake-compat':
    'github:edolstra/flake-compat/65f23138d8d09a92e30f1e5c87611b23ef451bf3' (2025-12-07)
  → 'github:edolstra/flake-compat/5edf11c44bc78a0d334f6334cdaf7d60d732daab' (2025-12-29)
2026-01-24 04:16:03 +00:00
Noah Masur e2a2d3de14 fix: playground vim plugin is archived 2026-01-17 10:40:01 -05:00
Noah Masur adbc2bd261 enable thunderbird for tasks, calendar, and email gui 2026-01-11 19:45:39 -06:00
Noah Masur 117fd8a06e replace nixfmt-rfc-style with equivalent nixfmt 2026-01-11 16:38:47 -05:00
Noah Masur d9fbdf7bfe Update flake, fix userControlled attribute
Also add nix-inspect
2026-01-10 14:21:43 -05:00
github-actions[bot] 2d13780d2e flake.lock: Update
Flake lock file updates:

• Updated input 'darwin':
    'github:lnl7/nix-darwin/5fb45ece6129bd7ad8f7310df0ae9c00bae7c562' (2025-12-18)
  → 'github:lnl7/nix-darwin/c31afa6e76da9bbc7c9295e39c7de9fca1071ea1' (2025-12-29)
• Updated input 'home-manager':
    'github:nix-community/home-manager/bb35f07cc95a73aacbaf1f7f46bb8a3f40f265b5' (2025-12-19)
  → 'github:nix-community/home-manager/2f06b726061b7e1aa69f718e943da9ffcecd6397' (2026-01-02)
• Updated input 'mac-app-util':
    'github:hraban/mac-app-util/8414fa1e2cb775b17793104a9095aabeeada63ef' (2025-08-24)
  → 'github:hraban/mac-app-util/4747968574ea58512c5385466400b2364c85d2d0' (2025-12-27)
• Updated input 'mac-app-util/cl-nix-lite':
    'github:hraban/cl-nix-lite/31cfe6275c341eb3120a99f4b1c8516c49a29d87' (2024-10-06)
  → 'github:hraban/cl-nix-lite/038e341cede255a83a8f04af114dc95717461d32' (2025-12-27)
• Added input 'mac-app-util/cl-nix-lite/flake-parts':
    'github:hercules-ci/flake-parts/a34fae9c08a15ad73f295041fec82323541400a9' (2025-12-15)
• Added input 'mac-app-util/cl-nix-lite/flake-parts/nixpkgs-lib':
    'github:nix-community/nixpkgs.lib/2075416fcb47225d9b68ac469a5c4801a9c4dd85' (2025-12-14)
• Added input 'mac-app-util/cl-nix-lite/nixpkgs':
    'github:nixos/nixpkgs/f560ccec6b1116b22e6ed15f4c510997d99d5852' (2025-12-26)
• Added input 'mac-app-util/cl-nix-lite/systems':
    'github:nix-systems/default/da67096a3b9bf56a91d16901293e51ba5b49a27e' (2023-04-09)
• Added input 'mac-app-util/cl-nix-lite/treefmt-nix':
    'github:numtide/treefmt-nix/42d96e75aa56a3f70cab7e7dc4a32868db28e8fd' (2025-12-17)
• Added input 'mac-app-util/cl-nix-lite/treefmt-nix/nixpkgs':
    'github:nixos/nixpkgs/d5faa84122bc0a1fd5d378492efce4e289f8eac1' (2025-10-23)
• Updated input 'mac-app-util/treefmt-nix':
    'github:numtide/treefmt-nix/74e1a52d5bd9430312f8d1b8b0354c92c17453e5' (2025-08-23)
  → 'github:numtide/treefmt-nix/42d96e75aa56a3f70cab7e7dc4a32868db28e8fd' (2025-12-17)
• Updated input 'mac-app-util/treefmt-nix/nixpkgs':
    'github:nixos/nixpkgs/cab778239e705082fe97bb4990e0d24c50924c04' (2025-08-04)
  → 'github:nixos/nixpkgs/d5faa84122bc0a1fd5d378492efce4e289f8eac1' (2025-10-23)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/c6245e83d836d0433170a16eb185cefe0572f8b8' (2025-12-18)
  → 'github:nixos/nixpkgs/cad22e7d996aea55ecab064e84834289143e44a0' (2025-12-30)
• Updated input 'nixpkgs-stable':
    'github:nixos/nixpkgs/2b0d2b456e4e8452cf1c16d00118d145f31160f9' (2025-12-17)
  → 'github:nixos/nixpkgs/40ee5e1944bebdd128f9fbada44faefddfde29bd' (2025-12-29)
• Updated input 'nur':
    'github:nix-community/nur/e036ffaac9c2869ab23d4fb1c0d9da50fe2f852a' (2025-12-20)
  → 'github:nix-community/nur/846861904f43cd2bb04314f664514c87e26c512b' (2026-01-03)
• Updated input 'rust-overlay':
    'github:oxalica/rust-overlay/66bb33fdfb50b1ee724381c3f5d6012dac6c89b3' (2025-12-20)
  → 'github:oxalica/rust-overlay/294198315a13d6d130565ad08e97685df7b0d458' (2026-01-03)
2026-01-03 04:12:23 +00:00
Noah Masur 53a712a217 update caddy hash 2026-01-01 18:16:43 +00:00
Noah Masur 31d34c6540 fixes to get nix flake check working with new updates 2025-12-30 16:33:23 -05:00
Noah Masur a978e67346 comment out spctl allow apps from anywhere
doesn't work when using nh because it requires a UI escalation when
run via indirectly
2025-12-26 10:31:31 -07:00
Noah Masur a6915a6d2d try to fix nix-darwin breaking starship prompt on rebuild 2025-12-26 10:31:12 -07:00
Noah Masur 44c4034236 more fixes on warning for renamed system 2025-12-26 10:29:18 -07:00
Noah Masur a99c14a8c2 use stable zed-editor to stop uncached builds 2025-12-26 10:28:31 -07:00
Noah Masur f1c8e26044 comment out 1password extension while it doesn't work in firefox 2025-12-26 10:27:55 -07:00
Noah Masur 29cd253d9c awscli2 overlay no longer required 2025-12-20 07:54:17 -07:00
Noah Masur 603b9a2eff fix terraform lsp in helix 2025-12-20 07:54:11 -07:00
github-actions[bot] 9c35744ab9 flake.lock: Update
Flake lock file updates:

• Updated input 'darwin':
    'github:lnl7/nix-darwin/7e22bf538aa3e0937effcb1cee73d5f1bcc26f79' (2025-12-06)
  → 'github:lnl7/nix-darwin/5fb45ece6129bd7ad8f7310df0ae9c00bae7c562' (2025-12-18)
• Updated input 'disko':
    'github:nix-community/disko/d64e5cdca35b5fad7c504f615357a7afe6d9c49e' (2025-12-10)
  → 'github:nix-community/disko/916506443ecd0d0b4a0f4cf9d40a3c22ce39b378' (2025-12-19)
• Updated input 'home-manager':
    'github:nix-community/home-manager/39cb677ed9e908e90478aa9fe5f3383dfc1a63f3' (2025-12-11)
  → 'github:nix-community/home-manager/bb35f07cc95a73aacbaf1f7f46bb8a3f40f265b5' (2025-12-19)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/addf7cf5f383a3101ecfba091b98d0a1263dc9b8' (2025-12-08)
  → 'github:nixos/nixpkgs/c6245e83d836d0433170a16eb185cefe0572f8b8' (2025-12-18)
• Updated input 'nixpkgs-stable':
    'github:nixos/nixpkgs/d2b1213bf5ec5e62d96b003ab4b5cbc42abfc0d0' (2025-12-10)
  → 'github:nixos/nixpkgs/2b0d2b456e4e8452cf1c16d00118d145f31160f9' (2025-12-17)
• Updated input 'nur':
    'github:nix-community/nur/da24c00523a3125a97b24783e2b59b5b98ac5da7' (2025-12-13)
  → 'github:nix-community/nur/e036ffaac9c2869ab23d4fb1c0d9da50fe2f852a' (2025-12-20)
• Updated input 'rust-overlay':
    'github:oxalica/rust-overlay/348b94ed9ddffccdf1a65582a2dcff0a4a3eeeb4' (2025-12-13)
  → 'github:oxalica/rust-overlay/66bb33fdfb50b1ee724381c3f5d6012dac6c89b3' (2025-12-20)
• Updated input 'wsl':
    'github:nix-community/NixOS-WSL/0c040f28b44b18e0d4240e027096078e34dbb029' (2025-12-11)
  → 'github:nix-community/NixOS-WSL/be4af8042e7a61fa12fda58fe9a3b3babdefe17b' (2025-12-15)
2025-12-20 04:04:34 +00:00
github-actions[bot] 7d6b29c30b flake.lock: Update
Flake lock file updates:

• Updated input 'darwin':
    'github:lnl7/nix-darwin/e95de00a471d07435e0527ff4db092c84998698e' (2025-11-26)
  → 'github:lnl7/nix-darwin/7e22bf538aa3e0937effcb1cee73d5f1bcc26f79' (2025-12-06)
• Updated input 'disko':
    'github:nix-community/disko/5a88a6eceb8fd732b983e72b732f6f4b8269bef3' (2025-12-01)
  → 'github:nix-community/disko/d64e5cdca35b5fad7c504f615357a7afe6d9c49e' (2025-12-10)
• Updated input 'home-manager':
    'github:nix-community/home-manager/ccd22c13b2200263fb59342a34bf7119a31aa363' (2025-12-06)
  → 'github:nix-community/home-manager/39cb677ed9e908e90478aa9fe5f3383dfc1a63f3' (2025-12-11)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/418468ac9527e799809c900eda37cbff999199b6' (2025-12-02)
  → 'github:nixos/nixpkgs/addf7cf5f383a3101ecfba091b98d0a1263dc9b8' (2025-12-08)
• Updated input 'nixpkgs-stable':
    'github:nixos/nixpkgs/ff06bd3398fb1bea6c937039ece7e7c8aa396ebf' (2025-12-04)
  → 'github:nixos/nixpkgs/d2b1213bf5ec5e62d96b003ab4b5cbc42abfc0d0' (2025-12-10)
• Updated input 'nur':
    'github:nix-community/nur/cfab17b2d4bf4e9fa3aa48d6b9cb36c749e096e9' (2025-12-06)
  → 'github:nix-community/nur/da24c00523a3125a97b24783e2b59b5b98ac5da7' (2025-12-13)
• Updated input 'rust-overlay':
    'github:oxalica/rust-overlay/086fd19a68e80fcc8a298e9df4674982e4c498a6' (2025-12-06)
  → 'github:oxalica/rust-overlay/348b94ed9ddffccdf1a65582a2dcff0a4a3eeeb4' (2025-12-13)
• Updated input 'wsl':
    'github:nix-community/NixOS-WSL/10124c58674360765adcb38c9a8b081fb72904e4' (2025-12-03)
  → 'github:nix-community/NixOS-WSL/0c040f28b44b18e0d4240e027096078e34dbb029' (2025-12-11)
• Updated input 'wsl/flake-compat':
    'github:edolstra/flake-compat/f387cd2afec9419c8ee37694406ca490c3f34ee5' (2025-10-27)
  → 'github:edolstra/flake-compat/65f23138d8d09a92e30f1e5c87611b23ef451bf3' (2025-12-07)
• Updated input 'zenyd-mpv-scripts':
    'github:zenyd/mpv-scripts/d20a64a008fc6fb03f026c379313111291bdd49f' (2025-12-02)
  → 'github:zenyd/mpv-scripts/62f4bb313c6cb6366672e78dea940e9da8fec84a' (2025-12-06)
2025-12-13 04:04:17 +00:00
github-actions[bot] fd589b66ef flake.lock: Update
Flake lock file updates:

• Updated input 'disko':
    'github:nix-community/disko/2055a08fd0e2fd41318279a5355eb8a161accf26' (2025-11-28)
  → 'github:nix-community/disko/5a88a6eceb8fd732b983e72b732f6f4b8269bef3' (2025-12-01)
• Updated input 'home-manager':
    'github:nix-community/home-manager/780be8ef503a28939cf9dc7996b48ffb1a3e04c6' (2025-11-28)
  → 'github:nix-community/home-manager/ccd22c13b2200263fb59342a34bf7119a31aa363' (2025-12-06)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/2fad6eac6077f03fe109c4d4eb171cf96791faa4' (2025-11-27)
  → 'github:nixos/nixpkgs/418468ac9527e799809c900eda37cbff999199b6' (2025-12-02)
• Updated input 'nixpkgs-stable':
    'github:nixos/nixpkgs/9a7b80b6f82a71ea04270d7ba11b48855681c4b0' (2025-11-28)
  → 'github:nixos/nixpkgs/ff06bd3398fb1bea6c937039ece7e7c8aa396ebf' (2025-12-04)
• Updated input 'nur':
    'github:nix-community/nur/c23e05e2d8e852c9c128b624cfc19ea8674ad793' (2025-11-29)
  → 'github:nix-community/nur/cfab17b2d4bf4e9fa3aa48d6b9cb36c749e096e9' (2025-12-06)
• Updated input 'rust-overlay':
    'github:oxalica/rust-overlay/4f5a90bf043a57add9b3288bbd25ed534bfaffb5' (2025-11-29)
  → 'github:oxalica/rust-overlay/086fd19a68e80fcc8a298e9df4674982e4c498a6' (2025-12-06)
• Updated input 'wsl':
    'github:nix-community/NixOS-WSL/c7832dd786175e20f2697179e0e03efadffe4201' (2025-11-25)
  → 'github:nix-community/NixOS-WSL/10124c58674360765adcb38c9a8b081fb72904e4' (2025-12-03)
• Updated input 'zenyd-mpv-scripts':
    'github:zenyd/mpv-scripts/8309b669f060f95fbb2abf9e6882c3ae4ec1ff2d' (2025-11-27)
  → 'github:zenyd/mpv-scripts/d20a64a008fc6fb03f026c379313111291bdd49f' (2025-12-02)
2025-12-06 03:58:44 +00:00
github-actions[bot] 853aa644fa flake.lock: Update
Flake lock file updates:

• Updated input 'darwin':
    'github:lnl7/nix-darwin/3bda9f6b14161becbd07b3c56411f1670e19b9b5' (2025-11-18)
  → 'github:lnl7/nix-darwin/e95de00a471d07435e0527ff4db092c84998698e' (2025-11-26)
• Updated input 'disko':
    'github:nix-community/disko/e86a89079587497174ccab6d0d142a65811a4fd9' (2025-11-20)
  → 'github:nix-community/disko/2055a08fd0e2fd41318279a5355eb8a161accf26' (2025-11-28)
• Updated input 'home-manager':
    'github:nix-community/home-manager/d10a9b16b2a3ee28433f3d1c603f4e9f1fecb8e1' (2025-11-21)
  → 'github:nix-community/home-manager/780be8ef503a28939cf9dc7996b48ffb1a3e04c6' (2025-11-28)
• Updated input 'nixos-generators':
    'github:nix-community/nixos-generators/032decf9db65efed428afd2fa39d80f7089085eb' (2025-07-07)
  → 'github:nix-community/nixos-generators/032a1878682fafe829edfcf5fdfad635a2efe748' (2025-11-27)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/89c2b2330e733d6cdb5eae7b899326930c2c0648' (2025-11-17)
  → 'github:nixos/nixpkgs/2fad6eac6077f03fe109c4d4eb171cf96791faa4' (2025-11-27)
• Updated input 'nixpkgs-stable':
    'github:nixos/nixpkgs/c58bc7f5459328e4afac201c5c4feb7c818d604b' (2025-11-20)
  → 'github:nixos/nixpkgs/9a7b80b6f82a71ea04270d7ba11b48855681c4b0' (2025-11-28)
• Updated input 'nur':
    'github:nix-community/nur/77b49ed77583b3e3fee9c8962bcd7c7992ab7e72' (2025-11-22)
  → 'github:nix-community/nur/c23e05e2d8e852c9c128b624cfc19ea8674ad793' (2025-11-29)
• Updated input 'rust-overlay':
    'github:oxalica/rust-overlay/7f3aa46dfa230ec2a4ca9281186a24771650ccd1' (2025-11-22)
  → 'github:oxalica/rust-overlay/4f5a90bf043a57add9b3288bbd25ed534bfaffb5' (2025-11-29)
• Updated input 'wsl':
    'github:nix-community/NixOS-WSL/3bcc267c4e0efa023b98b9c5cfbe11b88ec2dc8f' (2025-11-21)
  → 'github:nix-community/NixOS-WSL/c7832dd786175e20f2697179e0e03efadffe4201' (2025-11-25)
• Updated input 'zenyd-mpv-scripts':
    'github:zenyd/mpv-scripts/8bc3d8fd7660aaf08737eca4fb65f7193507b661' (2025-11-21)
  → 'github:zenyd/mpv-scripts/8309b669f060f95fbb2abf9e6882c3ae4ec1ff2d' (2025-11-27)
2025-11-29 03:59:46 +00:00
Noah Masur b6e7221cc6 fix: zellij switch command on darwin 2025-11-26 13:20:22 -07:00
Noah Masur 235901b3b0 fix jjui on darwin 2025-11-26 09:00:19 -07:00
github-actions[bot] 7cd74986df flake.lock: Update
Flake lock file updates:

• Updated input 'home-manager':
    'github:nix-community/home-manager/ea164b7c9ccdc2321379c2ff78fd4317b4c41312' (2025-11-17)
  → 'github:nix-community/home-manager/d10a9b16b2a3ee28433f3d1c603f4e9f1fecb8e1' (2025-11-21)
• Updated input 'nur':
    'github:nix-community/nur/9cfdb9c199ebf780c36a9998d27547563c7b2aaf' (2025-11-21)
  → 'github:nix-community/nur/77b49ed77583b3e3fee9c8962bcd7c7992ab7e72' (2025-11-22)
• Updated input 'rust-overlay':
    'github:oxalica/rust-overlay/6fbf5d328dce1828d887b8ee7d44a785196a34e7' (2025-11-21)
  → 'github:oxalica/rust-overlay/7f3aa46dfa230ec2a4ca9281186a24771650ccd1' (2025-11-22)
• Updated input 'zenyd-mpv-scripts':
    'github:zenyd/mpv-scripts/a1470f01cae24f06365fbe05e5295d906d7438fe' (2025-11-21)
  → 'github:zenyd/mpv-scripts/8bc3d8fd7660aaf08737eca4fb65f7193507b661' (2025-11-21)
2025-11-22 03:55:41 +00:00
Noah Masur a6e15b71cd update packages and fix helix language 2025-11-21 10:32:55 -07:00
Noah Masur 2e4467b6ea try to make builds work 2025-11-21 10:32:55 -07:00
Noah Masur 431ebd732c use alacritty for i3 terminal on macos 2025-11-21 10:32:55 -07:00
Noah Masur 2d576bd25d improve helix language server selection 2025-11-21 10:32:55 -07:00
Noah Masur a1615eda67 try improvements to helix git blame and bring yazi to zellij 2025-11-21 10:32:55 -07:00
Noah Masur 444582a5a5 try adding jiratui to homebrew 2025-11-21 10:32:55 -07:00
Noah Masur fbabdadb32 add bash to aws-ec2 launch script 2025-11-21 10:32:55 -07:00
Noah Masur f8dfa2a817 enable jujutsu as non-experimental 2025-11-17 02:48:06 +00:00
Noah Masur e4a8ef15ce fix rebuilds and broken packages after update 2025-11-15 13:10:48 -06:00
github-actions[bot] 5c922310f5 flake.lock: Update
Flake lock file updates:

• Updated input 'darwin':
    'github:lnl7/nix-darwin/e2b82ebd0f990a5d1b68fcc761b3d6383c86ccfd' (2025-11-07)
  → 'github:lnl7/nix-darwin/973db96394513fd90270ea5a1211a82a4a0ba47f' (2025-11-14)
• Updated input 'helix':
    'github:helix-editor/helix/65ea351cc30b23d40e9a5784a4be99768536b7f5' (2025-11-08)
  → 'github:helix-editor/helix/948ac05aa0db64e0e5d00710db36eb244076e988' (2025-11-12)
• Updated input 'home-manager':
    'github:nix-community/home-manager/0562fef070a1027325dd4ea10813d64d2c967b39' (2025-11-06)
  → 'github:nix-community/home-manager/827f2a23373a774a8805f84ca5344654c31f354b' (2025-11-12)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/ae814fd3904b621d8ab97418f1d0f2eb0d3716f4' (2025-11-05)
  → 'github:nixos/nixpkgs/c5ae371f1a6a7fd27823bc500d9390b38c05fa55' (2025-11-12)
• Updated input 'nur':
    'github:nix-community/nur/e7b4921cad8b7492ab9c441bda269be625bd2acc' (2025-11-08)
  → 'github:nix-community/nur/cb44dde82a279a626f8b3283fdcf52849d3ab3d4' (2025-11-15)
• Updated input 'rust-overlay':
    'github:oxalica/rust-overlay/a35a6144b976f70827c2fe2f5c89d16d8f9179d8' (2025-11-08)
  → 'github:oxalica/rust-overlay/89af6762b01409edbb595888a69311e8e5954110' (2025-11-15)
• Updated input 'wsl':
    'github:nix-community/NixOS-WSL/e001844d4553aef268f97b32d3a825b6370eed91' (2025-11-04)
  → 'github:nix-community/NixOS-WSL/debc562c48c445f9f08778ecb9fc6b35197623ad' (2025-11-12)
2025-11-15 03:59:13 +00:00
Noah Masur 2f274cd652 chawan as manpager and fixes to rebuild shortcuts 2025-11-14 19:31:42 -05:00
Noah Masur 407e9c3af8 enable mealie for recipes 2025-11-11 04:00:51 +00:00
Noah Masur c13e029805 update zellij for launching and quitting automatically 2025-11-10 21:17:13 -06:00
github-actions[bot] c56bc30200 flake.lock: Update
Flake lock file updates:

• Updated input 'darwin':
    'github:lnl7/nix-darwin/7cd9aac79ee2924a85c211d21fafd394b06a38de' (2025-10-24)
  → 'github:lnl7/nix-darwin/e2b82ebd0f990a5d1b68fcc761b3d6383c86ccfd' (2025-11-07)
• Updated input 'disko':
    'github:nix-community/disko/6f4cf5abbe318e4cd1e879506f6eeafd83f7b998' (2025-10-31)
  → 'github:nix-community/disko/af087d076d3860760b3323f6b583f4d828c1ac17' (2025-11-04)
• Updated input 'helix':
    'github:helix-editor/helix/5a92474bf0453715e3139eccaaccf3264bfb2001' (2025-10-31)
  → 'github:helix-editor/helix/65ea351cc30b23d40e9a5784a4be99768536b7f5' (2025-11-08)
• Updated input 'home-manager':
    'github:nix-community/home-manager/4ac96eb21c101a3e5b77ba105febc5641a8959aa' (2025-10-31)
  → 'github:nix-community/home-manager/0562fef070a1027325dd4ea10813d64d2c967b39' (2025-11-06)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/08dacfca559e1d7da38f3cf05f1f45ee9bfd213c' (2025-10-28)
  → 'github:nixos/nixpkgs/ae814fd3904b621d8ab97418f1d0f2eb0d3716f4' (2025-11-05)
• Updated input 'nur':
    'github:nix-community/nur/f20762096406e710b930858237046c139f03a061' (2025-11-01)
  → 'github:nix-community/nur/e7b4921cad8b7492ab9c441bda269be625bd2acc' (2025-11-08)
• Updated input 'rust-overlay':
    'github:oxalica/rust-overlay/08c33e87c4829bbdd42b5af247cf7a19e126369f' (2025-11-02)
  → 'github:oxalica/rust-overlay/a35a6144b976f70827c2fe2f5c89d16d8f9179d8' (2025-11-08)
• Updated input 'wsl':
    'github:nix-community/NixOS-WSL/761582d6ab431549fe1396d2cd681e3fe9376020' (2025-11-01)
  → 'github:nix-community/NixOS-WSL/e001844d4553aef268f97b32d3a825b6370eed91' (2025-11-04)
• Updated input 'wsl/flake-compat':
    'github:edolstra/flake-compat/9100a0f413b0c601e0533d1d94ffd501ce2e7885' (2025-05-12)
  → 'github:edolstra/flake-compat/f387cd2afec9419c8ee37694406ca490c3f34ee5' (2025-10-27)
2025-11-08 03:57:53 +00:00
Noah Masur 6064fdb0e0 add csvlens for viewing csvs alongside visidata 2025-11-06 20:38:45 -05:00
Noah Masur 5cf27d6d66 adjust chawan manpager to mancha 2025-11-06 20:38:23 -05:00
Noah Masur ceca1ffd5a get services to build properly again on flame 2025-11-07 00:26:00 +00:00
Noah Masur ebbc9c5a5d use yazi outside of helix and chawan as manpager 2025-11-02 18:26:40 -05:00
Noah Masur aea3e95ef5 fix build with rust-overlay 2025-11-02 18:22:56 -05:00
github-actions[bot] d79c1ba7df flake.lock: Update
Flake lock file updates:

• Updated input 'disko':
    'github:nix-community/disko/3a9450b26e69dcb6f8de6e2b07b3fc1c288d85f5' (2025-10-17)
  → 'github:nix-community/disko/6f4cf5abbe318e4cd1e879506f6eeafd83f7b998' (2025-10-31)
• Updated input 'helix':
    'github:helix-editor/helix/d79cce4e4bfc24dd204f1b294c899ed73f7e9453' (2025-10-22)
  → 'github:helix-editor/helix/5a92474bf0453715e3139eccaaccf3264bfb2001' (2025-10-31)
• Updated input 'home-manager':
    'github:nix-community/home-manager/c644cb018f9fdec55f5ac2afb4713a8c7beb757c' (2025-10-24)
  → 'github:nix-community/home-manager/4ac96eb21c101a3e5b77ba105febc5641a8959aa' (2025-10-31)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/01f116e4df6a15f4ccdffb1bcd41096869fb385c' (2025-10-22)
  → 'github:nixos/nixpkgs/08dacfca559e1d7da38f3cf05f1f45ee9bfd213c' (2025-10-28)
• Updated input 'nur':
    'github:nix-community/nur/cbe64052fb6a79ffaeba7d0b022d38d846e86334' (2025-10-25)
  → 'github:nix-community/nur/f20762096406e710b930858237046c139f03a061' (2025-11-01)
• Updated input 'wsl':
    'github:nix-community/NixOS-WSL/f98ee1de1fa36eca63c67b600f5d617e184e82ea' (2025-10-15)
  → 'github:nix-community/NixOS-WSL/761582d6ab431549fe1396d2cd681e3fe9376020' (2025-11-01)
2025-11-01 04:00:32 +00:00
Noah Masur 422131134a lower latency time on esc ctrl in kanata 2025-10-26 21:56:08 -04:00
Noah Masur 5d8e10b814 add crush coding agent to experimental 2025-10-26 21:55:24 -04:00
Noah Masur fdd5eb6418 add chawan for html in aerc 2025-10-26 21:55:14 -04:00
Noah Masur 72c548e707 update git settings renamed options 2025-10-26 12:06:48 -04:00
github-actions[bot] a57207dd5d flake.lock: Update
Flake lock file updates:

• Updated input 'darwin':
    'github:lnl7/nix-darwin/c3211fcd0c56c11ff110d346d4487b18f7365168' (2025-10-17)
  → 'github:lnl7/nix-darwin/7cd9aac79ee2924a85c211d21fafd394b06a38de' (2025-10-24)
• Updated input 'helix':
    'github:helix-editor/helix/f6f8634eb07f35f02bd2881666925a90513f6f3b' (2025-10-15)
  → 'github:helix-editor/helix/d79cce4e4bfc24dd204f1b294c899ed73f7e9453' (2025-10-22)
• Updated input 'home-manager':
    'github:nix-community/home-manager/722792af097dff5790f1a66d271a47759f477755' (2025-10-17)
  → 'github:nix-community/home-manager/c644cb018f9fdec55f5ac2afb4713a8c7beb757c' (2025-10-24)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/544961dfcce86422ba200ed9a0b00dd4b1486ec5' (2025-10-15)
  → 'github:nixos/nixpkgs/01f116e4df6a15f4ccdffb1bcd41096869fb385c' (2025-10-22)
• Updated input 'nur':
    'github:nix-community/nur/01a0d3a236b249cad7f054551671d5e77d218c40' (2025-10-18)
  → 'github:nix-community/nur/cbe64052fb6a79ffaeba7d0b022d38d846e86334' (2025-10-25)
2025-10-25 03:55:46 +00:00
github-actions[bot] 94b4217be3 flake.lock: Update
Flake lock file updates:

• Updated input 'darwin':
    'github:lnl7/nix-darwin/c48e963a5558eb1c3827d59d21c5193622a1477c' (2025-09-25)
  → 'github:lnl7/nix-darwin/c3211fcd0c56c11ff110d346d4487b18f7365168' (2025-10-17)
• Updated input 'disko':
    'github:nix-community/disko/67ff9807dd148e704baadbd4fd783b54282ca627' (2025-09-19)
  → 'github:nix-community/disko/3a9450b26e69dcb6f8de6e2b07b3fc1c288d85f5' (2025-10-17)
• Updated input 'helix':
    'github:helix-editor/helix/5b0563419eeeaf0595c848865c46be4abad246a7' (2025-10-07)
  → 'github:helix-editor/helix/f6f8634eb07f35f02bd2881666925a90513f6f3b' (2025-10-15)
• Updated input 'home-manager':
    'github:nix-community/home-manager/c4aaddeaecc09554c92518fd904e3e84b497ed09' (2025-10-12)
  → 'github:nix-community/home-manager/722792af097dff5790f1a66d271a47759f477755' (2025-10-17)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/0b4defa2584313f3b781240b29d61f6f9f7e0df3' (2025-10-09)
  → 'github:nixos/nixpkgs/544961dfcce86422ba200ed9a0b00dd4b1486ec5' (2025-10-15)
• Updated input 'nur':
    'github:nix-community/nur/a82226091501c0ee01e7fb55b8f357afe0faa392' (2025-10-12)
  → 'github:nix-community/nur/01a0d3a236b249cad7f054551671d5e77d218c40' (2025-10-18)
• Updated input 'wsl':
    'github:nix-community/NixOS-WSL/7c0c0f4c3a51761434f18209fa9499b8579ff730' (2025-10-07)
  → 'github:nix-community/NixOS-WSL/f98ee1de1fa36eca63c67b600f5d617e184e82ea' (2025-10-15)
2025-10-18 03:52:46 +00:00
Noah Masur 7619ac6ea2 enable cargo for work and home 2025-10-13 13:39:48 -04:00
Noah Masur 7543721020 launch helix for editing desktop text files 2025-10-13 13:06:42 -04:00
Noah Masur bf52069886 temp override to build awscli2 2025-10-12 18:57:40 +00:00
Noah Masur 839ca079c2 Merge branch 'caddy-cloudflare-pkg' 2025-10-12 17:26:05 +00:00
github-actions[bot] 85f09b1126 flake.lock: Update
Flake lock file updates:

• Updated input 'helix':
    'github:helix-editor/helix/bfcbef10c513108c7b43317569416c2eefc4ed44' (2025-09-30)
  → 'github:helix-editor/helix/5b0563419eeeaf0595c848865c46be4abad246a7' (2025-10-07)
• Updated input 'helix/rust-overlay':
    'github:oxalica/rust-overlay/d342e8b5fd88421ff982f383c853f0fc78a847ab' (2025-02-27)
  → 'github:oxalica/rust-overlay/1d7cbdaad90f8a5255a89a6eddd8af24dc89cafe' (2025-10-05)
• Updated input 'home-manager':
    'github:nix-community/home-manager/edafd6da1936426708f1be0b1a4288007f16639a' (2025-10-04)
  → 'github:nix-community/home-manager/d305eece827a3fe317a2d70138f53feccaf890a1' (2025-10-10)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/7df7ff7d8e00218376575f0acdcc5d66741351ee' (2025-10-02)
  → 'github:nixos/nixpkgs/0b4defa2584313f3b781240b29d61f6f9f7e0df3' (2025-10-09)
• Updated input 'nur':
    'github:nix-community/nur/d127643d50ec16f47ca67c9695b0200ea8b7cfd1' (2025-10-04)
  → 'github:nix-community/nur/886a5646695563cbae3c1e10369c6070c7645e73' (2025-10-11)
• Updated input 'wsl':
    'github:nix-community/NixOS-WSL/d96dda76c1f1827634ddf28d386feabd2d135d21' (2025-10-01)
  → 'github:nix-community/NixOS-WSL/7c0c0f4c3a51761434f18209fa9499b8579ff730' (2025-10-07)
2025-10-11 03:51:41 +00:00
github-actions[bot] 29c7a27135 flake.lock: Update
Flake lock file updates:

• Updated input 'helix':
    'github:helix-editor/helix/109c812233e442addccf1739dec4406248bd3244' (2025-09-25)
  → 'github:helix-editor/helix/bfcbef10c513108c7b43317569416c2eefc4ed44' (2025-09-30)
• Updated input 'home-manager':
    'github:nix-community/home-manager/bc2afee55bc5d3b825287829d6592b9cc1405aad' (2025-09-26)
  → 'github:nix-community/home-manager/edafd6da1936426708f1be0b1a4288007f16639a' (2025-10-04)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/e643668fd71b949c53f8626614b21ff71a07379d' (2025-09-24)
  → 'github:nixos/nixpkgs/7df7ff7d8e00218376575f0acdcc5d66741351ee' (2025-10-02)
• Updated input 'nur':
    'github:nix-community/nur/c898a1ed2da0164bc6f395f44aad52edb84c84d4' (2025-09-27)
  → 'github:nix-community/nur/d127643d50ec16f47ca67c9695b0200ea8b7cfd1' (2025-10-04)
• Updated input 'wsl':
    'github:nix-community/NixOS-WSL/1bfb978f2f6261b6086e04af17f9418e1fe36d70' (2025-09-25)
  → 'github:nix-community/NixOS-WSL/d96dda76c1f1827634ddf28d386feabd2d135d21' (2025-10-01)
2025-10-04 03:49:26 +00:00
github-actions[bot] 3523f20665 flake.lock: Update
Flake lock file updates:

• Updated input 'darwin':
    'github:lnl7/nix-darwin/8df64f819698c1fee0c2969696f54a843b2231e8' (2025-08-22)
  → 'github:lnl7/nix-darwin/c48e963a5558eb1c3827d59d21c5193622a1477c' (2025-09-25)
• Updated input 'disko':
    'github:nix-community/disko/bafad29f89e83b2d861b493aa23034ea16595560' (2025-08-25)
  → 'github:nix-community/disko/67ff9807dd148e704baadbd4fd783b54282ca627' (2025-09-19)
• Updated input 'helix':
    'github:helix-editor/helix/77ff51caa440b1066e0a1920007ab5e148dd4856' (2025-08-29)
  → 'github:helix-editor/helix/109c812233e442addccf1739dec4406248bd3244' (2025-09-25)
• Updated input 'home-manager':
    'github:nix-community/home-manager/77a71380c38fb2a440b4b5881bbc839f6230e1cb' (2025-08-29)
  → 'github:nix-community/home-manager/bc2afee55bc5d3b825287829d6592b9cc1405aad' (2025-09-26)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/dfb2f12e899db4876308eba6d93455ab7da304cd' (2025-08-28)
  → 'github:nixos/nixpkgs/e643668fd71b949c53f8626614b21ff71a07379d' (2025-09-24)
• Updated input 'nur':
    'github:nix-community/nur/e82a8b0095f54edb6bbbb1d862f3da502dca1396' (2025-08-30)
  → 'github:nix-community/nur/c898a1ed2da0164bc6f395f44aad52edb84c84d4' (2025-09-27)
• Updated input 'wsl':
    'github:nix-community/NixOS-WSL/203a7b463f307c60026136dd1191d9001c43457f' (2025-08-15)
  → 'github:nix-community/NixOS-WSL/1bfb978f2f6261b6086e04af17f9418e1fe36d70' (2025-09-25)
2025-09-27 03:51:21 +00:00
142 changed files with 4456 additions and 850 deletions
+13
View File
@@ -0,0 +1,13 @@
{
"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 *)"
]
}
}
+198
View File
@@ -0,0 +1,198 @@
# Changelog
## 2026-09-06
- **Configured OpenID Connect (OIDC) authentication for Immich**:
- Configured `services.immich.settings.oauth` with OIDC settings pointing to Pocket ID (`auth.masu.rs`), using client ID `1f4e0f8d-6cee-4d67-8d53-74bf6c18ae09`.
- Added secret management for `immich-oidc-secret.age` via `secrets.immich-oidc-secret` with owner `immich` and group `shared` (0440).
- Wired client secret substitution using NixOS's native `clientSecret._secret = config.secrets.immich-oidc-secret.dest`, leveraging `utils.genJqSecretsReplacement` with systemd `LoadCredential`.
- Configured `systemd.services.immich-server` to order after `immich-oidc-secret-secret.service`.
- Updated `docs/oidc-services.md` with the verified configuration and redirect URIs.
- **Fixed OpenSSH authorized principals certificate authentication for Cloudflare Tunnel**:
- Replaced manual `environment.etc."ssh/authorized_principals/${username}"` symlink and `Match User` config with NixOS native `users.users.<name>.openssh.authorizedPrincipals`.
- Root cause: `environment.etc` without an explicit `mode` creates symlinks pointing into `/nix/store`, which has group-writable mode `0775` (`nixbld` group). Under `StrictModes yes`, sshd refused authentication with `bad ownership or modes for directory /nix/store`, causing certificate principal matching to fail with `Certificate does not contain an authorized principal`.
- Setting `users.users.<name>.openssh.authorizedPrincipals` causes NixOS to generate `/etc/ssh/authorized_principals.d/<name>` with `mode = "0444"`, copying the file instead of symlinking into the store, and automatically configuring `services.openssh.settings.AuthorizedPrincipalsFile = "/etc/ssh/authorized_principals.d/%u"`.
- Also added `mode = "0444"` to `/etc/ssh/ca.pub` and moved `TrustedUserCAKeys` into `services.openssh.settings`.
- **Configured OpenID Connect (OIDC) authentication for Mealie**:
- Configured `services.mealie.settings` with OIDC settings pointing to Pocket ID (`auth.masu.rs`), using client ID `040925ed-b39e-4442-b8e8-369c948c0cd2`.
- Added secret management for `mealie-oidc-secret.age` via `secrets.mealie-oidc-secret`, using `prefix = "OIDC_CLIENT_SECRET="` to generate an environment file.
- Configured `services.mealie.credentialsFile` to load the client secret via systemd's `EnvironmentFile` without exposing it in the world-readable Nix store or systemd unit file.
- Configured `systemd.services.mealie` to order after `mealie-oidc-secret-secret.service`.
- Updated `docs/oidc-services.md` with the verified configuration and callback URI (`https://cooking.masu.rs/login`).
- **Configured OpenID Connect (OIDC) authentication for Actual Budget**:
- Configured `services.actual.settings` with `loginMethod = "openid"` and `openId` settings pointing to Pocket ID (`auth.masu.rs`), using client ID `92afe9f8-7ef6-42ab-8a06-701df3c7179d`.
- Added secret management for `actualbudget-oidc-secret.age` via `secrets.actualbudget-oidc-secret`, set with owner `actualbudget` and group `shared` (0440).
- Configured `systemd.services.actual` to order after the decrypted secret service and granted the dynamic unit access via `SupplementaryGroups = [ "shared" ]` and `PrivateUsers = false`.
- Updated `docs/oidc-services.md` with the verified callback URI (`https://money.masu.rs/openid/callback`) and NixOS configuration snippet.
## 2026-09-03: Ctrl-b did nothing because home-manager was never switched; two-phase toggle
- "Ctrl-b does nothing" root cause: the binding was built into the flake but never activated. The deployed `~/.config/fish/functions/` had no `heal-autosuggest.fish` and no `\cb` binding (0 matches), while the freshly-built config had both. On this setup a system rebuild does not switch home-manager — activation needs the home rebuild (`rebuild-home` / the Alt-Shift-H binding, i.e. `home-manager switch --flake`) followed by a fresh pane so `config.fish` re-runs `fish_user_key_bindings`. No fix works until it is actually activated; this should be the FIRST check next time a "did nothing" is reported.
- Made `heal-autosuggest` a two-phase toggle (chosen by the user over `exec fish`, to preserve the session): disable autosuggestions, `commandline -f repaint`, re-enable, `commandline -f repaint`. Grounded in `reader.rs` `update_autosuggestion`, which clears the wedged `in_flight_autosuggest_request` only on a repaint taken while autosuggestions are disabled. The old one-liner and the `fish_postexec` hook did a single back-to-back `set 0; set 1` with no disabled-state repaint, which likely never flushed the stuck request — matching the manual cure, which had prompt cycles between the off and the on. Still unverified against the real bug (not reproducible in a harness); confirm by activating, then pressing Ctrl-b in a live lagging shell.
- If the two-phase toggle still does not cure once activated: fall back to `exec fish` on the key (guaranteed per the user's day-one report that a fresh shell always fixes it), and capture a flight-recorder log for the upstream fish report.
## 2026-09-01: postexec hook fires but does not cure — moved heal to a keybinding
- Honest status: the `fish_postexec` self-heal hook IS registered and DOES fire (verified in the real config), yet the lag persists. So toggling `fish_autosuggestion_enabled` off/on from `fish_postexec` does not cure it, even though the user typing the same `set … 0; set … 1` at the prompt does.
- Why (code-level): variable dispatch is synchronous (`env_dispatch.rs``reader_set_autosuggestion_enabled` on every `set`), so the two sets net to no change and schedule a repaint. That repaint only has effect from inside the reader's active input loop. `fish_postexec` runs BETWEEN commands, outside that loop, so its effect is superseded before the next prompt. A key binding runs inside the loop; `fish_postexec` cannot.
- Change: bound **Ctrl-b** to a new `heal-autosuggest` function (toggle + `commandline -f repaint`) via `fish_user_key_bindings` (Ctrl-g was already taken). Verified that when `fish_user_key_bindings` runs to completion — as it does in the real config, since the existing `\cn` etc. work (`__fish_config_interactive.fish:105`) — `\cb` binds to heal-autosuggest and the toggle resets the variable. NOT verified to cure the real lag: the bug still cannot be reproduced in a harness, so only a test in a live lagging shell can confirm. The `fish_postexec`/`fish_cancel` hook is kept (harmless) but is no longer considered the fix.
- Guaranteed fallback if Ctrl-b does not cure: a fresh shell (`exec fish`), which the user has confirmed from the very start always fixes it — Ctrl-b can be rebound to that. The only path to a truly automatic fix is a flight-recorder capture (`~/.local/state/lag-triage/RECORD`) of the reader during an actual episode, then an upstream fish report.
## 2026-08-31 (evening): self-heal hook was never firing — fish cannot autoload event handlers
- The `__autosuggestion_unwedge` hook did not work because it was installed via `programs.fish.functions`, which writes to fish's **autoload** directory — and fish only registers `--on-event` handlers when a function is actually loaded, which never happens for a hook nothing calls by name. Verified in a PTY test: the autoloaded handler never fires; the identical definition `source`d eagerly fires immediately. (The zellij module's `__fish_update_cwd_osc` works as an autoloaded event function only because it overrides a function fish itself loads.)
- Meanwhile the user confirmed the instant back-to-back toggle (`set -g fish_autosuggestion_enabled 0 && set -g fish_autosuggestion_enabled 1`) cures a lagging shell — so the handler body is right; only its registration was broken.
- Fix: the handler is now defined eagerly in `config.fish` via `programs.fish.interactiveShellInit` (lag-triage module), registered on **fish_postexec** (fires after every command — the moment TUIs exit) and **fish_cancel** (fires on Ctrl-C at the prompt), so a bare Ctrl-C is an instant no-command cure. Verified in an interactive PTY against the actual nix-generated snippet: registers at startup, fires on both events, still respects a deliberate manual disable.
- Coverage note: if a wedge forms with no command running (and no Ctrl-C), it heals at the next command; worst-case lag window is "until you run anything or press Ctrl-C".
## 2026-08-31 (later): automatic self-heal hook
- Confirmed by A/B in the live shell: after curing the lag with `set -g fish_autosuggestion_enabled 0`, re-enabling with `1` does **not** bring the lag back — the toggle resets the wedged autosuggestion state rather than merely masking it.
- Added `__autosuggestion_unwedge` (lag-triage module): a `fish_postexec` event handler that toggles `fish_autosuggestion_enabled` off/on after every command — i.e. at the exact moment a TUI has just exited, when the wedge forms. Builtins only, no visible output (verified in an interactive PTY test), and it skips the reset when the user has deliberately disabled autosuggestions.
- Honest caveat: the manual cure had keystrokes between the off and the on; whether the instant off/on inside an event handler resets the same reader-internal state is unproven. The flight recorder therefore STAYS ARMED (`~/.local/state/lag-triage/RECORD`) until the hook has survived normal use for a while. If lag recurs despite the hook: cure manually (`set … 0`, type a few chars, `set … 1`), and keep the flight log for that pid — then the hook needs the stronger form (disable at postexec, re-enable one prompt-cycle later, scoped to TUI commands).
- Limitations by design: the hook fires only in shells that run commands, so a wedge formed without any command executing in that shell (if that is possible — e.g. floating-pane TUIs never touch the pane shell) would not be healed until the next command runs there.
## 2026-08-31: culprit confirmed — fish's autosuggestion pipeline
- A/B test in a live lagging shell (pid 56089): `set -g fish_autosuggestion_enabled 0` (builtin only, nothing else) **instantly cured the lag**. The post-TUI typing lag is in fish 4.8.1's autosuggestion pipeline.
- Sampling that shell afterwards showed it had **only one thread** (the main thread): the poisoned state is main-thread-side bookkeeping, not a hung worker still sitting in the process. Source review (`src/threads/threads.rs`, `src/threads/debounce.rs`): `ThreadPool::perform` silently queues work with no spawn and no wake when it believes `total_threads == max_threads` — a leaked `total_threads` count (workers that died without decrementing, e.g. across a TUI's lifetime) would strand all future autosuggestion work forever; the Debounce then abandons its token every 500ms and re-enqueues per keystroke. The exact step that delays keystroke *echo* is still unproven — the flight recorder (armed via `~/.local/state/lag-triage/RECORD`) logs the reader's per-keystroke behavior and will capture it on the next occurrence in a recorded shell.
- Precedent: fish had a closely-related bug class before (#11841 — unread terminal query responses "causing noticeable lags"). No fish release newer than 4.8.1 exists, so no upstream fix to adopt; an upstream report with the flight-recorder capture is the path to a real fix.
- Practical interim cure (harmless, instant, in the lagging shell): `set -g fish_autosuggestion_enabled 0`, and re-enable with `1` — whether lag returns on re-enable is the next discriminating datum.
## 2026-08-30 (later): sampler attach CURES the lag — wedged-thread evidence + flight recorder
- Major new datum: in a lagging shell, running `mkdir` + `/usr/bin/sample $fish_pid … &` + `disown` **cured the lag instantly**, before any planned reset/toggle test could run. Plain external commands do NOT cure it (the 2026-08-29 triage ran many and the lag survived), so the distinguishing action is the sampler **attaching and suspending/resuming fish's threads**. Conclusion: a fish-internal thread/wait is wedged (missed wakeup or stuck blocking wait), and per-keystroke work at the main commandline stalls against it; suspension/resume kicks it loose. Consistent with: `read` prompts unaffected (no autosuggestion/highlight pipeline), subshells immune (fresh threads), raw input clean. The captured sample (`~/.local/state/lag-triage/fish-sample.txt`) shows only the post-cure state — sampling is a cure, not a capture.
- Therefore the observer must be running BEFORE the lag starts: the `fish-no-query-term` wrapper is now a **flight recorder**`touch ~/.local/state/lag-triage/RECORD`, then every newly spawned pane shell logs `FISH_DEBUG=reader,term-support,proc-termowner,iothread,fd-monitor,topic-monitor` to `~/.local/state/lag-triage/flight/fish-<ts>-<pid>.log` (3-day auto-cleanup; remove RECORD to disable, zero overhead when off). When lag next occurs, the log already contains what each keystroke did during the lag.
- `lag-sample` now takes a PID and should be run from a DIFFERENT pane (`echo $fish_pid` — a builtin — in the lagging shell to get it), since attaching from inside cures the lag.
- **Next-occurrence checklist (in order, least perturbing first):** (1) in the lagging shell, builtins only: `set -g fish_autosuggestion_enabled 0` → type at the real commandline; if cured, the autosuggestion/debounce path is implicated (a worker thread was seen in `HistorySearch::go_to_next_match`); (2) still laggy: `fish_default_key_bindings` → test (vi-mode path); (3) from another pane: `kill -WINCH <pid>` → test, then `kill -CONT <pid>` → test (discriminates reader-wakeup vs generic unwedge; if WINCH cures, a window resize would too); (4) from another pane: `lag-sample <pid>` while typing in the lagging pane; (5) immediately save the flight log for that pid.
## 2026-08-30
- **The post-TUI typing lag is NOT resolved** by the `fish-no-query-term` wrapper: lag recurred in a fresh zellij session after exiting Claude Code, in a shell verified (via `ps eww`) to have `fish_features=no-query-term` in its environment. The query-term reader-degradation bug proven on 2026-08-29 is real (and the wrapper stays as hardening against it), but it is not the mechanism behind this lag. Downgraded the entry below from "root cause" to "a root cause".
- Known constraints on the real mechanism: per-keystroke lag at the main fish commandline; fish `read` prompts unaffected; raw input reaches the pane practical as plain bytes; a subshell/`exec fish` cures it (process-local state). Note the 2026-08-29 triage's reset ladder short-circuited on a false "y" at stage A, so stages BG (mouse/keypad/altscreen/stty/DECSTR resets) were never actually tested against real lag.
- Added `lag-sample` (fish function): stack-samples the lagging fish process plus the zellij server/client via `/usr/bin/sample` for 8s while the user types at the commandline. This directly names where the time goes (fish reader? highlighting/autosuggestion threads? zellij render loop?) instead of inferring it. Next occurrence: run `lag-sample` in the lagging shell, type junk at the prompt until done, then inspect `~/.local/state/lag-triage/sample-*.txt`. Follow with `unlag` (full reset ladder, never yet truly tested), then A/B toggles: `set -g fish_autosuggestion_enabled 0`, `fish_default_key_bindings`.
## 2026-08-29 (a root cause found and fixed — but not THE lag)
- **Root-caused and fixed the recurring post-TUI typing lag** (fish + Zellij + Ghostty) using a `lag-triage` capture from a live lagging shell plus a deterministic PTY reproduction (`presets/programs/lag-triage/upstream_repro.py`):
- **Root cause chain**: (1) fish latches feature flags from its **startup environment**, before `config.fish` runs — so the existing `set -gx fish_features no-query-term` in `shellInit` never applied to the shell that set it, only to its children. (2) Zellij spawns pane shells via `default_shell` with no `fish_features` in the environment, so every pane's fish latched `query-term` **on** (the fish 4.8.1 default; the triage log from the lagging shell confirmed `query-term on` while `$fish_features` was correctly set to `no-query-term`). (3) With query-term on, fish sends OSC 11 + CPR (`\e[6n`) + DA1 (`\e[0c`) after **every** command and waits for replies relayed by Zellij. (4) Reproduced on fish 4.8.1: if the terminal fails to reply during just **one** such cycle — answering everything before and after — that fish process's interactive reader is **permanently degraded** (keystroke echo >3s, never recovers; ~35ms before). In production Zellij drops/mangles a relay during TUI teardown or heavy output (cf. zellij-org/zellij#5158), e.g. after `nh home switch`, nvim, jjui, yazi.
- **Why every previous observation finally makes sense**: subshells and `exec fish` were never "resetting" anything — they *inherited* the exported `fish_features=no-query-term` from config.fish, latched query-term off at startup, and were therefore **immune**. The parent zellij-spawned shell never had the variable at startup and stayed vulnerable. Raw keystroke capture in the lagging pane showed instant plain bytes (input path fine) and no stuck terminal modes — the damage was inside the fish process, exactly as the repro shows.
- **Fix**: `zellij.nix` now spawns panes through a `fish-no-query-term` wrapper (`export fish_features=no-query-term; exec fish`), so the feature is latched off in every pane shell. Verified: interactive fish through the built wrapper with the real config reports `query-term off`; the PTY repro with `no-query-term` in the environment shows ~35ms echo through all failure phases.
- **Correction** to the earlier 2026-08-29 entry: `query-term` does **not** default to off in fish 4.8.1 — it defaults on; it only *appeared* off in non-interactive checks because the user config's `set -gx` takes effect for `fish -c` (no reader latch) but not for interactive shells.
- Upstream: fish-shell should bound the reader's wait for query replies instead of degrading permanently (repro script kept at `presets/programs/lag-triage/upstream_repro.py` for filing); Zellij's reply relaying is the trigger (zellij-org/zellij#5158).
- `lag-triage` now checks `status features` and calls out `query-term on` as the known root cause, and warns that its `read`-prompt typing tests may not exhibit main-commandline lag (which produced a false "fixed by stage A" in the first capture).
## 2026-08-29 (later)
- Added a diagnostic toolkit (`lag-triage` / `unlag` fish functions + `term-probe` binary, `presets/programs/lag-triage/`) for the still-recurring post-TUI typing lag in fish + Zellij + Ghostty, instead of another blind fix. Findings that motivated it:
- All three prior fixes were either no-ops or insufficient: `fish_features = no-query-term` is a **no-op** because `query-term` already defaults to *off* in fish 4.8.1 (verified with `status features`); disabling Ghostty's fish integration inside Zellij and setting `support_kitty_keyboard_protocol = false` did not stop recurrence.
- PTY captures of fish 4.8.1 (`TERM=xterm-256color`, with and without `$ZELLIJ`) show fish never writes Kitty keyboard sequences to the wire — it uses modifyOtherKeys (`\e[>4;1m`), application keypad (`\e=`), bracketed paste (`?2004`), and color-theme reporting (`?2031`), enabling them at every prompt and disabling them before every external command. Crucially, a fresh subshell's startup bytes are identical to the parent's post-command re-enable bytes, so "a subshell fixes the lag" cannot be explained by a simple terminal-state reset — leaving two competing hypotheses that only live capture can separate: (1) fish-internal reader state poisoned by stray/partial escape bytes (e.g. leaked from a closing floating pane), cleared only by a new fish process; (2) Zellij/Ghostty-level stuck state (Zellij 0.45's `StdinAnsiParser` is already a proven source of input delays — see the Alt-Shift-P fix below).
- Also note: the floating-pane TUIs (jjui via Alt-Shift-J, yazi via Alt-Shift-Y, scrollback editor) run in their own panes and never pass through the shell's fish process at all, while `nvim` runs inside the shell pane — the triage log records which path preceded the lag.
- **Next occurrence: run `lag-triage` in the lagging shell BEFORE starting a new shell.** It snapshots the environment, queries pane terminal state (kitty flags, modifyOtherKeys, DEC modes, DA1 round-trip latency), captures raw keystroke bytes+timing bypassing fish, then applies staged resets (kitty pop/clear, modifyOtherKeys off, keypad/cursor, mouse/focus/sync, altscreen, stty, DECSTR) — the stage that cures it names the stuck layer. Logs to `~/.local/state/lag-triage/` for an upstream issue. `unlag` is the one-shot convenience version (if `unlag` never helps but `exec fish` does, the bug is fish-internal).
## 2026-08-29
- Fixed 1.5-second latency when pressing `Alt-Shift-P` to trigger `zellij-session` in Zellij 0.45.0 + Ghostty:
- **Root Cause**: Zellij 0.45.0 introduced `StdinAnsiParser` (`zellij-client/src/stdin_ansi_parser.rs`) using `termwiz::InputParser` to parse ANSI control strings (OSCs, CSIs, DCSs) arriving on stdin. When pressing `Alt-Shift-P` (Option-Shift-P) with `support_kitty_keyboard_protocol = false`, Ghostty sent `\x1bP` (`ESC` + uppercase `P`). In ECMA-48 / VT100 standards, `ESC P` is the 7-bit ASCII representation of `DCS` (Device Control String). `StdinAnsiParser` buffered `\x1bP` waiting for a DCS string payload and string terminator (`ST` / `\x1b\`), hitting a ~1.5-second escape timeout before flushing `\x1bP` as residue to the keyboard handler.
- **Fix**: Added `alt+shift+p=text:\x1b[112;4u` and `super+shift+p=text:\x1b[112;4u` in `ghostty.nix` to send the explicit CSI-u sequence for `Alt+Shift+p` (`'p'` with modifier 4 = `ALT | SHIFT`). `StdinAnsiParser` immediately recognizes `\x1b[112;4u` as non-DCS input and passes it straight to the keyboard handler with 0ms latency.
## 2026-08-26
- Fixed macOS shortcuts (`Cmd+T`, `Ctrl+Tab`, `Cmd+Shift+]`, `Cmd+Shift+[`, `Cmd+K`, `Cmd+Shift+E`) in Zellij + Ghostty after disabling the Kitty keyboard protocol:
- Mapped Ghostty keybindings (`super+t`, `super+shift+]`, `super+shift+[`, `ctrl+tab`, `ctrl+shift+tab`, `super+k`, `super+shift+e`) to send standard `Alt` (`ESC`-prefix) text sequences (`\x1bt`, `\x1b}`, `\x1b{`, `\x1bK`, `\x1bE`).
- Added matching `Alt` keybindings (`Alt t`, `Alt ]`, `Alt }`, `Alt [`, `Alt {`, `Alt Shift k`, `Alt Shift e`) in `zellij.nix` for tab creation, tab navigation, scroll mode, and scrollback editing. Symbols like `]` and `}` are parsed by Zellij's termwiz input engine as distinct character codes (`'}'` vs `']'`), so binding both `Alt }` and `Alt Shift ]` ensures `\x1b}` triggers tab navigation correctly.
- Keeps Kitty keyboard protocol disabled in Zellij (`support_kitty_keyboard_protocol = false`) so no CSI-u flags leak into Fish shell, guaranteeing zero post-TUI typing lag while restoring all shortcuts.
- Fixed persistent Fish typing lag after long TUI sessions (Neovim, jjui, Yazi) inside Zellij + Ghostty, which the `no-query-term` / Ghostty-integration fixes from 2026-08-25 did not resolve:
- Verified on Fish 4.8.1 that the `query-term` feature already defaults to `off`, so exporting `fish_features = no-query-term` is a no-op on this Fish version — it isn't the cause of (or fix for) this class of lag.
- Set `support_kitty_keyboard_protocol = false` in `zellij.nix`. Zellij and Ghostty have several open upstream bugs (zellij-org/zellij#3887, #3723, #4178) where the Kitty keyboard protocol's enhancement-flag stack is left in an elevated state after a full-screen TUI exits without properly popping it. Every subsequent keystroke then arrives as a CSI-u sequence that Fish must wait out an escape-disambiguation timeout to parse, which reads as typing lag that worsens the longer the TUI session ran, and persists until the pane's protocol state resets (e.g. a fresh shell/pane). Disabling the protocol support in Zellij avoids the whole bug class; trades off precise modifier reporting (e.g. distinguishing Ctrl+Shift+key) for TUIs running inside Zellij panes, which this setup doesn't otherwise depend on (Shift+Enter is handled via a literal Ghostty `text:` keybind, not the Kitty protocol).
## 2026-08-25
- Fixed Nix evaluation warnings for `stdenv` deprecation and `gemini-cli`:
- Replaced deprecated `stdenv.isLinux` and `stdenv.isDarwin` checks across module presets and package definitions with `stdenv.hostPlatform.isLinux` and `stdenv.hostPlatform.isDarwin`.
- Replaced deprecated `pkgs.gemini-cli` with `pkgs.antigravity-cli` (and updated binary invocation to `agy`) in `experimental.nix` profile and `daily-summary.nix` launchd service.
## 2026-08-25
- Fixed multi-second hang and permanent typing latency in Fish after exiting TUIs inside Zellij and Ghostty:
- Exported `fish_features = "no-query-term"` in `home.sessionVariables` and added `set -gx fish_features no-query-term` to Fish's top-level `shellInit`. Previous attempt (`set -a fish_features no-query-term` in `interactiveShellInit`) set a local variable inside an anonymous initialization function block that went out of scope immediately after startup. Furthermore, Fish reads `fish_features` at binary launch before interactive init functions run. Without `no-query-term` exported prior to Fish startup, Fish attempted terminal feature queries (Primary Device Attributes `DA1` / `\e[?c` and termcap) whenever a TUI (e.g. Neovim, Lazygit, Yazi) exited and returned control to Fish. Zellij drops or delays DA1 response sequences, causing Fish to block on a multi-second stdin timeout, followed by severe input reader desynchronization and typing latency on every subsequent keystroke.
- Disabled `programs.ghostty.enableFishIntegration` and conditionally sourced Ghostty's shell integration script in `shellInit` only when NOT running inside a multiplexer (`not set -q ZELLIJ` and `not set -q TMUX`). Sourcing Ghostty's shell integration inside Zellij sent duplicate and conflicting OSC 133 prompt markers and DECSCUSR cursor escape sequences to Zellij's PTY parser.
## 2026-08-16
- Fixed Zellij new tab directory tracking by adding `__fish_update_cwd_osc` override in `presets/programs/zellij.nix`. Fish's default OSC 7 sequence includes `$hostname`, which on macOS or dynamic network environments evaluates to `Noah-MacBook-Pro.local` or a domain suffix. Zellij compares the OSC 7 hostname against its system hostname (`Noah-MacBook-Pro`), finds a mismatch, and silently ignores the CWD update, leaving new tabs stuck in a previous directory or session default. Overriding `__fish_update_cwd_osc` to send `file://<PWD>` (empty hostname) ensures Zellij always updates its cached CWD on every `cd` and prompt render.
- Fixed Firefox "profile cannot be loaded" error on macOS by removing `home.file."Library/Application Support/Firefox/installs.ini"`. Hardcoding an installation hash in `installs.ini` broke whenever Firefox was updated or rebuilt in the Nix store because the nix store path changed, causing Firefox to compute a new installation hash, fail to match or write to the read-only `installs.ini` symlink, and error out. Firefox on macOS uses `profiles.ini` (managed by Home Manager) and `MOZ_LEGACY_PROFILES=1` (exported by nixpkgs' launcher wrapper).
## 2026-08-03
- Added `presets/security/corporate-ca.nix` (nix-darwin) and enabled it on the
`lookingglass` host to trust a corporate TLS-intercepting proxy's root CA.
Behind the corp network, Nix fetches failed with `SSL peer certificate ...
self-signed certificate in certificate chain (19)` because Nix's stock Mozilla
CA bundle doesn't contain the interception root. The module appends the cert
to `security.pki.certificateFiles`, which rebuilds
`/etc/ssl/certs/ca-certificates.crt` (read by both the Nix daemon and, via
`NIX_SSL_CERT_FILE`, client-side flake fetches).
The cert is kept **out of this public repo** and referenced by absolute path.
It is passed as a string (not a Nix path literal) so pure flake evaluation
doesn't read it at eval time, and it lives at a root-owned, world-readable
path because the unprivileged `nixbld` build user cannot traverse `$HOME`
(mode `0750`) to read it at build time.
One-time setup on a machine behind the proxy:
```sh
# 1. Extract the self-signed corporate root from any TLS connection it MITMs
# (the last cert in the chain, subject == issuer). Any HTTPS host works:
echo | openssl s_client -connect example.com:443 -servername example.com \
-showcerts 2>/dev/null \
| awk '/BEGIN CERT/{c++} c==2' > /tmp/CorpCA.pem
openssl x509 -in /tmp/CorpCA.pem -noout -subject -issuer # sanity check
# 2. Install to the root-owned path the config points at:
sudo install -d -m 0755 -o root -g wheel /etc/ssl/corp-ca
sudo install -m 0644 -o root -g wheel /tmp/CorpCA.pem \
/etc/ssl/corp-ca/CorpCA.pem
# 3. Bootstrap the first rebuild (which must fetch inputs over the proxy)
# with a combined bundle, then it's permanent:
cat /etc/ssl/certs/ca-certificates.crt /etc/ssl/corp-ca/CorpCA.pem \
> /tmp/combined-ca.crt
NIX_SSL_CERT_FILE=/tmp/combined-ca.crt nh darwin switch . --configuration lookingglass
```
- Fixed the `zellij-session` fish function in `presets/programs/zellij.nix`
truncating the session name (derived from the target directory basename)
to 20 characters. Zellij names each session's Unix-domain IPC socket
`$TMPDIR/zellij-<uid>/<version>/<name>`, and on macOS the socket path is
capped at 103 bytes. The `/var/folders/...` `$TMPDIR` prefix consumes ~79
of those, leaving only ~24 chars for the name, so switching into directories
with long basenames overflowed the socket path. Because `switch-session`
had already detached from the current session by the time the new one failed
to bind, the failure took down the entire terminal instead of erroring
gracefully.
## 2026-09-06
- Configured Grafana OIDC authentication via Pocket ID in `platforms/nixos/modules/nmasur/presets/services/grafana/grafana.nix`.
- Enabled `auth.oauth_allow_insecure_email_lookup = true` in Grafana settings to allow linking an incoming OAuth login to an existing Grafana user account with the same email.
## 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.
+247
View File
@@ -0,0 +1,247 @@
# OIDC Service Analysis & Setup Requirements
This document analyzes the services defined in this repository (specifically within `platforms/nixos/modules/nmasur/presets/services/` and related server profiles like `flame` and `swan`), evaluates their OpenID Connect (OIDC) compatibility, and details the requirements for configuring OIDC logins.
---
## Identity Provider Context: Pocket ID
The configuration already includes a central self-hosted identity provider: **Pocket ID** (`platforms/nixos/modules/nmasur/presets/services/pocket-id/pocket-id.nix`), hosted on the communications server (`flame`) behind Caddy at **`https://auth.masu.rs`**.
Pocket ID is an OpenID Connect (OIDC) provider with WebAuthn/Passkey support. It exposes the following standard OIDC endpoints:
- **Issuer URL:** `https://auth.masu.rs`
- **Discovery Endpoint:** `https://auth.masu.rs/.well-known/openid-configuration`
- **Authorization Endpoint:** `https://auth.masu.rs/authorize`
- **Token Endpoint:** `https://auth.masu.rs/api/oidc/token`
- **Userinfo Endpoint:** `https://auth.masu.rs/api/oidc/userinfo`
- **JWKS Endpoint:** `https://auth.masu.rs/.well-known/jwks.json`
---
## 1. Service Compatibility Breakdown
### Tier 1: First-Class / Native OIDC Support
These services support OpenID Connect natively without requiring external authentication proxies or custom code:
| Service | Hostname | OIDC Support Level | Configuration Method |
| :--- | :--- | :--- | :--- |
| **Immich** | `photos.masu.rs` | Native core feature | NixOS config (`services.immich.settings.oauth`) |
| **Gitea** | `git.masu.rs` | Native core feature | NixOS config / CLI or Web UI |
| **Nextcloud** | `cloud.masu.rs` | Native (official `user_oidc` app) | Nextcloud app + `nextcloud-occ user_oidc:provider` |
| **Grafana** | `metrics.masu.rs` | Native (Generic OAuth) | NixOS config (`services.grafana.settings."auth.generic_oauth"`) |
| **Paperless-ngx** | `paper.masu.rs` | Native (`django-allauth`) | NixOS env vars (`PAPERLESS_SOCIALACCOUNT_PROVIDERS`) |
| **Mealie** | `cooking.masu.rs` | Native core feature | NixOS config (`services.mealie.settings` + `credentialsFile`) |
| **Karakeep / Hoarder** | `keep.masu.rs` | Native (NextAuth OIDC) | NixOS env vars (`OAUTH_WELLKNOWN_URL`, etc.) |
| **Audiobookshelf** | `read.masu.rs` | Native core feature (v2.3+) | Web UI (Settings → Authentication) |
| **Actual Budget** | `money.masu.rs` | Native core feature (v24.3+) | NixOS config (`services.actual.settings.openId`) |
---
### Tier 2: OIDC via Plugins or Reverse Proxy Header Auth
These services do not have generic OIDC in their core web UI, but can support single sign-on through plugins or reverse proxy headers (`Remote-User` / `X-Forwarded-User`):
| Service | Hostname | Strategy | Notes |
| :--- | :--- | :--- | :--- |
| **Jellyfin** | `stream.masu.rs` | `jellyfin-plugin-sso` | Web clients work well; TV and native apps typically rely on Quick Connect. |
| **Calibre-Web** | `books.masu.rs` | Reverse proxy header auth | Set `services.calibre-web.options.reverseProxyAuth.enable = true` behind an authenticating reverse proxy. |
| **File Browser** | `files.masu.rs` | Reverse proxy header auth | Set `auth.method = "proxy"` and `auth.header = "X-Forwarded-User"` behind an authenticating reverse proxy. |
| **Navidrome** | `music.masu.rs` | Reverse proxy header auth | Supports `ReverseProxyUserHeader` for web UI; Subsonic API clients (Feishin, etc.) still require native user passwords. |
| **Stalwart** | `contacts.masu.rs` | OIDC Directory / SASL OAuth | Stalwart supports OIDC directories, but CardDAV/CalDAV clients usually require HTTP Basic Auth or application passwords. |
---
### Tier 3: Incompatible or No Native OIDC Support
- **Vaultwarden (`vault.masu.rs`):** Incompatible for vault decryption. Vaultwarden uses client-side zero-knowledge encryption where vault keys are derived from the user's master password. Bitwarden Enterprise SSO relies on a proprietary Key Connector that Vaultwarden does not implement.
- **n8n (`n8n.masu.rs`):** SAML/OIDC SSO is an **Enterprise / commercial-only feature**; it is disabled in the free self-hosted Community edition.
- **The Arr Stack (`download.masu.rs`):** Radarr, Sonarr, Lidarr, Readarr, Prowlarr, Bazarr, and Sabnzbd only support API keys, Basic Auth, or Forms.
- **Transmission (`transmission.masu.rs`):** BitTorrent daemon; supports only HTTP Basic Auth / RPC whitelist.
- **Uptime Kuma (`status.masu.rs`), ntfy (`ntfy.masu.rs`), The Lounge (`irc.masu.rs`), Pgweb (`pg.masu.rs`), Mathesar (`mathesar.masu.rs`), Hister (`hister.masu.rs`):** No native generic OIDC login mechanism.
- **Infrastructure / Daemon Services:** PostgreSQL, InfluxDB, bind, avahi, cloudflared, wireguard, litestream (no user web UI).
---
## 2. General Setup Requirements
Configuring OIDC requires setup across four layers:
### A. Pocket ID Setup
For each service, an OIDC client application must be registered in the Pocket ID admin interface:
1. **Client ID:** A unique identifier slug (e.g. `gitea`, `immich`, `paperless`).
2. **Client Secret:** A cryptographically secure random token.
3. **Redirect URIs / Callback URLs:** The exact target URLs the service exposes for authorization code callbacks.
4. **Scopes:** Usually `openid`, `profile`, and `email`.
### B. Secrets Management (agenix)
All client secrets should be encrypted with `agenix` under the respective service directory:
- Example: `platforms/nixos/modules/nmasur/presets/services/<service>/<service>-oidc.age`
- Defined in NixOS under `config.secrets.<service>-oidc` with appropriate owner/group permissions.
### C. Network & Reverse Proxy (Caddy)
1. **Back-Channel Connectivity:** When a user logs in, the service backend makes a server-to-server HTTPS call to `https://auth.masu.rs/api/oidc/token` to exchange the authorization code for tokens. Services hosted on `swan` (NAS) must be able to resolve and reach `auth.masu.rs` over HTTPS.
2. **Proxy Headers:** Caddy's `reverse_proxy` handles `X-Forwarded-Proto`, `X-Forwarded-Host`, and `X-Forwarded-For` by default. Services should have reverse proxy trust enabled (e.g., `trusted_proxies = ["127.0.0.1"]`) so generated redirect URIs preserve the `https://` scheme.
---
## 3. Detailed Setup Requirements for Tier 1 Services
### 1. Immich (`photos.masu.rs`)
- **Pocket ID Redirect URIs:**
- Web: `https://photos.masu.rs/auth/login`
- Mobile: `app.immich:///oauth-callback`
- **Setup in `immich/immich.nix`:**
```nix
services.immich.settings.oauth = {
enabled = true;
issuerUrl = "https://${hostnames.auth}";
clientId = "1f4e0f8d-6cee-4d67-8d53-74bf6c18ae09";
clientSecret._secret = config.secrets.immich-oidc-secret.dest;
scope = "openid profile email";
autoRegister = true;
buttonText = "Login with Pocket ID";
};
```
### 2. Gitea (`git.masu.rs`)
- **Pocket ID Redirect URI:** `https://git.masu.rs/user/oauth2/pocket-id/callback`
- **Setup in Gitea:**
Can be configured in the Web UI under **Site Administration → Authentication Sources** or via CLI:
```bash
gitea admin auth add-oauth \
--name "Pocket ID" \
--provider openidConnect \
--key "<client_id>" \
--secret "<client_secret>" \
--auto-discover-url "https://auth.masu.rs/.well-known/openid-configuration"
```
- Optional: Enable automatic account linking by matching email.
### 3. Nextcloud (`cloud.masu.rs`)
- **Pocket ID Redirect URI:** `https://cloud.masu.rs/apps/user_oidc/code`
- **Setup in `nextcloud/nextcloud.nix`:**
1. Add `user_oidc` to `services.nextcloud.extraApps`.
2. Configure the provider via `nextcloud-occ`:
```bash
nextcloud-occ user_oidc:provider pocket-id \
--clientid="<client_id>" \
--clientsecret="<client_secret>" \
--discoveryuri="https://auth.masu.rs/.well-known/openid-configuration" \
--scope="openid profile email"
```
### 4. Grafana (`metrics.masu.rs`)
- **Pocket ID Redirect URI:** `https://metrics.masu.rs/login/generic_oauth`
- **Setup in `grafana/grafana.nix`:**
```nix
services.grafana.settings = {
auth.oauth_allow_insecure_email_lookup = true;
"auth.generic_oauth" = {
enabled = true;
name = "Pocket ID";
allow_sign_up = true;
client_id = "85d879ed-1a86-4984-b33d-43806500ef98";
client_secret = "$__file{${config.secrets.grafana-oidc-secret.dest}}";
scopes = "openid profile email";
auth_url = "https://${hostnames.auth}/authorize";
token_url = "https://${hostnames.auth}/api/oidc/token";
api_url = "https://${hostnames.auth}/api/oidc/userinfo";
login_attribute_path = "preferred_username";
skip_org_role_sync = true;
};
};
```
### 5. Paperless-ngx (`paper.masu.rs`)
- **Pocket ID Redirect URI:** `https://paper.masu.rs/accounts/oidc/pocket-id/login/callback/`
- **Setup in `paperless/paperless.nix`:**
```nix
services.paperless.settings = {
PAPERLESS_APPS = "allauth.socialaccount.providers.openid_connect";
PAPERLESS_SOCIALACCOUNT_PROVIDERS = builtins.toJSON {
openid_connect = {
SERVERS = [
{
id = "pocket-id";
name = "Pocket ID";
server_url = "https://auth.masu.rs";
token_auth_method = "client_secret_basic";
APP = {
client_id = "paperless";
secret = "..."; # or via environmentFile
};
}
];
};
};
PAPERLESS_REDIRECT_LOGIN_TO_SSO = "true"; # Optional: bypass local login
};
```
### 6. Mealie (`cooking.masu.rs`)
- **Pocket ID Redirect URI:** `https://cooking.masu.rs/login`
- **Setup in `mealie/mealie.nix`:**
```nix
services.mealie = {
credentialsFile = config.secrets.mealie-oidc-secret.dest;
settings = {
OIDC_AUTH_ENABLED = "true";
OIDC_SIGNUP_ENABLED = "true";
OIDC_CONFIGURATION_URL = "https://${hostnames.auth}/.well-known/openid-configuration";
OIDC_CLIENT_ID = "040925ed-b39e-4442-b8e8-369c948c0cd2";
OIDC_PROVIDER_NAME = "Pocket ID";
OIDC_USER_CLAIM = "email";
};
};
```
### 7. Karakeep / Hoarder (`keep.masu.rs`)
- **Pocket ID Redirect URI:** `https://keep.masu.rs/api/auth/callback/custom`
- **Setup in `karakeep.nix`:**
```nix
services.karakeep.extraEnvironment = {
OAUTH_WELLKNOWN_URL = "https://auth.masu.rs/.well-known/openid-configuration";
OAUTH_CLIENT_ID = "hoarder";
OAUTH_CLIENT_SECRET = "...";
OAUTH_PROVIDER_NAME = "Pocket ID";
OAUTH_ALLOW_DANGEROUS_EMAIL_ACCOUNT_LINKING = "true";
};
```
### 8. Audiobookshelf (`read.masu.rs`)
- **Pocket ID Redirect URIs:**
- Web: `https://read.masu.rs/auth/openid/callback`
- Mobile: `audiobookshelf://oauth`
- **Setup in Audiobookshelf:**
Configured in the Web UI (**Settings → Authentication → OpenID Connect**):
- Issuer URL: `https://auth.masu.rs`
- Client ID & Client Secret
- Match user by email or username
### 9. Actual Budget (`money.masu.rs`)
- **Pocket ID Redirect URI:** `https://money.masu.rs/openid/callback`
- **Setup in `actualbudget/actualbudget.nix`:**
```nix
services.actual.settings = {
loginMethod = "openid";
openId = {
discoveryURL = "https://${hostnames.auth}/.well-known/openid-configuration";
client_id = "92afe9f8-7ef6-42ab-8a06-701df3c7179d";
client_secret._secret = config.secrets.actualbudget-oidc-secret.dest;
server_hostname = "https://${hostnames.budget}";
authMethod = "openid";
};
};
```
*Note:* The optional end-to-end budget encryption password remains separate from the server authentication.
---
## 4. Forward Auth Architecture for Remaining Services
For services without native OIDC support (such as Calibre-Web, File Browser, Uptime Kuma, and the Arr stack), you can implement **Forward Auth via Caddy**:
1. Deploy an authenticating proxy (such as **OAuth2-Proxy** or **Authelia**) configured with Pocket ID as its OIDC provider.
2. Configure Caddy routes using the `forward_auth` directive to verify user sessions with the proxy before forwarding requests to the target service.
3. For services supporting reverse proxy authentication (Calibre-Web and File Browser), Caddy injects identity headers (e.g. `Remote-User: noah` or `X-Forwarded-User: noah`), enabling seamless single sign-on without requiring separate logins.
Generated
+286 -134
View File
@@ -1,12 +1,18 @@
{ {
"nodes": { "nodes": {
"cl-nix-lite": { "cl-nix-lite": {
"inputs": {
"flake-parts": "flake-parts",
"nixpkgs": "nixpkgs",
"systems": "systems",
"treefmt-nix": "treefmt-nix"
},
"locked": { "locked": {
"lastModified": 1728174978, "lastModified": 1782994178,
"narHash": "sha256-Grqqg+xuicANB85j0gNEXxi9SBKY7bzGeTuyi95eGcY=", "narHash": "sha256-VGc3/2fe6hnOmNSLlOygEAbeS69v7A7rjKDKRzAgE2Q=",
"owner": "hraban", "owner": "hraban",
"repo": "cl-nix-lite", "repo": "cl-nix-lite",
"rev": "31cfe6275c341eb3120a99f4b1c8516c49a29d87", "rev": "eb584721e5e799bafe0c6210a8a1a398f90e8ac0",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -22,11 +28,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1755825449, "lastModified": 1786845137,
"narHash": "sha256-XkiN4NM9Xdy59h69Pc+Vg4PxkSm9EWl6u7k6D5FZ5cM=", "narHash": "sha256-oQFip+v0luP8NIxJzmiW4Wu8bILsbFWom5l0zonl8hQ=",
"owner": "lnl7", "owner": "lnl7",
"repo": "nix-darwin", "repo": "nix-darwin",
"rev": "8df64f819698c1fee0c2969696f54a843b2231e8", "rev": "4cff07de74b50e64bdd68cd4e722ab5b6b35ee48",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -43,11 +49,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1756115622, "lastModified": 1781152676,
"narHash": "sha256-iv8xVtmLMNLWFcDM/HcAPLRGONyTRpzL9NS09RnryRM=", "narHash": "sha256-RxWs5ND31KzTG7wvMM+PMfUjyNpmIEr999lqNARaM5o=",
"owner": "nix-community", "owner": "nix-community",
"repo": "disko", "repo": "disko",
"rev": "bafad29f89e83b2d861b493aa23034ea16595560", "rev": "ff8702b4de27f72b4c78573dfb89ec74e36abdf1",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -59,11 +65,11 @@
"flake-compat": { "flake-compat": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1730663653, "lastModified": 1766808011,
"narHash": "sha256-kFCUWettiFHDIqxCWWQ9qY8pVh+Lj+XL0Giyy/kdomg=", "narHash": "sha256-s83BS0abtIj7vzUf8JE0209KphfHA6qRw/92D9k/F+0=",
"owner": "hraban", "owner": "hraban",
"repo": "flake-compat", "repo": "flake-compat",
"rev": "e5b16676185cb7548581c852f51ce7f3a49bba5e", "rev": "6e0aafdc4c4c2043c66f756d5045374b42184fc5",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -76,11 +82,27 @@
"flake-compat_2": { "flake-compat_2": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1747046372, "lastModified": 1767039857,
"narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=", "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=",
"owner": "edolstra", "owner": "edolstra",
"repo": "flake-compat", "repo": "flake-compat",
"rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885", "rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -90,6 +112,24 @@
} }
}, },
"flake-parts": { "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": { "inputs": {
"nixpkgs-lib": [ "nixpkgs-lib": [
"nur", "nur",
@@ -132,7 +172,7 @@
}, },
"flake-utils_2": { "flake-utils_2": {
"inputs": { "inputs": {
"systems": "systems_2" "systems": "systems_3"
}, },
"locked": { "locked": {
"lastModified": 1731533236, "lastModified": 1731533236,
@@ -148,27 +188,6 @@
"type": "github" "type": "github"
} }
}, },
"helix": {
"inputs": {
"nixpkgs": [
"nixpkgs"
],
"rust-overlay": "rust-overlay"
},
"locked": {
"lastModified": 1756477005,
"narHash": "sha256-e/FNNIT/LPuoruzRQZf5z5L5GApq1G2y2PShy+Lakhs=",
"owner": "helix-editor",
"repo": "helix",
"rev": "77ff51caa440b1066e0a1920007ab5e148dd4856",
"type": "github"
},
"original": {
"owner": "helix-editor",
"repo": "helix",
"type": "github"
}
},
"home-manager": { "home-manager": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
@@ -176,11 +195,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1756496801, "lastModified": 1788487777,
"narHash": "sha256-IYIsnPy+cJxe8RbDHBrCtfJY0ry2bG2H7WvMcewiGS8=", "narHash": "sha256-Ro/e1N4ZR8/XaFF+sF9SgfPK79HM5YNEppzFj8p+0Ak=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "77a71380c38fb2a440b4b5881bbc839f6230e1cb", "rev": "693e8ce0fb240a73c116a03cfd7b19269c87af88",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -195,18 +214,16 @@
"cl-nix-lite": "cl-nix-lite", "cl-nix-lite": "cl-nix-lite",
"flake-compat": "flake-compat", "flake-compat": "flake-compat",
"flake-utils": "flake-utils", "flake-utils": "flake-utils",
"nixpkgs": [ "nixpkgs": "nixpkgs_3",
"nixpkgs" "systems": "systems_2",
], "treefmt-nix": "treefmt-nix_2"
"systems": "systems",
"treefmt-nix": "treefmt-nix"
}, },
"locked": { "locked": {
"lastModified": 1756057867, "lastModified": 1783182903,
"narHash": "sha256-ziR5eQGqRWhW8tf8r0TIplaqNt+HXu1G1X41LUr4IYo=", "narHash": "sha256-7IteXipJZfFepi5zakxe0jQ5i3vRBQguk0+Gtte1Fu4=",
"owner": "hraban", "owner": "hraban",
"repo": "mac-app-util", "repo": "mac-app-util",
"rev": "8414fa1e2cb775b17793104a9095aabeeada63ef", "rev": "039f33deef21782d4db97087f426504951239887",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -215,6 +232,46 @@
"type": "github" "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"
]
},
"locked": {
"lastModified": 1788080100,
"narHash": "sha256-n14luQo3F/ZLfCEHk1QieiI1nGnW92ZQZeZ0UIb0UMQ=",
"owner": "nix-community",
"repo": "nix-index-database",
"rev": "dbb978fa87faf13398e90ccbc52c343d21c7dd6d",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nix-index-database",
"type": "github"
}
},
"nix2vim": { "nix2vim": {
"inputs": { "inputs": {
"flake-utils": "flake-utils_2", "flake-utils": "flake-utils_2",
@@ -223,11 +280,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1755344765, "lastModified": 1779563638,
"narHash": "sha256-k/Cvh/mzb5lSvilKdgwNBCyAyYmD8YPr1nc0sTSgwxI=", "narHash": "sha256-9CQKxDKDqVYdDhJW+A955AZwpwZjKUgvu0LbfsL6uyI=",
"owner": "gytis-ivaskevicius", "owner": "gytis-ivaskevicius",
"repo": "nix2vim", "repo": "nix2vim",
"rev": "78467c8de07719f92397179844bf75cdf2e58b83", "rev": "6927414f0de10a18fb6bc9977717088777d50d0d",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -259,11 +316,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1751903740, "lastModified": 1769813415,
"narHash": "sha256-PeSkNMvkpEvts+9DjFiop1iT2JuBpyknmBUs0Un0a4I=", "narHash": "sha256-nnVmNNKBi1YiBNPhKclNYDORoHkuKipoz7EtVnXO50A=",
"owner": "nix-community", "owner": "nix-community",
"repo": "nixos-generators", "repo": "nixos-generators",
"rev": "032decf9db65efed428afd2fa39d80f7089085eb", "rev": "8946737ff703382fda7623b9fab071d037e897d5",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -274,11 +331,58 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1754340878, "lastModified": 1779796641,
"narHash": "sha256-lgmUyVQL9tSnvvIvBp7x1euhkkCho7n3TMzgjdvgPoU=", "narHash": "sha256-ZsIrKmhp4vbBXoXXmR/tBXA/UCsAQiJL9vsgZEduhVY=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "cab778239e705082fe97bb4990e0d24c50924c04", "rev": "25f538306313eae3927264466c70d7001dcea1df",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-25.11",
"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": 1788405554,
"narHash": "sha256-r2f1oUwixlgq9zOdYLqJLfS/lWBT60/IITjhTKI59JU=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "a5cc6f2c37bf518436dc8d1c288ccd0c43c2f4c4",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-26.05",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1761236834,
"narHash": "sha256-+pthv6hrL5VLW2UqPdISGuLiUZ6SnAXdd2DdUE+fV2Q=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "d5faa84122bc0a1fd5d378492efce4e289f8eac1",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -288,29 +392,61 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs-stable": { "nixpkgs_3": {
"locked": { "locked": {
"lastModified": 1735563628, "lastModified": 1782999065,
"narHash": "sha256-OnSAY7XDSx7CtDoqNh8jwVwh4xNL/2HaJxGjryLWzX8=", "narHash": "sha256-5Dgj5+pIQYZKrXUGaLCk7CKfN3MmpwIhO94++WVxvng=",
"owner": "nixos", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "b134951a4c9f3c995fd7be05f3243f8ecd65d798", "rev": "80d591ed473cfc46329932c2aadac9b435342c7c",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "nixos", "owner": "NixOS",
"ref": "nixos-24.05", "ref": "nixos-26.05",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }
}, },
"nixpkgs_2": { "nixpkgs_4": {
"locked": { "locked": {
"lastModified": 1756386758, "lastModified": 1770107345,
"narHash": "sha256-1wxxznpW2CKvI9VdniaUnTT2Os6rdRJcRUf65ZK9OtE=", "narHash": "sha256-tbS0Ebx2PiA1FRW8mt8oejR0qMXmziJmPaU1d4kYY9g=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "dfb2f12e899db4876308eba6d93455ab7da304cd", "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": 1788531059,
"narHash": "sha256-hLD4l3QOGBQhkVp3mQ2lJ/YbEi99qUgKapb40KovZ88=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "801bef6abd86b91e51083066b83fb354a11fc640",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -320,13 +456,13 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs_3": { "nixpkgs_7": {
"locked": { "locked": {
"lastModified": 1728538411, "lastModified": 1744536153,
"narHash": "sha256-f0SBJz1eZ2yOuKUr5CA9BHULGXVSn6miBuUWdTyhUhU=", "narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "b69de56fac8c2b6f8fd27f2eca01dcda8e0a4221", "rev": "18dd725c29603f582cf1900e0d25f9f1063dbf11",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -338,17 +474,17 @@
}, },
"nur": { "nur": {
"inputs": { "inputs": {
"flake-parts": "flake-parts", "flake-parts": "flake-parts_2",
"nixpkgs": [ "nixpkgs": [
"nixpkgs" "nixpkgs"
] ]
}, },
"locked": { "locked": {
"lastModified": 1756524478, "lastModified": 1788594396,
"narHash": "sha256-2oSBlcYCgwrVxUZwM8MV6hBFsfsWFbeN5ErQiCA+38s=", "narHash": "sha256-HLvxvUIMxBHl+vv/1OVTLPKrSLTinId97WBIxWWByJ0=",
"owner": "nix-community", "owner": "nix-community",
"repo": "nur", "repo": "nur",
"rev": "e82a8b0095f54edb6bbbb1d862f3da502dca1396", "rev": "82ca52a282cd5f90afabcf7c9acd27571b253523",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -361,14 +497,16 @@
"inputs": { "inputs": {
"darwin": "darwin", "darwin": "darwin",
"disko": "disko", "disko": "disko",
"helix": "helix",
"home-manager": "home-manager", "home-manager": "home-manager",
"mac-app-util": "mac-app-util", "mac-app-util": "mac-app-util",
"nix-caddy-withplugins": "nix-caddy-withplugins",
"nix-index-database": "nix-index-database",
"nix2vim": "nix2vim", "nix2vim": "nix2vim",
"nixos-generators": "nixos-generators", "nixos-generators": "nixos-generators",
"nixpkgs": "nixpkgs_2", "nixpkgs": "nixpkgs_6",
"nixpkgs-stable": "nixpkgs-stable", "nixpkgs-stable": "nixpkgs-stable",
"nur": "nur", "nur": "nur",
"rust-overlay": "rust-overlay",
"wsl": "wsl", "wsl": "wsl",
"zellij-switch": "zellij-switch", "zellij-switch": "zellij-switch",
"zenyd-mpv-scripts": "zenyd-mpv-scripts" "zenyd-mpv-scripts": "zenyd-mpv-scripts"
@@ -376,35 +514,14 @@
}, },
"rust-overlay": { "rust-overlay": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": "nixpkgs_7"
"helix",
"nixpkgs"
]
}, },
"locked": { "locked": {
"lastModified": 1740623427, "lastModified": 1788591095,
"narHash": "sha256-3SdPQrZoa4odlScFDUHd4CUPQ/R1gtH4Mq9u8CBiK8M=", "narHash": "sha256-Vh+BeLWfbTT9AecazIsQ/Tkg/RzJeX3lEduANf256WA=",
"owner": "oxalica", "owner": "oxalica",
"repo": "rust-overlay", "repo": "rust-overlay",
"rev": "d342e8b5fd88421ff982f383c853f0fc78a847ab", "rev": "c361047d3a538f547f1617bb6b410411929ac9cc",
"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" "type": "github"
}, },
"original": { "original": {
@@ -414,21 +531,6 @@
} }
}, },
"systems": { "systems": {
"locked": {
"lastModified": 1689347925,
"narHash": "sha256-ozenz5bFe1UUqOn7f60HRmgc01BgTGIKZ4Xl+HbocGQ=",
"owner": "nix-systems",
"repo": "default-darwin",
"rev": "2235d7e6cc29ae99878133c95e9fe5e157661ffb",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default-darwin",
"type": "github"
}
},
"systems_2": {
"locked": { "locked": {
"lastModified": 1681028828, "lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
@@ -443,6 +545,21 @@
"type": "github" "type": "github"
} }
}, },
"systems_2": {
"locked": {
"lastModified": 1689347925,
"narHash": "sha256-ozenz5bFe1UUqOn7f60HRmgc01BgTGIKZ4Xl+HbocGQ=",
"owner": "nix-systems",
"repo": "default-darwin",
"rev": "2235d7e6cc29ae99878133c95e9fe5e157661ffb",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default-darwin",
"type": "github"
}
},
"systems_3": { "systems_3": {
"locked": { "locked": {
"lastModified": 1681028828, "lastModified": 1681028828,
@@ -458,16 +575,49 @@
"type": "github" "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": { "treefmt-nix": {
"inputs": { "inputs": {
"nixpkgs": "nixpkgs" "nixpkgs": "nixpkgs_2"
}, },
"locked": { "locked": {
"lastModified": 1755934250, "lastModified": 1766000401,
"narHash": "sha256-CsDojnMgYsfshQw3t4zjRUkmMmUdZGthl16bXVWgRYU=", "narHash": "sha256-+cqN4PJz9y0JQXfAK5J1drd0U05D5fcAGhzhfVrDlsI=",
"owner": "numtide", "owner": "numtide",
"repo": "treefmt-nix", "repo": "treefmt-nix",
"rev": "74e1a52d5bd9430312f8d1b8b0354c92c17453e5", "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",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -478,17 +628,17 @@
}, },
"wsl": { "wsl": {
"inputs": { "inputs": {
"flake-compat": "flake-compat_2", "flake-compat": "flake-compat_3",
"nixpkgs": [ "nixpkgs": [
"nixpkgs" "nixpkgs"
] ]
}, },
"locked": { "locked": {
"lastModified": 1755261305, "lastModified": 1784642409,
"narHash": "sha256-EOqCupB5X5WoGVHVcfOZcqy0SbKWNuY3kq+lj1wHdu8=", "narHash": "sha256-hcbDqFuySAJawljt5r0sKBCJKYnbtGD0T/ZIozH1Dq0=",
"owner": "nix-community", "owner": "nix-community",
"repo": "NixOS-WSL", "repo": "NixOS-WSL",
"rev": "203a7b463f307c60026136dd1191d9001c43457f", "rev": "eaeb18da90024448a60eb1ec7132eafa4003404e",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -502,15 +652,17 @@
"nixpkgs": [ "nixpkgs": [
"nixpkgs" "nixpkgs"
], ],
"rust-overlay": "rust-overlay_2", "rust-overlay": [
"systems": "systems_3" "rust-overlay"
],
"systems": "systems_4"
}, },
"locked": { "locked": {
"lastModified": 1742588229, "lastModified": 1781873766,
"narHash": "sha256-IPg0pBw0ciF+xl6viq3nK+dvZoDZrfBDui7dkPLz258=", "narHash": "sha256-V8baEgRBa2SqtCLbQ4EaphIMKsnAogY2oMdttWYhkEs=",
"owner": "mostafaqanbaryan", "owner": "mostafaqanbaryan",
"repo": "zellij-switch", "repo": "zellij-switch",
"rev": "0e3c303c19890ccb03589230ac5a7c4307e573e4", "rev": "ced3c681afe40785b2853e3a976908466786ee79",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -522,11 +674,11 @@
"zenyd-mpv-scripts": { "zenyd-mpv-scripts": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1707704915, "lastModified": 1765050776,
"narHash": "sha256-9P/8q/OZXfaJMS08acQP4h3/zUA5mKRQee0JmkXcz1w=", "narHash": "sha256-9gO+GkNoGsxAbMRrBWu0FfXEQtyTmHivlaxlYLpV2YM=",
"owner": "zenyd", "owner": "zenyd",
"repo": "mpv-scripts", "repo": "mpv-scripts",
"rev": "9bdce0050144cb24f92475f7bdd77180e0e4c26b", "rev": "62f4bb313c6cb6366672e78dea940e9da8fec84a",
"type": "github" "type": "github"
}, },
"original": { "original": {
+74 -50
View File
@@ -8,7 +8,7 @@
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
# Used for specific stable packages # Used for specific stable packages
nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-24.05"; nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-26.05";
# Used for MacOS system config # Used for MacOS system config
darwin = { darwin = {
@@ -37,7 +37,13 @@
# Better App install management in macOS # Better App install management in macOS
mac-app-util = { mac-app-util = {
url = "github:hraban/mac-app-util"; url = "github:hraban/mac-app-util";
inputs.nixpkgs.follows = "nixpkgs"; # Use system packages list for their inputs # 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
}; };
# Manage disk format and partitioning # Manage disk format and partitioning
@@ -52,6 +58,11 @@
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
nix-index-database = {
url = "github:nix-community/nix-index-database";
inputs.nixpkgs.follows = "nixpkgs";
};
# Convert Nix to Neovim config # Convert Nix to Neovim config
nix2vim = { nix2vim = {
url = "github:gytis-ivaskevicius/nix2vim"; url = "github:gytis-ivaskevicius/nix2vim";
@@ -64,17 +75,23 @@
flake = false; flake = false;
}; };
rust-overlay = {
url = "github:oxalica/rust-overlay";
};
# Zellij Switcher # Zellij Switcher
zellij-switch = { zellij-switch = {
url = "github:mostafaqanbaryan/zellij-switch"; url = "github:mostafaqanbaryan/zellij-switch";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
inputs.rust-overlay.follows = "rust-overlay";
}; };
# Text editor # # Text editor
helix = { # helix = {
url = "github:helix-editor/helix"; # url = "github:helix-editor/helix";
inputs.nixpkgs.follows = "nixpkgs"; # inputs.nixpkgs.follows = "nixpkgs";
}; # inputs.rust-overlay.follows = "rust-overlay";
# };
# # Nextcloud Apps # # Nextcloud Apps
# nextcloud-news = { # nextcloud-news = {
@@ -111,6 +128,7 @@
in in
{ {
audiobooks = "read.${baseName}"; audiobooks = "read.${baseName}";
auth = "auth.${baseName}";
bookmarks = "keep.${baseName}"; bookmarks = "keep.${baseName}";
books = "books.${baseName}"; books = "books.${baseName}";
budget = "money.${baseName}"; budget = "money.${baseName}";
@@ -119,6 +137,7 @@
download = "download.${baseName}"; download = "download.${baseName}";
files = "files.${baseName}"; files = "files.${baseName}";
git = "git.${baseName}"; git = "git.${baseName}";
hister = "hister.${baseName}";
imap = "imap.purelymail.com"; imap = "imap.purelymail.com";
influxdb = "influxdb.${baseName}"; influxdb = "influxdb.${baseName}";
irc = "irc.${baseName}"; irc = "irc.${baseName}";
@@ -126,6 +145,7 @@
mathesar = "mathesar.${baseName}"; mathesar = "mathesar.${baseName}";
metrics = "metrics.${baseName}"; metrics = "metrics.${baseName}";
minecraft = "minecraft.${baseName}"; minecraft = "minecraft.${baseName}";
mumble = "mumble.${baseName}";
n8n = "n8n.${baseName}"; n8n = "n8n.${baseName}";
navidrome = "music.${baseName}"; navidrome = "music.${baseName}";
notifications = "ntfy.${baseName}"; notifications = "ntfy.${baseName}";
@@ -133,6 +153,7 @@
photos = "photos.${baseName}"; photos = "photos.${baseName}";
postgresql = "pg.${baseName}"; postgresql = "pg.${baseName}";
prometheus = "prom.${baseName}"; prometheus = "prom.${baseName}";
recipes = "cooking.${baseName}";
secrets = "vault.${baseName}"; secrets = "vault.${baseName}";
smtp = "smtp.purelymail.com"; smtp = "smtp.purelymail.com";
status = "status.${baseName}"; status = "status.${baseName}";
@@ -140,38 +161,9 @@
transmission = "transmission.${baseName}"; transmission = "transmission.${baseName}";
}; };
in
rec {
lib = import ./lib inputs; lib = import ./lib inputs;
flattenAttrset = attrs: builtins.foldl' lib.mergeAttrs { } (builtins.attrValues attrs); flattenAttrset = attrs: builtins.foldl' lib.mergeAttrs { } (builtins.attrValues attrs);
nixosConfigurations = flattenAttrset (
builtins.mapAttrs (
system: hosts:
builtins.mapAttrs (
name: module:
lib.buildNixos {
inherit system module;
specialArgs = { inherit hostnames; };
}
) hosts
) lib.linuxHosts
);
darwinConfigurations = flattenAttrset (
builtins.mapAttrs (
system: hosts:
builtins.mapAttrs (
name: module:
lib.buildDarwin {
inherit system module;
specialArgs = { inherit hostnames; };
}
) hosts
) lib.darwinHosts
);
homeModules = builtins.mapAttrs ( homeModules = builtins.mapAttrs (
system: hosts: system: hosts:
builtins.mapAttrs ( builtins.mapAttrs (
@@ -179,19 +171,6 @@
) hosts ) hosts
) lib.hosts; ) lib.hosts;
homeConfigurations = flattenAttrset (
builtins.mapAttrs (
system: hosts:
builtins.mapAttrs (
name: module:
lib.buildHome {
inherit system module;
specialArgs = { inherit hostnames; };
}
) hosts
) homeModules
);
# Disk formatting, only used once # Disk formatting, only used once
diskoConfigurations = { diskoConfigurations = {
root = import ./hosts/x86_64-linux/swan/root.nix; root = import ./hosts/x86_64-linux/swan/root.nix;
@@ -221,6 +200,51 @@
) lib.linuxHosts # x86_64-linux = { arrow = ...; swan = ...; } ) lib.linuxHosts # x86_64-linux = { arrow = ...; swan = ...; }
; ;
in
{
inherit lib;
nixosConfigurations = flattenAttrset (
builtins.mapAttrs (
system: hosts:
builtins.mapAttrs (
name: module:
lib.buildNixos {
inherit system module;
specialArgs = { inherit hostnames; };
}
) hosts
) lib.linuxHosts
);
darwinConfigurations = flattenAttrset (
builtins.mapAttrs (
system: hosts:
builtins.mapAttrs (
name: module:
lib.buildDarwin {
inherit system module;
specialArgs = { inherit hostnames; };
}
) hosts
) lib.darwinHosts
);
homeConfigurations = flattenAttrset (
builtins.mapAttrs (
system: hosts:
builtins.mapAttrs (
name: module:
lib.buildHome {
inherit system module;
specialArgs = { inherit hostnames; };
}
) hosts
) homeModules
);
# packages = # packages =
# lib.forSystems lib.linuxSystems ( # lib.forSystems lib.linuxSystems (
# system: generateImagesForHosts system // lib.pkgsBySystem.${system}.nmasur # system: generateImagesForHosts system // lib.pkgsBySystem.${system}.nmasur
@@ -280,7 +304,7 @@
inherit (lib) overlays; inherit (lib) overlays;
}; };
in in
pkgs.nixfmt-rfc-style pkgs.nixfmt
); );
# Templates for starting other projects quickly # Templates for starting other projects quickly
+16 -3
View File
@@ -12,9 +12,19 @@ rec {
nmasur.profiles = { nmasur.profiles = {
base.enable = true; base.enable = true;
work.enable = true; # work.enable = true;
extra.enable = true; # extra.enable = true;
gaming.enable = true; # gaming.enable = true;
};
# Corporate network runs a TLS-intercepting proxy. Trust its root CA so Nix
# fetches don't fail with "self-signed certificate in certificate chain". The
# cert lives outside this public repo at a root-owned, world-readable path so
# the unprivileged Nix build user can read it (a copy under $HOME is not
# traversable by nixbld). See docs/CHANGELOG.md to extract and install it.
nmasur.presets.security.corporateCa = {
enable = true;
certFile = "/etc/ssl/corp-ca/CorpCA.pem";
}; };
home-manager.users."Noah.Masur" = { home-manager.users."Noah.Masur" = {
@@ -26,10 +36,13 @@ rec {
nmasur.profiles = { nmasur.profiles = {
common.enable = true; common.enable = true;
darwin-base.enable = true; darwin-base.enable = true;
darwin-gaming.enable = true;
llm-development.enable = true;
power-user.enable = true; power-user.enable = true;
work.enable = true; work.enable = true;
experimental.enable = true; experimental.enable = true;
}; };
nmasur.presets.services.mbsync.user = "noah";
nmasur.presets.programs.git-work.work = { nmasur.presets.programs.git-work.work = {
name = "Noah-Masur_1701"; name = "Noah-Masur_1701";
email = "${nmasur.settings.username}@take2games.com"; email = "${nmasur.settings.username}@take2games.com";
+1
View File
@@ -28,6 +28,7 @@ rec {
nmasur.profiles = { nmasur.profiles = {
common.enable = true; common.enable = true;
linux-base.enable = true; linux-base.enable = true;
llm-development.enable = true;
power-user.enable = true; power-user.enable = true;
}; };
nmasur.presets.programs.helix.enable = true; nmasur.presets.programs.helix.enable = true;
+4
View File
@@ -26,6 +26,7 @@ rec {
nmasur.profiles = { nmasur.profiles = {
common.enable = true; common.enable = true;
linux-base.enable = true; linux-base.enable = true;
llm-development.enable = true;
power-user.enable = true; power-user.enable = true;
}; };
home.stateVersion = "23.05"; home.stateVersion = "23.05";
@@ -33,6 +34,9 @@ rec {
system.stateVersion = "23.05"; 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 # Not sure what's necessary but too afraid to remove anything
boot.initrd.availableKernelModules = [ boot.initrd.availableKernelModules = [
"xhci_pci" "xhci_pci"
+12 -11
View File
@@ -30,6 +30,7 @@ rec {
linux-base.enable = true; linux-base.enable = true;
linux-gui.enable = true; linux-gui.enable = true;
linux-gaming.enable = true; linux-gaming.enable = true;
llm-development.enable = true;
power-user.enable = true; power-user.enable = true;
developer.enable = true; developer.enable = true;
experimental.enable = true; experimental.enable = true;
@@ -51,7 +52,7 @@ rec {
# Graphics and VMs # Graphics and VMs
boot.initrd.kernelModules = [ "amdgpu" ]; boot.initrd.kernelModules = [ "amdgpu" ];
boot.kernelModules = [ "kvm-amd" ]; boot.kernelModules = [ "kvm-amd" "it87" ];
services.xserver.videoDrivers = [ "amdgpu" ]; services.xserver.videoDrivers = [ "amdgpu" ];
# Required binary blobs to boot on this machine # Required binary blobs to boot on this machine
@@ -68,16 +69,16 @@ rec {
hardware.fancontrol.config = '' hardware.fancontrol.config = ''
# Configuration file generated by pwmconfig, changes will be lost # Configuration file generated by pwmconfig, changes will be lost
INTERVAL=10 INTERVAL=10
DEVPATH=hwmon0=devices/pci0000:00/0000:00:03.1/0000:06:00.0/0000:07:00.0/0000:08:00.0 DEVPATH=hwmon1=devices/pci0000:00/0000:00:03.1/0000:06:00.0/0000:07:00.0/0000:08:00.0
DEVNAME=hwmon0=amdgpu DEVNAME=hwmon1=amdgpu
FCTEMPS=hwmon0/pwm1=hwmon0/temp1_input FCTEMPS=hwmon1/pwm1=hwmon1/temp1_input
FCFANS= hwmon0/pwm1=hwmon0/fan1_input FCFANS= hwmon1/pwm1=hwmon1/fan1_input
MINTEMP=hwmon0/pwm1=50 MINTEMP=hwmon1/pwm1=50
MAXTEMP=hwmon0/pwm1=70 MAXTEMP=hwmon1/pwm1=70
MINSTART=hwmon0/pwm1=100 MINSTART=hwmon1/pwm1=100
MINSTOP=hwmon0/pwm1=10 MINSTOP=hwmon1/pwm1=10
MINPWM=hwmon0/pwm1=10 MINPWM=hwmon1/pwm1=10
MAXPWM=hwmon0/pwm1=240 MAXPWM=hwmon1/pwm1=240
''; '';
# File systems must be declared in order to boot # File systems must be declared in order to boot
+39 -19
View File
@@ -66,14 +66,16 @@ lib
overlays = [ overlays = [
inputs.nur.overlays.default inputs.nur.overlays.default
inputs.nix2vim.overlay inputs.nix2vim.overlay
inputs.zellij-switch.overlays.default (final: prev: {
inputs.helix.overlays.default zellij-switch = inputs.zellij-switch.packages.${prev.stdenv.hostPlatform.system}.default;
] ++ (importOverlays ../overlays); })
# inputs.helix.overlays.default
]
++ (importOverlays ../overlays);
# System types to support. # System types to support.
supportedSystems = [ supportedSystems = [
"x86_64-linux" "x86_64-linux"
"x86_64-darwin"
"aarch64-linux" "aarch64-linux"
"aarch64-darwin" "aarch64-darwin"
]; ];
@@ -97,7 +99,14 @@ lib
system: system:
import inputs.nixpkgs { import inputs.nixpkgs {
inherit system overlays; inherit system overlays;
config.permittedInsecurePackages = [ "litestream-0.3.13" ]; 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"
"keybase-gui-6.5.1"
];
config.allowUnfree = true; config.allowUnfree = true;
} }
); );
@@ -130,7 +139,8 @@ lib
]; ];
extraSpecialArgs = { extraSpecialArgs = {
inherit colorscheme; inherit colorscheme;
} // specialArgs; }
// specialArgs;
}; };
buildNixos = buildNixos =
@@ -144,16 +154,20 @@ lib
pkgs = pkgsBySystem.${system}; pkgs = pkgsBySystem.${system};
modules = [ modules = [
inputs.home-manager.nixosModules.home-manager inputs.home-manager.nixosModules.home-manager
inputs.nix-index-database.nixosModules.default
inputs.disko.nixosModules.disko inputs.disko.nixosModules.disko
inputs.wsl.nixosModules.wsl inputs.wsl.nixosModules.wsl
{ imports = (nixFiles ../platforms/nixos); } { imports = (nixFiles ../platforms/nixos); }
module module
# (builtins.removeAttrs module [ "home-manager" ])
{ {
home-manager = { home-manager = {
extraSpecialArgs = { extraSpecialArgs = {
inherit colorscheme; inherit colorscheme;
} // specialArgs; }
} // homeModule.home-manager; // specialArgs;
}
// homeModule.home-manager;
} }
]; ];
}; };
@@ -168,19 +182,21 @@ lib
inherit system specialArgs; inherit system specialArgs;
modules = [ modules = [
inputs.home-manager.darwinModules.home-manager inputs.home-manager.darwinModules.home-manager
inputs.nix-index-database.darwinModules.nix-index
inputs.mac-app-util.darwinModules.default inputs.mac-app-util.darwinModules.default
{ {
imports = (nixFiles ../platforms/nix-darwin); imports = (nixFiles ../platforms/nix-darwin);
nixpkgs.pkgs = pkgsBySystem.${system}; nixpkgs.pkgs = pkgsBySystem.${system};
} }
module # Home Manager is intentionally NOT activated here. It is managed
{ # standalone via `nh home switch` (see homeConfigurations, extracted
home-manager = { # from the host module's `home-manager.users`). Strip that attr so
extraSpecialArgs = { # darwin-rebuild doesn't also activate a second, divergent HM
inherit colorscheme; # generation with different store paths (useUserPackages puts packages
} // specialArgs; # in /etc/profiles/per-user vs. ~/.nix-profile standalone) -- that
} // homeModule.home-manager; # mismatch broke the prompt after every darwin-rebuild until the next
} # `nh home switch`.
(builtins.removeAttrs module [ "home-manager" ])
]; ];
}; };
@@ -211,6 +227,7 @@ lib
pkgs = pkgsBySystem.${system}; pkgs = pkgsBySystem.${system};
modules = [ modules = [
inputs.home-manager.nixosModules.home-manager inputs.home-manager.nixosModules.home-manager
inputs.nix-index-database.nixosModules.default
inputs.disko.nixosModules.disko inputs.disko.nixosModules.disko
inputs.wsl.nixosModules.wsl inputs.wsl.nixosModules.wsl
{ {
@@ -222,12 +239,15 @@ lib
home-manager = { home-manager = {
extraSpecialArgs = { extraSpecialArgs = {
inherit colorscheme; inherit colorscheme;
} // specialArgs; }
} // homeModule.home-manager; // specialArgs;
}
// homeModule.home-manager;
} }
]; ];
specialArgs = { specialArgs = {
} // specialArgs; }
// specialArgs;
}; };
} }
-67
View File
@@ -1,67 +0,0 @@
{
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
@@ -1,56 +0,0 @@
{
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
@@ -0,0 +1,9 @@
_inputs: _final: prev: {
pythonPackagesExtensions = prev.pythonPackagesExtensions ++ [
(_pyfinal: pyprev: {
cheetah3 = pyprev.cheetah3.overridePythonAttrs (_old: {
dontCheckPythonMetadata = true;
});
})
];
}
+6
View File
@@ -0,0 +1,6 @@
inputs: final: prev: {
# Switch firefox to stable or unstable depending on need
firefox-unwrapped = final.unstable.firefox-unwrapped;
}
+7
View File
@@ -0,0 +1,7 @@
_inputs: _final: prev: {
kubernetes-helm = prev.kubernetes-helm.overrideAttrs (_old: {
doCheck = false;
});
}
+1
View File
@@ -0,0 +1 @@
inputs: inputs.nix-caddy-withplugins.overlays.default
+20
View File
@@ -0,0 +1,20 @@
# 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,6 +21,9 @@ let
# [ package1.drv package2.drv ] # [ package1.drv package2.drv ]
(builtins.map (name: prev.callPackage name { })) (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 # Convert the list to an attrset
# { package1 = package1.drv, package2 = package2.drv } # { package1 = package1.drv, package2 = package2.drv }
listToAttrsByPnameOrName listToAttrsByPnameOrName
+2 -1
View File
@@ -4,7 +4,8 @@
inputs: _final: prev: { inputs: _final: prev: {
# Provides `pkgs.stable`. # Provides `pkgs.stable`.
stable = import inputs.nixpkgs-stable { stable = import inputs.nixpkgs-stable {
inherit (prev) system config; system = prev.stdenv.hostPlatform.system;
config = { };
overlays = [ overlays = [
# inputs.self.overlays.vim-plugins # inputs.self.overlays.vim-plugins
]; ];
+2 -1
View File
@@ -4,7 +4,8 @@
inputs: _final: prev: { inputs: _final: prev: {
# Provides `pkgs.unstable`. # Provides `pkgs.unstable`.
unstable = import inputs.nixpkgs { unstable = import inputs.nixpkgs {
inherit (prev) system config; system = prev.stdenv.hostPlatform.system;
inherit (prev) config;
overlays = [ overlays = [
# inputs.self.overlays.vim-plugins # inputs.self.overlays.vim-plugins
]; ];
+44
View File
@@ -0,0 +1,44 @@
{
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 = [ ];
mainProgram = "actualtap";
};
}
@@ -100,7 +100,7 @@
lua.command = "${pkgs.stylua}/bin/stylua"; lua.command = "${pkgs.stylua}/bin/stylua";
black.command = "${pkgs.black}/bin/black"; black.command = "${pkgs.black}/bin/black";
fish_indent.command = "${pkgs.fish}/bin/fish_indent"; fish_indent.command = "${pkgs.fish}/bin/fish_indent";
nixfmt.command = "${pkgs.nixfmt-rfc-style}/bin/nixfmt"; nixfmt.command = "${pkgs.nixfmt}/bin/nixfmt";
rustfmt.command = "${pkgs.rustfmt}/bin/rustfmt"; rustfmt.command = "${pkgs.rustfmt}/bin/rustfmt";
shfmt = { shfmt = {
command = "${pkgs.shfmt}/bin/shfmt"; command = "${pkgs.shfmt}/bin/shfmt";
@@ -3,10 +3,10 @@
plugins = [ plugins = [
(pkgs.vimPlugins.nvim-treesitter.withPlugins (_plugins: [ (pkgs.vimPlugins.nvim-treesitter.withPlugins (_plugins: [
pkgs.nmasur.ini-grammar pkgs.nmasur.tree-sitter-ini
pkgs.nmasur.puppet-grammar pkgs.nmasur.tree-sitter-puppet
pkgs.nmasur.rasi-grammar pkgs.nmasur.tree-sitter-rasi
pkgs.nmasur.vimdoc-grammar pkgs.nmasur.tree-sitter-vimdoc
pkgs.tree-sitter-grammars.tree-sitter-bash pkgs.tree-sitter-grammars.tree-sitter-bash
pkgs.tree-sitter-grammars.tree-sitter-c pkgs.tree-sitter-grammars.tree-sitter-c
pkgs.tree-sitter-grammars.tree-sitter-fish pkgs.tree-sitter-grammars.tree-sitter-fish
@@ -21,7 +21,6 @@
pkgs.tree-sitter-grammars.tree-sitter-yaml pkgs.tree-sitter-grammars.tree-sitter-yaml
])) ]))
pkgs.vimPlugins.vim-matchup # Better % jumping in languages pkgs.vimPlugins.vim-matchup # Better % jumping in languages
pkgs.vimPlugins.playground # Tree-sitter experimenting
pkgs.vimPlugins.nginx-vim pkgs.vimPlugins.nginx-vim
pkgs.vimPlugins.vim-helm pkgs.vimPlugins.vim-helm
# pkgs.vimPlugins.hmts-nvim # Tree-sitter injections for home-manager # pkgs.vimPlugins.hmts-nvim # Tree-sitter injections for home-manager
+4 -1
View File
@@ -1,6 +1,9 @@
# Fix: Volnoti error: 'volnoti' has been removed due to lack of maintenance upstream. # Fix: Volnoti error: 'volnoti' has been removed due to lack of maintenance upstream.
{ pkgs, lib, ... }: { pkgs, lib, ... }:
if !pkgs.stdenv.hostPlatform.isLinux then
null
else
pkgs.stdenv.mkDerivation { pkgs.stdenv.mkDerivation {
pname = "volnoti"; pname = "volnoti";
version = "2013-09-23"; version = "2013-09-23";
@@ -27,7 +30,7 @@ pkgs.stdenv.mkDerivation {
dbus dbus
gdk-pixbuf gdk-pixbuf
glib glib
xorg.libX11 libx11
gtk2 gtk2
dbus-glib dbus-glib
librsvg librsvg
+3 -14
View File
@@ -2,21 +2,10 @@
{ {
pkgs, pkgs,
fetchFromGitHub,
... ...
}: }:
# Maintain a static version so that the plugin hash doesn't keep breaking pkgs.caddy.withPlugins {
(pkgs.caddy.overrideAttrs rec {
version = "2.10.2";
src = fetchFromGitHub {
owner = "caddyserver";
repo = "caddy";
tag = "v${version}";
hash = "sha256-KvikafRYPFZ0xCXqDdji1rxlkThEDEOHycK8GP5e8vk=";
};
}).withPlugins
{
plugins = [ "github.com/caddy-dns/cloudflare@v0.2.1" ]; plugins = [ "github.com/caddy-dns/cloudflare@v0.2.1" ];
hash = "sha256-AcWko5513hO8I0lvbCLqVbM1eWegAhoM0J0qXoWL/vI="; hash = "sha256-HuVBmiT3kD6RrDejQ6SnjCN8f7pFdZlGtZFbEf47bks=";
} }
@@ -0,0 +1,41 @@
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();
}
});
@@ -0,0 +1,25 @@
{
"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
@@ -0,0 +1,26 @@
{ 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
@@ -0,0 +1,25 @@
<!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
@@ -0,0 +1,9 @@
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,6 +89,13 @@ let
drf-access-policy drf-access-policy
# psycopg-binary # 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;
});
}; };
}; };
+11 -10
View File
@@ -1,9 +1,10 @@
{ {
lib, lib,
fetchFromGitHub, fetchFromGitHub,
nodejs_20, nodejs_22,
buildNpmPackage, buildNpmPackage,
nodePackages, typescript,
node-gyp,
python3, python3,
gcc, gcc,
gnumake, gnumake,
@@ -29,10 +30,10 @@ buildNpmPackage (finalAttrs: rec {
npmDepsHash = "sha256-N8xqRYFelolNGTEhG22M7KJ7B5U/uW7o+/XfLF8rHMg="; npmDepsHash = "sha256-N8xqRYFelolNGTEhG22M7KJ7B5U/uW7o+/XfLF8rHMg=";
nativeBuildInputs = [ nativeBuildInputs = [
nodejs_20 nodejs_22
nodePackages.typescript typescript
python3 python3
nodePackages.node-gyp node-gyp
gcc gcc
gnumake gnumake
]; ];
@@ -53,8 +54,8 @@ buildNpmPackage (finalAttrs: rec {
# export npm_config_build_from_source=true # export npm_config_build_from_source=true
# export npm_config_unsafe_perm=true # export npm_config_unsafe_perm=true
# export BINARY_SITE=none # export BINARY_SITE=none
# export PATH=${nodePackages.node-gyp}/bin:$PATH # export PATH=${node-gyp}/bin:$PATH
# export npm_config_node_gyp=${nodePackages.node-gyp}/bin/node-gyp # export npm_config_node_gyp=${node-gyp}/bin/node-gyp
# npm rebuild better-sqlite3 --build-from-source --verbose # npm rebuild better-sqlite3 --build-from-source --verbose
@@ -64,7 +65,7 @@ buildNpmPackage (finalAttrs: rec {
installPhase = '' installPhase = ''
mkdir -p $out/{bin,lib} mkdir -p $out/{bin,lib}
cp -r . $out/lib/prometheus-actual-exporter cp -r . $out/lib/prometheus-actual-exporter
makeWrapper ${lib.getExe nodejs_20} $out/bin/prometheus-actual-exporter \ makeWrapper ${lib.getExe nodejs_22} $out/bin/prometheus-actual-exporter \
--add-flags "$out/lib/prometheus-actual-exporter/dist/app.js" --add-flags "$out/lib/prometheus-actual-exporter/dist/app.js"
''; '';
@@ -74,8 +75,8 @@ buildNpmPackage (finalAttrs: rec {
export npm_config_build_from_source=true export npm_config_build_from_source=true
export npm_config_unsafe_perm=true export npm_config_unsafe_perm=true
export BINARY_SITE=none export BINARY_SITE=none
export PATH=${nodePackages.node-gyp}/bin:$PATH export PATH=${node-gyp}/bin:$PATH
export npm_config_node_gyp=${nodePackages.node-gyp}/bin/node-gyp export npm_config_node_gyp=${node-gyp}/bin/node-gyp
sed -i '/"install"/d' node_modules/better-sqlite3/package.json sed -i '/"install"/d' node_modules/better-sqlite3/package.json
rm -f node_modules/better-sqlite3/build/Release/better_sqlite3.node || true rm -f node_modules/better-sqlite3/build/Release/better_sqlite3.node || true
+6 -3
View File
@@ -1,11 +1,15 @@
{ {
lib, lib,
stdenv,
buildDotnetModule, buildDotnetModule,
fetchFromGitHub, fetchFromGitHub,
dotnetCorePackages, dotnetCorePackages,
}: }:
buildDotnetModule rec { if !stdenv.hostPlatform.isLinux then
null
else
buildDotnetModule rec {
pname = "slsk-batchdl"; pname = "slsk-batchdl";
version = "2.4.7"; version = "2.4.7";
@@ -22,7 +26,6 @@ buildDotnetModule rec {
dotnet-sdk = dotnetCorePackages.sdk_8_0; dotnet-sdk = dotnetCorePackages.sdk_8_0;
dotnet-runtime = dotnetCorePackages.runtime_8_0; dotnet-runtime = dotnetCorePackages.runtime_8_0;
# Patch the project file to use .NET 8
postPatch = '' postPatch = ''
substituteInPlace slsk-batchdl/slsk-batchdl.csproj \ substituteInPlace slsk-batchdl/slsk-batchdl.csproj \
--replace-fail "net6.0" "net8.0" --replace-fail "net6.0" "net8.0"
@@ -36,4 +39,4 @@ buildDotnetModule rec {
platforms = platforms.linux; platforms = platforms.linux;
mainProgram = "slsk-batchdl"; mainProgram = "slsk-batchdl";
}; };
} }
+1 -1
View File
@@ -19,4 +19,4 @@ aws ec2 describe-instances \
--layout reverse \ --layout reverse \
--header $'Press Enter to start SSM session\nInstance ID - Private IP - Public IP - Name' \ --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]'" \ --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))" --bind "enter:become(aws ssm start-session --document-name 'AWS-StartInteractiveCommand' --parameters '{\"command\": [\"bash\"]}' --target \$(echo {} | cut -d' ' -f1))"
@@ -5,7 +5,7 @@ pkgs.mkShell {
buildInputs = with pkgs; [ buildInputs = with pkgs; [
git git
stylua stylua
nixfmt-rfc-style nixfmt
shfmt shfmt
shellcheck shellcheck
]; ];
+6 -3
View File
@@ -1,9 +1,12 @@
{ pkgs, ... }: { pkgs, lib, ... }:
# Inspired by https://github.com/cleverca22/nix-tests/blob/master/kexec/justdoit.nix # 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! # This script will partition and format drives; use at your own risk!
pkgs.writeShellScriptBin "installer" '' if !pkgs.stdenv.hostPlatform.isLinux then
null
else
pkgs.writeShellScriptBin "installer" ''
set -e set -e
DISK=$1 DISK=$1
@@ -41,4 +44,4 @@ pkgs.writeShellScriptBin "installer" ''
mount /dev/disk/by-label/boot /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}
'' ''
+2 -2
View File
@@ -1,8 +1,8 @@
{ pkgs, ... }: { pkgs, ... }:
pkgs.writeShellScriptBin "rebuild" '' pkgs.writeShellScriptBin "rebuild" ''
echo ${pkgs.system} echo ${pkgs.stdenv.hostPlatform.system}
SYSTEM=${if pkgs.stdenv.isDarwin then "darwin" else "linux"} SYSTEM=${if pkgs.stdenv.hostPlatform.isDarwin then "darwin" else "linux"}
if [ "$SYSTEM" == "darwin" ]; then if [ "$SYSTEM" == "darwin" ]; then
sudo darwin-rebuild switch --flake ${builtins.toString ../../../../.} sudo darwin-rebuild switch --flake ${builtins.toString ../../../../.}
else else
@@ -17,23 +17,27 @@ in
home.packages = [ home.packages = [
pkgs.nerd-fonts.victor-mono # Used for Vim and Terminal pkgs.nerd-fonts.victor-mono # Used for Vim and Terminal
pkgs.nerd-fonts.hack # For Polybar, Rofi pkgs.nerd-fonts.hack # For Polybar, Rofi
# Maple Mono NF (Ligature unhinted)
pkgs.maple-mono.NF-unhinted
]; ];
fonts.fontconfig = { fonts.fontconfig = {
enable = true; enable = true;
defaultFonts.monospace = [ "Victor Mono" ]; defaultFonts.monospace = [ "Maple Mono NF" ];
}; };
xsession.windowManager.i3.config.fonts = { xsession.windowManager.i3.config.fonts = {
names = [ "pango:Victor Mono" ]; # names = [ "pango:Victor Mono" ];
names = [ "pango:Maple Mono" ];
# style = "Regular"; # style = "Regular";
# size = 11.0; # size = 11.0;
}; };
services.polybar.config."bar/main".font-0 = "Hack Nerd Font:size=10;2"; services.polybar.config."bar/main".font-0 = "Hack Nerd Font:size=10;2";
programs.rofi.font = "Hack Nerd Font 14"; programs.rofi.font = "Hack Nerd Font 14";
programs.alacritty.settings.font.normal.family = "VictorMono"; programs.alacritty.settings.font.normal.family = "Maple Mono NF";
programs.kitty.font.name = "VictorMono Nerd Font Mono"; programs.kitty.font.name = "Maple Mono NF";
nmasur.presets.programs.wezterm.font = "VictorMono Nerd Font Mono"; nmasur.presets.programs.wezterm.font = "Maple Mono NF";
programs.ghostty.settings.font-family = "VictorMono Nerd Font Mono"; programs.ghostty.settings.font-family = "Maple Mono NF";
services.dunst.settings.global.font = "Hack Nerd Font 14"; services.dunst.settings.global.font = "Hack Nerd Font 14";
}; };
} }
@@ -25,6 +25,7 @@ in
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
# Cursor # Cursor
home.pointerCursor = { home.pointerCursor = {
enable = true;
name = "Adwaita"; name = "Adwaita";
package = pkgs.adwaita-icon-theme; package = pkgs.adwaita-icon-theme;
size = 24; size = 24;
@@ -48,6 +49,7 @@ in
gtk4.extraConfig = { gtk4.extraConfig = {
gtk-application-prefer-dark-theme = config.theme.mode == "dark"; gtk-application-prefer-dark-theme = config.theme.mode == "dark";
}; };
gtk4.theme = null;
}; };
}; };
@@ -18,16 +18,17 @@ in
"1password" "1password"
"_1password-gui" "_1password-gui"
"1password-cli" "1password-cli"
"onepassword-password-manager" # Firefox extension # "onepassword-password-manager" # Firefox extension
]; ];
home.packages = [ home.packages = [
pkgs._1password-cli pkgs._1password-cli
] ++ (if pkgs.stdenv.isLinux then [ pkgs._1password-gui ] else [ ]); ]
++ (if pkgs.stdenv.hostPlatform.isLinux then [ pkgs._1password-gui ] else [ ]);
# Firefox extension # # Firefox extension
programs.firefox.profiles.default.extensions.packages = [ # programs.firefox.profiles.default.extensions.packages = [
pkgs.nur.repos.rycee.firefox-addons.onepassword-password-manager # pkgs.nur.repos.rycee.firefox-addons.onepassword-password-manager
]; # ];
}; };
# # https://1password.community/discussion/135462/firefox-extension-does-not-connect-to-linux-app # # https://1password.community/discussion/135462/firefox-extension-does-not-connect-to-linux-app
@@ -174,8 +174,10 @@ in
filters = { filters = {
"text/plain" = "${pkgs.aerc}/libexec/aerc/filters/colorize"; "text/plain" = "${pkgs.aerc}/libexec/aerc/filters/colorize";
"text/calendar" = "${pkgs.gawk}/bin/awk -f ${pkgs.aerc}/libexec/aerc/filters/calendar"; "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" = "text/html" =
"${pkgs.aerc}/libexec/aerc/filters/html | ${pkgs.aerc}/libexec/aerc/filters/colorize"; # Requires w3m, dante "!${pkgs.chawan}/bin/cha --type text/html --opt display.image-mode=kitty --opt display.columns=100 --opt display.force-columns=true";
# "text/*" = # "text/*" =
# ''${pkgs.bat}/bin/bat -fP --file-name="$AERC_FILENAME "''; # ''${pkgs.bat}/bin/bat -fP --file-name="$AERC_FILENAME "'';
"message/delivery-status" = "${pkgs.aerc}/libexec/aerc/filters/colorize"; "message/delivery-status" = "${pkgs.aerc}/libexec/aerc/filters/colorize";
@@ -200,11 +202,14 @@ in
}; };
}; };
xdg.desktopEntries.aerc = lib.mkIf (pkgs.stdenv.isLinux) { # Used for macOS
xdg.enable = lib.mkIf pkgs.stdenv.hostPlatform.isDarwin true;
xdg.desktopEntries.aerc = lib.mkIf (pkgs.stdenv.hostPlatform.isLinux) {
name = "aerc"; name = "aerc";
exec = "${lib.getExe config.nmasur.presets.services.i3.terminal} aerc %u"; exec = "${lib.getExe config.nmasur.presets.services.i3.terminal} -e aerc %u";
}; };
xsession.windowManager.i3.config.keybindings = lib.mkIf pkgs.stdenv.isLinux { xsession.windowManager.i3.config.keybindings = lib.mkIf pkgs.stdenv.hostPlatform.isLinux {
"${config.xsession.windowManager.i3.config.modifier}+Shift+e" = "${config.xsession.windowManager.i3.config.modifier}+Shift+e" =
let let
terminal = config.nmasur.presets.services.i3.terminal; terminal = config.nmasur.presets.services.i3.terminal;
@@ -212,7 +217,7 @@ in
if terminal == pkgs.wezterm then if terminal == pkgs.wezterm then
"start --class com.noah.aerc -- aerc" "start --class com.noah.aerc -- aerc"
else else
"--class=com.noah.aerc --command=aerc"; "--class=com.noah.aerc -e aerc";
in in
"exec ${ "exec ${
# Don't name the script `aerc` or it will affect grep # Don't name the script `aerc` or it will affect grep
@@ -32,7 +32,6 @@ in
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
accounts.calendar.accounts.default = { accounts.calendar.accounts.default = {
basePath = "other/calendars"; # Where to save calendars in ~ directory
name = "personal"; name = "personal";
local.type = "filesystem"; local.type = "filesystem";
primary = true; primary = true;
@@ -14,9 +14,14 @@ in
options.nmasur.presets.programs.calibre.enable = lib.mkEnableOption "Calibre e-book manager"; options.nmasur.presets.programs.calibre.enable = lib.mkEnableOption "Calibre e-book manager";
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
home.packages = [ pkgs.calibre ]; home.packages = lib.mkIf pkgs.stdenv.hostPlatform.isLinux [ pkgs.calibre ];
home.sessionVariables = { home.sessionVariables = {
CALIBRE_USE_DARK_PALETTE = 1; CALIBRE_USE_DARK_PALETTE = 1;
}; };
home.file.".Brewfile".text = lib.mkIf pkgs.stdenv.hostPlatform.isDarwin /* homebrew */ ''
cask "calibre" # Nix package broken on macOS
'';
}; };
} }
@@ -18,15 +18,16 @@ in
ca = "cargo"; ca = "cargo";
}; };
home.packages = with pkgs; [ home.packages = [
gcc pkgs.gcc
rustc pkgs.rustc
cargo pkgs.cargo
cargo-watch pkgs.stable.cargo-watch
clippy pkgs.clippy
rustfmt pkgs.rustfmt
pkg-config pkgs.pkg-config
openssl pkgs.openssl
pkgs.rust-analyzer
]; ];
}; };
} }
@@ -0,0 +1,34 @@
{
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.hostPlatform.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 { config = lib.mkIf cfg.enable {
# Always make the dotfiles directory considered safe for git and direnv # Always make the dotfiles directory considered safe for git and direnv
programs.git.extraConfig.safe.directory = cfg.path; programs.git.settings.safe.directory = cfg.path;
programs.direnv.config.whitelist.prefix = [ cfg.path ]; programs.direnv.config.whitelist.prefix = [ cfg.path ];
home.activation = { home.activation = {
@@ -24,6 +24,8 @@ in
programs.firefox = { programs.firefox = {
enable = true; enable = true;
package = pkgs.firefox; package = pkgs.firefox;
# Use appropriate default path depending on the OS
configPath = if pkgs.stdenv.hostPlatform.isDarwin then "Library/Application Support/Firefox" else ".mozilla/firefox";
profiles.default = { profiles.default = {
id = 0; id = 0;
name = "default"; name = "default";
@@ -46,6 +48,8 @@ in
ublacklist ublacklist
vimium vimium
wappalyzer # TODO: only for work profile wappalyzer # TODO: only for work profile
# pkgs.nmasur.firefox-history-exporter
# copy-as-markdown
# saml-tracer # saml-tracer
# text-fragment # text-fragment
]; ];
@@ -53,7 +57,7 @@ in
"app.update.auto" = false; "app.update.auto" = false;
"browser.aboutConfig.showWarning" = false; "browser.aboutConfig.showWarning" = false;
"browser.warnOnQuit" = false; "browser.warnOnQuit" = false;
"browser.quitShortcut.disabled" = if pkgs.stdenv.isLinux then true else false; "browser.quitShortcut.disabled" = if pkgs.stdenv.hostPlatform.isLinux then true else false;
"browser.theme.dark-private-windows" = true; "browser.theme.dark-private-windows" = true;
"browser.toolbars.bookmarks.visibility" = false; "browser.toolbars.bookmarks.visibility" = false;
"browser.startup.page" = 3; # Restore previous session "browser.startup.page" = 3; # Restore previous session
@@ -61,6 +65,7 @@ in
"trailhead.firstrun.didSeeAboutWelcome" = true; # Disable welcome splash "trailhead.firstrun.didSeeAboutWelcome" = true; # Disable welcome splash
"dom.forms.autocomplete.formautofill" = false; # Disable autofill "dom.forms.autocomplete.formautofill" = false; # Disable autofill
"extensions.formautofill.creditCards.enabled" = false; # Disable credit cards "extensions.formautofill.creditCards.enabled" = false; # Disable credit cards
"extensions.autoDisableScopes" = false; # Enable extensions automatically
"dom.payments.defaults.saveAddress" = false; # Disable address save "dom.payments.defaults.saveAddress" = false; # Disable address save
"general.autoScroll" = true; # Drag middle-mouse to scroll "general.autoScroll" = true; # Drag middle-mouse to scroll
"services.sync.prefs.sync.general.autoScroll" = false; # Prevent disabling autoscroll "services.sync.prefs.sync.general.autoScroll" = false; # Prevent disabling autoscroll
@@ -184,10 +189,10 @@ in
}; };
xsession.windowManager.i3.config.keybindings = lib.mkIf pkgs.stdenv.isLinux { xsession.windowManager.i3.config.keybindings = lib.mkIf pkgs.stdenv.hostPlatform.isLinux {
"${config.xsession.windowManager.i3.config.modifier}+Shift+b" = "exec ${ "${config.xsession.windowManager.i3.config.modifier}+Shift+b" = "exec ${
# Don't name the script `firefox` or it will affect grep # Don't name the script `firefox` or it will affect grep
builtins.toString ( toString (
pkgs.writeShellScript "focus-ff.sh" '' pkgs.writeShellScript "focus-ff.sh" ''
count=$(ps aux | grep -c firefox) count=$(ps aux | grep -c firefox)
if [ "$count" -eq 1 ]; then if [ "$count" -eq 1 ]; then
@@ -13,13 +13,35 @@ in
options.nmasur.presets.programs.fish-darwin.enable = lib.mkEnableOption { options.nmasur.presets.programs.fish-darwin.enable = lib.mkEnableOption {
description = "Fish macOS options"; description = "Fish macOS options";
default = config.nmasur.presets.programs.fish && pkgs.stdenv.isDarwin;
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
programs.fish.shellAbbrs = { # Default shell setting doesn't work
home.sessionVariables = {
SHELL = "${pkgs.fish}/bin/fish";
};
programs.fish = {
shellAbbrs = {
# Shortcut to edit hosts file # Shortcut to edit hosts file
hosts = "sudo nvim /etc/hosts"; 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;
}; };
}; };
} }
@@ -114,10 +114,17 @@ in
dr = "docker run --rm -it"; dr = "docker run --rm -it";
db = "docker build . -t"; db = "docker build . -t";
}; };
shellInit = ""; shellInit = ''
# Fix for lagging/hanging after exiting TUIs inside terminal multiplexers like Zellij:
# Disable fish terminal querying at startup so fish does not query DA1/termcap on return.
set -gx fish_features no-query-term
'';
}; };
home.sessionVariables.fish_greeting = ""; home.sessionVariables = {
fish_greeting = "";
fish_features = "no-query-term";
};
}; };
} }
@@ -21,9 +21,9 @@ in
programs.ghostty = { programs.ghostty = {
enable = true; enable = true;
package = if pkgs.stdenv.isDarwin then null else pkgs.ghostty; package = if pkgs.stdenv.hostPlatform.isDarwin then pkgs.ghostty-bin else pkgs.ghostty;
enableFishIntegration = true; enableFishIntegration = false; # Handled conditionally below to avoid conflicts inside Zellij/TMUX
enableBashIntegration = true; enableBashIntegration = true;
enableZshIntegration = true; enableZshIntegration = true;
installBatSyntax = false; # The file doesn't seem to exist in the pkg installBatSyntax = false; # The file doesn't seem to exist in the pkg
@@ -33,18 +33,21 @@ in
macos-titlebar-style = "hidden"; macos-titlebar-style = "hidden";
window-decoration = false; window-decoration = false;
macos-non-native-fullscreen = true; macos-non-native-fullscreen = true;
quit-after-last-window-closed = lib.mkIf pkgs.stdenv.isDarwin true; quit-after-last-window-closed = lib.mkIf pkgs.stdenv.hostPlatform.isDarwin true;
fullscreen = if pkgs.stdenv.isDarwin then true else false; fullscreen = if pkgs.stdenv.hostPlatform.isDarwin then true else false;
keybind = [ keybind = [
"super+t=unbind" # Pass super-t to underlying tool (e.g. zellij tabs) # Translate Mac Super & Ctrl combinations into Alt (ESC prefix) sequences
"super+shift+bracket_right=unbind" # so Zellij receives them without needing Kitty keyboard protocol
"super+shift+bracket_left=unbind" "super+t=text:\\x1bt"
"ctrl+tab=unbind" "super+shift+]=text:\\x1b}"
"ctrl+shift+tab=unbind" "super+shift+[=text:\\x1b{"
"ctrl+tab=text:\\x1b[9;5u" "ctrl+tab=text:\\x1b}"
"ctrl+shift+tab=text:\\x1b[9;6u" "ctrl+shift+tab=text:\\x1b{"
"super+k=unbind" "super+k=text:\\x1bK"
"super+shift+e=unbind" "super+shift+e=text:\\x1bE"
# Send CSI-u sequence for Alt+Shift+P / Super+Shift+P to bypass Zellij 0.45's DCS (ESC P) parser timeout (~1.5s delay)
"alt+shift+p=text:\\x1b[112;4u"
"super+shift+p=text:\\x1b[112;4u"
]; ];
}; };
themes."gruvbox" = { themes."gruvbox" = {
@@ -81,5 +84,12 @@ in
}; };
# Conditionally enable Ghostty fish shell integration only when NOT running inside multiplexers like Zellij/TMUX
programs.fish.shellInit = ''
if set -q GHOSTTY_RESOURCES_DIR; and not set -q ZELLIJ; and not set -q TMUX
source "$GHOSTTY_RESOURCES_DIR/shell-integration/fish/vendor_conf.d/ghostty-shell-integration.fish"
end
'';
}; };
} }
@@ -39,8 +39,19 @@ in
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
programs.git = { programs.git = {
userName = lib.mkForce cfg.work.name; settings = {
userEmail = lib.mkForce cfg.work.email; user = {
name = lib.mkForce cfg.work.name;
email = lib.mkForce cfg.work.email;
signingKey = "~/.ssh/work_github";
};
commit = {
gpgsign = true;
};
tag = {
gpgsign = true;
};
};
includes = [ includes = [
{ {
path = "${config.home.homeDirectory}/${config.xdg.configFile."git/personal".target}"; path = "${config.home.homeDirectory}/${config.xdg.configFile."git/personal".target}";
@@ -50,6 +61,11 @@ in
}; };
# Add work to signers file
xdg.configFile."git/allowed-signers".text = ''
${cfg.work.email} ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIP7aXbmKHmWUZgwG5HPtwx+nREVeMIRplpAAzxPOFXL
'';
# Personal git config # Personal git config
xdg.configFile."git/personal".text = lib.generators.toGitINI { xdg.configFile."git/personal".text = lib.generators.toGitINI {
user = { user = {
@@ -57,12 +73,6 @@ in
email = cfg.personal.email; email = cfg.personal.email;
signingkey = "~/.ssh/id_ed25519"; signingkey = "~/.ssh/id_ed25519";
}; };
commit = {
gpgsign = true;
};
tag = {
gpgsign = true;
};
}; };
# Personal jj config # Personal jj config
@@ -29,9 +29,11 @@ in
programs.git = { programs.git = {
enable = true; enable = true;
userName = cfg.name; settings = {
userEmail = cfg.email; user = {
extraConfig = { name = cfg.name;
email = cfg.email;
};
core.pager = "${pkgs.git}/share/git/contrib/diff-highlight/diff-highlight | less --no-init"; 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"; interactive.difffilter = "${pkgs.git}/share/git/contrib/diff-highlight/diff-highlight";
pager = { pager = {
@@ -63,7 +65,7 @@ in
}; };
xdg.configFile."git/allowed-signers".text = '' xdg.configFile."git/allowed-signers".text = ''
7386960+nmasur@users.noreply.github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB+AbmjGEwITk5CK9y7+Rg27Fokgj9QEjgc9wST6MA3s ${config.nmasur.presets.programs.git.email} ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB+AbmjGEwITk5CK9y7+Rg27Fokgj9QEjgc9wST6MA3s
''; '';
programs.fish.shellAbbrs = { programs.fish.shellAbbrs = {
@@ -22,7 +22,6 @@ in
extensions = [ extensions = [
pkgs.nmasur.gh-collaborators pkgs.nmasur.gh-collaborators
pkgs.gh-dash pkgs.gh-dash
pkgs.gh-copilot
]; ];
}; };
@@ -7,6 +7,62 @@
let let
cfg = config.nmasur.presets.programs.helix; 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 in
{ {
@@ -16,13 +72,13 @@ in
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
# Use Neovim as the editor for git commit messages # Use Neovim as the editor for git commit messages
programs.git.extraConfig.core.editor = lib.mkForce "${lib.getExe pkgs.helix}"; programs.git.settings.core.editor = lib.mkForce "${lib.getExe pkgs.helix}";
programs.jujutsu.settings.ui.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 # Set Neovim as the default app for text editing and manual pages
home.sessionVariables = { home.sessionVariables = {
EDITOR = lib.mkForce "${lib.getExe pkgs.helix}"; 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; MANWIDTH = 87;
MANROFFOPT = "-c"; MANROFFOPT = "-c";
}; };
@@ -62,6 +118,11 @@ in
command = lib.getExe pkgs.marksman; command = lib.getExe pkgs.marksman;
}; };
language-server.rumdl = {
command = lib.getExe pkgs.rumdl;
args = [ "server" ];
};
language-server.terraform-ls = { language-server.terraform-ls = {
command = "${lib.getExe pkgs.terraform-ls}"; command = "${lib.getExe pkgs.terraform-ls}";
args = [ "serve" ]; args = [ "serve" ];
@@ -87,10 +148,16 @@ in
{ {
name = "markdown"; name = "markdown";
auto-format = false; auto-format = false;
language-servers = [ "marksman" ]; language-servers = [
"marksman"
"rumdl"
];
formatter = { formatter = {
command = lib.getExe pkgs.mdformat; command = lib.getExe pkgs.rumdl;
args = [ "-" ]; args = [
"fmt"
"-"
];
}; };
# Allows return key to continue the token on the next line # Allows return key to continue the token on the next line
comment-tokens = [ comment-tokens = [
@@ -102,9 +169,18 @@ in
]; ];
} }
{ {
name = "tfvars"; name = "hcl";
scope = "source.hcl";
# injection-regex = "terraform";
auto-format = true; auto-format = true;
language-servers = [ "terraform-ls" ]; language-servers = [ "terraform-ls" ];
language-id = "terraform";
file-types = [
"tf"
"tfvars"
"terraform"
{ glob = "*.auto.tfvars"; }
];
formatter = { formatter = {
command = lib.getExe pkgs.terraform; command = lib.getExe pkgs.terraform;
args = [ args = [
@@ -114,11 +190,15 @@ in
}; };
} }
{ {
name = "hcl"; name = "hcl-packer";
scope = "source.hcl-packer";
auto-format = true; auto-format = true;
language-servers = [ "terraform-ls" ]; file-types = [
"hcl"
"pkr.hcl"
];
formatter = { formatter = {
command = lib.getExe pkgs.terraform; command = "${pkgs.packer}/bin/packer";
args = [ args = [
"fmt" "fmt"
"-" "-"
@@ -179,18 +259,9 @@ in
]; ];
# Commandline git blame # 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 = ":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 }'';
# Open yazi space.i = '':open %sh{ ${blame_file_pretty}/bin/blame_file_pretty "%{buffer_name}" %{cursor_line} 3 }'';
# 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 # Extend selection above
X = "select_line_above"; X = "select_line_above";
@@ -256,6 +327,10 @@ in
git-exclude = true; # Skip excluded files 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 # Show whitespace visible to the user
# Waiting for trailing whitespace option ideally # Waiting for trailing whitespace option ideally
whitespace = { whitespace = {
@@ -272,7 +347,7 @@ in
}; };
themes."${config.programs.helix.settings.theme}" = { themes.base16 = {
"attributes" = config.theme.colors.base09; "attributes" = config.theme.colors.base09;
"comment" = { "comment" = {
fg = config.theme.colors.base03; fg = config.theme.colors.base03;
@@ -452,7 +527,219 @@ 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.hostPlatform.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"$@" '')
];
}; };
@@ -0,0 +1,83 @@
{
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,6 +7,7 @@
let let
cfg = config.nmasur.presets.programs.jujutsu; cfg = config.nmasur.presets.programs.jujutsu;
tomlFormat = pkgs.formats.toml { };
in in
{ {
@@ -20,8 +21,8 @@ in
# https://github.com/martinvonz/jj/blob/main/docs/config.md # https://github.com/martinvonz/jj/blob/main/docs/config.md
settings = { settings = {
user = { user = {
name = config.programs.git.userName; name = config.programs.git.settings.user.name;
email = config.programs.git.userEmail; email = config.programs.git.settings.user.email;
}; };
ui.paginate = "never"; ui.paginate = "never";
@@ -31,9 +32,37 @@ 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 = [ home.packages = [
# Required for the fsmonitor to auto-snapshot # Required for the fsmonitor to auto-snapshot
pkgs.watchman pkgs.watchman
# Required to be on path to work in Zellij
pkgs.jjui
]; ];
}; };
@@ -18,7 +18,7 @@ in
nmasur.presets.services.i3.terminal = pkgs.kitty; nmasur.presets.services.i3.terminal = pkgs.kitty;
# Set the Rofi terminal for running programs # Set the Rofi terminal for running programs
programs.rofi.terminal = lib.mkIf pkgs.stdenv.isLinux (lib.mkDefault "${pkgs.kitty}/bin/kitty"); programs.rofi.terminal = lib.mkIf pkgs.stdenv.hostPlatform.isLinux (lib.mkDefault "${pkgs.kitty}/bin/kitty");
# Display images in the terminal # Display images in the terminal
programs.fish.interactiveShellInit = # fish programs.fish.interactiveShellInit = # fish
@@ -0,0 +1,72 @@
{
config,
pkgs,
lib,
...
}:
let
cfg = config.nmasur.presets.programs.lag-triage;
term-probe = pkgs.writeScriptBin "term-probe" ''
#!${lib.getExe pkgs.python3}
${builtins.readFile ./term_probe.py}
'';
in
{
options.nmasur.presets.programs.lag-triage.enable =
lib.mkEnableOption "Terminal input-lag triage tools";
config = lib.mkIf cfg.enable {
home.packages = [ term-probe ];
# Ctrl-b: EXECUTE the proven manual cure as a real commandline. The cure
# is not the variable's end value (it starts and ends at 1) — it is the
# reader fully exiting readline and re-entering, which only command
# EXECUTION does. Setting the variable inline (a plain binding body, or the
# old fish_postexec/fish_cancel hook) never makes the reader exit/re-enter,
# so it never cured and, with extra repaints on a wedged reader, made it
# worse. `commandline -f execute` reproduces exactly what typing the cure
# and pressing Enter does — indistinguishable to fish from the manual cure.
# Note: this submits the current commandline, so it runs the cure in place
# of whatever is typed (fine for a rescue key hit at an empty prompt).
# Ctrl-b chosen because it is otherwise unbound (Ctrl-g is taken).
nmasur.presets.programs.fish.fish_user_key_bindings = # fish
''
for mode in insert default visual
bind -M $mode \cb heal-autosuggest
end
'';
programs.fish.functions = {
lag-triage = {
description = "Diagnose post-TUI typing lag in the current shell";
body = builtins.readFile ./lag-triage.fish;
};
unlag = {
description = "Reset terminal state left behind by a TUI";
body = builtins.readFile ./unlag.fish;
};
lag-sample = {
description = "Stack-sample fish and zellij while typing lag is happening";
body = builtins.readFile ./lag-sample.fish;
};
heal-autosuggest = {
description = "Heal post-TUI typing lag by executing the autosuggestion-toggle cure (bind to a key)";
# Replace the commandline with the exact cure the user runs by hand and
# execute it. Executing (not inline-setting) is what cures: it forces
# the reader to leave and re-enter readline. Runs in place of whatever
# is currently typed.
body = # fish
''
commandline -r 'set -g fish_autosuggestion_enabled 0; and set -g fish_autosuggestion_enabled 1'
commandline -f execute
'';
};
};
};
}
@@ -0,0 +1,53 @@
# Capture stack samples of this fish process, the zellij server, and the
# zellij client WHILE the typing lag is happening. This names the guilty
# component directly: if fish's main thread is busy/blocked per keystroke the
# stacks show exactly where; if fish is idle while typing feels laggy, the
# delay is in zellij's render path instead.
#
# CAUTION (learned 2026-08-30): attaching the sampler to a lagging fish CURES
# the lag (thread suspend/resume unwedges it), so run this from a DIFFERENT
# pane with the lagging shell's pid: `lag-sample <pid>` (get it in the lagging
# shell with the builtin-only `echo $fish_pid`). Have someone type in the
# lagging pane while sampling runs — the first samples may catch the wedge.
# With no argument it samples the current shell.
set -l target $fish_pid
if test (count $argv) -ge 1; and test -n "$argv[1]"
set target $argv[1]
end
set -l outdir ~/.local/state/lag-triage
mkdir -p $outdir
set -l ts (date +%Y%m%d-%H%M%S)
set -l dur 8
set -l fishfile $outdir/sample-$ts-fish-$target.txt
/usr/bin/sample $target $dur 1 -file $fishfile &>/dev/null &
disown
# this session's zellij server (socket path ends in the session name)
set -l serverpid (pgrep -f "zellij --server.*/$ZELLIJ_SESSION_NAME\$")
test -z "$serverpid"; and set serverpid (pgrep -f "zellij --server" | head -3)
for pid in $serverpid
/usr/bin/sample $pid $dur 1 -file $outdir/sample-$ts-zellij-server-$pid.txt &>/dev/null &
disown
end
# zellij clients (attached to ghostty): named zellij but without --server args
set -l allserver (pgrep -f "zellij --server")
set -l clientpid
for pid in (pgrep -x zellij)
contains $pid $allserver; or set -a clientpid $pid
end
for pid in $clientpid[1..3]
/usr/bin/sample $pid $dur 1 -file $outdir/sample-$ts-zellij-client-$pid.txt &>/dev/null &
disown
end
# notify when done, without occupying the commandline
fish -c "sleep (math $dur + 2); echo; echo '== lag-sample done: '$outdir'/sample-$ts-*.txt =='" &
disown
echo "Sampling fish (pid $target), zellij server(s) [$serverpid], client(s) [$clientpid] for $dur s."
echo ">>> TYPE CONTINUOUSLY IN THE LAGGING PANE NOW (junk text is fine) <<<"
echo "Files: $outdir/sample-$ts-*.txt"
@@ -0,0 +1,182 @@
# Guided diagnosis for the post-TUI typing-lag problem (Ghostty + Zellij + fish).
# Run this IN THE LAGGING SHELL the moment you notice the lag, BEFORE starting
# a new shell. It captures evidence, then applies targeted resets one at a time
# so the stage that cures the lag identifies the layer holding stuck state.
# Everything is logged for filing an upstream issue.
set -l logdir ~/.local/state/lag-triage
mkdir -p $logdir
set -l logfile $logdir/(date +%Y%m%d-%H%M%S).log
function _lt --inherit-variable logfile
echo $argv | tee -a $logfile
end
function _lt_ask --inherit-variable logfile
# usage: _lt_ask VARNAME prompt... -> sets global $VARNAME (default: skip)
set -l __name $argv[1]
read -g -P "$argv[2..] " $__name
or set -g $__name skip
test -z "$$__name"; and set -g $__name skip
echo "ANSWER $__name: $$__name" >>$logfile
end
_lt "== lag-triage "(date)" =="
_lt "Log: $logfile"
_lt "Answer y / n, or press Enter to skip a question."
_lt ""
# ---- 1. Context -------------------------------------------------------------
_lt_ask ans_tui "Which TUI did you just exit (nvim/jjui/yazi/other)?"
_lt_ask ans_launch "Launched via (f)loating-pane keybind or (c)ommand typed in this shell?"
# ---- 2. Snapshot ------------------------------------------------------------
begin
echo "-- snapshot --"
fish --version
echo "fish pid: $fish_pid, started: "(ps -o lstart= -p $fish_pid 2>/dev/null)
zellij --version 2>/dev/null
echo "escape delay: '$fish_escape_delay_ms' sequence delay: '$fish_sequence_key_delay_ms'"
env | grep -iE '^(TERM|ZELLIJ|GHOSTTY|COLORTERM)' | sort
echo "-- status features --"
status features
echo "-- stty -a --"
stty -a
end >>$logfile 2>&1
_lt "Captured shell + environment snapshot."
# Proven root cause of the 2026-08 lag (see docs/CHANGELOG.md 2026-08-29):
# fish latches feature flags from its startup env before config.fish runs, so
# a shell with query-term ON sends terminal queries after every command; one
# reply zellij fails to relay permanently degrades this process's reader.
if status features | string match -qr '^query-term\s+on'
_lt ""
_lt "!! query-term is ON in this shell: fish did NOT get fish_features="
_lt "!! no-query-term in its STARTUP environment (config.fish is too late)."
_lt "!! This is the proven root cause of the post-TUI lag — a query reply"
_lt "!! lost by zellij permanently degrades this fish process's reader."
_lt "!! Fix: spawn fish with the variable exported (zellij default_shell"
_lt "!! wrapper fish-no-query-term). Subshells are immune because they"
_lt "!! inherit the exported variable — that's why a new shell 'fixes' it."
else
_lt "query-term is off in this shell (good — the known root cause is ruled out)."
end
# ---- 3. Terminal state below the shell --------------------------------------
_lt ""
_lt "Querying terminal state (takes a few seconds)..."
term-probe report 2>&1 | tee -a $logfile
_lt ""
_lt " ^ Things to look for: kitty flags with a reply > 0, modifyOtherKeys > 1,"
_lt " any mouse/alternate-screen mode SET while at a shell prompt, or a slow"
_lt " DA1 round-trip (> 100 ms means the input path itself is delayed)."
# ---- 4. Raw keystroke capture (bypasses fish entirely) ----------------------
_lt ""
_lt "Raw input capture: type ~10 characters at a steady pace, including one"
_lt "ESC press and one arrow key. This shows the exact bytes this pane delivers"
_lt "and their timing, with fish's input handling out of the picture."
term-probe keylog 2>&1 | tee -a $logfile
_lt_ask ans_keylog_instant "Did each keypress appear INSTANTLY in the capture? (y/n)"
_lt_ask ans_keylog_plain "Were plain letters single plain bytes like b'a' (not escape sequences)? (y/n)"
# ---- 5. Scope ---------------------------------------------------------------
_lt ""
_lt_ask ans_scope_pane "Optional: open a NEW zellij pane/tab and type — laggy there too? (y/n)"
_lt_ask ans_scope_window "Optional: type in a separate Ghostty window (outside this zellij session) — laggy? (y/n)"
# ---- 6. Staged resets -------------------------------------------------------
# Each stage resets one category of state a TUI could have left behind.
# The first stage that cures the lag names the culprit.
set -l fixed none
_lt ""
_lt "Now applying resets one at a time. After each, type into the test prompt"
_lt "to judge whether the lag is gone."
_lt "CAVEAT: fish's read prompt may NOT exhibit lag even when the main"
_lt "commandline does. If typing at these test prompts never feels laggy at"
_lt "all, answer 'u' (unsure) instead of 'y' — a 'y' here is only meaningful"
_lt "if you could feel the lag at the test prompts before the reset."
if test $fixed = none
_lt ""
_lt "Stage A - kitty keyboard protocol: pop stack + clear all flags"
printf '\e[<9u\e[=0;1u'
_lt_ask ans_stage_a " Test typing here, then Enter — lag gone? (y/n)"
test "$ans_stage_a" = y; and set fixed "A (kitty keyboard state)"
end
if test $fixed = none
_lt "Stage B - modifyOtherKeys off"
printf '\e[>4;0m'
_lt_ask ans_stage_b " Test typing here, then Enter — lag gone? (y/n)"
test "$ans_stage_b" = y; and set fixed "B (modifyOtherKeys)"
end
if test $fixed = none
_lt "Stage C - normal keypad + normal cursor keys"
printf '\e>\e[?1l'
_lt_ask ans_stage_c " Test typing here, then Enter — lag gone? (y/n)"
test "$ans_stage_c" = y; and set fixed "C (application keypad/cursor mode)"
end
if test $fixed = none
_lt "Stage D - disable mouse, focus reporting, synchronized output"
printf '\e[?1000l\e[?1001l\e[?1002l\e[?1003l\e[?1005l\e[?1006l\e[?1015l\e[?1016l\e[?1004l\e[?2026l'
_lt_ask ans_stage_d " Test typing here, then Enter — lag gone? (y/n)"
test "$ans_stage_d" = y; and set fixed "D (mouse/focus/sync modes)"
end
if test $fixed = none
_lt "Stage E - leave alternate screen"
printf '\e[?1049l'
_lt_ask ans_stage_e " Test typing here, then Enter — lag gone? (y/n)"
test "$ans_stage_e" = y; and set fixed "E (alternate screen)"
end
if test $fixed = none
_lt "Stage F - stty sane (line-discipline reset)"
stty sane
_lt_ask ans_stage_f " Test typing here, then Enter — lag gone? (y/n)"
test "$ans_stage_f" = y; and set fixed "F (termios/line discipline)"
end
if test $fixed = none
_lt "Stage G - DECSTR soft terminal reset"
printf '\e[!p'
_lt_ask ans_stage_g " Test typing here, then Enter — lag gone? (y/n)"
test "$ans_stage_g" = y; and set fixed "G (DECSTR-resettable mode)"
end
# ---- 7. Verdict --------------------------------------------------------------
_lt ""
_lt "== Verdict =="
if test $fixed != none
_lt "Lag cleared by stage $fixed."
_lt "That state was stuck BELOW fish — in the Zellij pane or relayed to"
_lt "Ghostty — and the TUI you exited ($ans_tui) failed to restore it, or"
_lt "Zellij failed to restore it when the pane closed."
_lt "Re-probing terminal state after the fix for comparison:"
term-probe report 2>&1 | tee -a $logfile
_lt ""
_lt "-> File this log against zellij (or ghostty, if a separate window also"
_lt " lagged). The before/after probe diff pinpoints the exact stuck mode."
else if test "$ans_keylog_instant" = y; and test "$ans_keylog_plain" = y
_lt "Raw input reaches this pane instantly as plain bytes, and no terminal"
_lt "state reset helps: the lag lives INSIDE this fish process (reader state)."
_lt "Confirm now: run 'exec fish' — if that cures it, it is fish-internal."
_lt ""
_lt "-> To catch it in the act, run your next long-lived shell as:"
_lt " FISH_DEBUG='reader,term-support' FISH_DEBUG_OUTPUT=$logdir/fish-debug.log fish"
_lt " then re-run lag-triage when it recurs and file both logs to fish-shell."
else
_lt "Keystrokes were delayed or arrived as escape sequences BEFORE fish saw"
_lt "them: the problem is in Zellij (client stdin parser / server) or Ghostty."
_lt " new pane also laggy: $ans_scope_pane (y -> session-wide, not this pane)"
_lt " separate window laggy: $ans_scope_window (y -> Ghostty itself)"
_lt "-> File this log against zellij; include the keylog byte capture."
end
_lt ""
_lt "Full log: $logfile"
functions -e _lt _lt_ask
@@ -0,0 +1,165 @@
"""Probe the terminal state of the current pane, below the shell.
Modes:
report - query kitty-keyboard flags, modifyOtherKeys, and DEC private
modes directly on /dev/tty, reporting each reply (or lack of
one) and its round-trip latency. Answers may come from Zellij
(pane state) or be relayed from Ghostty (window state).
keylog - raw-mode keystroke capture: prints the exact bytes and
inter-key latency for every keypress, bypassing the shell's
input machinery entirely. Press q to finish.
Used by the `lag-triage` fish function to pin down which layer
(fish / zellij / ghostty) is holding stuck state when typing lags
after a TUI exits.
"""
import os
import re
import select
import sys
import termios
import time
import tty
# DECRQM reply values
DECRQM_VALUES = {
"0": "not recognized",
"1": "SET",
"2": "reset",
"3": "permanently set",
"4": "permanently reset",
}
DEC_MODES = [
(1, "application cursor keys (DECCKM)"),
(25, "cursor visible"),
(1000, "mouse click reporting"),
(1002, "mouse drag reporting"),
(1003, "mouse all-motion reporting"),
(1004, "focus reporting"),
(1006, "SGR mouse encoding"),
(1049, "alternate screen"),
(2004, "bracketed paste"),
(2026, "synchronized output"),
(2031, "color theme reporting"),
]
QUERIES = [
("kitty keyboard flags (\\e[?u)", b"\x1b[?u", rb"\x1b\[\?(\d+)u", None),
("modifyOtherKeys (XTQMODKEYS)", b"\x1b[?4m", rb"\x1b\[>4;(\d+)m", None),
("background color (OSC 11)", b"\x1b]11;?\x1b\\", rb"\x1b\]11;([^\x07\x1b]+)", None),
] + [
(
f"DEC mode {num}{desc}",
b"\x1b[?%d$p" % num,
rb"\x1b\[\?%d;(\d+)\$y" % num,
DECRQM_VALUES,
)
for num, desc in DEC_MODES
]
def read_for(fd, seconds):
buf = b""
end = time.monotonic() + seconds
while True:
remaining = end - time.monotonic()
if remaining <= 0:
break
r, _, _ = select.select([fd], [], [], remaining)
if not r:
break
buf += os.read(fd, 4096)
return buf
def report(fd):
lines = []
raw_dump = b""
for label, query, pattern, value_names in QUERIES:
raw_dump += read_for(fd, 0.02) # drain stragglers
start = time.monotonic()
os.write(fd, query)
buf = b""
match = None
deadline = time.monotonic() + 0.35
while time.monotonic() < deadline:
buf += read_for(fd, 0.05)
match = re.search(pattern, buf)
if match:
break
raw_dump += buf
if match:
latency = (time.monotonic() - start) * 1000
value = match.group(1).decode("ascii", "replace")
if value_names:
value = f"{value} ({value_names.get(value, '?')})"
lines.append(f" {label:45s} = {value:24s} [{latency:6.1f} ms]")
else:
lines.append(f" {label:45s} = (no reply)")
# DA1 as a fence: every terminal answers it, so its round-trip time
# measures the whole input path (ghostty -> zellij -> pane -> here).
start = time.monotonic()
os.write(fd, b"\x1b[c")
buf = b""
match = None
deadline = time.monotonic() + 2.0
while time.monotonic() < deadline:
buf += read_for(fd, 0.05)
match = re.search(rb"\x1b\[\?([0-9;]*)c", buf)
if match:
break
raw_dump += buf
if match:
latency = (time.monotonic() - start) * 1000
lines.append(
f" {'device attributes (DA1) round-trip':45s} = "
f"{match.group(1).decode():24s} [{latency:6.1f} ms]"
)
else:
lines.append(f" {'device attributes (DA1) round-trip':45s} = (NO REPLY in 2s!)")
lines.append(f" raw bytes received: {raw_dump!r}")
return lines
def keylog(fd):
sys.stdout.write("keylog: capturing raw bytes from the tty. Press q to finish.\r\n")
sys.stdout.flush()
last = time.monotonic()
while True:
select.select([fd], [], [], None)
data = os.read(fd, 4096)
now = time.monotonic()
delta_ms = (now - last) * 1000
last = now
sys.stdout.write(f" +{delta_ms:8.1f} ms {data!r} hex={data.hex(' ')}\r\n")
sys.stdout.flush()
if data in (b"q", b"\x03", b"\x04"):
break
def main():
mode = sys.argv[1] if len(sys.argv) > 1 else "report"
fd = os.open("/dev/tty", os.O_RDWR)
old = termios.tcgetattr(fd)
lines = None
try:
tty.setraw(fd)
if mode == "report":
lines = report(fd)
elif mode == "keylog":
keylog(fd)
else:
raise SystemExit(f"unknown mode: {mode}")
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old)
os.close(fd)
if lines:
print("terminal state as seen from this pane:")
print("\n".join(lines))
if __name__ == "__main__":
main()
@@ -0,0 +1,15 @@
# One-shot reset of terminal state a TUI may have left behind (kitty keyboard
# flags, modifyOtherKeys, application keypad/cursor, mouse/focus reporting,
# alternate screen, termios). fish re-enables the modes it wants at the next
# prompt, so this is safe to run any time.
#
# Diagnostic value: if this cures the lag, the stuck state was below fish
# (run lag-triage next time to find which mode). If only `exec fish` cures
# it, the lag is inside the fish process itself.
printf '\e[<9u\e[=0;1u'
printf '\e[>4;0m'
printf '\e>\e[?1l'
printf '\e[?1000l\e[?1001l\e[?1002l\e[?1003l\e[?1005l\e[?1006l\e[?1015l\e[?1016l\e[?1004l\e[?2026l'
printf '\e[?1049l'
stty sane
echo "terminal state reset — if typing still lags, run lag-triage (before exec fish!)"
@@ -0,0 +1,151 @@
#!/usr/bin/env python3
"""Deterministic repro of permanent fish reader degradation (fish 4.8.1).
This is evidence for an upstream fish-shell report, and the proof behind the
fish-no-query-term wrapper in presets/programs/zellij.nix. Not installed by
the nix module; run directly: python3 upstream_repro.py [queryterm|noqueryterm]
Finding: with the query-term feature enabled (latched from the startup env,
which is fish's default), fish sends OSC 11 + CPR (\e[6n) + DA1 (\e[0c)
after every external command and waits for the replies. If the terminal
fails to reply during ONE such cycle -- even though it answered every query
before and answers every query after -- that fish process's interactive
reader is PERMANENTLY degraded: keystrokes are no longer echoed (>3s each,
never recovers). In production this happens when zellij drops/mis-relays a
reply during TUI teardown or heavy output (cf. zellij-org/zellij#5158), and
it presents as permanent typing lag cured only by replacing the process.
With fish_features=no-query-term in the startup environment, the same
sequence has zero effect (~35ms echo throughout).
Phases:
A. terminal answers all queries -> echo ~35ms (both variants)
B. replies dropped for one command -> queryterm: echo dead, permanently
C. replies restored, another command -> queryterm: still dead
"""
import os, pty, re, select, subprocess, sys, time, fcntl, termios
VARIANT = sys.argv[1] if len(sys.argv) > 1 else "queryterm"
env = dict(os.environ)
env["TERM"] = "xterm-ghostty"
env["ZELLIJ"] = "0"
env["ZELLIJ_SESSION_NAME"] = "repro"
env["FISH_DEBUG"] = "term-support"
env["FISH_DEBUG_OUTPUT"] = f"/tmp/fish-lagrepro-{VARIANT}.log"
env.pop("fish_features", None)
if VARIANT == "noqueryterm":
env["fish_features"] = "no-query-term"
master, slave = pty.openpty()
# give it a size
fcntl.ioctl(master, termios.TIOCSWINSZ, b"\x00\x28\x00\x78\x00\x00\x00\x00")
proc = subprocess.Popen(
["fish", "-i", "--no-config"],
stdin=slave, stdout=slave, stderr=slave, env=env,
preexec_fn=lambda: (os.setsid(), fcntl.ioctl(0, termios.TIOCSCTTY, 0)),
close_fds=True,
)
os.close(slave)
RESPOND = True
transcript = []
def respond(data):
"""Answer terminal queries the way a well-behaved terminal would."""
out = b""
for m in re.finditer(rb"\x1b\[6n", data):
out += b"\x1b[40;1R" # CPR
for m in re.finditer(rb"\x1b\[0?c", data):
out += b"\x1b[?62;22c" # DA1
for m in re.finditer(rb"\x1b\[\?u", data):
out += b"\x1b[?0u" # kitty flags
for m in re.finditer(rb"\x1b\]11;\?", data):
out += b"\x1b]11;rgb:2828/2828/2828\x1b\\" # OSC 11
for m in re.finditer(rb"\x1b\[>0?q", data):
out += b"\x1bP>|ghostty 1.3.1\x1b\\" # XTVERSION
for m in re.finditer(rb"\x1bP\+q[0-9a-fA-F;]+\x1b\\", data):
out += b"\x1bP0+r\x1b\\" # XTGETTCAP: not found
for m in re.finditer(rb"\x1b\[\?(\d+)\$p", data):
out += b"\x1b[?%s;2$y" % m.group(1) # DECRQM: reset
return out
def pump(timeout):
"""Read fish output for `timeout` seconds, answering queries if RESPOND."""
buf = b""
end = time.monotonic() + timeout
while time.monotonic() < end:
r, _, _ = select.select([master], [], [], 0.03)
if r:
try:
data = os.read(master, 65536)
except OSError:
return buf
buf += data
transcript.append(data)
if RESPOND:
reply = respond(data)
if reply:
os.write(master, reply)
return buf
def send(s):
os.write(master, s if isinstance(s, bytes) else s.encode())
def measure_echo(chars, settle=0.1):
"""Send chars one at a time; measure time until each is echoed."""
results = []
for ch in chars:
pump(settle)
t0 = time.monotonic()
send(ch)
deadline = time.monotonic() + 3.0
latency = None
buf = b""
while time.monotonic() < deadline:
buf += pump(0.02)
if ch.encode() in buf:
latency = (time.monotonic() - t0) * 1000
break
results.append((ch, latency))
return results
print(f"=== variant: {VARIANT} ===")
pump(1.2) # startup, queries answered
send("echo warmup\r")
pump(0.8)
print("phase A: terminal responsive, echo latency per key:")
for ch, ms in measure_echo("abcde"):
print(f" {ch}: {ms:.0f} ms" if ms else f" {ch}: NO ECHO in 3s")
send("\x15") # ctrl-u clear line
pump(0.3)
# Run external command, then STOP answering queries (simulate lost relay)
send("sh -c true\r")
time.sleep(0.05)
RESPOND = False
pump(1.0)
print("phase B: after external command with query replies DROPPED:")
for ch, ms in measure_echo("fghij"):
print(f" {ch}: {ms:.0f} ms" if ms else f" {ch}: NO ECHO in 3s")
send("\x15")
pump(0.3)
# Does it persist across further commands, with responses restored?
RESPOND = True
send("sh -c true\r")
pump(1.0)
print("phase C: responses restored, after another external command:")
for ch, ms in measure_echo("klmno"):
print(f" {ch}: {ms:.0f} ms" if ms else f" {ch}: NO ECHO in 3s")
send("\x15")
pump(0.2)
send("exit\r")
pump(0.5)
try:
proc.wait(timeout=3)
except subprocess.TimeoutExpired:
proc.kill()
@@ -26,7 +26,7 @@ let
-E pr=5000/prompt \ -E pr=5000/prompt \
-H "${ldap_scheme}://''${LDAP_HOST}:${builtins.toString ldap_port}" \ -H "${ldap_scheme}://''${LDAP_HOST}:${builtins.toString ldap_port}" \
-D "${pkgs.lib.toUpper magic_prefix}2\\${pkgs.lib.toLower config.home.username}" \ -D "${pkgs.lib.toUpper magic_prefix}2\\${pkgs.lib.toLower config.home.username}" \
-w "$(${pkgs._1password-cli}/bin/op item get T2 --fields label=password --reveal)" \ -w "$(/usr/local/bin/op item get T2 --fields label=password --reveal)" \
-b "dc=''${LDAP_HOST//./,dc=}" \ -b "dc=''${LDAP_HOST//./,dc=}" \
-s "sub" -x "(cn=''${SEARCH_FILTER})" \ -s "sub" -x "(cn=''${SEARCH_FILTER})" \
| ${jq_parse}/bin/ljq | ${jq_parse}/bin/ljq
@@ -38,13 +38,13 @@ in
); );
# Use Neovim as the editor for git commit messages # Use Neovim as the editor for git commit messages
programs.git.extraConfig.core.editor = "${lib.getExe cfg.package}"; programs.git.settings.core.editor = "${lib.getExe cfg.package}";
programs.jujutsu.settings.ui.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 # Set Neovim as the default app for text editing and manual pages
home.sessionVariables = { home.sessionVariables = {
EDITOR = "${lib.getExe cfg.package}"; EDITOR = "${lib.getExe cfg.package}";
MANPAGER = "${lib.getExe cfg.package} +Man!"; # MANPAGER = "${lib.getExe cfg.package} +Man!";
}; };
# Create quick aliases for launching Neovim # Create quick aliases for launching Neovim
@@ -63,10 +63,10 @@ in
# Create a desktop option for launching Neovim from a file manager # Create a desktop option for launching Neovim from a file manager
# (Requires launching the terminal and then executing Neovim) # (Requires launching the terminal and then executing Neovim)
xdg.desktopEntries.nvim = xdg.desktopEntries.nvim =
lib.mkIf (pkgs.stdenv.isLinux && config.nmasur.presets.services.i3.enable) lib.mkIf (pkgs.stdenv.hostPlatform.isLinux && config.nmasur.presets.services.i3.enable)
{ {
name = "Neovim wrapper"; name = "Neovim wrapper";
exec = "${lib.getExe config.nmasur.presets.services.i3.terminal} nvim %F"; # TODO: change to generic exec = ''${lib.getExe config.nmasur.presets.services.i3.terminal} --command="nvim %F"''; # TODO: change to generic
mimeType = [ mimeType = [
"text/plain" "text/plain"
"text/markdown" "text/markdown"
@@ -1,6 +1,6 @@
{ {
config, config,
pkgs, # pkgs,
lib, lib,
... ...
}: }:
@@ -23,17 +23,18 @@ in
}; };
# Create nix-index if doesn't exist # Create nix-index if doesn't exist
home.activation.createNixIndex = # Should not be necessary with the nix-index-database flake
let # home.activation.createNixIndex =
cacheDir = "${config.xdg.cacheHome}/nix-index"; # let
in # cacheDir = "${config.xdg.cacheHome}/nix-index";
lib.mkIf config.programs.nix-index.enable ( # in
config.lib.dag.entryAfter [ "writeBoundary" ] '' # lib.mkIf config.programs.nix-index.enable (
if [ ! -d ${cacheDir} ]; then # config.lib.dag.entryAfter [ "writeBoundary" ] ''
run ${pkgs.nix-index}/bin/nix-index -f ${pkgs.path} # if [ ! -d ${cacheDir} ]; then
fi # run ${pkgs.nix-index}/bin/nix-index -f ${pkgs.path}
'' # fi
); # ''
# );
}; };
@@ -15,7 +15,7 @@ in
description = "Nixpkgs tools for macOS"; description = "Nixpkgs tools for macOS";
default = default =
config.nmasur.presets.programs.nixpkgs.enable config.nmasur.presets.programs.nixpkgs.enable
&& pkgs.stdenv.isDarwin && pkgs.stdenv.hostPlatform.isDarwin
&& config.nmasur.presets.programs.dotfiles.enable; && config.nmasur.presets.programs.dotfiles.enable;
}; };
@@ -29,6 +29,18 @@ in
doas nixos-rebuild switch --flake ${config.nmasur.presets.programs.dotfiles.path} 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
'';
};
}; };
}; };
@@ -13,12 +13,23 @@ in
options.nmasur.presets.programs.noti.enable = lib.mkEnableOption "Noti CLI notifications"; options.nmasur.presets.programs.noti.enable = lib.mkEnableOption "Noti CLI notifications";
config = lib.mkIf (cfg.enable && (pkgs.stdenv.isDarwin || config.services.dunst.enable)) { config = lib.mkIf (cfg.enable && (pkgs.stdenv.hostPlatform.isDarwin || config.services.dunst.enable)) {
home.packages = [ pkgs.noti ]; home.packages = [ pkgs.noti ];
programs.fish.shellAbbrs = { programs.fish = {
shellAbbrs = {
# Add noti for ghpr in Darwin # Add noti for ghpr in Darwin
ghpr = lib.mkForce "gh pr create && sleep 3 && noti gh run watch"; ghpr = lib.mkForce "gh pr create && sleep 3 && noti gh run watch";
grw = lib.mkForce "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
'';
};
};
};
}; };
} }
@@ -22,6 +22,6 @@ in
# Broken on 2023-12-11 # Broken on 2023-12-11
# https://forum.obsidian.md/t/electron-25-is-now-eol-please-upgrade-to-a-newer-version/72878/8 # https://forum.obsidian.md/t/electron-25-is-now-eol-please-upgrade-to-a-newer-version/72878/8
# insecurePackages = [ "electron-25.9.0" ]; # allowInsecurePackages = [ "electron-36.9.5" ];
}; };
} }
@@ -24,6 +24,7 @@ in
.terraform/ .terraform/
.target/ .target/
/Library/ /Library/
.jj/
''; '';
}; };
}; };
@@ -15,6 +15,8 @@ in
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
home.packages = [ pkgs.jj-starship ];
programs.starship = { programs.starship = {
enable = true; enable = true;
enableFishIntegration = true; enableFishIntegration = true;
@@ -27,6 +29,7 @@ in
"$git_branch" "$git_branch"
"$git_commit" "$git_commit"
"$git_status" "$git_status"
"\${custom.jj}"
"$hostname" "$hostname"
"$cmd_duration" "$cmd_duration"
"$character" "$character"
@@ -38,23 +41,37 @@ in
vicmd_symbol = "[](bold green)"; vicmd_symbol = "[](bold green)";
}; };
cmd_duration = { cmd_duration = {
min_time = 5000; min_time = 5001;
show_notifications = if pkgs.stdenv.isLinux then false else true; show_notifications = if pkgs.stdenv.hostPlatform.isLinux then false else true;
min_time_to_notify = 30000; min_time_to_notify = 30000;
format = "[$duration]($style) "; format = "[$duration]($style) ";
}; };
custom = {
jj = {
when = "jj-starship detect";
shell = [
"jj-starship"
"--no-jj-prefix"
"--no-git-prefix"
];
format = "$output ";
};
};
directory = { directory = {
truncate_to_repo = true; truncate_to_repo = true;
truncation_length = 100; truncation_length = 100;
}; };
git_branch = { git_branch = {
disabled = true;
format = "[$symbol$branch]($style)"; format = "[$symbol$branch]($style)";
}; };
git_commit = { git_commit = {
disabled = true;
format = "( @ [$hash]($style) )"; format = "( @ [$hash]($style) )";
only_detached = false; only_detached = false;
}; };
git_status = { git_status = {
disabled = true;
format = "([$all_status$ahead_behind]($style) )"; format = "([$all_status$ahead_behind]($style) )";
conflicted = "="; conflicted = "=";
ahead = ""; ahead = "";
@@ -0,0 +1,17 @@
-----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-----
@@ -0,0 +1,106 @@
{
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" ];
# };
# };
};
}
@@ -105,7 +105,7 @@ in
} }
config.font = wezterm.font('${cfg.font}', { weight = 'Bold'}) config.font = wezterm.font('${cfg.font}', { weight = 'Bold'})
config.font_size = ${if pkgs.stdenv.isLinux then "14.0" else "18.0"} config.font_size = ${if pkgs.stdenv.hostPlatform.isLinux then "14.0" else "18.0"}
-- Fix color blocks instead of text -- Fix color blocks instead of text
config.front_end = "WebGpu" config.front_end = "WebGpu"
@@ -114,7 +114,7 @@ in
config.hide_tab_bar_if_only_one_tab = true config.hide_tab_bar_if_only_one_tab = true
config.window_frame = { config.window_frame = {
font = wezterm.font('${cfg.font}', { weight = 'Bold'}), font = wezterm.font('${cfg.font}', { weight = 'Bold'}),
font_size = ${if pkgs.stdenv.isLinux then "12.0" else "16.0"}, font_size = ${if pkgs.stdenv.hostPlatform.isLinux then "12.0" else "16.0"},
} }
config.colors = { config.colors = {
@@ -191,7 +191,7 @@ in
-- super-t open new tab in new dir -- super-t open new tab in new dir
{ {
key = 't', key = 't',
mods = ${if pkgs.stdenv.isDarwin then "'SUPER'" else "'ALT'"}, mods = ${if pkgs.stdenv.hostPlatform.isDarwin then "'SUPER'" else "'ALT'"},
action = wezterm.action.SpawnCommandInNewTab { action = wezterm.action.SpawnCommandInNewTab {
cwd = wezterm.home_dir, cwd = wezterm.home_dir,
}, },
@@ -16,6 +16,7 @@ in
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
programs.zed-editor = { programs.zed-editor = {
enable = true; enable = true;
package = pkgs.stable.zed-editor;
extensions = [ extensions = [
"nix" "nix"
@@ -6,15 +6,45 @@
}: }:
let let
inherit (config.nmasur.settings) username;
cfg = config.nmasur.presets.programs.zellij; cfg = config.nmasur.presets.programs.zellij;
# fish latches feature flags from its startup ENVIRONMENT before config.fish
# runs, so the `set -gx fish_features no-query-term` in config.fish only
# protects CHILD fish processes — which is why subshells/exec fish were always
# immune to the post-TUI typing lag while zellij-spawned pane shells were not.
# With query-term latched on, fish sends OSC 11 + CPR + DA1 queries after
# every command and waits for replies; if zellij fails to relay even one
# reply (a race during TUI teardown or heavy output), that fish process's
# reader is PERMANENTLY degraded — reproduced deterministically in a PTY
# harness on fish 4.8.1 (see docs/CHANGELOG.md 2026-08-29 and
# presets/programs/lag-triage/upstream_repro.py). Spawning fish with the
# variable already exported makes every pane shell immune.
# Flight recorder for the still-unsolved post-TUI typing lag: sampling the
# process CURES the lag (a wedged thread gets kicked loose), so the only way
# to observe it is a recorder that is already running before the lag starts.
# Armed by `touch ~/.local/state/lag-triage/RECORD`; new panes then log
# fish's reader/thread internals to ~/.local/state/lag-triage/flight/.
# Remove the RECORD file to disable (zero overhead when off).
fish-no-query-term = pkgs.writeShellScriptBin "fish-no-query-term" ''
export fish_features=no-query-term
dir="$HOME/.local/state/lag-triage"
if [ -e "$dir/RECORD" ]; then
mkdir -p "$dir/flight"
find "$dir/flight" -type f -mtime +3 -delete 2>/dev/null
export FISH_DEBUG='reader,term-support,proc-termowner,iothread,fd-monitor,topic-monitor'
export FISH_DEBUG_OUTPUT="$dir/flight/fish-$(date +%Y%m%d-%H%M%S)-$$.log"
fi
exec ${lib.getExe pkgs.fish} "$@"
'';
zellij-switch-to-last = pkgs.writeShellScriptBin "zellij-switch-to-last" '' zellij-switch-to-last = pkgs.writeShellScriptBin "zellij-switch-to-last" ''
TARGET_SESSION=$(cat ~/.local/state/zellij-last-session) TARGET_SESSION=$(cat ~/.local/state/zellij-last-session)
if [ -z "$TARGET_SESSION" ]; then if [ -z "$TARGET_SESSION" ]; then
return 1 return 1
fi fi
echo "$ZELLIJ_SESSION_NAME" > ~/.local/state/zellij-last-session echo "$ZELLIJ_SESSION_NAME" > ~/.local/state/zellij-last-session
zellij pipe --plugin file:$(which zellij-switch.wasm) -- "--session $TARGET_SESSION" ${lib.getExe pkgs.zellij} action switch-session $TARGET_SESSION
''; '';
in in
@@ -24,8 +54,6 @@ in
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
home.packages = [ pkgs.zellij-switch ];
programs.fish = { programs.fish = {
shellAbbrs.z = "zellij"; shellAbbrs.z = "zellij";
functions = { functions = {
@@ -33,25 +61,62 @@ in
# description = "Open a session in Zellij"; # description = "Open a session in Zellij";
body = # fish body = # fish
'' ''
set TARGET_DIR $(zoxide query --interactive) 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 \
)
if test -z $TARGET_DIR if test -z $TARGET_DIR
return 0 return 0
end end
if test "$TARGET_DIR" = $(pwd) if test "$TARGET_DIR" = $(pwd)
return 1 return 1
end end
# Zellij names each session's IPC socket $TMPDIR/zellij-<uid>/<ver>/<name>.
# On macOS the socket path is capped at 103 bytes; the $TMPDIR prefix under
# /var/folders/... eats ~79 of those, leaving only ~24 chars for the name.
# A longer basename overflows the socket path, and because switch-session has
# already detached from the current session by the time the new one fails to
# bind, it takes the whole terminal down. Truncate to stay well under the limit.
set SESSION_NAME (basename $TARGET_DIR | string sub --length 20)
echo "$ZELLIJ_SESSION_NAME" > ~/.local/state/zellij-last-session echo "$ZELLIJ_SESSION_NAME" > ~/.local/state/zellij-last-session
zellij pipe --plugin file:$(which zellij-switch.wasm) -- "--cwd $TARGET_DIR --layout default --session $(basename $TARGET_DIR)" ${lib.getExe pkgs.zellij} action switch-session $SESSION_NAME --cwd $TARGET_DIR --layout default
''; '';
}; };
gh-run = { gh-run = {
body = # fish body = # fish
'' ''
zellij action new-pane --start-suspended -- gh run watch ${lib.getExe pkgs.zellij} action new-pane --start-suspended -- gh run watch
''; '';
}; };
__fish_update_cwd_osc = {
description = "Notify Zellij/terminal of CWD changes without hostname mismatch";
body = # fish
''
if test "$TERM" != "dumb"
printf \e\]7\;file://%s\a (string escape --style=url -- $PWD)
end
'';
onVariable = "PWD";
onEvent = "fish_prompt";
}; };
}; };
};
programs.ghostty.settings.initial-command = lib.getExe pkgs.zellij;
xdg.configFile."zellij/layouts/compact-top.kdl".text = # kdl xdg.configFile."zellij/layouts/compact-top.kdl".text = # kdl
'' ''
@@ -85,19 +150,55 @@ in
enableFishIntegration = true; enableFishIntegration = true;
enableZshIntegration = true; enableZshIntegration = true;
attachExistingSession = true; attachExistingSession = true;
exitShellOnExit = false; exitShellOnExit = true;
settings = { settings = {
default_mode = "locked"; 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.
# Wrapped to export fish_features=no-query-term BEFORE fish starts —
# see the fish-no-query-term comment above for why this must happen in
# the environment rather than in config.fish.
default_shell = lib.getExe fish-no-query-term;
# default_layout = "compact-top"; # default_layout = "compact-top";
# Remove border # Remove border
pane_frames = false; pane_frames = false;
# Ghostty + Zellij have several open upstream bugs where the Kitty
# keyboard protocol's "enhancement" flags get left in a stuck/elevated
# state after a full-screen TUI exits (e.g. zellij-org/zellij#3887,
# #3723, #4178), causing every subsequent keystroke to be sent as a
# CSI-u sequence that fish has to wait out an escape-timeout to
# disambiguate. This shows up as typing lag that builds up the longer
# you were inside the TUI, until the pane's protocol state resets.
# Disabling it entirely avoids the whole bug class.
support_kitty_keyboard_protocol = false;
# Scrollback # Scrollback
scrollback_editor = config.home.sessionVariables.EDITOR; scrollback_editor = config.home.sessionVariables.EDITOR;
show_startup_tips = false; show_startup_tips = false;
keybinds = { keybinds = {
locked = lib.mkIf (pkgs.stdenv.hostPlatform.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.hostPlatform.isLinux && !config.programs.ghostty.enable)
{
SwitchToMode = {
_args = [ "normal" ];
};
};
};
normal = lib.mkIf (pkgs.stdenv.hostPlatform.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.hostPlatform.isLinux && !config.programs.ghostty.enable)
{
SwitchToMode = {
_args = [ "locked" ];
};
};
};
session = { session = {
"bind \"w\"" = { "bind \"w\"" = {
LaunchOrFocusPlugin = { LaunchOrFocusPlugin = {
@@ -121,9 +222,15 @@ in
shared = { shared = {
"bind \"Alt Shift s\"" = { "bind \"Alt Shift s\"" = {
Run = { Run = {
_args = [ _args =
if pkgs.stdenv.hostPlatform.isDarwin then
[
# "env"
# "PATH=/nix/var/nix/profiles/default/bin:/run/current-system/sw/bin:/usr/bin:/bin"
(lib.getExe zellij-switch-to-last) (lib.getExe zellij-switch-to-last)
]; ]
else
[ (lib.getExe zellij-switch-to-last) ];
close_on_exit = true; close_on_exit = true;
}; };
}; };
@@ -155,7 +262,9 @@ in
}; };
"bind \"Alt Shift w\"" = { "bind \"Alt Shift w\"" = {
Run = { Run = {
_args = [ _args =
(if config.nmasur.presets.programs.noti.enable then [ (lib.getExe pkgs.noti) ] else [ ])
++ [
(lib.getExe pkgs.gh) (lib.getExe pkgs.gh)
"run" "run"
"watch" "watch"
@@ -186,9 +295,28 @@ in
}; };
}; };
"bind \"Alt Shift j\"" = { "bind \"Alt Shift j\"" = {
Run = {
_args =
if pkgs.stdenv.hostPlatform.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 = { Run = {
_args = [ _args = [
(lib.getExe pkgs.lazyjj) (lib.getExe pkgs.yazi)
]; ];
close_on_exit = true; close_on_exit = true;
floating = true; floating = true;
@@ -201,33 +329,62 @@ in
"bind \"Super Shift ]\"" = { "bind \"Super Shift ]\"" = {
GoToNextTab = { }; GoToNextTab = { };
}; };
"bind \"Alt ]\"" = {
GoToNextTab = { };
};
"bind \"Alt }\"" = {
GoToNextTab = { };
};
"bind \"Alt Shift ]\"" = {
GoToNextTab = { };
};
"bind \"Alt Shift }\"" = {
GoToNextTab = { };
};
"bind \"Super Shift [\"" = { "bind \"Super Shift [\"" = {
GoToPreviousTab = { }; GoToPreviousTab = { };
}; };
"bind \"Alt [\"" = {
GoToPreviousTab = { };
};
"bind \"Alt {\"" = {
GoToPreviousTab = { };
};
"bind \"Alt Shift [\"" = {
GoToPreviousTab = { };
};
"bind \"Alt Shift {\"" = {
GoToPreviousTab = { };
};
"bind \"Ctrl Tab\"" = { "bind \"Ctrl Tab\"" = {
GoToNextTab = { }; GoToNextTab = { };
}; };
"bind \"Ctrl Shift Tab\"" = { "bind \"Ctrl Shift Tab\"" = {
GoToPreviousTab = { }; GoToPreviousTab = { };
}; };
"bind \"Super t\"" = lib.mkIf pkgs.stdenv.isDarwin { "bind \"Super t\"" = lib.mkIf pkgs.stdenv.hostPlatform.isDarwin {
NewTab = { }; NewTab = { };
}; };
"bind \"Alt t\"" = lib.mkIf pkgs.stdenv.isLinux { "bind \"Alt t\"" = {
NewTab = { }; NewTab = { };
}; };
"bind \"Super k\"" = lib.mkIf pkgs.stdenv.isDarwin { "bind \"Super k\"" = lib.mkIf pkgs.stdenv.hostPlatform.isDarwin {
SwitchToMode = { SwitchToMode = {
_args = [ "scroll" ]; _args = [ "scroll" ];
}; };
}; };
"bind \"Super Shift e\"" = lib.mkIf pkgs.stdenv.isDarwin { "bind \"Alt Shift k\"" = {
SwitchToMode = {
_args = [ "scroll" ];
};
};
"bind \"Super Shift e\"" = lib.mkIf pkgs.stdenv.hostPlatform.isDarwin {
EditScrollback = { }; EditScrollback = { };
SwitchToMode = { SwitchToMode = {
_args = [ "locked" ]; _args = [ "locked" ];
}; };
}; };
"bind \"Alt Shift e\"" = lib.mkIf pkgs.stdenv.isLinux { "bind \"Alt Shift e\"" = {
EditScrollback = { }; EditScrollback = { };
SwitchToMode = { SwitchToMode = {
_args = [ "locked" ]; _args = [ "locked" ];
@@ -243,6 +400,16 @@ in
_args = [ "Left" ]; _args = [ "Left" ];
}; };
}; };
"bind \"Alt j\"" = {
MoveFocus = {
_args = [ "Down" ];
};
};
"bind \"Alt k\"" = {
MoveFocus = {
_args = [ "Up" ];
};
};
}; };
}; };
@@ -0,0 +1,93 @@
{
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;
};
};
};
}
@@ -0,0 +1,81 @@
{
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
'';
};
};
}
@@ -0,0 +1,50 @@
{
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;
};
};
};
}
@@ -0,0 +1,45 @@
--- === 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
@@ -57,7 +57,7 @@ function obj:init()
self.launcher:bind("ctrl", "space", function() end) self.launcher:bind("ctrl", "space", function() end)
self.launcher:bind("", "return", function() self.launcher:bind("", "return", function()
-- self:switch("@wezterm@") -- self:switch("@wezterm@")
self:switch("/Applications/Ghostty.app") self:switch("@ghostty@")
end) end)
self.launcher:bind("", "C", function() self.launcher:bind("", "C", function()
self:switch("Calendar.app") self:switch("Calendar.app")
@@ -80,6 +80,9 @@ function obj:init()
self.launcher:bind("", "H", function() self.launcher:bind("", "H", function()
self:switch("Hammerspoon.app") self:switch("Hammerspoon.app")
end) end)
self.launcher:bind("", "L", function()
self:switch("Claude.app")
end)
self.launcher:bind("", "M", function() self.launcher:bind("", "M", function()
self:switch("Messages.app") self:switch("Messages.app")
end) end)
@@ -7,6 +7,7 @@
let let
cfg = config.nmasur.presets.services.hammerspoon; cfg = config.nmasur.presets.services.hammerspoon;
# inherit (config.nmasur.settings) username;
in in
{ {
@@ -15,25 +16,47 @@ in
lib.mkEnableOption "Hammerspoon macOS automation"; lib.mkEnableOption "Hammerspoon macOS automation";
config = lib.mkIf cfg.enable { 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/init.lua".source = ./init.lua;
xdg.configFile."hammerspoon/Spoons/ControlEscape.spoon".source = ./Spoons/ControlEscape.spoon; xdg.configFile."hammerspoon/Spoons/ControlEscape.spoon".source = ./Spoons/ControlEscape.spoon;
xdg.configFile."hammerspoon/Spoons/DismissAlerts.spoon".source = ./Spoons/DismissAlerts.spoon; xdg.configFile."hammerspoon/Spoons/DismissAlerts.spoon".source = ./Spoons/DismissAlerts.spoon;
xdg.configFile."hammerspoon/Spoons/Launcher.spoon/init.lua".source = xdg.configFile."hammerspoon/Spoons/Launcher.spoon/init.lua".source =
pkgs.replaceVars ./Spoons/Launcher.spoon/init.lua pkgs.replaceVars ./Spoons/Launcher.spoon/init.lua
{ {
discord = "${pkgs.discord}/Applications/Discord.app"; discord = "Discord.app";
firefox = "${pkgs.firefox-unwrapped}/Applications/Firefox.app"; firefox = "${pkgs.firefox-unwrapped}/Applications/Firefox.app";
ghostty = "${pkgs.ghostty-bin}/Applications/Ghostty.app";
obsidian = "${pkgs.obsidian}/Applications/Obsidian.app"; obsidian = "${pkgs.obsidian}/Applications/Obsidian.app";
slack = "${pkgs.slack}/Applications/Slack.app"; slack = "${pkgs.slack}/Applications/Slack.app";
wezterm = "${pkgs.wezterm}/Applications/WezTerm.app"; wezterm = "${pkgs.wezterm}/Applications/WezTerm.app";
zed = "${pkgs.zed-editor}/Applications/Zed.app"; zed = "${config.programs.zed-editor.package}/Applications/Zed.app";
}; };
xdg.configFile."hammerspoon/Spoons/MoveWindow.spoon".source = ./Spoons/MoveWindow.spoon; 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" ] '' home.activation.reloadHammerspoon = config.lib.dag.entryAfter [ "writeBoundary" ] ''
$DRY_RUN_CMD /Applications/Hammerspoon.app/Contents/Frameworks/hs/hs -c "hs.reload()" # 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 sleep 1
$DRY_RUN_CMD /Applications/Hammerspoon.app/Contents/Frameworks/hs/hs -c "hs.console.clearConsole()" $DRY_RUN_CMD ${pkgs.coreutils}/bin/timeout 10 "$hs" -c "hs.console.clearConsole()" || true
else
verboseEcho "Hammerspoon not running; skipping reload."
fi
''; '';
}; };
@@ -3,3 +3,4 @@ hs.loadSpoon("ControlEscape"):start() -- Load Hammerspoon bits from https://gith
hs.loadSpoon("Launcher"):init() hs.loadSpoon("Launcher"):init()
hs.loadSpoon("DismissAlerts"):init() hs.loadSpoon("DismissAlerts"):init()
hs.loadSpoon("MoveWindow"):init() hs.loadSpoon("MoveWindow"):init()
hs.loadSpoon("HideZoomWindow"):init()
@@ -214,9 +214,9 @@ in
cfg.commands.lockScreen != null cfg.commands.lockScreen != null
) "exec ${cfg.commands.lockScreen}"; ) "exec ${cfg.commands.lockScreen}";
"${modifier}+Mod1+h" = "${modifier}+Mod1+h" =
''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" ''; ''exec --no-startup-id ${lib.getExe cfg.terminal} -e "${lib.getExe config.nmasur.presets.programs.nixpkgs.commands.rebuildHome} '';
"${modifier}+Mod1+r" = "${modifier}+Mod1+r" =
"exec --no-startup-id ${lib.getExe cfg.terminal} --command='doas nixos-rebuild switch --flake ${config.nmasur.presets.programs.dotfiles.path} || read'"; "exec --no-startup-id ${lib.getExe cfg.terminal} -e ${lib.getExe config.nmasur.presets.programs.nixpkgs.commands.rebuildNixos}";
# Window options # Window options
"${modifier}+q" = "kill"; "${modifier}+q" = "kill";
@@ -43,14 +43,14 @@ in
}; };
# Automatically check for mail and keep files synced locally # Automatically check for mail and keep files synced locally
services.mbsync = lib.mkIf pkgs.stdenv.isLinux { services.mbsync = lib.mkIf pkgs.stdenv.hostPlatform.isLinux {
enable = true; enable = true;
frequency = "*:0/5"; frequency = "*:0/5";
postExec = "${lib.getExe pkgs.notmuch} new"; postExec = "${lib.getExe pkgs.notmuch} new";
}; };
# Used to watch for new mail and trigger sync # Used to watch for new mail and trigger sync
services.imapnotify.enable = pkgs.stdenv.isLinux; services.imapnotify.enable = pkgs.stdenv.hostPlatform.isLinux;
# Allows sending email from CLI/sendmail # Allows sending email from CLI/sendmail
programs.msmtp.enable = true; programs.msmtp.enable = true;
@@ -0,0 +1,53 @@
{
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"'';
};
};
};
}
@@ -15,7 +15,7 @@ in
home.username = config.nmasur.settings.username; home.username = config.nmasur.settings.username;
home.homeDirectory = home.homeDirectory =
if pkgs.stdenv.isDarwin then "/Users/${config.home.username}" else "/home/${config.home.username}"; if pkgs.stdenv.hostPlatform.isDarwin then "/Users/${config.home.username}" else "/home/${config.home.username}";
home.packages = [ home.packages = [
pkgs.dig # DNS lookup pkgs.dig # DNS lookup
@@ -33,6 +33,7 @@ in
nmasur.presets = { nmasur.presets = {
programs = { programs = {
bat.enable = lib.mkDefault true; bat.enable = lib.mkDefault true;
chawan.enable = lib.mkDefault true;
fd.enable = lib.mkDefault true; fd.enable = lib.mkDefault true;
ripgrep.enable = lib.mkDefault true; ripgrep.enable = lib.mkDefault true;
starship.enable = lib.mkDefault true; starship.enable = lib.mkDefault true;
@@ -17,33 +17,24 @@ in
nmasur.presets = { nmasur.presets = {
fonts.enable = lib.mkDefault true; fonts.enable = lib.mkDefault true;
services.hammerspoon.enable = lib.mkDefault true; services = {
programs.nixpkgs-darwin.enable = lib.mkDefault true; darwin-settings.enable = lib.mkDefault true;
programs.mpv.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 = {
calibre.enable = lib.mkDefault true;
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;
};
}; };
home.homeDirectory = lib.mkForce "/Users/${config.home.username}"; 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"' # Fix for: 'Error: HOME is set to "/var/root" but we expect "/var/empty"'
@@ -0,0 +1,24 @@
{
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,6 +19,10 @@ in
pkgs.pgcli # Postgres client with autocomplete pkgs.pgcli # Postgres client with autocomplete
]; ];
nmasur.presets = {
programs.cargo.enable = lib.mkDefault true;
};
}; };
} }
@@ -17,19 +17,31 @@ in
nmasur.presets.programs = { nmasur.presets.programs = {
zed-editor.enable = lib.mkDefault true; zed-editor.enable = lib.mkDefault true;
jujutsu.enable = lib.mkDefault true;
}; };
home.packages = [ home.packages = [
# pkgs.nmasur.ren-find # Rename files
# pkgs.nmasur.rep-grep # Replace text in files
# Charm tools # Charm tools
pkgs.glow # Markdown previews pkgs.glow # Markdown previews
pkgs.skate # Key-value store pkgs.skate # Key-value store
pkgs.charm # Manage account and filesystem pkgs.charm # Manage account and filesystem
pkgs.pop # Send emails from a TUI pkgs.pop # Send emails from a TUI
# pkgs.crush # AI LLM Agent
pkgs.chawan # Browser TUI # Other utilities
pkgs.snitch # Network
pkgs.comma # Nix-index auto-launch
pkgs.nix-inspect # TUI for browsing Nix configs
# LLM
pkgs.antigravity-cli # AI LLM Agent
pkgs.pi-coding-agent # AI LLM Agent
]; ];
@@ -30,8 +30,9 @@ in
publicShare = lib.mkDefault "$HOME/other/public"; publicShare = lib.mkDefault "$HOME/other/public";
templates = lib.mkDefault "$HOME/other/templates"; templates = lib.mkDefault "$HOME/other/templates";
extraConfig = { extraConfig = {
XDG_DEV_DIR = lib.mkDefault "$HOME/dev"; DEV = lib.mkDefault "$HOME/dev";
}; };
setSessionVariables = true;
}; };
nmasur.presets.programs = { nmasur.presets.programs = {
@@ -32,6 +32,7 @@ in
nsxiv.enable = lib.mkDefault true; nsxiv.enable = lib.mkDefault true;
obsidian.enable = lib.mkDefault true; obsidian.enable = lib.mkDefault true;
rofi.enable = lib.mkDefault true; rofi.enable = lib.mkDefault true;
thunderbird.enable = lib.mkDefault true;
xclip.enable = lib.mkDefault true; xclip.enable = lib.mkDefault true;
zathura.enable = lib.mkDefault true; zathura.enable = lib.mkDefault true;
}; };
@@ -0,0 +1,26 @@
{
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,24 +16,23 @@ in
pkgs.age # Encryption pkgs.age # Encryption
pkgs.bc # Calculator pkgs.bc # Calculator
pkgs.bottom # System monitor (top) pkgs.bottom # System monitor (top)
pkgs.csvlens # CSV viewer (easier than visidata)
pkgs.delta # Fancy diffs pkgs.delta # Fancy diffs
pkgs.difftastic # Other fancy diffs pkgs.difftastic # Other fancy diffs
pkgs.doggo # DNS client (dig) pkgs.doggo # DNS client (dig)
pkgs.du-dust # Disk usage tree (ncdu) pkgs.dust # Disk usage tree (ncdu)
pkgs.dua # File sizes (du) pkgs.dua # File sizes (du)
pkgs.duf # Basic disk information (df) pkgs.duf # Basic disk information (df)
pkgs.jless # JSON viewer pkgs.jless # JSON viewer
pkgs.jo # JSON output pkgs.jo # JSON output
pkgs.mpd # TUI slideshows pkgs.stable.mpd # TUI slideshows
pkgs.nixfmt-rfc-style # Format Nix code pkgs.nixfmt # Format Nix code
pkgs.nmasur.jqr # FZF fq JSON tool pkgs.nmasur.jqr # FZF fq JSON tool
pkgs.nmasur.osc # Clipboard over SSH 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.pandoc # Convert text documents
pkgs.qrencode # Generate qr codes pkgs.qrencode # Generate qr codes
pkgs.spacer # Output lines in terminal pkgs.spacer # Output lines in terminal
pkgs.tealdeer # Cheatsheets pkgs.stable.tealdeer # Cheatsheets
pkgs.tree # Print tree in terminal pkgs.tree # Print tree in terminal
pkgs.vimv-rs # Batch rename files pkgs.vimv-rs # Batch rename files
pkgs.yazi # TUI file explorer pkgs.yazi # TUI file explorer
@@ -42,7 +41,7 @@ in
programs.fish.shellAliases = { programs.fish.shellAliases = {
"du" = lib.mkDefault (lib.getExe pkgs.dua); "du" = lib.mkDefault (lib.getExe pkgs.dua);
"ncdu" = lib.mkDefault (lib.getExe pkgs.du-dust); "ncdu" = lib.mkDefault (lib.getExe pkgs.dust);
"df" = lib.mkDefault (lib.getExe pkgs.duf); "df" = lib.mkDefault (lib.getExe pkgs.duf);
# Use eza (exa) instead of ls for fancier output # Use eza (exa) instead of ls for fancier output
@@ -63,8 +62,10 @@ in
ghostty.enable = lib.mkDefault true; ghostty.enable = lib.mkDefault true;
git.enable = lib.mkDefault true; git.enable = lib.mkDefault true;
helix.enable = lib.mkDefault true; helix.enable = lib.mkDefault true;
jujutsu.enable = lib.mkDefault true;
lag-triage.enable = lib.mkDefault true;
lazygit.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; nix-index.enable = lib.mkDefault true;
nixpkgs.enable = lib.mkDefault true; nixpkgs.enable = lib.mkDefault true;
notes.enable = lib.mkDefault true; notes.enable = lib.mkDefault true;
@@ -21,7 +21,9 @@ in
]; ];
home.packages = [ home.packages = [
pkgs.visidata # CSV inspector pkgs.actionlint # Lint for GitHub Actions Workflows
pkgs.claude-code # AI LLM Agent
pkgs.stable.visidata # CSV inspector
pkgs.dos2unix # Convert Windows text files pkgs.dos2unix # Convert Windows text files
pkgs.inetutils # Includes telnet pkgs.inetutils # Includes telnet
pkgs.gnupg # Encryption pkgs.gnupg # Encryption
@@ -29,6 +31,7 @@ in
pkgs.ssm-session-manager-plugin pkgs.ssm-session-manager-plugin
pkgs.awslogs pkgs.awslogs
pkgs.stu # TUI for AWS S3 pkgs.stu # TUI for AWS S3
pkgs.pre-commit
pkgs.google-cloud-sdk pkgs.google-cloud-sdk
pkgs.vault-bin pkgs.vault-bin
pkgs.ipcalc # Make IP network calculations pkgs.ipcalc # Make IP network calculations
@@ -37,18 +40,28 @@ in
pkgs.nmasur.ocr # Converts images to text pkgs.nmasur.ocr # Converts images to text
pkgs.nmasur.aws-ec2 # Browse EC2 instances pkgs.nmasur.aws-ec2 # Browse EC2 instances
pkgs.nmasur.terraform-init # Quick shortcut for initializing Terraform backend 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"; programs.fish.shellAliases.ec2 = "aws-ec2";
nmasur.presets = { nmasur.presets = {
fonts.enable = lib.mkDefault true; fonts.enable = lib.mkDefault true;
programs = { programs = {
_1password.enable = lib.mkDefault true; # _1password.enable = lib.mkDefault true;
atuin.enable = lib.mkDefault true; atuin.enable = lib.mkDefault true;
aws-ssh.enable = lib.mkDefault true; aws-ssh.enable = lib.mkDefault true;
bash.enable = lib.mkDefault true; bash.enable = lib.mkDefault true;
bat.enable = lib.mkDefault true; bat.enable = lib.mkDefault true;
cargo.enable = lib.mkDefault true;
direnv.enable = lib.mkDefault true; direnv.enable = lib.mkDefault true;
dotfiles.enable = lib.mkDefault true; dotfiles.enable = lib.mkDefault true;
fd.enable = lib.mkDefault true; fd.enable = lib.mkDefault true;
@@ -67,8 +80,12 @@ in
ripgrep.enable = lib.mkDefault true; ripgrep.enable = lib.mkDefault true;
starship.enable = lib.mkDefault true; starship.enable = lib.mkDefault true;
terraform.enable = lib.mkDefault true; terraform.enable = lib.mkDefault true;
thunderbird.enable = lib.mkDefault true;
weather.enable = lib.mkDefault true; weather.enable = lib.mkDefault true;
}; };
services = {
mbsync.enable = lib.mkDefault true;
};
}; };
}; };
@@ -0,0 +1,26 @@
{
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,5 +23,19 @@ in
# Speeds up fish launch time on macOS # Speeds up fish launch time on macOS
programs.fish.useBabelfish = true; 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,7 +33,6 @@ in
}; };
global = { global = {
brewfile = true; # Run brew bundle from anywhere brewfile = true; # Run brew bundle from anywhere
lockfiles = false; # Don't save lockfile (since running from anywhere)
}; };
}; };

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