about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rwxr-xr-xbuild.sh6
-rw-r--r--flake.lock303
-rw-r--r--flake.nix52
-rw-r--r--flake/default.nix17
-rw-r--r--flake/nixosConfigurations/default.nix15
-rw-r--r--flake/packages/default.nix9
-rw-r--r--hosts/_unmaintained/isimud/command-line.html1491
-rw-r--r--hosts/_unmaintained/isimud/default.nix44
-rw-r--r--hosts/_unmaintained/isimud/hardware/default.nix24
-rw-r--r--hosts/_unmaintained/isimud/networking.nix8
-rw-r--r--hosts/_unmaintained/lahmu/default.nix24
-rw-r--r--hosts/_unmaintained/lahmu/hardware/cpu.nix4
-rw-r--r--hosts/_unmaintained/lahmu/hardware/default.nix33
-rw-r--r--hosts/_unmaintained/lahmu/hardware/gpu.nix15
-rw-r--r--hosts/_unmaintained/lahmu/networking.nix14
-rw-r--r--hosts/_unmaintained/mammun/default.nix23
-rw-r--r--hosts/_unmaintained/mammun/hardware/cpu.nix3
-rw-r--r--hosts/_unmaintained/mammun/hardware/default.nix27
-rw-r--r--hosts/_unmaintained/mammun/hardware/gpu.nix14
-rw-r--r--hosts/_unmaintained/mammun/networking.nix16
-rw-r--r--hosts/_unmaintained/marduk/default.nix14
-rw-r--r--hosts/_unmaintained/marduk/hardware/default.nix19
-rw-r--r--hosts/_unmaintained/marduk/networking.nix14
-rw-r--r--hosts/apzu/default.nix85
-rw-r--r--hosts/hostinfo.toml12
-rw-r--r--hosts/tiamat/default.nix100
-rw-r--r--lib/default.nix97
-rw-r--r--modules/by-name/at/atuin/atuin.zsh126
-rw-r--r--modules/by-name/at/atuin/module.nix6
-rw-r--r--modules/by-name/ca/cargo/module.nix18
-rw-r--r--modules/by-name/di/direnv/module.nix21
-rw-r--r--modules/by-name/fi/firefox/extensions.json (renamed from modules/home.legacy/conf/firefox/config/extensions/extensions.json)30
-rw-r--r--modules/by-name/fi/firefox/module.nix234
-rw-r--r--modules/by-name/fi/firefox/profile.nix180
-rw-r--r--modules/by-name/fi/firefox/search_engines/default.nix (renamed from modules/home.legacy/conf/firefox/config/search/engines/default.nix)56
-rw-r--r--modules/by-name/fi/firefox/search_engines/logos/arch_linux.svg (renamed from modules/home.legacy/conf/firefox/config/search/engines/logos/arch_linux.svg)0
-rw-r--r--modules/by-name/fi/firefox/search_engines/logos/brave.svg (renamed from modules/home.legacy/conf/firefox/config/search/engines/logos/brave.svg)0
-rw-r--r--modules/by-name/fi/firefox/search_engines/logos/google_scholar.ico (renamed from modules/home.legacy/conf/firefox/config/search/engines/logos/google_scholar.ico)bin3871 -> 3871 bytes
-rw-r--r--modules/by-name/fi/firefox/search_engines/logos/rust_std.svg (renamed from modules/home.legacy/conf/firefox/config/search/engines/logos/rust_std.svg)0
-rw-r--r--modules/by-name/fi/firefox/search_engines/logos/rust_tokio.png (renamed from modules/home.legacy/conf/firefox/config/search/engines/logos/rust_tokio.png)bin3551 -> 3551 bytes
-rw-r--r--modules/by-name/fi/firefox/search_engines/logos/wikipedia.svg (renamed from modules/home.legacy/conf/firefox/config/search/engines/logos/wikipedia.svg)0
-rwxr-xr-xmodules/by-name/fi/firefox/update_extensions.sh12
-rw-r--r--modules/by-name/fi/firefox/userChrome.css (renamed from modules/home.legacy/conf/firefox/config/chrome/userChrome.css)0
-rw-r--r--modules/by-name/ho/home-manager/module.nix4
-rw-r--r--modules/by-name/im/impermanence/module.nix2
-rw-r--r--modules/by-name/lf/lf/colors5
-rwxr-xr-xmodules/by-name/lf/lf/commands/base.sh78
-rw-r--r--modules/by-name/lf/lf/commands/default.nix261
-rwxr-xr-xmodules/by-name/lf/lf/commands/run.sh30
-rwxr-xr-xmodules/by-name/lf/lf/commands/scripts/archive.sh77
-rwxr-xr-xmodules/by-name/lf/lf/commands/scripts/archive_compress.sh63
-rwxr-xr-xmodules/by-name/lf/lf/commands/scripts/archive_decompress.sh23
-rwxr-xr-xmodules/by-name/lf/lf/commands/scripts/broot_jump.sh25
-rwxr-xr-xmodules/by-name/lf/lf/commands/scripts/cd_project_root.sh19
-rwxr-xr-xmodules/by-name/lf/lf/commands/scripts/chmod.sh16
-rwxr-xr-xmodules/by-name/lf/lf/commands/scripts/clear_trash.sh8
-rwxr-xr-xmodules/by-name/lf/lf/commands/scripts/dl_file.sh43
-rwxr-xr-xmodules/by-name/lf/lf/commands/scripts/dragon.sh9
-rwxr-xr-xmodules/by-name/lf/lf/commands/scripts/dragon_individual.sh9
-rwxr-xr-xmodules/by-name/lf/lf/commands/scripts/dragon_stay.sh9
-rwxr-xr-xmodules/by-name/lf/lf/commands/scripts/execute.sh5
-rwxr-xr-xmodules/by-name/lf/lf/commands/scripts/follow_link.sh13
-rwxr-xr-xmodules/by-name/lf/lf/commands/scripts/fzf_jump.sh24
-rwxr-xr-xmodules/by-name/lf/lf/commands/scripts/go_project_root.sh22
-rwxr-xr-xmodules/by-name/lf/lf/commands/scripts/mk_directory.sh (renamed from modules/by-name/lf/lf/commands/scripts/mk_dir.sh)7
-rwxr-xr-xmodules/by-name/lf/lf/commands/scripts/mk_file.sh7
-rwxr-xr-xmodules/by-name/lf/lf/commands/scripts/mk_file_and_edit.sh33
-rwxr-xr-xmodules/by-name/lf/lf/commands/scripts/mk_link.sh (renamed from modules/by-name/lf/lf/commands/scripts/mk_ln.sh)16
-rwxr-xr-xmodules/by-name/lf/lf/commands/scripts/mk_scr_temp.sh38
-rwxr-xr-xmodules/by-name/lf/lf/commands/scripts/mk_script.sh (renamed from modules/by-name/lf/lf/commands/scripts/mk_scr_default.sh)21
-rwxr-xr-xmodules/by-name/lf/lf/commands/scripts/open.sh15
-rwxr-xr-xmodules/by-name/lf/lf/commands/scripts/restore_trash.sh16
-rwxr-xr-xmodules/by-name/lf/lf/commands/scripts/set_clipboard_path.sh9
-rwxr-xr-xmodules/by-name/lf/lf/commands/scripts/set_wall_paper.sh19
-rwxr-xr-xmodules/by-name/lf/lf/commands/scripts/set_wallpaper.sh19
-rwxr-xr-xmodules/by-name/lf/lf/commands/scripts/stripspace.sh36
-rwxr-xr-xmodules/by-name/lf/lf/commands/scripts/trash.sh26
-rwxr-xr-xmodules/by-name/lf/lf/commands/scripts/trash_clear.sh9
-rwxr-xr-xmodules/by-name/lf/lf/commands/scripts/trash_restore.sh17
-rwxr-xr-xmodules/by-name/lf/lf/commands/scripts/unarchive.sh36
-rwxr-xr-xmodules/by-name/lf/lf/commands/scripts/view_file.sh7
-rw-r--r--modules/by-name/lf/lf/ctpv/default.nix41
-rw-r--r--modules/by-name/lf/lf/ctpv/helpers.sh2
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/any.sh13
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/application/archive/atool.sh5
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/application/archive/default.nix2
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/application/dll/dll.sh9
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/application/epub/default.nix10
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/application/epub/epub.sh9
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/application/pdf/default.nix1
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/application/pdf/pdf.sh5
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/application/pgp/pgp.sh5
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/application/sqlite/sqlite.sh5
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/application/x-bittorrent/torrent.sh5
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/application/x-pem-file/default.nix11
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/application/x-pem-file/pem.sh8
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/audio/audio.sh5
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/audio/default.nix1
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/default.nix9
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/font/default.nix1
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/font/font.sh5
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/image/image.sh5
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/image/svg+xml/svg.sh5
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/image/x-xcf/xcf.sh5
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/inode/ls.sh5
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/inode/symlink.sh5
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/libreoffice.sh5
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/text/bat.sh5
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/text/diff/delta.sh5
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/text/glow.sh5
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/text/html/default.nix13
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/text/html/elinks.sh18
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/text/json/jq.sh5
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/video/video.sh5
-rw-r--r--modules/by-name/lf/lf/keybindings/default.nix27
-rw-r--r--modules/by-name/li/libvirtd/module.nix4
-rw-r--r--modules/by-name/lo/locale/keymaps/us_modified.xkb9
-rw-r--r--modules/by-name/lo/locale/module.nix5
-rw-r--r--modules/by-name/mp/mpv/module.nix315
-rw-r--r--modules/by-name/ni/nix/module.nix4
-rw-r--r--modules/by-name/nv/nvim/module.nix3
-rw-r--r--modules/by-name/nv/nvim/plgs/flatten-nvim/default.nix3
-rw-r--r--modules/by-name/nv/nvim/plgs/lf-nvim/default.nix4
-rw-r--r--modules/by-name/nv/nvim/plgs/telescope/extensions/bibtex/default.nix53
-rw-r--r--modules/by-name/ol/ollama/module.nix10
-rwxr-xr-xmodules/by-name/ri/river/init_base.sh22
-rw-r--r--modules/by-name/ri/river/module.nix199
-rw-r--r--modules/by-name/so/sound/module.nix2
-rw-r--r--modules/by-name/sw/swaylock/images/GTDcanonical.png (renamed from modules/home.legacy/conf/swaylock/GTDcanonical.png)bin34659 -> 34659 bytes
-rw-r--r--modules/by-name/sw/swaylock/images/commands.jpg (renamed from modules/home.legacy/conf/swaylock/commands.jpg)bin629695 -> 629695 bytes
-rw-r--r--modules/by-name/sw/swaylock/images/duwon-lee-tempano-port.jpgbin0 -> 671125 bytes
-rw-r--r--modules/by-name/sw/swaylock/images/gnu.png (renamed from modules/home.legacy/conf/swaylock/gnu.png)bin327518 -> 327518 bytes
-rw-r--r--modules/by-name/sw/swaylock/module.nix27
-rw-r--r--modules/by-name/ta/taskwarrior/module.nix164
-rw-r--r--modules/by-name/ta/taskwarrior/nord.theme (renamed from modules/home.legacy/conf/taskwarrior/nord.theme)0
-rw-r--r--modules/by-name/ta/taskwarrior/secrets/ca.cert161
-rw-r--r--modules/by-name/ta/taskwarrior/secrets/credentials15
-rw-r--r--modules/by-name/ta/taskwarrior/secrets/private.key449
-rw-r--r--modules/by-name/ta/taskwarrior/secrets/public.cert83
-rw-r--r--modules/by-name/ti/timewarrior/module.nix88
-rw-r--r--modules/by-name/ti/timewarrior/nord.theme (renamed from modules/home.legacy/conf/timewarrior/nord.theme)0
-rwxr-xr-xmodules/by-name/ti/timewarrior/taskwarrior_hooks/on-modify.track-timewarrior.py124
-rwxr-xr-xmodules/by-name/ti/timewarrior/taskwarrior_hooks/on-modify.track-total-active-time.py (renamed from modules/home.legacy/conf/taskwarrior/hooks/scripts/on-modify_track-total-active-time.py)43
-rw-r--r--modules/by-name/ts/tskm/module.nix127
-rwxr-xr-xmodules/by-name/ts/tskm/taskwarrior_hooks/enforce-projects.sh12
-rw-r--r--modules/by-name/wa/water-reminder/module.nix57
-rw-r--r--modules/by-name/xd/xdg/module.nix141
-rwxr-xr-xmodules/by-name/xd/xdg/scripts/lf-wrapper.sh39
-rwxr-xr-xmodules/by-name/xd/xdg/scripts/lf_wrapper.sh79
-rwxr-xr-xmodules/by-name/xd/xdg/scripts/ranger_wrapper.sh68
-rwxr-xr-xmodules/by-name/xd/xdg/scripts/url-handler.sh18
-rw-r--r--modules/by-name/yt/yt/input.conf4
-rw-r--r--modules/by-name/yt/yt/mpv.conf1
-rw-r--r--modules/by-name/zs/zsh/module.nix210
-rw-r--r--modules/common/abstract-nord.png (renamed from modules/home.legacy/files/wallpaper/abstract-nord.png)bin140219 -> 140219 bytes
-rw-r--r--modules/common/default.nix (renamed from flake/nixosConfigurations/common.nix)93
-rw-r--r--modules/common/hooks/default.nix8
-rwxr-xr-xmodules/common/hooks/scripts/sync-git-repo.sh13
-rw-r--r--modules/common/projects.json132
-rw-r--r--modules/default.nix8
-rw-r--r--modules/home.legacy/conf/beets/default.nix19
-rw-r--r--modules/home.legacy/conf/beets/plugins.nix2
-rw-r--r--modules/home.legacy/conf/beets/plugins/default.nix2
-rw-r--r--modules/home.legacy/conf/btop/default.nix2
-rw-r--r--modules/home.legacy/conf/default.nix8
-rw-r--r--modules/home.legacy/conf/direnv/default.nix6
-rw-r--r--modules/home.legacy/conf/firefox/config/bookmarks/default.nix31
-rw-r--r--modules/home.legacy/conf/firefox/config/bookmarks/lib.nix49
-rw-r--r--modules/home.legacy/conf/firefox/config/extensions/native_messaging_hosts/default.nix15
-rw-r--r--modules/home.legacy/conf/firefox/config/policies/default.nix146
-rw-r--r--modules/home.legacy/conf/firefox/config/prefs/default.nix21
-rw-r--r--modules/home.legacy/conf/firefox/config/prefs/override.js202
-rw-r--r--modules/home.legacy/conf/firefox/default.nix133
-rw-r--r--modules/home.legacy/conf/firefox/package.nix30
-rw-r--r--modules/home.legacy/conf/firefox/scripts/default.nix29
-rwxr-xr-xmodules/home.legacy/conf/firefox/scripts/extract_cookies.sh77
-rwxr-xr-xmodules/home.legacy/conf/firefox/scripts/unzip_mozlz4.py45
-rwxr-xr-xmodules/home.legacy/conf/firefox/scripts/update_extensions.sh18
-rw-r--r--modules/home.legacy/conf/gtk/default.nix2
-rw-r--r--modules/home.legacy/conf/keepassxc/default.nix6
-rw-r--r--modules/home.legacy/conf/latexindent/default.nix6
-rw-r--r--modules/home.legacy/conf/mail/accounts/benedikt.nix4
-rw-r--r--modules/home.legacy/conf/mail/accounts/soispha.nix4
-rw-r--r--modules/home.legacy/conf/mail/default.nix38
-rw-r--r--modules/home.legacy/conf/mako/default.nix6
-rw-r--r--modules/home.legacy/conf/mbsync/default.nix17
-rw-r--r--modules/home.legacy/conf/mpv/default.nix10
-rw-r--r--modules/home.legacy/conf/neomutt/default.nix5
-rw-r--r--modules/home.legacy/conf/npm/default.nix6
-rw-r--r--modules/home.legacy/conf/rclone/default.nix6
-rw-r--r--modules/home.legacy/conf/starship/default.nix1
-rw-r--r--modules/home.legacy/conf/swayidle/default.nix7
-rw-r--r--modules/home.legacy/conf/swaylock/default.nix10
-rw-r--r--modules/home.legacy/conf/taskwarrior/default.nix125
-rw-r--r--modules/home.legacy/conf/taskwarrior/firefox/default.nix32
-rw-r--r--modules/home.legacy/conf/taskwarrior/hooks/default.nix114
-rwxr-xr-xmodules/home.legacy/conf/taskwarrior/hooks/scripts/on-add_enforce-policies.sh41
-rwxr-xr-xmodules/home.legacy/conf/taskwarrior/hooks/scripts/on-add_sync-git-repo.sh42
-rwxr-xr-xmodules/home.legacy/conf/taskwarrior/hooks/scripts/on-modify_sync-git-repo.sh43
-rwxr-xr-xmodules/home.legacy/conf/taskwarrior/hooks/scripts/on-modify_track-timewarrior.py94
-rw-r--r--modules/home.legacy/conf/taskwarrior/projects/default.nix123
-rw-r--r--modules/home.legacy/conf/timewarrior/default.nix22
-rw-r--r--modules/home.legacy/conf/xdg/default.nix63
-rwxr-xr-xmodules/home.legacy/conf/xdg/url_handler.sh18
-rw-r--r--modules/home.legacy/conf/xdg/xdg_vars.nix29
-rw-r--r--modules/home.legacy/conf/ytcc/default.nix11
-rw-r--r--modules/home.legacy/conf/ytcc/ytcc.conf37
-rw-r--r--modules/home.legacy/default.nix3
-rw-r--r--modules/home.legacy/files/default.nix1
-rw-r--r--modules/home.legacy/files/wallpaper/default.nix14
-rw-r--r--modules/home.legacy/pkgs/default.nix87
-rw-r--r--modules/home.legacy/wms/default.nix7
-rw-r--r--modules/home.legacy/wms/plasma/default.nix5
-rw-r--r--modules/home.legacy/wms/river/default.nix91
-rwxr-xr-xmodules/home.legacy/wms/river/init.sh80
-rw-r--r--modules/home.legacy/wms/river/res/keys.ron58
-rw-r--r--modules/home.legacy/wms/river/res/moonlander.ron66
-rw-r--r--modules/home.legacy/wms/sway/default.nix16
-rw-r--r--pkgs/by-name/be/beetsExtraPlugins/package.nix4
-rw-r--r--pkgs/by-name/be/beetsExtraPlugins/xtractor.nix100
-rw-r--r--pkgs/by-name/bl/blake3/add_cargo_lock.patch431
-rw-r--r--pkgs/by-name/bl/blake3/package.nix29
-rw-r--r--pkgs/by-name/ge/generate_moz_extension/Cargo.lock414
-rw-r--r--pkgs/by-name/ge/generate_moz_extension/Cargo.toml10
-rw-r--r--pkgs/by-name/ge/generate_moz_extension/flake.lock18
-rwxr-xr-xpkgs/by-name/gi/git-cleanup/git-cleanup.sh78
-rw-r--r--pkgs/by-name/gi/git-cleanup/package.nix17
-rw-r--r--pkgs/by-name/hi/hibernate/package.nix4
-rw-r--r--pkgs/by-name/lf/lf-make-map/.envrc3
-rw-r--r--pkgs/by-name/lf/lf-make-map/Cargo.lock127
-rw-r--r--pkgs/by-name/lf/lf-make-map/Cargo.toml6
-rw-r--r--pkgs/by-name/lf/lf-make-map/flake.lock24
-rwxr-xr-xpkgs/by-name/lo/lock/lock.sh13
-rw-r--r--pkgs/by-name/lo/lock/package.nix17
-rwxr-xr-xpkgs/by-name/na/nato/nato.py106
-rw-r--r--pkgs/by-name/na/nato/package.nix34
-rw-r--r--pkgs/by-name/ne/neorg/functions/add.sh23
-rw-r--r--pkgs/by-name/ne/neorg/functions/context.sh43
-rw-r--r--pkgs/by-name/ne/neorg/functions/dmenu.sh14
-rw-r--r--pkgs/by-name/ne/neorg/functions/f_start.sh7
-rw-r--r--pkgs/by-name/ne/neorg/functions/f_stop.sh7
-rw-r--r--pkgs/by-name/ne/neorg/functions/inputs.sh62
-rw-r--r--pkgs/by-name/ne/neorg/functions/list.sh8
-rw-r--r--pkgs/by-name/ne/neorg/functions/project.sh41
-rw-r--r--pkgs/by-name/ne/neorg/functions/review.sh12
-rw-r--r--pkgs/by-name/ne/neorg/functions/utils.sh40
-rw-r--r--pkgs/by-name/ne/neorg/functions/workspace.sh9
-rwxr-xr-xpkgs/by-name/ne/neorg/main.sh189
-rwxr-xr-xpkgs/by-name/ne/neorg/neorg_id_function.sh16
-rw-r--r--pkgs/by-name/ne/neorg/package.nix72
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/.envrc (renamed from pkgs/by-name/up/update-vim-plugins/.envrc)1
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/.gitignore2
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/Cargo.lock334
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/Cargo.toml71
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/TODO1
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/contrib/example.json5
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/flake.lock27
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/flake.nix25
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/package.nix14
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/src/cli.rs11
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/src/key_map/commands.rs109
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/src/key_map/mod.rs79
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/src/main.rs34
-rwxr-xr-xpkgs/by-name/ri/river-mk-keymap/update.sh3
-rw-r--r--pkgs/by-name/ri/river-start/package.nix14
-rwxr-xr-xpkgs/by-name/ri/river-start/river-start.sh10
-rw-r--r--pkgs/by-name/sc/screenshot_persistent/package.nix13
-rwxr-xr-xpkgs/by-name/sc/screenshot_persistent/screenshot_persistent.sh10
-rw-r--r--pkgs/by-name/so/sort_song/package.nix17
-rwxr-xr-xpkgs/by-name/so/sort_song/sort_song.sh34
-rw-r--r--pkgs/by-name/sp/spodi/package.nix39
-rwxr-xr-xpkgs/by-name/sp/spodi/sh/download.sh58
-rwxr-xr-xpkgs/by-name/sp/spodi/sh/update.sh52
-rwxr-xr-xpkgs/by-name/sp/spodi/spodi.sh71
-rwxr-xr-xpkgs/by-name/st/stamp/stamp.sh2
-rw-r--r--pkgs/by-name/ts/tskm/.envrc8
-rw-r--r--pkgs/by-name/ts/tskm/.gitignore2
-rw-r--r--pkgs/by-name/ts/tskm/Cargo.lock1252
-rw-r--r--pkgs/by-name/ts/tskm/Cargo.toml91
-rw-r--r--pkgs/by-name/ts/tskm/build.rs52
-rw-r--r--pkgs/by-name/ts/tskm/flake.lock27
-rw-r--r--pkgs/by-name/ts/tskm/flake.nix29
-rw-r--r--pkgs/by-name/ts/tskm/package.nix53
-rw-r--r--pkgs/by-name/ts/tskm/src/cli.rs153
-rw-r--r--pkgs/by-name/ts/tskm/src/interface/input/handle.rs112
-rw-r--r--pkgs/by-name/ts/tskm/src/interface/input/mod.rs257
-rw-r--r--pkgs/by-name/ts/tskm/src/interface/mod.rs4
-rw-r--r--pkgs/by-name/ts/tskm/src/interface/neorg/handle.rs88
-rw-r--r--pkgs/by-name/ts/tskm/src/interface/neorg/mod.rs25
-rw-r--r--pkgs/by-name/ts/tskm/src/interface/open/handle.rs232
-rw-r--r--pkgs/by-name/ts/tskm/src/interface/open/mod.rs106
-rw-r--r--pkgs/by-name/ts/tskm/src/interface/project/handle.rs87
-rw-r--r--pkgs/by-name/ts/tskm/src/interface/project/mod.rs73
-rw-r--r--pkgs/by-name/ts/tskm/src/main.rs67
-rw-r--r--pkgs/by-name/ts/tskm/src/rofi/mod.rs37
-rw-r--r--pkgs/by-name/ts/tskm/src/state.rs45
-rw-r--r--pkgs/by-name/ts/tskm/src/task/mod.rs342
-rwxr-xr-xpkgs/by-name/ts/tskm/update.sh3
-rwxr-xr-xpkgs/by-name/up/update-vim-plugins/check-duplicates.sh43
-rw-r--r--pkgs/by-name/up/update-vim-plugins/flake.lock61
-rw-r--r--pkgs/by-name/up/update-vim-plugins/flake.nix24
-rw-r--r--pkgs/by-name/up/update-vim-plugins/package.nix47
-rw-r--r--pkgs/by-name/up/update-vim-plugins/poetry.lock740
-rw-r--r--pkgs/by-name/up/update-vim-plugins/pyproject.toml45
-rwxr-xr-xpkgs/by-name/up/update-vim-plugins/update.sh5
-rw-r--r--pkgs/by-name/up/update-vim-plugins/update_vim_plugins/__init__.py0
-rw-r--r--pkgs/by-name/up/update-vim-plugins/update_vim_plugins/__main__.py15
-rw-r--r--pkgs/by-name/up/update-vim-plugins/update_vim_plugins/cleanup.py100
-rw-r--r--pkgs/by-name/up/update-vim-plugins/update_vim_plugins/helpers.py61
-rw-r--r--pkgs/by-name/up/update-vim-plugins/update_vim_plugins/nix.py121
-rw-r--r--pkgs/by-name/up/update-vim-plugins/update_vim_plugins/plugin.py182
-rw-r--r--pkgs/by-name/up/update-vim-plugins/update_vim_plugins/spec.py143
-rw-r--r--pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/__init__.py0
-rw-r--r--pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/fixtures.py44
-rw-r--r--pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/test_nix.py32
-rw-r--r--pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/test_plugin.py144
-rw-r--r--pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/test_spec.py136
-rw-r--r--pkgs/by-name/up/update-vim-plugins/update_vim_plugins/update.py212
-rw-r--r--pkgs/by-name/vi/vimExtraPlugins/README.md92
-rw-r--r--pkgs/by-name/vi/vimExtraPlugins/check.nix37
-rw-r--r--pkgs/by-name/vi/vimExtraPlugins/overrides.nix34
-rw-r--r--pkgs/by-name/vi/vimExtraPlugins/package.nix19
-rw-r--r--pkgs/by-name/vi/vimExtraPlugins/plugins/.plugins.json7
-rw-r--r--pkgs/by-name/vi/vimExtraPlugins/plugins/blacklist.txt1
-rw-r--r--pkgs/by-name/vi/vimExtraPlugins/plugins/default.nix39
-rw-r--r--pkgs/by-name/vi/vimExtraPlugins/plugins/manifest.txt2
-rw-r--r--pkgs/by-name/vi/vimExtraPlugins/plugins/plugins.md6
-rw-r--r--pkgs/by-name/vi/vimExtraPlugins/plugins/whitelist.txt0
-rwxr-xr-xpkgs/by-name/vi/vimExtraPlugins/update.sh27
-rw-r--r--pkgs/by-name/vi/virsh-del/package.nix13
-rwxr-xr-xpkgs/by-name/vi/virsh-del/virsh-del.sh10
-rw-r--r--pkgs/by-name/yt/yt/package.nix22
-rw-r--r--pkgs/by-name/yt/yti/package.nix17
-rwxr-xr-xpkgs/by-name/yt/yti/yti.sh33
-rw-r--r--tests/by-name/nv/nvim-neorg/test.desc2
-rw-r--r--tests/default.nix4
-rw-r--r--tests/infrastructure/default.nix10
-rwxr-xr-xupdate.sh2
338 files changed, 7685 insertions, 10495 deletions
diff --git a/build.sh b/build.sh
index 3c3d387c..0e574a3a 100755
--- a/build.sh
+++ b/build.sh
@@ -1,6 +1,8 @@
 #!/usr/bin/env sh
 
 host="${1-tiamat}"
+[ "$#" -gt 0 ] && shift 1
+
 root="$(git rev-parse --show-toplevel)"
 
 SYSTEM_OUT="$root/result-system"
@@ -19,7 +21,7 @@ check() {
 }
 
 build_system() {
-    _val="$(nix build ".#nixosConfigurations.$host.config.system.build.toplevel" --print-out-paths --no-link)"
+    _val="$(nix build ".#nixosConfigurations.$host.config.system.build.toplevel" --print-out-paths --no-link "$@")"
     exit_val="$?"
 
     if [ "$exit_val" -ne 0 ]; then
@@ -30,7 +32,7 @@ build_system() {
     fi
 }
 
-system="$(build_system)"
+system="$(build_system "$@")"
 [ "$system" = "1" ] && exit 1
 
 check "$SYSTEM_OUT"
diff --git a/flake.lock b/flake.lock
index d3588c79..ac446ada 100644
--- a/flake.lock
+++ b/flake.lock
@@ -16,11 +16,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1723293904,
-        "narHash": "sha256-b+uqzj+Wa6xgMS9aNbX4I+sXeb5biPDi39VgvSFqFvU=",
+        "lastModified": 1736955230,
+        "narHash": "sha256-uenf8fv2eG5bKM8C/UvFaiJMZ4IpUFaQxk9OH5t/1gA=",
         "owner": "ryantm",
         "repo": "agenix",
-        "rev": "f6291c5935fdc4e0bef208cfc0dcab7e3f7a1c41",
+        "rev": "e600439ec4c273cf11e06fe4d9d906fb98fa097c",
         "type": "github"
       },
       "original": {
@@ -29,6 +29,32 @@
         "type": "github"
       }
     },
+    "arkenfox-nixos": {
+      "inputs": {
+        "flake-compat": [
+          "flake-compat"
+        ],
+        "nixpkgs": [
+          "nixpkgs"
+        ],
+        "pre-commit": [
+          "pre-commit-hooks"
+        ]
+      },
+      "locked": {
+        "lastModified": 1739094253,
+        "narHash": "sha256-yDTgmfSuL5Ax7LRuxhdoMJrBi4X9Q3fyyI7TerTXVBA=",
+        "owner": "dwarfmaster",
+        "repo": "arkenfox-nixos",
+        "rev": "27e0c3094e778bd73f93bea799f627ef317e7f22",
+        "type": "github"
+      },
+      "original": {
+        "owner": "dwarfmaster",
+        "repo": "arkenfox-nixos",
+        "type": "github"
+      }
+    },
     "beautysh": {
       "inputs": {
         "nixpkgs": [
@@ -57,11 +83,11 @@
     },
     "crane": {
       "locked": {
-        "lastModified": 1734808813,
-        "narHash": "sha256-3aH/0Y6ajIlfy7j52FGZ+s4icVX0oHhqBzRdlOeztqg=",
+        "lastModified": 1742394900,
+        "narHash": "sha256-vVOAp9ahvnU+fQoKd4SEXB2JG2wbENkpqcwlkIXgUC0=",
         "owner": "ipetkov",
         "repo": "crane",
-        "rev": "72e2d02dbac80c8c86bf6bf3e785536acf8ee926",
+        "rev": "70947c1908108c0c551ddfd73d4f750ff2ea67cd",
         "type": "github"
       },
       "original": {
@@ -77,11 +103,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1728330715,
-        "narHash": "sha256-xRJ2nPOXb//u1jaBnDP56M7v5ldavjbtR6lfGqSvcKg=",
+        "lastModified": 1741473158,
+        "narHash": "sha256-kWNaq6wQUbUMlPgw8Y+9/9wP0F8SHkjy24/mN3UAppg=",
         "owner": "numtide",
         "repo": "devshell",
-        "rev": "dd6b80932022cea34a019e2bb32f6fa9e494dfef",
+        "rev": "7c9e793ebe66bcba8292989a68c0419b737a22a0",
         "type": "github"
       },
       "original": {
@@ -97,11 +123,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1735468753,
-        "narHash": "sha256-2dt1nOe9zf9pDkf5Kn7FUFyPRo581s0n90jxYXJ94l0=",
+        "lastModified": 1741786315,
+        "narHash": "sha256-VT65AE2syHVj6v/DGB496bqBnu1PXrrzwlw07/Zpllc=",
         "owner": "nix-community",
         "repo": "disko",
-        "rev": "84a5b93637cc16cbfcc61b6e1684d626df61eb21",
+        "rev": "0d8c6ad4a43906d14abd5c60e0ffe7b587b213de",
         "type": "github"
       },
       "original": {
@@ -133,11 +159,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1733312601,
-        "narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=",
+        "lastModified": 1741352980,
+        "narHash": "sha256-+u2UunDA4Cl5Fci3m7S643HzKmIDAe+fiXrLqYsR2fs=",
         "owner": "hercules-ci",
         "repo": "flake-parts",
-        "rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9",
+        "rev": "f4330d22f1c5d2ba72d3d22df5597d123fdb60a9",
         "type": "github"
       },
       "original": {
@@ -202,17 +228,14 @@
         ],
         "nixpkgs": [
           "nixpkgs"
-        ],
-        "nixpkgs-stable": [
-          "nixpkgs-stable"
         ]
       },
       "locked": {
-        "lastModified": 1734797603,
-        "narHash": "sha256-ulZN7ps8nBV31SE+dwkDvKIzvN6hroRY8sYOT0w+E28=",
+        "lastModified": 1742649964,
+        "narHash": "sha256-DwOTp7nvfi8mRfuL1escHDXabVXFGT1VlPD1JHrtrco=",
         "owner": "cachix",
         "repo": "git-hooks.nix",
-        "rev": "f0f0dc4920a903c3e08f5bdb9246bb572fcae498",
+        "rev": "dcf5072734cb576d2b0c59b2ac44f5050b5eac82",
         "type": "github"
       },
       "original": {
@@ -268,11 +291,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1735381016,
-        "narHash": "sha256-CyCZFhMUkuYbSD6bxB/r43EdmDE7hYeZZPTCv0GudO4=",
+        "lastModified": 1743136572,
+        "narHash": "sha256-uwaVrKgi6g1TUq56247j6QvvFtYHloCkjCrEpGBvV54=",
         "owner": "nix-community",
         "repo": "home-manager",
-        "rev": "10e99c43cdf4a0713b4e81d90691d22c6a58bdf2",
+        "rev": "1efd2503172016a6742c87b47b43ca2c8145607d",
         "type": "github"
       },
       "original": {
@@ -284,11 +307,11 @@
     },
     "impermanence": {
       "locked": {
-        "lastModified": 1734945620,
-        "narHash": "sha256-olIfsfJK4/GFmPH8mXMmBDAkzVQ1TWJmeGT3wBGfQPY=",
+        "lastModified": 1737831083,
+        "narHash": "sha256-LJggUHbpyeDvNagTUrdhe/pRVp4pnS6wVKALS782gRI=",
         "owner": "nix-community",
         "repo": "impermanence",
-        "rev": "d000479f4f41390ff7cf9204979660ad5dd16176",
+        "rev": "4b3e914cdf97a5b536a889e939fb2fd2b043a170",
         "type": "github"
       },
       "original": {
@@ -334,9 +357,6 @@
         "flake-parts": [
           "flake-parts"
         ],
-        "flake-utils": [
-          "flake-utils"
-        ],
         "nixpkgs": [
           "nixpkgs-stable"
         ],
@@ -348,27 +368,27 @@
         ]
       },
       "locked": {
-        "lastModified": 1718178907,
-        "narHash": "sha256-eSZyrQ9uoPB9iPQ8Y5H7gAmAgAvCw3InStmU3oEjqsE=",
+        "lastModified": 1737639419,
+        "narHash": "sha256-AEEDktApTEZ5PZXNDkry2YV2k6t0dTgLPEmAZbnigXU=",
         "owner": "nix-community",
         "repo": "lanzaboote",
-        "rev": "b627ccd97d0159214cee5c7db1412b75e4be6086",
+        "rev": "a65905a09e2c43ff63be8c0e86a93712361f871e",
         "type": "github"
       },
       "original": {
         "owner": "nix-community",
-        "ref": "v0.4.1",
+        "ref": "v0.4.2",
         "repo": "lanzaboote",
         "type": "github"
       }
     },
     "library": {
       "locked": {
-        "lastModified": 1735055361,
-        "narHash": "sha256-wZmUlcUG6ktcMuI3DVO2HsnpqX7z5iLdMwOo0YgVdGM=",
+        "lastModified": 1738443114,
+        "narHash": "sha256-IV7n/l3rFoz5UuavrDv0a7IIOPne0jDQVmJAR8bve8U=",
         "ref": "prime",
-        "rev": "10c82665cb197b68ff0d9bb02e12a4287f1b8925",
-        "revCount": 2,
+        "rev": "65bf71bb6ef05ce684924a1dc248bb2e8e2869fb",
+        "revCount": 17,
         "type": "git",
         "url": "https://git.foss-syndicate.org/vhack.eu/nix-library"
       },
@@ -385,11 +405,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1735478292,
-        "narHash": "sha256-Ys9pSP9ch0SthhpbjnkCSJ9ZLfaNKnt/dcy7swjmS1A=",
+        "lastModified": 1743221873,
+        "narHash": "sha256-i8VPNm4UBsC3Ni6VwjojVJvCpS9GZ4vPrpFRtCGJzBs=",
         "owner": "lnl7",
         "repo": "nix-darwin",
-        "rev": "71a3a075e3229a7518d76636bb762aef2bcb73ac",
+        "rev": "53d0f0ed11487a4476741fde757d0feabef4cc4e",
         "type": "github"
       },
       "original": {
@@ -426,11 +446,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1735443188,
-        "narHash": "sha256-AydPpRBh8+NOkrLylG7vTsHrGO2b5L7XkMEL5HlzcA8=",
+        "lastModified": 1742701275,
+        "narHash": "sha256-AulwPVrS9859t+eJ61v24wH/nfBEIDSXYxlRo3fL/SA=",
         "owner": "nix-community",
         "repo": "nix-index-database",
-        "rev": "55ab1e1df5daf2476e6b826b69a82862dcbd7544",
+        "rev": "36dc43cb50d5d20f90a28d53abb33a32b0a2aae6",
         "type": "github"
       },
       "original": {
@@ -441,40 +461,22 @@
     },
     "nixVim": {
       "inputs": {
-        "devshell": [
-          "devshell"
-        ],
-        "flake-compat": [
-          "flake-compat"
-        ],
         "flake-parts": [
           "flake-parts"
         ],
-        "git-hooks": [
-          "git-hooks"
-        ],
-        "home-manager": [
-          "home-manager"
-        ],
-        "nix-darwin": [
-          "nix-darwin"
-        ],
         "nixpkgs": [
           "nixpkgs"
         ],
         "nuschtosSearch": [
           "nuschtosSearch"
-        ],
-        "treefmt-nix": [
-          "treefmt-nix"
         ]
       },
       "locked": {
-        "lastModified": 1735378670,
-        "narHash": "sha256-A8aQA+YhJfA8mUpzXOZdlXNnKiZg2EcpCn1srgtBjTs=",
+        "lastModified": 1743157969,
+        "narHash": "sha256-ldlSyVKNaXL7ys7Jr7mLhlpGDE4VPVcWmV7Odupn5TY=",
         "owner": "nix-community",
         "repo": "nixvim",
-        "rev": "f4b0b81ef9eb4e37e75f32caf1f02d5501594811",
+        "rev": "95573411bc9be155a93b0f15d2bad62c6b43b3cc",
         "type": "github"
       },
       "original": {
@@ -493,11 +495,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1734915500,
-        "narHash": "sha256-A7CTIQ8SW0hfbhKlwK+vSsu4pD+Oaelw3v6goX6go+U=",
+        "lastModified": 1742568034,
+        "narHash": "sha256-QaMEhcnscfF2MqB7flZr+sLJMMYZPnvqO4NYf9B4G38=",
         "owner": "nix-community",
         "repo": "nixos-generators",
-        "rev": "051d1b2dda3b2e81b38d82e2b691e5c2f4d335f4",
+        "rev": "42ee229088490e3777ed7d1162cb9e9d8c3dbb11",
         "type": "github"
       },
       "original": {
@@ -508,11 +510,11 @@
     },
     "nixpkgs": {
       "locked": {
-        "lastModified": 1733940404,
-        "narHash": "sha256-Pj39hSoUA86ZePPF/UXiYHHM7hMIkios8TYG29kQT4g=",
+        "lastModified": 1743095683,
+        "narHash": "sha256-gWd4urRoLRe8GLVC/3rYRae1h+xfQzt09xOfb0PaHSk=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "5d67ea6b4b63378b9c13be21e2ec9d1afc921713",
+        "rev": "5e5402ecbcb27af32284d4a62553c019a3a49ea6",
         "type": "github"
       },
       "original": {
@@ -522,44 +524,44 @@
         "type": "github"
       }
     },
-    "nixpkgs-lib": {
+    "nixpkgs-lf": {
       "locked": {
-        "lastModified": 1735434288,
-        "narHash": "sha256-zg9W8r2xBLoWW47mFYzodngQmalqV7abjXncBcwAQZ8=",
-        "owner": "nix-community",
-        "repo": "nixpkgs.lib",
-        "rev": "97ed8d4ba97b1d4858bdc39cdabfdebc623de82b",
+        "lastModified": 1743256538,
+        "narHash": "sha256-fG19N9PvPtsV3UUwT7lauNJ7tE4ZB/EPKwwENrqqKCQ=",
+        "owner": "bpeetz",
+        "repo": "nixpkgs",
+        "rev": "e315c0e09beaf4daf4041d402067cbdbc84870d9",
         "type": "github"
       },
       "original": {
-        "owner": "nix-community",
-        "repo": "nixpkgs.lib",
+        "owner": "bpeetz",
+        "ref": "init-lf.nvim",
+        "repo": "nixpkgs",
         "type": "github"
       }
     },
-    "nixpkgs-onlykey": {
+    "nixpkgs-lib": {
       "locked": {
-        "lastModified": 1711294706,
-        "narHash": "sha256-KhDQnSH2cZNiw8QUvcaTmz/xRR0TdsAGz1S5yvCSbls=",
-        "owner": "soispha",
-        "repo": "nixpkgs",
-        "rev": "16367bebf75f1beaa64dcda55ebcc2c87cb7cd34",
+        "lastModified": 1742692082,
+        "narHash": "sha256-s3XOULQj7BVO7myY5V4Sob0tRZ7nRpwEOIzXg/MkD/Q=",
+        "owner": "nix-community",
+        "repo": "nixpkgs.lib",
+        "rev": "a09310bc940f245e51b1ffea68731244ca38f2bd",
         "type": "github"
       },
       "original": {
-        "owner": "soispha",
-        "ref": "fix-onlykey-agent",
-        "repo": "nixpkgs",
+        "owner": "nix-community",
+        "repo": "nixpkgs.lib",
         "type": "github"
       }
     },
     "nixpkgs-stable": {
       "locked": {
-        "lastModified": 1735531152,
-        "narHash": "sha256-As8I+ebItDKtboWgDXYZSIjGlKeqiLBvjxsQHUmAf1Q=",
+        "lastModified": 1742937945,
+        "narHash": "sha256-lWc+79eZRyvHp/SqMhHTMzZVhpxkRvthsP1Qx6UCq0E=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "3ffbbdbac0566a0977da3d2657b89cbcfe9a173b",
+        "rev": "d02d88f8de5b882ccdde0465d8fa2db3aa1169f7",
         "type": "github"
       },
       "original": {
@@ -569,22 +571,6 @@
         "type": "github"
       }
     },
-    "nixpkgs-tfc": {
-      "locked": {
-        "lastModified": 1723544577,
-        "narHash": "sha256-OclFNxcgAFCBQPSxCzy7mO/sB5TGzhe/JWmbUGVV7Lw=",
-        "owner": "soispha",
-        "repo": "nixpkgs",
-        "rev": "727bfcd1e1ffba0f4f58c9eea91087703025670a",
-        "type": "github"
-      },
-      "original": {
-        "owner": "soispha",
-        "ref": "add-termfilechooser",
-        "repo": "nixpkgs",
-        "type": "github"
-      }
-    },
     "nuschtosSearch": {
       "inputs": {
         "flake-utils": [
@@ -596,11 +582,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1733773348,
-        "narHash": "sha256-Y47y+LesOCkJaLvj+dI/Oa6FAKj/T9sKVKDXLNsViPw=",
+        "lastModified": 1743201766,
+        "narHash": "sha256-bb/dqoIjtIWtJRzASOe8g4m8W2jUIWtuoGPXdNjM/Tk=",
         "owner": "NuschtOS",
         "repo": "search",
-        "rev": "3051be7f403bff1d1d380e4612f0c70675b44fc9",
+        "rev": "2651dbfad93d6ef66c440cbbf23238938b187bde",
         "type": "github"
       },
       "original": {
@@ -626,11 +612,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1735164664,
-        "narHash": "sha256-DaWy+vo3c4TQ93tfLjUgcpPaSoDw4qV4t76Y3Mhu84I=",
+        "lastModified": 1742397518,
+        "narHash": "sha256-nzgO/ZCSBzWjbMkYDxG+yl9Z2eGbCgQu06Oku3ir5D4=",
         "owner": "nix-community",
         "repo": "poetry2nix",
-        "rev": "1fb01e90771f762655be7e0e805516cd7fa4d58e",
+        "rev": "b9a98080beff0903a5e5fe431f42cde1e3e50d6b",
         "type": "github"
       },
       "original": {
@@ -649,17 +635,14 @@
         ],
         "nixpkgs": [
           "nixpkgs"
-        ],
-        "nixpkgs-stable": [
-          "nixpkgs-stable"
         ]
       },
       "locked": {
-        "lastModified": 1734797603,
-        "narHash": "sha256-ulZN7ps8nBV31SE+dwkDvKIzvN6hroRY8sYOT0w+E28=",
+        "lastModified": 1742649964,
+        "narHash": "sha256-DwOTp7nvfi8mRfuL1escHDXabVXFGT1VlPD1JHrtrco=",
         "owner": "cachix",
         "repo": "pre-commit-hooks.nix",
-        "rev": "f0f0dc4920a903c3e08f5bdb9246bb572fcae498",
+        "rev": "dcf5072734cb576d2b0c59b2ac44f5050b5eac82",
         "type": "github"
       },
       "original": {
@@ -684,11 +667,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1735596984,
-        "narHash": "sha256-cNBVmvi/5xckx+8x7Eb/nzfmUoL1G9VJWSlzWlu7GeE=",
+        "lastModified": 1738406121,
+        "narHash": "sha256-N3scpt+nwPbqzsRs4gjZpDiBivfPRQJ0D75bPeYhHME=",
         "ref": "prime",
-        "rev": "45823b74a36391f585f4040c64b1e7f7cd8cb87f",
-        "revCount": 14,
+        "rev": "2b6889092e5839c8987e800f1d3d847dd5b50153",
+        "revCount": 19,
         "type": "git",
         "url": "https://git.foss-syndicate.org/bpeetz/qmk_layout.git"
       },
@@ -717,11 +700,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1726755133,
-        "narHash": "sha256-03XIEjHeZEjHXctsXYUB+ZLQmM0WuhR6qWQjwekFk/M=",
+        "lastModified": 1741508717,
+        "narHash": "sha256-iQf1WdNxaApOFHIx4RLMRZ4f8g+8Xp0Z1/E/Mz2rLxY=",
         "owner": "yaxitech",
         "repo": "ragenix",
-        "rev": "687ee92114bce9c4724376cf6b21235abe880bfa",
+        "rev": "2a2bea99d74927e54adf53cbf113219def67d5c9",
         "type": "github"
       },
       "original": {
@@ -730,41 +713,10 @@
         "type": "github"
       }
     },
-    "river_init_lesser": {
-      "inputs": {
-        "crane": [
-          "crane"
-        ],
-        "flake-compat": [
-          "flake-compat"
-        ],
-        "flake-utils": [
-          "flake-utils"
-        ],
-        "nixpkgs": [
-          "nixpkgs"
-        ],
-        "rust-overlay": [
-          "rust-overlay"
-        ]
-      },
-      "locked": {
-        "lastModified": 1683353540,
-        "narHash": "sha256-tOf9gfFzWjZxIF/2BAU64aH55xfic6SapKsFqVn6U/8=",
-        "ref": "refs/heads/prime",
-        "rev": "aedd2bf8863802443d7b6df94646c239d67b2796",
-        "revCount": 10,
-        "type": "git",
-        "url": "https://codeberg.org/soispha/river_keymap_init.git"
-      },
-      "original": {
-        "type": "git",
-        "url": "https://codeberg.org/soispha/river_keymap_init.git"
-      }
-    },
     "root": {
       "inputs": {
         "agenix": "agenix",
+        "arkenfox-nixos": "arkenfox-nixos",
         "beautysh": "beautysh",
         "crane": "crane",
         "devshell": "devshell",
@@ -785,23 +737,20 @@
         "nixVim": "nixVim",
         "nixos-generators": "nixos-generators",
         "nixpkgs": "nixpkgs",
+        "nixpkgs-lf": "nixpkgs-lf",
         "nixpkgs-lib": "nixpkgs-lib",
-        "nixpkgs-onlykey": "nixpkgs-onlykey",
         "nixpkgs-stable": "nixpkgs-stable",
-        "nixpkgs-tfc": "nixpkgs-tfc",
         "nuschtosSearch": "nuschtosSearch",
         "poetry2nix": "poetry2nix",
         "pre-commit-hooks": "pre-commit-hooks",
         "qmk_firmware": "qmk_firmware",
         "ragenix": "ragenix",
-        "river_init_lesser": "river_init_lesser",
         "rust-overlay": "rust-overlay",
         "serverphone": "serverphone",
         "shell_library": "shell_library",
         "systems": "systems",
         "templates": "templates",
-        "treefmt-nix": "treefmt-nix",
-        "user_js": "user_js"
+        "treefmt-nix": "treefmt-nix"
       }
     },
     "rust-overlay": {
@@ -811,11 +760,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1735525800,
-        "narHash": "sha256-pcN8LAL021zdC99a9F7iEiFCI1wmrE4DpIYUgKpB/jY=",
+        "lastModified": 1743215516,
+        "narHash": "sha256-52qbrkG65U1hyrQWltgHTgH4nm0SJL+9TWv2UDCEPNI=",
         "owner": "oxalica",
         "repo": "rust-overlay",
-        "rev": "10faa81b4c0135a04716cbd1649260d82b2890cd",
+        "rev": "524463199fdee49338006b049bc376b965a2cfed",
         "type": "github"
       },
       "original": {
@@ -939,11 +888,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1735135567,
-        "narHash": "sha256-8T3K5amndEavxnludPyfj3Z1IkcFdRpR23q+T0BVeZE=",
+        "lastModified": 1743081648,
+        "narHash": "sha256-WRAylyYptt6OX5eCEBWyTwOEqEtD6zt33rlUkr6u3cE=",
         "owner": "numtide",
         "repo": "treefmt-nix",
-        "rev": "9e09d30a644c57257715902efbb3adc56c79cf28",
+        "rev": "29a3d7b768c70addce17af0869f6e2bd8f5be4b7",
         "type": "github"
       },
       "original": {
@@ -951,22 +900,6 @@
         "repo": "treefmt-nix",
         "type": "github"
       }
-    },
-    "user_js": {
-      "flake": false,
-      "locked": {
-        "lastModified": 1731156949,
-        "narHash": "sha256-0qwqVc3hrpbQMMJOhbelSrR8cZOqLLWs4T+qyeHfiAc=",
-        "owner": "arkenfox",
-        "repo": "user.js",
-        "rev": "eae5762d29f18115fbffd73d89bd9e2510b25427",
-        "type": "github"
-      },
-      "original": {
-        "owner": "arkenfox",
-        "repo": "user.js",
-        "type": "github"
-      }
     }
   },
   "root": "root",
diff --git a/flake.nix b/flake.nix
index d08eb34a..8d8ce03a 100644
--- a/flake.nix
+++ b/flake.nix
@@ -11,8 +11,7 @@
 
     # open nixpkgs prs
     # FIXME: Close these PRs <2024-09-07>
-    nixpkgs-tfc.url = "github:soispha/nixpkgs/add-termfilechooser";
-    nixpkgs-onlykey.url = "github:soispha/nixpkgs/fix-onlykey-agent";
+    nixpkgs-lf.url = "github:bpeetz/nixpkgs/init-lf.nvim";
 
     library = {
       url = "git+https://git.foss-syndicate.org/vhack.eu/nix-library?ref=prime";
@@ -40,7 +39,6 @@
       inputs = {
         flake-compat.follows = "flake-compat";
         gitignore.follows = "gitignore";
-        nixpkgs-stable.follows = "nixpkgs-stable";
         nixpkgs.follows = "nixpkgs";
       };
     };
@@ -93,7 +91,6 @@
       inputs = {
         nixpkgs.follows = "nixpkgs";
         flake-compat.follows = "flake-compat";
-        nixpkgs-stable.follows = "nixpkgs-stable";
         gitignore.follows = "gitignore";
       };
     };
@@ -142,14 +139,8 @@
     nixVim = {
       url = "github:nix-community/nixvim";
       inputs = {
-        devshell.follows = "devshell";
-        flake-compat.follows = "flake-compat";
         flake-parts.follows = "flake-parts";
-        git-hooks.follows = "git-hooks";
-        home-manager.follows = "home-manager";
-        nix-darwin.follows = "nix-darwin";
         nixpkgs.follows = "nixpkgs";
-        treefmt-nix.follows = "treefmt-nix";
         nuschtosSearch.follows = "nuschtosSearch";
       };
     };
@@ -196,12 +187,10 @@
       };
     };
     lanzaboote = {
-      # TODO: Subscribe to their update feed. <2024-12-18>
-      url = "github:nix-community/lanzaboote/v0.4.1";
+      url = "github:nix-community/lanzaboote/v0.4.2";
       inputs = {
         nixpkgs.follows = "nixpkgs-stable";
         flake-compat.follows = "flake-compat";
-        flake-utils.follows = "flake-utils";
         flake-parts.follows = "flake-parts";
         crane.follows = "crane";
         rust-overlay.follows = "rust-overlay";
@@ -214,6 +203,14 @@
         nixpkgs.follows = "nixpkgs";
       };
     };
+    arkenfox-nixos = {
+      url = "github:dwarfmaster/arkenfox-nixos";
+      inputs = {
+        nixpkgs.follows = "nixpkgs";
+        pre-commit.follows = "pre-commit-hooks";
+        flake-compat.follows = "flake-compat";
+      };
+    };
 
     # my configs
     templates = {
@@ -236,16 +233,6 @@
         flake_version_update.follows = "flake_version_update";
       };
     };
-    river_init_lesser = {
-      url = "git+https://codeberg.org/soispha/river_keymap_init.git";
-      inputs = {
-        nixpkgs.follows = "nixpkgs";
-        crane.follows = "crane";
-        flake-utils.follows = "flake-utils";
-        rust-overlay.follows = "rust-overlay";
-        flake-compat.follows = "flake-compat";
-      };
-    };
     qmk_firmware = {
       url = "git+https://git.foss-syndicate.org/bpeetz/qmk_layout.git?ref=prime";
       inputs = {
@@ -257,10 +244,6 @@
     };
 
     # external resources
-    user_js = {
-      url = "github:arkenfox/user.js";
-      flake = false;
-    };
     treefmt-nix = {
       url = "github:numtide/treefmt-nix";
       inputs = {
@@ -274,8 +257,7 @@
     self,
     nixpkgs,
     nixpkgs-stable,
-    nixpkgs-tfc,
-    nixpkgs-onlykey,
+    nixpkgs-lf,
     library,
     # modules
     home-manager,
@@ -288,19 +270,20 @@
     lanzaboote,
     nixVim,
     nix-index-database,
+    arkenfox-nixos,
     # external dependencies
-    user_js,
     treefmt-nix,
     templates,
     # my binaries
     shell_library,
-    river_init_lesser,
     qmk_firmware,
     ...
   }: let
     system = "x86_64-linux";
     sysLib = shell_library.lib.${system};
 
+    baseLib = import ./lib {inherit (pkgs) lib;};
+
     inherit (library) nixLib;
 
     pkgsStable = nixpkgs-stable.legacyPackages.${system};
@@ -312,8 +295,7 @@
     nixpkgs_as_input = nixpkgs;
     nixpkgs_open_prs = {
       inherit
-        nixpkgs-tfc
-        nixpkgs-onlykey
+        nixpkgs-lf
         ;
     };
 
@@ -327,6 +309,7 @@
         myPkgs
         system
         sysLib
+        baseLib
         nixpkgs_as_input
         nixpkgs_open_prs
         # modules
@@ -340,13 +323,12 @@
         disko
         lanzaboote
         nix-index-database
+        arkenfox-nixos
         # external dependencies
         treefmt-nix
-        user_js
         templates
         # my binaries
         shell_library
-        river_init_lesser
         qmk_firmware
         ;
     };
diff --git a/flake/default.nix b/flake/default.nix
index be6d2b70..ae17ad39 100644
--- a/flake/default.nix
+++ b/flake/default.nix
@@ -4,6 +4,7 @@
   pkgs,
   pkgsStable,
   nixLib,
+  baseLib,
   myPkgs,
   system,
   sysLib,
@@ -20,13 +21,12 @@
   disko,
   lanzaboote,
   nix-index-database,
+  arkenfox-nixos,
   # external dependencies
-  user_js,
   treefmt-nix,
   templates,
   # my binaries
   shell_library,
-  river_init_lesser,
   qmk_firmware,
 }: let
   treefmtEval = import ./treefmt.nix {inherit treefmt-nix pkgs;};
@@ -43,6 +43,7 @@
       shell_library
       sysLib
       nixLib
+      baseLib
       templates
       # modules
       home-manager
@@ -55,20 +56,16 @@
       disko
       lanzaboote
       nix-index-database
+      arkenfox-nixos
       # bins
-      river_init_lesser
       qmk_firmware
-      # external
-      user_js
       ;
   };
 
   tests = import ../tests {
-    inherit pkgs nixpkgs_as_input myPkgs sysLib nixLib;
+    inherit pkgs nixpkgs_as_input myPkgs sysLib nixLib nixpkgs_open_prs system;
     inherit (pkgs) lib;
     extraModules = {
-      termfilechooser = "${nixpkgs_open_prs.nixpkgs-tfc}/nixos/modules/config/xdg/portals/termfilechooser.nix";
-
       nixvim = {
         homeManagerModule = nixVim.homeManagerModules.nixvim;
       };
@@ -111,6 +108,8 @@ in {
 
   formatter."${system}" = treefmtEval.config.build.wrapper;
 
+  baseLib."${system}" = baseLib;
+
   apps."${system}" = import ./apps {inherit self system;};
 
   devShells."${system}" = {
@@ -136,11 +135,11 @@ in {
 
         # nix
         pkgs.alejandra
+        pkgs.deadnix
 
         # update
         myPkgs.generate_moz_extension # needed for the firefox extension update script
         myPkgs.lf-make-map # needed to generate the lf cd mappings
-        myPkgs.update-vim-plugins
       ];
     };
   };
diff --git a/flake/nixosConfigurations/default.nix b/flake/nixosConfigurations/default.nix
index b0a02580..1831cd1b 100644
--- a/flake/nixosConfigurations/default.nix
+++ b/flake/nixosConfigurations/default.nix
@@ -9,6 +9,7 @@
   shell_library,
   sysLib,
   nixLib,
+  baseLib,
   templates,
   # modules
   home-manager,
@@ -21,15 +22,11 @@
   disko,
   lanzaboote,
   nix-index-database,
+  arkenfox-nixos,
   # bins
-  river_init_lesser,
   qmk_firmware,
-  # external
-  user_js,
 }: let
   modules = [
-    "${nixpkgs_open_prs.nixpkgs-tfc}/nixos/modules/config/xdg/portals/termfilechooser.nix"
-
     agenix.nixosModules.default
     disko.nixosModules.default
     home-manager.nixosModules.home-manager
@@ -38,7 +35,7 @@
     serverphone.nixosModules.default
 
     ../../modules
-    ./common.nix
+    ../../modules/common
   ];
 
   specialArgs = {
@@ -50,23 +47,22 @@
       shell_library
       sysLib
       nixLib
+      baseLib
       # extra information
       system
       # modules
       impermanence
       nix-index-database
       nixVim
+      arkenfox-nixos
       # nix registry
       nixpkgs_as_input
       self
       templates
       # bins
       # TODO: Integrate these into `pkgs/by-name` <2024-05-22>
-      river_init_lesser
       qmk_firmware
       serverphone
-      # external deps
-      user_js
       ;
   };
 
@@ -84,7 +80,6 @@
 
   # FIXME: These need to stay in this position for the install script
   hosts = ["tiamat" "apzu"];
-  inactiveHosts = ["mammun" "lahmu"];
 
   generatedHosts = builtins.listToAttrs (builtins.map generateHost hosts);
 in
diff --git a/flake/packages/default.nix b/flake/packages/default.nix
index a8fc2d64..95aa539a 100644
--- a/flake/packages/default.nix
+++ b/flake/packages/default.nix
@@ -5,7 +5,6 @@
   myPkgs,
   pkgsStable,
   sysLib,
-  nixVim,
   system,
   shell_library,
   ...
@@ -23,7 +22,10 @@
         # NOTE: This is copied from `nixvim`, and could be achieved by setting
         # `config.wrapRc` to `true`. But I have yet to find a way to set this in this
         # context, but not in the general context.  <2024-11-09>
-        wrapped = config.build.package.override (prev: {
+        # NOTE: I'm not sure why we need `nvimPackage` instead of just the `package`
+        # attribute here, but the bare `package` attribute does not provide a `override`
+        # function. <2025-02-02>
+        wrapped = config.build.nvimPackage.override (prev: {
           wrapperArgs =
             (
               if lib.isString prev.wrapperArgs
@@ -64,8 +66,6 @@
             value)
         myPkgs
       )));
-
-  firefox = (import ../../modules/home.legacy/conf/firefox/scripts) {inherit pkgs sysLib;};
 in
   {
     # install-iso = nixos-generators.nixosGenerate {
@@ -94,5 +94,4 @@ in
   }
   // output
   // output_neovim
-  // firefox
   // myPkgsFlat
diff --git a/hosts/_unmaintained/isimud/command-line.html b/hosts/_unmaintained/isimud/command-line.html
deleted file mode 100644
index 4534001e..00000000
--- a/hosts/_unmaintained/isimud/command-line.html
+++ /dev/null
@@ -1,1491 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-    <meta charset="utf-8">
-<meta http-equiv="X-UA-Compatible" content="IE=edge">
-<meta name="viewport" content="width=device-width, initial-scale=1">
-<meta name="description" content="The OnlyKey Command-Line Utility is a command line interface to OnlyKey.">
-<meta name="keywords" content="OnlyKeyCommand linePython,  OnlyKey, Command line">
-<title>OnlyKey Command-Line Utility | Docs</title>
-<link rel="stylesheet" href="css/syntax.css">
-
-<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
-<!--<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">-->
-<link rel="stylesheet" href="css/modern-business.css">
-<!-- Latest compiled and minified CSS -->
-<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
-<link rel="stylesheet" href="css/customstyles.css">
-<link rel="stylesheet" href="css/boxshadowproperties.css">
-<!-- most color styles are extracted out to here -->
-<link rel="stylesheet" href="css/theme-blue.css">
-
-<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
-
-<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js"></script>
-<script src="js/jquery.navgoco.min.js"></script>
-
-
-<!-- Latest compiled and minified JavaScript -->
-<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
-<!-- Anchor.js -->
-<script src="https://cdnjs.cloudflare.com/ajax/libs/anchor-js/4.2.0/anchor.min.js"></script>
-<script src="js/toc.js"></script>
-<script src="js/customscripts.js"></script>
-
-<link rel="shortcut icon" href="images/favicon.ico">
-
-<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
-<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
-<!--[if lt IE 9]>
-<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
-<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
-<![endif]-->
-
-<link rel="alternate" type="application/rss+xml" title="trustcrypto.github.io" href="https://docs.onlykey.io/feed.xml">
-
-    <script>
-        $(document).ready(function() {
-            // Initialize navgoco with default options
-            $("#mysidebar").navgoco({
-                caretHtml: '',
-                accordion: true,
-                openClass: 'active', // open
-                save: false, // leave false or nav highlighting doesn't work right
-                cookie: {
-                    name: 'navgoco',
-                    expires: false,
-                    path: '/'
-                },
-                slide: {
-                    duration: 400,
-                    easing: 'swing'
-                }
-            });
-
-            $("#collapseAll").click(function(e) {
-                e.preventDefault();
-                $("#mysidebar").navgoco('toggle', false);
-            });
-
-            $("#expandAll").click(function(e) {
-                e.preventDefault();
-                $("#mysidebar").navgoco('toggle', true);
-            });
-
-        });
-
-    </script>
-    <script>
-        $(function () {
-            $('[data-toggle="tooltip"]').tooltip()
-        })
-    </script>
-    <script>
-        $(document).ready(function() {
-            $("#tg-sb-link").click(function() {
-                $("#tg-sb-sidebar").toggle();
-                $("#tg-sb-content").toggleClass('col-md-9');
-                $("#tg-sb-content").toggleClass('col-md-12');
-                $("#tg-sb-icon").toggleClass('fa-toggle-on');
-                $("#tg-sb-icon").toggleClass('fa-toggle-off');
-            });
-        });
-    </script>
-    
-
-</head>
-<body>
-<!-- Navigation -->
-<nav class="navbar navbar-inverse navbar-static-top">
-    <div class="container topnavlinks">
-        <div class="navbar-header">
-            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
-                <span class="sr-only">Toggle navigation</span>
-                <span class="icon-bar"></span>
-                <span class="icon-bar"></span>
-                <span class="icon-bar"></span>
-            </button>
-            <a class="fa fa-home fa-lg navbar-brand" href="index.html">&nbsp;<span class="projectTitle"> Docs</span></a>
-        </div>
-        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
-            <ul class="nav navbar-nav navbar-right">
-                <!-- toggle sidebar button -->
-                <li><a id="tg-sb-link" href="#"><i id="tg-sb-icon" class="fa fa-toggle-on"></i> Nav</a></li>
-                <!-- entries without drop-downs appear here -->
-
-
-
-
-                
-                
-                
-                <li><a href="https://onlykey.io" target="_blank" rel="noopener">Purchase OnlyKey</a></li>
-                
-                
-                
-                <li><a href="https://docs.crp.to/index.html" target="_blank" rel="noopener">Get Started</a></li>
-                
-                
-                
-                <!-- entries with drop-downs appear here -->
-                <!-- conditional logic to control which topnav appears for the audience defined in the configuration file.-->
-                
-                
-                <!--comment out this block if you want to hide search-->
-                <li>
-                    <!--start search-->
-                    <div id="search-demo-container">
-                        <input type="text" id="search-input" placeholder="search...">
-                        <ul id="results-container"></ul>
-                    </div>
-                    <script src="js/jekyll-search.js" type="text/javascript"></script>
-                    <script type="text/javascript">
-                            SimpleJekyllSearch.init({
-                                searchInput: document.getElementById('search-input'),
-                                resultsContainer: document.getElementById('results-container'),
-                                dataSource: 'search.json',
-                                searchResultTemplate: '<li><a href="{url}" title="OnlyKey Command-Line Utility">{title}</a></li>',
-                    noResultsText: 'No results found.',
-                            limit: 10,
-                            fuzzy: true,
-                    })
-                    </script>
-                    <!--end search-->
-                </li>
-            </ul>
-        </div>
-        </div>
-        <!-- /.container -->
-</nav>
-
-<!-- Page Content -->
-<div class="container">
-  <div id="main">
-    <!-- Content Row -->
-    <div class="row">
-        
-        
-            <!-- Sidebar Column -->
-            <div class="col-md-3" id="tg-sb-sidebar">
-                
-
-<ul id="mysidebar" class="nav">
-  <li class="sidebarTitle">OnlyKey Documentation </li>
-  
-  
-  
-  <li>
-      <a title="General Information" href="#">General Information</a>
-      <ul>
-          
-          
-          
-          <li><a title="Get Started" href="index.html">Get Started</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="FAQs" href="faq.html">FAQs</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="About Security" href="security.html">About Security</a></li>
-          
-          
-          
-          
-      </ul>
-   </li>
-     
-      
-  
-  <li>
-      <a title="OnlyKey User's Guide" href="#">OnlyKey User's Guide</a>
-      <ul>
-          
-          
-          
-          <li><a title="Unpacking OnlyKey" href="usersguide.html#unpacking">Unpacking OnlyKey</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Setting up OnlyKey" href="usersguide.html#initial-setup">Setting up OnlyKey</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Reset OnlyKey (Factory Default)" href="usersguide.html#reset-default">Reset OnlyKey (Factory Default)</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Configure Basic Login Info" href="usersguide.html#all-about-slots">Configure Basic Login Info</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="OnlyKey On-The-Go" href="usersguide.html#otg">OnlyKey On-The-Go</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Configure Two Factor Authentication (2FA)" href="usersguide.html#two-factor-authentication-2fa">Configure Two Factor Authentication (2FA)</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Google Authenticator (TOTP)" href="usersguide.html#google-authenticator-totp">Google Authenticator (TOTP)</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Yubico® One-Time Password" href="usersguide.html#Yubico-one-time-password">Yubico® One-Time Password</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Security Key (FIDO2 / U2F)" href="usersguide.html#universal-2nd-factor-u2f">Security Key (FIDO2 / U2F)</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Using With A Software Password Manager" href="usersguide.html#using-onlykey-with-a-software-password-manager">Using With A Software Password Manager</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="OpenPGP Encryption (Files / Messages)" href="usersguide.html#openpgp">OpenPGP Encryption (Files / Messages)</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Preferences" href="usersguide.html#preferences">Preferences</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="About Encryption Keys" href="usersguide.html#encryption-keys">About Encryption Keys</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Generating Keys" href="importpgp.html#generating-keys">Generating Keys</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Loading Keys" href="importpgp.html#loading-keys">Loading Keys</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Secure Encrypted Backup Anywhere" href="usersguide.html#secure-encrypted-backup-anywhere">Secure Encrypted Backup Anywhere</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Restore From Backup" href="usersguide.html#restore-from-backup">Restore From Backup</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Loading OnlyKey Firmware" href="usersguide.html#loading-onlykey-firmware">Loading OnlyKey Firmware</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Troubleshooting" href="usersguide.html#troubleshooting">Troubleshooting</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Change your PIN" href="usersguide.html#pin-change">Change your PIN</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Additional Information" href="usersguide.html#web-links">Additional Information</a></li>
-          
-          
-          
-          
-      </ul>
-   </li>
-     
-      
-  
-  <li>
-      <a title="OnlyKey DUO User's Guide" href="#">OnlyKey DUO User's Guide</a>
-      <ul>
-          
-          
-          
-          <li><a title="Unpacking OnlyKey DUO" href="duousersguide.html#unpacking">Unpacking OnlyKey DUO</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Setting up OnlyKey DUO" href="duousersguide.html#initial-setup">Setting up OnlyKey DUO</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Reset OnlyKey (Factory Default)" href="duousersguide.html#reset-default">Reset OnlyKey (Factory Default)</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Configure Basic Login Info" href="duousersguide.html#all-about-slots">Configure Basic Login Info</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="On-The-Go" href="duousersguide.html#otg">On-The-Go</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Configure Two Factor Authentication (2FA)" href="duousersguide.html#two-factor-authentication-2fa">Configure Two Factor Authentication (2FA)</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Google Authenticator (TOTP)" href="duousersguide.html#google-authenticator-totp">Google Authenticator (TOTP)</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Yubico® One-Time Password" href="duousersguide.html#Yubico-one-time-password">Yubico® One-Time Password</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Security Key (FIDO2 / U2F)" href="duousersguide.html#universal-2nd-factor-u2f">Security Key (FIDO2 / U2F)</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Using With A Software Password Manager" href="duousersguide.html#using-onlykey-with-a-software-password-manager">Using With A Software Password Manager</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="OpenPGP Encryption (Files / Messages)" href="duousersguide.html#openpgp">OpenPGP Encryption (Files / Messages)</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Preferences" href="duousersguide.html#preferences">Preferences</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="About Encryption Keys" href="duousersguide.html#encryption-keys">About Encryption Keys</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Generating Keys" href="importpgp.html#generating-keys">Generating Keys</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Loading Keys" href="importpgp.html#loading-keys">Loading Keys</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Secure Encrypted Backup Anywhere" href="duousersguide.html#secure-encrypted-backup-anywhere">Secure Encrypted Backup Anywhere</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Restore From Backup" href="duousersguide.html#restore-from-backup">Restore From Backup</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Loading OnlyKey Firmware" href="duousersguide.html#loading-onlykey-firmware">Loading OnlyKey Firmware</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Troubleshooting" href="duousersguide.html#troubleshooting">Troubleshooting</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Change your PIN" href="duousersguide.html#pin-change">Change your PIN</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Additional Information" href="duousersguide.html#web-links">Additional Information</a></li>
-          
-          
-          
-          
-      </ul>
-   </li>
-     
-      
-  
-  <li>
-      <a title="Features" href="#">Features</a>
-      <ul>
-          
-          
-          
-          <li><a title="Universal Support" href="features.html#universal-support">Universal Support</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Portable. Durable. Waterproof" href="features.html#portable-durable-waterproof">Portable. Durable. Waterproof</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Pin Protected" href="features.html#pin-protected">Pin Protected</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Hardware Password Manager" href="features.html#hardware-password-manager">Hardware Password Manager</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Universal Two-Factor Authentication" href="features.html#universal-2-factor-token">Universal Two-Factor Authentication</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="SSH Authentication" href="features.html#ssh-authentication">SSH Authentication</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="OpenPGP Everywhere" href="features.html#openpgp-support">OpenPGP Everywhere</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Self-Destruct" href="features.html#self-destruct-feature">Self-Destruct</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Encrypted Backup Anywhere" href="features.html#encrypted-backup-anywhere">Encrypted Backup Anywhere</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Automatic Lock" href="features.html#automatic-lock-feature">Automatic Lock</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="International Keyboard Layouts" href="features.html#international-keyboard-layouts">International Keyboard Layouts</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Sysadmin Mode" href="features.html#sysadmin-mode">Sysadmin Mode</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="LED Definitions" href="features.html#led-definitions-onlykey-color">LED Definitions</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Button Definitions" href="features.html#button-definitions">Button Definitions</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="OnlyKey / OnlyKey DUO Differences" href="features.html##onlykey-and-onlykey-duo-differences">OnlyKey / OnlyKey DUO Differences</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Config Mode" href="security.html#config-mode">Config Mode</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Plausible Deniability" href="features.html#plausible-deniability-feature">Plausible Deniability</a></li>
-          
-          
-          
-          
-      </ul>
-   </li>
-     
-      
-  
-  <li>
-      <a title="Apps and Software" href="#">Apps and Software</a>
-      <ul>
-          
-          
-          
-          <li><a title="Desktop App" href="app.html">Desktop App</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="WebCrypt (OpenPGP Webapp)" href="webcrypt.html">WebCrypt (OpenPGP Webapp)</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="SSH/GPG Agent (onlykey-agent)" href="onlykey-agent.html">SSH/GPG Agent (onlykey-agent)</a></li>
-          
-          
-          
-          
-          
-          
-          <li class="active"><a title="Command-Line Utility (onlykey-cli)" href="command-line.html">Command-Line Utility (onlykey-cli)</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Firmware" href="firmware.html">Firmware</a></li>
-          
-          
-          
-          
-      </ul>
-   </li>
-     
-      
-  
-  <li>
-      <a title="Knowledge Base" href="#">Knowledge Base</a>
-      <ul>
-          
-          
-          
-          <li><a title="Works with OnlyKey" href="workswithonlykey.html">Works with OnlyKey</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Upgrade Guide" href="upgradeguide.html">Upgrade Guide</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Legacy Firmware Upgrade Guide" href="legacyupgradeguide.html">Legacy Firmware Upgrade Guide</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="International Travel Edition Guide" href="ite.html">International Travel Edition Guide</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Plausible Deniability Setup Guide" href="pdguide.html">Plausible Deniability Setup Guide</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Windows Active Directory Guide" href="activedirectory.html">Windows Active Directory Guide</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Linux - Using OnlyKey with Linux" href="linux.html">Linux - Using OnlyKey with Linux</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Mobile - Using OnlyKey with iOS and Android" href="mobile.html">Mobile - Using OnlyKey with iOS and Android</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="OpenPGP Keys - Import keys from Protonmail, Keybase, and Mailvelope" href="importpgp.html">OpenPGP Keys - Import keys from Protonmail, Keybase, and Mailvelope</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Virtual Machines with OnlyKey" href="virtualmachines.html">Virtual Machines with OnlyKey</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Qubes OS with OnlyKey" href="qubes.html">Qubes OS with OnlyKey</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="Full-Disk Encryption with OnlyKey" href="full-disk-encryption.html">Full-Disk Encryption with OnlyKey</a></li>
-          
-          
-          
-          
-          
-          
-          <li><a title="OpenSSH With OnlyKey" href="openssh.html">OpenSSH With OnlyKey</a></li>
-          
-          
-          
-          
-      </ul>
-   </li>
-     
-      
-      
-      <!-- if you aren't using the accordion, uncomment this block:
-         <p class="external">
-             <a href="#" id="collapseAll">Collapse All</a> | <a href="#" id="expandAll">Expand All</a>
-         </p>
-         -->
-</ul>
-
-<!-- this highlights the active parent class in the navgoco sidebar. this is critical so that the parent expands when you're viewing a page. This must appear below the sidebar code above. Otherwise, if placed inside customscripts.js, the script runs before the sidebar code runs and the class never gets inserted.-->
-<script>$("li.active").parents('li').toggleClass("active");</script>
-
-            </div>
-            
-        
-
-        <!-- Content Column -->
-        <div class="col-md-9" id="tg-sb-content">
-            <div class="post-header">
-   <h1 class="post-title-main">OnlyKey Command-Line Utility</h1>
-</div>
-
-
-
-<div class="post-content">
-
-   
-    <div class="summary">The OnlyKey Command-Line Utility is a command line interface to OnlyKey.</div>
-   
-
-    
-    
-<!-- this handles the automatic toc. use ## for subheads to auto-generate the on-page minitoc. if you use html tags, you must supply an ID for the heading element in order for it to appear in the minitoc. -->
-<script>
-$( document ).ready(function() {
-  // Handler for .ready() called.
-
-$('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3,h4' });
-
-/* this offset helps account for the space taken up by the floating toolbar. */
-$('#toc').on('click', 'a', function() {
-  var target = $(this.getAttribute('href'))
-    , scroll_target = target.offset().top
-
-  $(window).scrollTop(scroll_target - 10);
-  return false
-})
-  
-});
-</script>
-
-<div id="toc"></div>
-
-    
-
-
-   <h1 id="onlykey-cli">onlykey-cli</h1>
-
-<p>OnlyKey-cli - A command line interface to the OnlyKey (Similar functionality to <a href="https://docs.crp.to/app.html">OnlyKey App</a>) that can be used for configuration, scripting, and testing.</p>
-
-<h2 id="installation">Installation</h2>
-
-<h3 id="windows-stand-alone-exe">Windows Stand-Alone EXE</h3>
-<p>No install is required. Download and run the EXE to open OnlyKey CLI interactive mode or run directly from command line like this:</p>
-<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>C:\ onlykey-cli.exe getlabels
-</code></pre></div></div>
-
-<p><a href="https://github.com/trustcrypto/python-onlykey/releases/download/v1.2.9/onlykey-cli.exe">Download here</a></p>
-
-<h3 id="windows-install-with-dependencies">Windows Install with dependencies</h3>
-<p>1) Python 3.8 and pip3 are required. To setup a Python environment on Windows we recommend Anaconda <a href="https://www.anaconda.com/download/#windows">https://www.anaconda.com/download/#windows</a></p>
-
-<p>2) From an administrator command prompt run:</p>
-<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pip3 install hidapi==0.9.0 onlykey
-</code></pre></div></div>
-
-<p>You should see a message showing where the executable is installed. This is usually c:\python39\scripts\onlykey-cli.exe</p>
-
-<h3 id="macos-install-with-dependencies">MacOS Install with dependencies</h3>
-<p>Python 3.8 and pip3 are required. To setup a Python environment on MacOS we recommend Anaconda <a href="https://www.anaconda.com/download/#macos">https://www.anaconda.com/download/#macos</a></p>
-<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ brew install libusb
-$ pip3 install onlykey
-</code></pre></div></div>
-
-<h3 id="linuxbsd-install-with-dependencies">Linux/BSD Install with dependencies</h3>
-
-<p>In order for non-root users in Linux to be able to communicate with OnlyKey a udev rule must be created as described <a href="https://docs.crp.to/linux">here</a>.</p>
-
-<h4 id="ubuntu-install-with-dependencies">Ubuntu Install with dependencies</h4>
-<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ sudo apt update &amp;&amp; sudo apt upgrade
-$ sudo apt install python3-pip python3-tk libusb-1.0-0-dev libudev-dev
-$ pip3 install onlykey
-$ wget https://raw.githubusercontent.com/trustcrypto/trustcrypto.github.io/pages/49-onlykey.rules
-$ sudo cp 49-onlykey.rules /etc/udev/rules.d/
-$ sudo udevadm control --reload-rules &amp;&amp; udevadm trigger
-</code></pre></div></div>
-
-<h4 id="debian-install-with-dependencies">Debian Install with dependencies</h4>
-<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ sudo apt update &amp;&amp; sudo apt upgrade
-$ sudo apt install python3-pip python3-tk libusb-1.0-0-dev libudev-dev
-$ pip3 install onlykey
-$ wget https://raw.githubusercontent.com/trustcrypto/trustcrypto.github.io/pages/49-onlykey.rules
-$ sudo cp 49-onlykey.rules /etc/udev/rules.d/
-$ sudo udevadm control --reload-rules &amp;&amp; udevadm trigger
-</code></pre></div></div>
-
-<h4 id="redhat-install-with-dependencies">RedHat Install with dependencies</h4>
-<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ yum update
-$ yum install python3-pip python3-devel python3-tk libusb-devel libudev-devel \
-              gcc redhat-rpm-config
-$ pip3 install onlykey
-$ wget https://raw.githubusercontent.com/trustcrypto/trustcrypto.github.io/pages/49-onlykey.rules
-$ sudo cp 49-onlykey.rules /etc/udev/rules.d/
-$ sudo udevadm control --reload-rules &amp;&amp; udevadm trigger
-</code></pre></div></div>
-
-<h4 id="fedora-install-with-dependencies">Fedora Install with dependencies</h4>
-<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ dnf install python3-pip python3-devel python3-tkinter libusb-devel libudev-devel \
-              gcc redhat-rpm-config
-$ pip3 install onlykey
-$ wget https://raw.githubusercontent.com/trustcrypto/trustcrypto.github.io/pages/49-onlykey.rules
-$ sudo cp 49-onlykey.rules /etc/udev/rules.d/
-$ sudo udevadm control --reload-rules &amp;&amp; udevadm trigger
-</code></pre></div></div>
-
-<h4 id="opensuse-install-with-dependencies">OpenSUSE Install with dependencies</h4>
-<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ zypper install python3-pip python3-devel python3-tk libusb-1_0-devel libudev-devel
-$ pip3 install onlykey
-$ wget https://raw.githubusercontent.com/trustcrypto/trustcrypto.github.io/pages/49-onlykey.rules
-$ sudo cp 49-onlykey.rules /etc/udev/rules.d/
-$ sudo udevadm control --reload-rules &amp;&amp; udevadm trigger
-</code></pre></div></div>
-
-<h4 id="arch-linux-install-with-dependencies">Arch Linux Install with dependencies</h4>
-<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ sudo pacman -Sy git python3-setuptools python3 libusb python3-pip
-$ pip3 install onlykey
-$ wget https://raw.githubusercontent.com/trustcrypto/trustcrypto.github.io/pages/49-onlykey.rules
-$ sudo cp 49-onlykey.rules /etc/udev/rules.d/
-$ sudo udevadm control --reload-rules &amp;&amp; udevadm trigger
-</code></pre></div></div>
-
-<h4 id="freebsd-install-with-dependencies">FreeBSD Install with dependencies</h4>
-
-<p>See forum thread <a href="https://groups.google.com/d/msg/onlykey/CEYwdXjB508/MCe14p0gAwAJ">here</a></p>
-
-<h2 id="quickstart">QuickStart</h2>
-
-<p>Usage: onlykey-cli [OPTIONS]</p>
-
-<h3 id="setup-options">Setup Options</h3>
-
-<h4 id="init">init</h4>
-<p>A command line tool for setting PIN on OnlyKey (Initial Configuration)</p>
-
-<h3 id="general-options">General Options</h3>
-
-<h4 id="version">version</h4>
-<p>Displays the version of the app</p>
-
-<h4 id="fwversion">fwversion</h4>
-<p>Displays the version of the OnlyKey firmware</p>
-
-<h4 id="wink">wink</h4>
-<p>OnlyKey flashes blue (winks), may be used for visual confirmation of connectivity</p>
-
-<h4 id="getlabels">getlabels</h4>
-<p>Returns slot labels</p>
-
-<h4 id="settime">settime</h4>
-<p>A command for setting time on OnlyKey, time is needed for TOTP (Google Authenticator)</p>
-
-<h4 id="getkeylabels">getkeylabels</h4>
-<p>Returns key labels for RSA keys 1-4 and ECC keys 1-16</p>
-
-<h4 id="rng-type">rng [type]</h4>
-<p>Access OnlyKey TRNG to generate random numbers:</p>
-<ul>
-  <li>[type] must be one of the following:
-    <ul>
-      <li>hexbytes - Output hex encoded random bytes. Default 8 bytes; Maximum 255 bytes. Specify number of bytes to return with –count <number of="" bytes=""> i.e. 'onlykey-cli rng hexbytes --count 32'</number></li>
-      <li>feedkernel - Feed random bytes to /dev/random.</li>
-    </ul>
-  </li>
-</ul>
-
-<h3 id="onlykey-preferences-options">OnlyKey Preferences Options</h3>
-
-<h4 id="idletimeout-num">idletimeout [num]</h4>
-<p>OnlyKey locks after ideletimeout is reached (1 – 255 minutes; default = 30; 0 to disable). <a href="https://docs.crp.to/usersguide.html#configurable-inactivity-lockout-period">More info</a></p>
-
-<h4 id="wipemode-num">wipemode [num]</h4>
-<p>Configure how the OnlyKey responds to
-a factory reset. WARNING - Setting to Full Wipe mode cannot be changed.
-1 = Sensitive Data Only (default); 2 = Full Wipe (recommended for plausible deniability users) Entire device is wiped. Firmware must be reloaded. <a href="https://docs.crp.to/usersguide.html#configurable-wipe-mode">More info</a></p>
-
-<h4 id="keylayout-num">keylayout [num]</h4>
-<p>Set keyboard layout</p>
-<ul>
-  <li>1 - USA_ENGLISH	(Default)</li>
-  <li>2 - CANADIAN_FRENCH</li>
-  <li>3 - CANADIAN_MULTILINGUAL</li>
-  <li>4 - DANISH</li>
-  <li>5 - FINNISH</li>
-  <li>6 - FRENCH</li>
-  <li>7 - FRENCH_BELGIAN</li>
-  <li>8 - FRENCH_SWISS</li>
-  <li>9 - GERMAN</li>
-  <li>10 - GERMAN_MAC</li>
-  <li>11 - GERMAN_SWISS</li>
-  <li>12 - ICELANDIC</li>
-  <li>13 - IRISH</li>
-  <li>14 - ITALIAN</li>
-  <li>15 - NORWEGIAN</li>
-  <li>16 - PORTUGUESE</li>
-  <li>17 - PORTUGUESE_BRAZILIAN</li>
-  <li>18 - SPANISH</li>
-  <li>19 - SPANISH_LATIN_AMERICA</li>
-  <li>20 - SWEDISH</li>
-  <li>21 - TURKISH</li>
-  <li>22 - UNITED_KINGDOM</li>
-  <li>23 - US_INTERNATIONAL</li>
-  <li>24 - CZECH</li>
-  <li>25 - SERBIAN_LATIN_ONLY</li>
-  <li>26 - HUNGARIAN</li>
-  <li>27 - DANISH MAC</li>
-  <li>28 - US_DVORAK</li>
-</ul>
-
-<p><a href="https://docs.crp.to/usersguide.html#configurable-keyboard-layouts">More info</a></p>
-
-<h4 id="keytypespeed-num">keytypespeed [num]</h4>
-<p>1 = slowest; 10 = fastest [7 = default]
-<a href="https://docs.crp.to/usersguide.html#configurable-keyboard-type-speed">More info</a></p>
-
-<h4 id="ledbrightness-num">ledbrightness [num]</h4>
-<p>1 = dimmest; 10 = brightest [8 = default]
-<a href="https://docs.crp.to/usersguide.html#configurable-led-brightness">More info</a></p>
-
-<h4 id="touchsense-num">touchsense [num]</h4>
-<p>Change the OnlyKey’s button touch sensitivity.
-WARNING: Setting button’s touch sensitivity lower than 5 is not recommended as this could result in inadvertent button press.
-2 = highest sensitivity; 100 = lowest sensitivity [12 = default]</p>
-
-<h4 id="2ndprofilemode-num">2ndprofilemode [num]</h4>
-<p>Set during init (Initial Configuration) to set 2nd profile type 1 = standard (default); 2 = plausible deniability</p>
-
-<h4 id="storedkeymode-num">storedkeymode [num]</h4>
-<p>Enable or disable challenge for stored keys (SSH/PGP)
-0 = Challenge Code Required (default); 1 = Button Press Required
-<a href="https://docs.crp.to/usersguide.html#stored-challenge-mode">More info</a></p>
-
-<h4 id="derivedkeymode-num">derivedkeymode [num]</h4>
-<p>Enable or disable challenge for stored keys (SSH/PGP)
-0 = Challenge Code Required (default); 1 = Button Press Required
-<a href="https://docs.crp.to/usersguide.html#derived-challenge-mode">More info</a></p>
-
-<h4 id="hmackeymode-num">hmackeymode [num]</h4>
-<p>Enable or disable button press for HMAC challenge-response
-0 = Button Press Required (default); 1 = Button Press Not Required.
-<a href="https://docs.crp.to/usersguide.html#hmac-mode">More info</a></p>
-
-<h4 id="backupkeymode-num">backupkeymode [num]</h4>
-<p>1 = Lock backup key so this may not be changed on device
-WARNING - Once set to “Locked” this cannot be changed unless a factory reset occurs.
-<a href="https://docs.crp.to/usersguide.html#backup-key-mode">More info</a></p>
-
-<h4 id="sysadminmode">sysadminmode</h4>
-<p>Enable or disable challenge for stored keys (SSH/PGP)
-0 = Challenge Code Required (default); 1 = Button Press Required
-<a href="https://docs.crp.to/usersguide.html#derived-challenge-mode">More info</a></p>
-
-<h4 id="lockbutton">lockbutton</h4>
-<p>Enable or disable challenge for stored keys (SSH/PGP)
-0 = Challenge Code Required (default); 1 = Button Press Required
-<a href="https://docs.crp.to/usersguide.html#derived-challenge-mode">More info</a></p>
-
-<h3 id="slot-config-options">Slot Config Options</h3>
-
-<h4 id="setslot-id-type-value">setslot [id] [type] [value]</h4>
-<ul>
-  <li>[id] must be slot number 1a - 6b for OnlyKey or 1-24 for OnlyKey DUO</li>
-  <li>[type] must be one of the following:
-    <ul>
-      <li>label - set slots (1a - 6b) to have a descriptive label i.e. My Google Acct</li>
-      <li>url - URL to login page</li>
-      <li>delay1 - set a 0 - 9 second delay</li>
-      <li>addchar1 - Additional character before username 1 for TAB, 0 to clear</li>
-      <li>username - Username to login</li>
-      <li>addchar2 - Additional character after username 1 for TAB, 2 for RETURN</li>
-      <li>delay2 - set a 0 - 9 second delay</li>
-      <li>password - Password to login</li>
-      <li>addchar3 - Additional character after password 1 for TAB, 2 for RETURN</li>
-      <li>delay3 - set a 0 - 9 second delay</li>
-      <li>addchar4 - Additional character before OTP 1 for TAB</li>
-      <li>2fa - type of two factor authentication
-        <ul>
-          <li>g - Google Authenticator</li>
-          <li>y - Yubico OTP</li>
-          <li>u - U2F</li>
-        </ul>
-      </li>
-      <li>totpkey - Google Authenticator key</li>
-      <li>addchar5 - Additional character after OTP 2 for RETURN</li>
-    </ul>
-  </li>
-</ul>
-
-<h4 id="wipeslot-id">wipeslot [id]</h4>
-<ul>
-  <li>[id] must be slot number 1a - 6b for OnlyKey or 1-24 for OnlyKey DUO</li>
-</ul>
-
-<h3 id="key-config-options">Key Config Options</h3>
-
-<h4 id="setkey-key-slot-type-features-hex-key">setkey [key slot] [type] [features] [hex key]</h4>
-<p>Sets raw private keys and key labels, to set PEM format keys use the OnlyKey App</p>
-<ul>
-  <li>[key slot] must be key number RSA1 - RSA4, ECC1 - ECC16, HMAC1 - HMAC2</li>
-  <li>[type] must be one of the following:
-    <ul>
-      <li>label - set to have a descriptive key label i.e. My GPG signing key</li>
-      <li>x - X25519 Key Type (32 bytes)</li>
-      <li>n - NIST256P1 Key Type (32 bytes)</li>
-      <li>s - SECP256K1 Key Type (32 bytes)</li>
-      <li>2 - RSA Key Type 2048bits (256 bytes)</li>
-      <li>4 - RSA Key Type 4096bits (512 bytes)</li>
-      <li>h - HMAC Key Type (20 bytes)</li>
-    </ul>
-  </li>
-  <li>[features] must be one of the following:
-    <ul>
-      <li>s - Use for signing</li>
-      <li>d - Use for decryption</li>
-      <li>b - Use for encryption/decryption of backups</li>
-    </ul>
-  </li>
-  <li>For setting keys see examples <a href="https://docs.crp.to/command-line.html#writing-private-keys-and-passwords">here</a>.</li>
-</ul>
-
-<h4 id="genkey-key-slot-type-features">genkey [key slot] [type] [features]</h4>
-<p>Generates random private key on device</p>
-<ul>
-  <li>[key slot] must be key number ECC1 - ECC16 (only ECC keys supported)</li>
-  <li>[type] must be one of the following:
-    <ul>
-      <li>x - X25519 Key Type (32 bytes)</li>
-      <li>n - NIST256P1 Key Type (32 bytes)</li>
-      <li>s - SECP256K1 Key Type (32 bytes)</li>
-    </ul>
-  </li>
-  <li>[features] must be one of the following:
-    <ul>
-      <li>s - Use for signing</li>
-      <li>d - Use for decryption</li>
-      <li>b - Use for encryption/decryption of backups</li>
-    </ul>
-  </li>
-  <li>For generating key see example <a href="https://docs.crp.to/command-line.html#writing-private-keys-and-passwords">here</a>.</li>
-</ul>
-
-<h4 id="wipekey-key-id">wipekey [key id]</h4>
-<p>Erases key stored at [key id]</p>
-<ul>
-  <li>[key id] must be key number RSA1 - RSA4, ECC1 - ECC16, HMAC1 - HMAC2</li>
-</ul>
-
-<h3 id="fido2-config-options">FIDO2 Config Options</h3>
-
-<h4 id="ping">ping</h4>
-<p>Sends a FIDO2 transaction to the device, which immediately echoes the same data back. This command is defined to be a uniform function for debugging, latency and performance measurements (CTAPHID_PING).</p>
-
-<h4 id="set-pin">set-pin</h4>
-<p>Set new FIDO PIN, this is the PIN entered via keyboard and used for FIDO2 register/login (not the OnlyKey PIN entered on device).</p>
-
-<h4 id="change-pin">change-pin</h4>
-<p>Change FIDO PIN, this is the PIN entered via keyboard and used for FIDO2 register/login (not the OnlyKey PIN entered on device, to change that PIN use the OnlyKey Desktop App).</p>
-
-<h4 id="credential-operation-credential-id">credential [operation] [credential ID]</h4>
-<ul>
-  <li>[operation] must be one of the following:
-    <ul>
-      <li>info - Display number of existing resident keys and remaining space.</li>
-      <li>ls - List resident keys.</li>
-      <li>rm [credential ID] - Remove resident keys, <a href="https://docs.crp.to/command-line.html#list-and-remove-fido2-resident-key">example here</a>.</li>
-    </ul>
-  </li>
-</ul>
-
-<h4 id="reset">reset</h4>
-<p>Reset wipes all FIDO U2F and FIDO2 credentials!!! It is highly recommended to backup device prior to reset.</p>
-
-<h3 id="running-command-options">Running Command Options</h3>
-
-<p>You can run commands in two ways:</p>
-
-<h4 id="1-directly-in-terminal">1) Directly in terminal</h4>
-
-<p>Like this:</p>
-
-<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ onlykey-cli getlabels
-
-Slot 1a:
-Slot 1b:
-
-Slot 2a:
-Slot 2b:
-
-Slot 3a:
-Slot 3b:
-
-Slot 4a:
-Slot 4b:
-
-Slot 5a:
-Slot 5b:
-
-Slot 6a:
-Slot 6b:
-
-$ onlykey-cli setslot 1a label ok
-Successfully set Label
-$ onlykey-cli getlabels
-
-Slot 1a: ok
-Slot 1b:
-
-Slot 2a:
-Slot 2b:
-
-Slot 3a:
-Slot 3b:
-
-Slot 4a:
-Slot 4b:
-
-Slot 5a:
-Slot 5b:
-
-Slot 6a:
-Slot 6b:
-
-</code></pre></div></div>
-
-<h4 id="2-interactive-mode">2) Interactive Mode</h4>
-
-<p>Or you can run commands in an interactive shell like this:</p>
-
-<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ onlykey-cli
-OnlyKey CLI v1.2.8
-Press the right arrow to insert the suggestion.
-Press Control-C to retry. Control-D to exit.
-
-OnlyKey&gt; getlabels
-
-Slot 1a:
-Slot 1b:
-
-Slot 2a:
-Slot 2b:
-
-Slot 3a:
-Slot 3b:
-
-Slot 4a:
-Slot 4b:
-
-Slot 5a:
-Slot 5b:
-
-Slot 6a:
-Slot 6b:
-
-OnlyKey&gt; setslot 1a label ok
-
-Successfully set Label
-
-OnlyKey&gt; getlabels
-
-Slot 1a: ok
-Slot 1b:
-
-Slot 2a:
-Slot 2b:
-
-Slot 3a:
-Slot 3b:
-
-Slot 4a:
-Slot 4b:
-
-Slot 5a:
-Slot 5b:
-
-Slot 6a:
-Slot 6b:
-
-OnlyKey&gt; setslot 1a url accounts.google.com
-
-Successfully set URL
-
-OnlyKey&gt; setslot 1a addchar1 2
-
-Successfully set Character1
-
-OnlyKey&gt; setslot 1a delay1 2
-
-Successfully set Delay1
-
-OnlyKey&gt; setslot 1a username onlykey.1234
-
-Successfully set Username
-
-OnlyKey&gt; setslot 1a addchar2 2
-
-Successfully set Character2
-
-OnlyKey&gt; setslot 1a delay2 2
-
-Successfully set Delay2
-
-OnlyKey&gt; setslot 1a password
-
-Type Control-T to toggle password visible.
-Password: *********
-Successfully set Password
-
-OnlyKey&gt; setslot 1a addchar3 2
-
-Successfully set Character3
-
-OnlyKey&gt; setslot 1a delay3 2
-
-Successfully set Delay3
-
-OnlyKey&gt; setslot 1a 2fa g
-
-Successfully set 2FA Type
-
-OnlyKey&gt; setslot 1a totpkey
-
-Type Control-T to toggle password visible.
-Password: ********************************
-Successfully set TOTP Key
-
-OnlyKey&gt; setslot 1a addchar4 2
-
-Successfully set Character4
-
-OnlyKey&gt;
-
-Bye!
-</code></pre></div></div>
-
-<h2 id="examples">Examples</h2>
-
-<h3 id="writing-private-keys-and-passwords">Writing Private Keys and Passwords</h3>
-
-<p>Keys/passwords are masked when entered and should only be set from interactive mode and not directly from terminal. Entering directly from terminal is not secure as command history is stored.</p>
-
-<p><strong>Setkey Examples</strong></p>
-
-<p>To set key a device must first be put into config mode.</p>
-
-<p><strong>Set HMAC key 1 to a custom value</strong></p>
-
-<p>$ onlykey-cli</p>
-
-<p>OnlyKey&gt; setkey HMAC1 h</p>
-
-<p>Type Control-T to toggle password visible.
-Password/Key: <strong>**</strong><strong>**</strong><strong>**</strong><strong>**</strong><strong>**</strong><strong>**</strong><em>**</em></p>
-
-<p>Successfully set ECC Key</p>
-
-<p><em>HMAC key must be 20 bytes, h is HMAC type</em></p>
-
-<p><strong>Set HMAC key 2 to a custom value</strong></p>
-
-<p>$ onlykey-cli</p>
-
-<p>OnlyKey&gt; setkey HMAC2 h</p>
-
-<p>Type Control-T to toggle password visible.
-Password/Key: <strong>**</strong><strong>**</strong><strong>**</strong><strong>**</strong><strong>**</strong><strong>**</strong><em>**</em></p>
-
-<p>Successfully set ECC Key</p>
-
-<p><em>HMAC key must be 20 bytes, h is HMAC type</em></p>
-
-<p><strong>Set ECC key in slot ECC1 to a custom value (Slots ECC1-ECC16 are available for ECC keys. Supported ECC curves X25519(x), NIST256P1(n), SECP256K1(s))</strong></p>
-
-<p>$ onlykey-cli</p>
-
-<p>OnlyKey&gt; setkey ECC1 x</p>
-
-<p>Type Control-T to toggle password visible.
-Password/Key: <strong>**</strong><strong>**</strong><strong>**</strong><strong>**</strong><strong>**</strong><strong>**</strong><strong>**</strong><strong>**</strong><strong>**</strong><strong>**</strong>*</p>
-
-<p>Successfully set ECC Key</p>
-
-<p><em>ECC key must be 32 bytes, x is X25519 type</em></p>
-
-<p><strong>Genkey Examples</strong></p>
-
-<p>To set key a device must first be put into config mode.</p>
-
-<p><strong>Generate ECC key in slot ECC1 to a custom value (Slots ECC1-ECC16 are available for ECC keys. Supported ECC curves X25519(x), NIST256P1(n), SECP256K1(s))</strong></p>
-
-<p>$ onlykey-cli</p>
-
-<p>OnlyKey&gt; genkey ECC1 x</p>
-
-<p>Successfully set ECC Key</p>
-
-<h3 id="scripting-example">Scripting Example</h3>
-
-<p><strong>Set time on OnlyKey (required for TOTP)</strong></p>
-
-<p>$ onlykey-cli settime</p>
-
-<p>This can be added to scripts such as the UDEV rule to automatically set time when device is inserted into USB port. See example <a href="https://raw.githubusercontent.com/trustcrypto/trustcrypto.github.io/pages/49-onlykey.rules">here</a></p>
-
-<p><strong>Scripted provisioning of an OnlyKey slots and keys can be done by creating a script that sets multiple values on OnlyKey</strong></p>
-
-<h3 id="list-and-remove-fido2-resident-key">List and Remove FIDO2 Resident Key</h3>
-
-<p>List current resident keys:</p>
-
-<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>onlykey-cli credential ls
-</code></pre></div></div>
-<p><img src="https://raw.githubusercontent.com/trustcrypto/trustcrypto.github.io/pages/images/cli-cred-ls.png" alt="" /></p>
-
-<p>Remove a resident key by credential ID</p>
-
-<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>onlykey-cli credential rm eu7LPIjTNwIJt2Ws9LWJlXkiNKaueSEEGteZM2MT/lZtEuYo49V6deCiIRMb6EDC29XG13nBL60+Yx+6hxSUYS1uxX9+AA==
-</code></pre></div></div>
-
-<p>Once removed, list current resident keys to verify:</p>
-
-<p><img src="https://raw.githubusercontent.com/trustcrypto/trustcrypto.github.io/pages/images/cli-cred-ls2.png" alt="" /></p>
-
-<h2 id="source">Source</h2>
-
-<p><a href="https://github.com/trustcrypto/python-onlykey">OnlyKey CLI on Github</a></p>
-
-
-
-    <div class="tags">
-        
-        <b>Tags: </b>
-        
-        
-        
-        
-        
-        
-        
-        
-        
-    </div>
-
-
-
-
-
-
-<a target="_blank" rel="noopener" href="https://github.com/trustcrypto/trustcrypto.github.io/edit/pages/pages/mydoc/command-line.md" class="btn btn-default githubEditButton" role="button"><i class="fa fa-github fa-lg"></i> Edit me</a>
-
-
-
-</div>
-
-<hr class="shaded"/>
-
-<footer>
-            <div class="row">
-                <div class="col-lg-12 footer">
-               &copy;2023 CryptoTrust. All rights reserved. <br />
-<span>Page last updated:</span> Jan, 19, 2022<br/> Site last generated: Jun 7, 2023 <br />
-<p><a href="https://crp.to"><img src="images/company_logo.png" alt="Company logo"/></a></p>
-                </div>
-            </div>
-</footer>
-
-
-        </div>
-    <!-- /.row -->
-</div>
-<!-- /.container -->
-</div>
-<!-- /#main -->
-    </div>
-
-</body>
-
-<!-- the google_analytics_id gets auto inserted from the config file -->
-
-
-
-<script>(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');ga('create','UA-66296557-1','auto');ga('require','displayfeatures');ga('send','pageview');</script>
-
-
-</html>
diff --git a/hosts/_unmaintained/isimud/default.nix b/hosts/_unmaintained/isimud/default.nix
deleted file mode 100644
index 5aa6ad3c..00000000
--- a/hosts/_unmaintained/isimud/default.nix
+++ /dev/null
@@ -1,44 +0,0 @@
-{pkgs, ...}: {
-  imports = [
-    ./hardware
-    ./networking.nix
-    ../../sys
-  ];
-
-  isoImage = {
-    contents = [
-      {
-        source = ./command-line.html;
-        # TODO:: remove the implied dependency
-        target = "/home/soispha/cli.html";
-      }
-    ];
-    makeEfiBootable = true;
-    makeUsbBootable = true;
-    makeBiosBootable = true;
-    appendToMenuLabel = " Gpg-disk";
-  };
-  environment.systemPackages = [
-    pkgs.onlykey
-    pkgs.onlykey-cli
-    pkgs.onlykey-agent
-    pkgs.cryptsetup
-  ];
-
-  soispha = {
-    secrets.enable = false;
-    impermanence.enable = false;
-    locale = {
-      enable = true;
-      keyMap = "dvorak";
-    };
-    fs.backup = {
-      enable = false;
-    };
-    users = {
-      hashedPassword = "$y$jFT$YvneNBxEtbrysV2OMG0X30$eKHdzZxJkjD3pXuGOuqbnTaeym5.4ik6kxhE.rJxs3.";
-    };
-  };
-
-  system.stateVersion = "23.05";
-}
diff --git a/hosts/_unmaintained/isimud/hardware/default.nix b/hosts/_unmaintained/isimud/hardware/default.nix
deleted file mode 100644
index f55365b3..00000000
--- a/hosts/_unmaintained/isimud/hardware/default.nix
+++ /dev/null
@@ -1,24 +0,0 @@
-{
-  lib,
-  pkgs,
-  modulesPath,
-  ...
-}: {
-  imports = [
-    (modulesPath + "/installer/scan/not-detected.nix")
-  ];
-
-  hardware.cpu.amd.updateMicrocode = true; # Why not?
-  hardware.cpu.intel.updateMicrocode = true; # Why not?
-
-  nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
-
-  soispha.disks = {
-    enable = false;
-  };
-
-  boot = {
-    kernelModules = [];
-    kernelPackages = lib.mkDefault pkgs.linuxPackages_6_1; # use this kernel, as it's supported by zfs
-  };
-}
diff --git a/hosts/_unmaintained/isimud/networking.nix b/hosts/_unmaintained/isimud/networking.nix
deleted file mode 100644
index 58c84ee5..00000000
--- a/hosts/_unmaintained/isimud/networking.nix
+++ /dev/null
@@ -1,8 +0,0 @@
-{lib, ...}: {
-  # Disable networking
-  networking.useDHCP = lib.mkForce false;
-  networking.interfaces = lib.mkForce {};
-  boot.blacklistedKernelModules = ["igb" "iwlwifi" "rtw89"];
-
-  networking.hostName = "isimud";
-}
diff --git a/hosts/_unmaintained/lahmu/default.nix b/hosts/_unmaintained/lahmu/default.nix
deleted file mode 100644
index 94d8b054..00000000
--- a/hosts/_unmaintained/lahmu/default.nix
+++ /dev/null
@@ -1,24 +0,0 @@
-{
-  config,
-  lib,
-  nixpkgs,
-  home-manager,
-  ...
-}: {
-  imports = [
-    ./hardware
-    ./networking.nix
-
-    ../../sys
-  ];
-
-  soispha = {
-    locale.enable = true;
-    users = {
-      # enable = true;
-      hashedPassword = "$y$jFT$qi3wS9njrMl2y55b3NOBI0$j40Qt6AAkMSfZ82KPhqMaUaPztWtPps1wOqaXaF/L.6";
-    };
-  };
-
-  system.stateVersion = "23.05";
-}
diff --git a/hosts/_unmaintained/lahmu/hardware/cpu.nix b/hosts/_unmaintained/lahmu/hardware/cpu.nix
deleted file mode 100644
index 2d7232cd..00000000
--- a/hosts/_unmaintained/lahmu/hardware/cpu.nix
+++ /dev/null
@@ -1,4 +0,0 @@
-{config, ...}: {
-  powerManagement.cpuFreqGovernor = "powersave";
-  hardware.cpu.amd.updateMicrocode = true; # Why not?
-}
diff --git a/hosts/_unmaintained/lahmu/hardware/default.nix b/hosts/_unmaintained/lahmu/hardware/default.nix
deleted file mode 100644
index bc7b1f96..00000000
--- a/hosts/_unmaintained/lahmu/hardware/default.nix
+++ /dev/null
@@ -1,33 +0,0 @@
-{
-  config,
-  lib,
-  pkgs,
-  modulesPath,
-  ...
-}: {
-  imports = [
-    (modulesPath + "/installer/scan/not-detected.nix") # TODO: is this necessary?
-    (modulesPath + "/profiles/qemu-guest.nix")
-    ./cpu.nix
-    ./gpu.nix
-  ];
-
-  nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
-
-  system.fileSystemLayouts = {
-    enable = true;
-    mainDisk = "/dev/disk/by-uuid/c0382dda-1f55-4209-967d-b8b22cb0f6e1";
-    efiDisk = "/dev/disk/by-uuid/167D-2F0B";
-    ssd = true;
-    swap = {
-      uuid = "c0382dda-1f55-4209-967d-b8b22cb0f6e1";
-      resumeOffset = "140544";
-    };
-  };
-
-  boot = {
-    kernelModules = [];
-
-    initrd.availableKernelModules = ["ahci" "xhci_pci" "virtio_pci" "sr_mod" "virtio_blk"];
-  };
-}
diff --git a/hosts/_unmaintained/lahmu/hardware/gpu.nix b/hosts/_unmaintained/lahmu/hardware/gpu.nix
deleted file mode 100644
index 88c9b88a..00000000
--- a/hosts/_unmaintained/lahmu/hardware/gpu.nix
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  config,
-  pkgs,
-  lib,
-  ...
-}: {
-  #   hardware.opengl.extraPackages = with pkgs; [
-  #     rocm-opencl-icd # open-cl
-  #     amdvlk # or directly through mesa
-  #     amd-media-driver # libva
-  #   ];
-  #
-  #   # Force radv, TODO: is this logical?
-  #   environment.variables.AMD_VULKAN_ICD = "RADV";
-}
diff --git a/hosts/_unmaintained/lahmu/networking.nix b/hosts/_unmaintained/lahmu/networking.nix
deleted file mode 100644
index 1ef69e7c..00000000
--- a/hosts/_unmaintained/lahmu/networking.nix
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-  config,
-  lib,
-  ...
-}: {
-  # Enables DHCP on each ethernet and wireless interface. In case of scripted networking
-  # (the default) this is the recommended approach. When using systemd-networkd it's
-  # still possible to use this option, but it's recommended to use it in conjunction
-  # with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
-  networking.useDHCP = lib.mkDefault true;
-  # networking.interfaces.enp0s31f6.useDHCP = lib.mkDefault true;
-  # networking.interfaces.wlp3s0.useDHCP = lib.mkDefault true;
-  networking.hostName = "lahmu";
-}
diff --git a/hosts/_unmaintained/mammun/default.nix b/hosts/_unmaintained/mammun/default.nix
deleted file mode 100644
index 5c66d9fa..00000000
--- a/hosts/_unmaintained/mammun/default.nix
+++ /dev/null
@@ -1,23 +0,0 @@
-{
-  config,
-  lib,
-  nixpkgs,
-  home-manager,
-  pkgs,
-  ...
-}: {
-  imports = [
-    ./hardware
-    ./networking.nix
-
-    ../../sys
-  ];
-  soispha = {
-    locale.enable = true;
-    users = {
-      hashedPassword = "$y$jDT$O/42/7REOL50onRYcTV9R1$Ot3bPAh2raHmPN3yScP4wsJRtNqrMtTBzOq9oRJeRA0";
-    };
-  };
-
-  system.stateVersion = "23.05";
-}
diff --git a/hosts/_unmaintained/mammun/hardware/cpu.nix b/hosts/_unmaintained/mammun/hardware/cpu.nix
deleted file mode 100644
index 70eaff6f..00000000
--- a/hosts/_unmaintained/mammun/hardware/cpu.nix
+++ /dev/null
@@ -1,3 +0,0 @@
-{...}: {
-  hardware.cpu.amd.updateMicrocode = true; # Why not?
-}
diff --git a/hosts/_unmaintained/mammun/hardware/default.nix b/hosts/_unmaintained/mammun/hardware/default.nix
deleted file mode 100644
index b1683d47..00000000
--- a/hosts/_unmaintained/mammun/hardware/default.nix
+++ /dev/null
@@ -1,27 +0,0 @@
-{
-  config,
-  lib,
-  pkgs,
-  modulesPath,
-  ...
-}: {
-  imports = [
-    (modulesPath + "/installer/scan/not-detected.nix")
-    ./cpu.nix
-    ./gpu.nix
-  ];
-
-  nixpkgs.hostPlatform = "x86_64-linux";
-
-  system.fileSystemLayouts = {
-    enable = true;
-    mainDisk = "/dev/disk/by-uuid/ac6c5efd-51a7-42e7-a8cd-668a350554b1";
-    efiDisk = "/dev/disk/by-uuid/7931-40E5";
-  };
-
-  boot = {
-    kernelModules = ["kvm-amd"];
-
-    initrd.availableKernelModules = ["xhci_pci" "ahci" "ehci_pci" "sd_mod" "sr_mod" "sdhci_pci"];
-  };
-}
diff --git a/hosts/_unmaintained/mammun/hardware/gpu.nix b/hosts/_unmaintained/mammun/hardware/gpu.nix
deleted file mode 100644
index 939497db..00000000
--- a/hosts/_unmaintained/mammun/hardware/gpu.nix
+++ /dev/null
@@ -1,14 +0,0 @@
-{pkgs, ...}: {
-  boot.initrd.kernelModules = ["amdgpu"];
-  # for Southern Islands (SI ie. GCN 1) cards and for Sea Islands (CIK ie. GCN 2) cards
-  boot.kernelParams = ["radeon.si_support=0" "amdgpu.si_support=1" "radeon.cik_support=0" "amdgpu.cik_support=1"];
-
-  hardware.opengl.driSupport = true;
-  # For 32 bit applications
-  hardware.opengl.driSupport32Bit = true;
-
-  hardware.opengl.extraPackages = with pkgs; [
-    rocm-opencl-icd
-    rocm-opencl-runtime
-  ];
-}
diff --git a/hosts/_unmaintained/mammun/networking.nix b/hosts/_unmaintained/mammun/networking.nix
deleted file mode 100644
index e243ebe0..00000000
--- a/hosts/_unmaintained/mammun/networking.nix
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  config,
-  lib,
-  ...
-}: {
-  networking = {
-    networkmanager = {
-      enable = true;
-      dns = "default";
-      wifi = {
-        powersave = true;
-      };
-    };
-    hostName = "mammun";
-  };
-}
diff --git a/hosts/_unmaintained/marduk/default.nix b/hosts/_unmaintained/marduk/default.nix
deleted file mode 100644
index 2379fcdf..00000000
--- a/hosts/_unmaintained/marduk/default.nix
+++ /dev/null
@@ -1,14 +0,0 @@
-{lib, ...}: {
-  imports = [
-    ./hardware
-    ./networking.nix
-  ];
-
-  console = {
-    keyMap = "dvorak";
-  };
-  # needed to override defaults
-  isoImage.isoName = lib.mkForce "nixos-iso";
-
-  system.stateVersion = "23.05";
-}
diff --git a/hosts/_unmaintained/marduk/hardware/default.nix b/hosts/_unmaintained/marduk/hardware/default.nix
deleted file mode 100644
index 4fed1d06..00000000
--- a/hosts/_unmaintained/marduk/hardware/default.nix
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  lib,
-  pkgs,
-  modulesPath,
-  ...
-}: {
-  imports = [
-    (modulesPath + "/installer/cd-dvd/installation-cd-graphical-gnome.nix")
-  ];
-
-  nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
-
-  boot = {
-    kernelModules = ["rtw89"];
-    # FIXME: The kernel version should probably be updated, considering that it's 6.1 <2024-03-23>
-    kernelPackages = pkgs.linuxPackages_6_1; # use this kernel, as it's supported by zfs
-    zfs.package = pkgs.zfs_unstable; # Default zfs is "broken" (to nixos) on the newest kernel
-  };
-}
diff --git a/hosts/_unmaintained/marduk/networking.nix b/hosts/_unmaintained/marduk/networking.nix
deleted file mode 100644
index da8f3850..00000000
--- a/hosts/_unmaintained/marduk/networking.nix
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-  config,
-  lib,
-  ...
-}: {
-  # Enables DHCP on each ethernet and wireless interface. In case of scripted networking
-  # (the default) this is the recommended approach. When using systemd-networkd it's
-  # still possible to use this option, but it's recommended to use it in conjunction
-  # with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
-  networking.useDHCP = lib.mkDefault true;
-  # networking.interfaces.enp0s31f6.useDHCP = lib.mkDefault true;
-  # networking.interfaces.wlp3s0.useDHCP = lib.mkDefault true;
-  networking.hostName = "marduk";
-}
diff --git a/hosts/apzu/default.nix b/hosts/apzu/default.nix
index d0090339..133342c3 100644
--- a/hosts/apzu/default.nix
+++ b/hosts/apzu/default.nix
@@ -1,4 +1,9 @@
-{...}: {
+{
+  lib,
+  pkgs,
+  baseLib,
+  ...
+}: {
   imports = [
     ./hardware.nix
   ];
@@ -19,6 +24,84 @@
         laptop = true;
         backlight = "intel_backlight";
       };
+      river.init = {
+        mappings = {
+          layout = "dvorak-modified";
+          keymap =
+            {
+              # Focus change
+              "<Meta-T>" = {command = ["focus-view" "next"];};
+              "<Meta-N>" = {command = ["focus-view" "previous"];};
+              "<Meta+Ctrl-T>" = {command = ["focus-output" "next"];};
+              "<Meta+Ctrl-N>" = {command = ["focus-output" "previous"];};
+
+              # Standard programs
+              "<Meta-<ENTER>>" = {command = ["spawn" "${lib.getExe pkgs.alacritty}"];};
+              "<Meta+Shift-q>" = {command = ["exit"];};
+              "<Meta-L>" = {command = ["spawn" "${lib.getExe pkgs.lock}"];};
+
+              # Screenshot
+              "<PRINTSCREEN>" = {command = ["spawn" "${lib.getExe pkgs.screenshot_persistent}"];};
+
+              # Audio
+              "<MEDIA_RAISEVOLUME>" = {
+                command = ["spawn" "${lib.getExe' pkgs.wireplumber "wpctl"} set-volume @DEFAULT_SINK@ 5%+"];
+                modes = ["normal" "locked"];
+              };
+              "<MEDIA_LOWERVOLUME>" = {
+                command = ["spawn" "${lib.getExe' pkgs.wireplumber "wpctl"} set-volume @DEFAULT_SINK@ 5%-"];
+                modes = ["normal" "locked"];
+              };
+              "<MEDIA_MUTEVOLUME>" = {
+                command = ["spawn" "${lib.getExe pkgs.mpc} toggle"];
+                modes = ["normal" "locked"];
+              };
+
+              # Launcher
+              "<Meta-R>" = {command = ["spawn" "${lib.getExe pkgs.rofi} -show combi -modes combi -combi-modes 'window, drun, run' -show-icons"];};
+              "<Meta-<F1>>" = {command = ["spawn" "${lib.getExe pkgs.tskm} open select"];};
+              "<Meta-<F2>>" = {command = ["spawn" "${lib.getExe pkgs.keepassxc}"];};
+              "<Meta-<F3>>" = {command = ["spawn" "${lib.getExe pkgs.signal-desktop}"];};
+              # "<Meta-<F4>>" = {command = ["spawn" "${lib.getExe pkgs.steam}"];};
+
+              # Client
+              "<Meta-f>" = {command = ["toggle-fullscreen"];};
+              "<Meta+Shift-c>" = {command = ["close"];};
+              "<Meta+Ctrl- >" = {command = ["toggle-float"];};
+              "<Meta+Ctrl-<ENTER>>" = {command = ["zoom"];};
+              "<Meta-o>" = {command = ["send-to-output" "next"];};
+              "<Meta+Shift-T>" = {command = ["swap" "next"];};
+              "<Meta+Shift-N>" = {command = ["swap" "previous"];};
+
+              # Toggle all tags
+              "<Meta-0>" = {command = ["set-focused-tags" (builtins.toString ((baseLib.pow 2 32) - 1))];};
+              "<Meta+Shift-0>" = {command = ["set-view-tags" (builtins.toString ((baseLib.pow 2 32) - 1))];};
+
+              # Mouse
+              "<Meta-<MOUSE_LEFT>>" = {
+                command = ["move-view"];
+                map_mode = "MapMouse";
+              };
+              "<Meta-<MOUSE_RIGHT>>" = {
+                command = ["resize-view"];
+                map_mode = "MapMouse";
+              };
+            }
+            // (
+              builtins.foldl' (acc: elem: acc // elem) {} (
+                builtins.map (index: let
+                  num = builtins.toString index;
+                  index2tag = input: builtins.toString (baseLib.pow 2 (input - 1));
+                in {
+                  "<Meta-${num}>" = {command = ["set-focused-tags" (index2tag index)];};
+                  "<Meta+Shift-${num}>" = {command = ["set-view-tags" (index2tag index)];};
+                  "<Meta+Shift+Ctrl-${num}>" = {command = ["toggle-view-tags" (index2tag index)];};
+                }) (builtins.genList (i: i + 1) 9)
+              )
+            );
+        };
+        screenSetupCode = {};
+      };
     };
 
     locale.enable = true;
diff --git a/hosts/hostinfo.toml b/hosts/hostinfo.toml
index 4ee5918c..b51c0501 100644
--- a/hosts/hostinfo.toml
+++ b/hosts/hostinfo.toml
@@ -3,15 +3,3 @@ description = "This is my main desktop"
 
 [Apzu]
 description = "This is my light laptop, with modern hardware"
-
-[Mammun]
-description = "This is my older and heavier laptop"
-
-[Lahmu]
-description = "This is my config running on a vm"
-
-[Marduk]
-description = "This is a small compilation target, to get a install-iso"
-
-[Marduk]
-description = "A host mainly used to setup private gpg keys, without network access or other such things"
diff --git a/hosts/tiamat/default.nix b/hosts/tiamat/default.nix
index 4e76675c..470f88cb 100644
--- a/hosts/tiamat/default.nix
+++ b/hosts/tiamat/default.nix
@@ -1,4 +1,11 @@
-{...}: {
+{
+  lib,
+  pkgs,
+  baseLib,
+  qmk_firmware,
+  system,
+  ...
+}: {
   imports = [
     ./hardware.nix
   ];
@@ -24,6 +31,97 @@
     programs = {
       river = {
         unicodeInput.enable = true;
+        init = {
+          mappings = {
+            layout = "us";
+            keymap = let
+              map = key: "<Alt+Ctrl+Meta+Shift-${key}>";
+            in
+              (lib.mapAttrs' (name: value: lib.nameValuePair (map name) value) {
+                # Movement
+                "A" = {command = ["exit"];};
+                "B" = {command = ["close"];};
+
+                "C" = {command = ["focus-view" "previous"];};
+                "D" = {command = ["focus-view" "next"];};
+
+                "E" = {command = ["swap" "previous"];};
+                "F" = {command = ["swap" "next"];};
+
+                "G" = {command = ["zoom"];};
+
+                "H" = {command = ["toggle-fullscreen"];};
+                "I" = {command = ["toggle-float"];};
+
+                "J" = {command = ["send-to-output" "next"];};
+
+                "K" = {command = ["spawn" "${lib.getExe pkgs.alacritty}"];};
+                "L" = {command = ["spawn" "${lib.getExe pkgs.screenshot_persistent}"];};
+
+                # Audio
+                # "M" = {command = ["spawn" "video-pause toggle"]; modes = ["normal" "locked"]; };
+                "N" = {
+                  command = ["spawn" "${lib.getExe pkgs.mpc} toggle"];
+                  modes = ["normal" "locked"];
+                };
+
+                # Launcher
+                "O" = {command = ["spawn" "${lib.getExe pkgs.rofi} -show combi -modes combi -combi-modes 'window,drun,run' -show-icons"];};
+                "P" = {command = ["spawn" "${lib.getExe pkgs.tskm} open select"];};
+                "Q" = {command = ["spawn" "${lib.getExe pkgs.keepassxc}"];};
+                # "R" = {command = ["spawn" "nheko"];};
+                "S" = {command = ["spawn" "${lib.getExe pkgs.signal-desktop}"];};
+                "T" = {command = ["spawn" "${lib.getExe pkgs.lock}"];};
+
+                "U" = {command = ["focus-output" "next"];};
+                "V" = {command = ["focus-previous-tags"];};
+                "W" = {command = ["send-to-previous-tags"];};
+                # "X" = {command = ["spawn" "bemenu-run"];};
+                # "Y" = {command = ["spawn" "bemenu-run"];};
+
+                # Toggle all tags
+                "0" = {command = ["set-focused-tags" "${builtins.toString ((baseLib.pow 2 32) - 1)}"];};
+
+                # Support Unicode input
+                "Z" = {command = ["spawn" "${lib.getExe qmk_firmware.packages.${system}.qmk_unicode_type} 106 65377"];};
+              })
+              // ({
+                  # TODO: add toggle-focus mapping
+
+                  # Toggle all tags
+                  "<Alt+Ctrl+Shift-0>" = {command = ["set-view-tags" "${builtins.toString ((baseLib.pow 2 32) - 1)}"];};
+
+                  # Mouse
+                  "<Meta-<MOUSE_LEFT>>" = {
+                    command = ["move-view"];
+                    map_mode = "MapMouse";
+                  };
+                  "<Meta-<MOUSE_RIGHT>>" = {
+                    command = ["resize-view"];
+                    map_mode = "MapMouse";
+                  };
+                }
+                // (
+                  builtins.foldl' (acc: elem: acc // elem) {} (
+                    builtins.map (index: let
+                      num = builtins.toString index;
+                      index2tag = input: builtins.toString (baseLib.pow 2 (input - 1));
+                    in {
+                      "${map num}" = {command = ["set-focused-tags" (index2tag index)];};
+                      "<Alt+Ctrl+Shift-${num}>" = {command = ["set-view-tags" (index2tag index)];};
+                      # "<Super+Shift+Ctrl-${num}>" = {command = ["toggle-view-tags" (index2tag index)];};
+                    }) (builtins.genList (i: i + 1) 9)
+                  )
+                ));
+          };
+          screenSetupCode = {
+            "DP-2" = {pos = "2560,0";};
+            "DP-1" = {
+              scale = "1.5";
+              pos = "0,0";
+            };
+          };
+        };
       };
     };
     locale = {
diff --git a/lib/default.nix b/lib/default.nix
new file mode 100644
index 00000000..f18e4b33
--- /dev/null
+++ b/lib/default.nix
@@ -0,0 +1,97 @@
+{lib}: let
+  /*
+  Converts `number` from a binary number to a decimal one.
+
+  The input is indented to be a number composed only of `1`s and `0` (e.g., 10010.)
+
+  # Type
+
+  binaryToDecimal :: Int -> Int
+
+  # Arguments
+
+  number
+  : The sequence of `1`s and `0`s defining a binary number, in little endian.
+
+  # Examples
+
+  binaryToDecimal 1001
+  => 9
+  */
+  binaryToDecimal = number: let
+    binaryList =
+      builtins.map lib.strings.toInt (lib.lists.reverseList (lib.strings.stringToCharacters (builtins.toString number)));
+  in
+    builtins.foldl' (acc: num: acc + num) 0
+    (lib.lists.imap0 (index: elem: elem * (pow 2 index)) binaryList);
+
+  /*
+  Converts `string` to a (probably) unique numerical id.
+
+  This is achieved by hashing the string and returning the first six hex-digits
+  converted to a base 10 number.
+
+  # Type
+
+  idFromString :: String -> Int
+
+  # Arguments
+
+  string
+  : The string to use as seed for the id generation.
+
+  # Examples
+
+  idFromString "3d-printer"
+  => 10365713
+  */
+  idFromString = string: let
+    inputSeed =
+      builtins.concatStringsSep ""
+      (lib.lists.take 6
+        (lib.strings.stringToCharacters (builtins.hashString "sha256" string)));
+  in
+    lib.trivial.fromHexString inputSeed;
+
+  /*
+  source: https://github.com/NixOS/nix/issues/10387#issuecomment-2494597690
+
+  Raises the `base` to the power of `power`.
+
+  Considering the small input size and the lack of a built-in power function [2],
+  this naive power implementation should satisfy reasonable performance
+  requirements.
+
+  Due to the lack of a modulo and bitwise AND operator, it is questionable whether
+  the recursive exponentiation by squaring [1] implementation would even be
+  faster.
+
+  [1]: https://en.wikipedia.org/wiki/Exponentiation_by_squaring
+  [2]: https://github.com/NixOS/nix/issues/10387
+
+  # Type
+
+  pow :: Number -> Number -> Number
+
+  # Arguments
+
+  base
+  : The base number to be raised.
+
+  power
+  : The exponent to raise `base` to.
+
+  # Examples
+
+  pow 2 5
+  => 32
+  */
+  pow = base: power:
+    if power == 0
+    then 1
+    else if power > 0
+    then (base * (pow base (power - 1)))
+    else builtins.throw "Negative powers are not supported";
+in {
+  inherit binaryToDecimal idFromString pow;
+}
diff --git a/modules/by-name/at/atuin/atuin.zsh b/modules/by-name/at/atuin/atuin.zsh
new file mode 100644
index 00000000..60fb74fe
--- /dev/null
+++ b/modules/by-name/at/atuin/atuin.zsh
@@ -0,0 +1,126 @@
+#! /usr/bin/env zsh
+# shellcheck disable=SC2034,SC2153,SC2086,SC2155
+
+# Above line is because shellcheck doesn't support zsh, per
+# https://github.com/koalaman/shellcheck/wiki/SC1071, and the ignore: param in
+# ludeeus/action-shellcheck only supports _directories_, not _files_. So
+# instead, we manually add any error the shellcheck step finds in the file to
+# the above line ...
+
+if ! [[ $options[zle] = on ]]; then
+    return 0
+fi
+
+# Source this in your ~/.zshrc
+autoload -U add-zsh-hook
+
+zmodload zsh/datetime 2>/dev/null
+
+# If zsh-autosuggestions is installed, configure it to use Atuin's search. If
+# you'd like to override this, then add your config after the $(atuin init zsh)
+# in your .zshrc
+_zsh_autosuggest_strategy_atuin() {
+    suggestion=$(ATUIN_QUERY="$1" atuin search --cmd-only --limit 1 --search-mode prefix)
+}
+
+if [ -n "${ZSH_AUTOSUGGEST_STRATEGY:-}" ]; then
+    ZSH_AUTOSUGGEST_STRATEGY=("atuin" "${ZSH_AUTOSUGGEST_STRATEGY[@]}")
+else
+    ZSH_AUTOSUGGEST_STRATEGY=("atuin")
+fi
+
+export ATUIN_SESSION=$(atuin uuid)
+ATUIN_HISTORY_ID=""
+
+_atuin_preexec() {
+    local id
+    id=$(atuin history start -- "$1")
+    export ATUIN_HISTORY_ID="$id"
+    __atuin_preexec_time=${EPOCHREALTIME-}
+}
+
+_atuin_precmd() {
+    local EXIT="$?" __atuin_precmd_time=${EPOCHREALTIME-}
+
+    [[ -z "${ATUIN_HISTORY_ID:-}" ]] && return
+
+    local duration=""
+    if [[ -n $__atuin_preexec_time && -n $__atuin_precmd_time ]]; then
+        printf -v duration %.0f $(((__atuin_precmd_time - __atuin_preexec_time) * 1000000000))
+    fi
+
+    (ATUIN_LOG=error atuin history end --exit $EXIT ${duration:+--duration=$duration} -- $ATUIN_HISTORY_ID &) >/dev/null 2>&1
+    export ATUIN_HISTORY_ID=""
+}
+
+_atuin_search() {
+    emulate -L zsh
+    zle -I
+
+    # swap stderr and stdout, so that the tui stuff works
+    # TODO: not this
+    local output
+    # shellcheck disable=SC2048
+    output=$(ATUIN_SHELL_ZSH=t ATUIN_LOG=error ATUIN_QUERY=$BUFFER atuin search $* -i 3>&1 1>&2 2>&3)
+
+    zle reset-prompt
+
+    if [[ -n $output ]]; then
+        RBUFFER=""
+        LBUFFER=$output
+
+        if [[ $LBUFFER == __atuin_accept__:* ]]
+        then
+            LBUFFER=${LBUFFER#__atuin_accept__:}
+            zle accept-line
+        fi
+    fi
+}
+_atuin_search_vicmd() {
+    _atuin_search --keymap-mode=vim-normal
+}
+_atuin_search_viins() {
+    _atuin_search --keymap-mode=vim-insert
+}
+
+_atuin_up_search() {
+    # Only trigger if the buffer is a single line
+    if [[ ! $BUFFER == *$'\n'* ]]; then
+        _atuin_search --shell-up-key-binding "$@"
+    else
+        zle up-line
+    fi
+}
+_atuin_up_search_vicmd() {
+    _atuin_up_search --keymap-mode=vim-normal
+}
+_atuin_up_search_viins() {
+    _atuin_up_search --keymap-mode=vim-insert
+}
+
+add-zsh-hook preexec _atuin_preexec
+add-zsh-hook precmd _atuin_precmd
+
+zle -N atuin-search _atuin_search
+zle -N atuin-search-vicmd _atuin_search_vicmd
+zle -N atuin-search-viins _atuin_search_viins
+zle -N atuin-up-search _atuin_up_search
+zle -N atuin-up-search-vicmd _atuin_up_search_vicmd
+zle -N atuin-up-search-viins _atuin_up_search_viins
+
+# These are compatibility widget names for "atuin <= 17.2.1" users.
+zle -N _atuin_search_widget _atuin_search
+zle -N _atuin_up_search_widget _atuin_up_search
+
+bindkey -M emacs '^r' atuin-search
+bindkey -M viins '^r' atuin-search-viins
+bindkey -M vicmd '/' atuin-search
+bindkey -M emacs '^[[A' atuin-up-search
+bindkey -M vicmd '^[[A' atuin-up-search-vicmd
+bindkey -M viins '^[[A' atuin-up-search-viins
+bindkey -M emacs '^[OA' atuin-up-search
+bindkey -M vicmd '^[OA' atuin-up-search-vicmd
+bindkey -M viins '^[OA' atuin-up-search-viins
+bindkey -M vicmd 'k' atuin-up-search-vicmd
+
+# vim: ft=zsh
diff --git a/modules/by-name/at/atuin/module.nix b/modules/by-name/at/atuin/module.nix
index 604ee4ef..2061fd71 100644
--- a/modules/by-name/at/atuin/module.nix
+++ b/modules/by-name/at/atuin/module.nix
@@ -18,11 +18,15 @@ in {
       group = "users";
     };
 
+    soispha.programs.zsh.integrations.atuin = ./atuin.zsh;
+
     home-manager.users.soispha = {
       programs.atuin = {
         enable = true;
         package = pkgs.atuin-dvorak;
-        enableZshIntegration = config.soispha.programs.zsh.enable;
+
+        # We can do this on our own.
+        enableZshIntegration = false;
         settings = {
           key_path = "${config.age.secrets.atuin_encryption_key.path}";
 
diff --git a/modules/by-name/ca/cargo/module.nix b/modules/by-name/ca/cargo/module.nix
new file mode 100644
index 00000000..f7153509
--- /dev/null
+++ b/modules/by-name/ca/cargo/module.nix
@@ -0,0 +1,18 @@
+{
+  config,
+  lib,
+  ...
+}: let
+  cfg = config.soispha.programs.cargo;
+in {
+  options.soispha.programs.cargo = {
+    enable = lib.mkEnableOption "cargo";
+  };
+  config = lib.mkIf cfg.enable {
+    home-manager.users.soispha = {
+      home.sessionVariables = {
+        CARGO_HOME = "${config.home-manager.users.soispha.xdg.dataHome}/cargo";
+      };
+    };
+  };
+}
diff --git a/modules/by-name/di/direnv/module.nix b/modules/by-name/di/direnv/module.nix
new file mode 100644
index 00000000..1ddf3d5d
--- /dev/null
+++ b/modules/by-name/di/direnv/module.nix
@@ -0,0 +1,21 @@
+{
+  config,
+  lib,
+  ...
+}: let
+  cfg = config.soispha.programs.direnv;
+in {
+  options.soispha.programs.direnv = {
+    enable = lib.mkEnableOption "direnv";
+  };
+
+  config.home-manager.users.soispha.programs.direnv = lib.mkIf cfg.enable {
+    enable = true;
+    nix-direnv.enable = true;
+    config = {
+      warn_timeout = 0;
+      # strict_env = true;
+      # disable_stdin = true;
+    };
+  };
+}
diff --git a/modules/home.legacy/conf/firefox/config/extensions/extensions.json b/modules/by-name/fi/firefox/extensions.json
index 0c59b2f7..062f1a5e 100644
--- a/modules/home.legacy/conf/firefox/config/extensions/extensions.json
+++ b/modules/by-name/fi/firefox/extensions.json
@@ -3,25 +3,25 @@
     "addonId": "addon@darkreader.org",
     "default_area": "navbar",
     "pname": "darkreader",
-    "sha256": "sha256:02c67ce2b3cd96719b5e369b9207ef11ed6c3a79eccb454d1e6ec3e005004e72",
-    "url": "https://addons.mozilla.org/firefox/downloads/file/4405074/darkreader-4.9.99.xpi",
-    "version": "4.9.99"
+    "sha256": "sha256:f565b2263a71626a0310380915b7aef90be8cc6fe16ea43ac1a0846efedc2e4c",
+    "url": "https://addons.mozilla.org/firefox/downloads/file/4439735/darkreader-4.9.103.xpi",
+    "version": "4.9.103"
   },
   "keepassxc-browser": {
     "addonId": "keepassxc-browser@keepassxc.org",
     "default_area": "navbar",
     "pname": "keepassxc-browser",
-    "sha256": "sha256:248f90ba6bffc82ef43b97c9e501b0889f70519703f27434e2d920b47f6ead45",
-    "url": "https://addons.mozilla.org/firefox/downloads/file/4395146/keepassxc_browser-1.9.5.xpi",
-    "version": "1.9.5"
+    "sha256": "sha256:f4ecad9cabe70511fbff42fe4fe831c560cc3a0b6da10a740ce670f4f6597f42",
+    "url": "https://addons.mozilla.org/firefox/downloads/file/4441759/keepassxc_browser-1.9.7.xpi",
+    "version": "1.9.7"
   },
   "torproject-snowflake": {
     "addonId": "{b11bea1f-a888-4332-8d8a-cec2be7d24b9}",
     "default_area": "navbar",
     "pname": "torproject-snowflake",
-    "sha256": "sha256:4028bad3bef6610a985edda954d5c4f1487480a8f32f230d9edf88d97c8dd88e",
-    "url": "https://addons.mozilla.org/firefox/downloads/file/4379590/torproject_snowflake-0.9.2.xpi",
-    "version": "0.9.2"
+    "sha256": "sha256:615c0d570f41e721a91fc4f334377a61732171b65eb1a4429d78681e85bc8878",
+    "url": "https://addons.mozilla.org/firefox/downloads/file/4458115/torproject_snowflake-0.9.3.xpi",
+    "version": "0.9.3"
   },
   "tridactyl-vim": {
     "addonId": "tridactyl.vim@cmcaine.co.uk",
@@ -35,16 +35,16 @@
     "addonId": "uBlock0@raymondhill.net",
     "default_area": "menupanel",
     "pname": "ublock-origin",
-    "sha256": "sha256:ee3a724a46ff32c17d1723077fecc6ede7fdab742154020b51fb6253ddcbba14",
-    "url": "https://addons.mozilla.org/firefox/downloads/file/4391011/ublock_origin-1.61.2.xpi",
-    "version": "1.61.2"
+    "sha256": "sha256:d93176cef4dc042e41ba500aa2a90e5d57b5be77449cbd522111585e3a0cd158",
+    "url": "https://addons.mozilla.org/firefox/downloads/file/4458450/ublock_origin-1.63.2.xpi",
+    "version": "1.63.2"
   },
   "vhack-libredirect": {
     "addonId": "vhack-libredirect@addons.vhack.eu",
     "default_area": "navbar",
     "pname": "vhack-libredirect",
-    "sha256": "sha256:2cb6befac6f414e0dd79a11db8905a0d988b98633b74afbe52ffe8006da841f5",
-    "url": "https://addons.mozilla.org/firefox/downloads/file/4351448/vhack_libredirect-2.9.1.xpi",
-    "version": "2.9.1"
+    "sha256": "sha256:08ccfd4b32ba15b357252208da7f383099ed5aefb9e92ffb5b9ae33f9146caf6",
+    "url": "https://addons.mozilla.org/firefox/downloads/file/4427811/vhack_libredirect-3.0.2.xpi",
+    "version": "3.0.2"
   }
 }
diff --git a/modules/by-name/fi/firefox/module.nix b/modules/by-name/fi/firefox/module.nix
new file mode 100644
index 00000000..17bfa049
--- /dev/null
+++ b/modules/by-name/fi/firefox/module.nix
@@ -0,0 +1,234 @@
+{
+  lib,
+  config,
+  pkgs,
+  ...
+}: let
+  cfg = config.soispha.programs.firefox;
+
+  mkAllowedExtension = extension:
+    lib.attrsets.nameValuePair extension.addonId {
+      installation_mode = "normal_installed";
+      updates_disabled = true;
+      inherit (extension) default_area;
+      install_url = "file://${builtins.fetchurl {
+        inherit
+          (extension)
+          url
+          sha256
+          ;
+      }}";
+    };
+
+  allowedExtensions =
+    builtins.listToAttrs
+    (builtins.map mkAllowedExtension (builtins.attrValues
+        cfg.extensions));
+
+  mkBlockedExtension = id:
+    lib.attrsets.nameValuePair id {
+      install_mode = "blocked";
+    };
+  blockedExtensions = builtins.listToAttrs (builtins.map mkBlockedExtension [
+    # these are the default search engines
+    "addons-search-detection@mozilla.com"
+    "amazon@search.mozilla.org"
+    "bing@search.mozilla.org"
+    "ddg@search.mozilla.org"
+    "google@search.mozilla.org"
+    "wikipedia@search.mozilla.org"
+  ]);
+
+  mkProfile = import ./profile.nix {inherit config pkgs;};
+in {
+  options.soispha.programs.firefox = {
+    enable = lib.mkEnableOption "firefox";
+
+    profiles = lib.mkOption {
+      type = lib.types.attrsOf (lib.types.submodule {
+        options = {
+          id = lib.mkOption {
+            type = lib.types.int;
+            description = "The id of this profile.";
+          };
+          name = lib.mkOption {
+            type = lib.types.str;
+            description = "The name of this profile";
+          };
+        };
+      });
+      description = "A list of profies to create besides the default `default` profile.";
+      default = {};
+      apply = value:
+        lib.attrsets.mapAttrs' (name: value: lib.attrsets.nameValuePair name (mkProfile value))
+        value;
+    };
+
+    extensions = lib.mkOption {
+      type = lib.types.attrsOf (
+        lib.types.submodule {
+          options = {
+            addonId = lib.mkOption {
+              type = lib.types.str;
+              example = "addon@darkreader.org";
+              description = "The addon id of this extension";
+            };
+            default_area = lib.mkOption {
+              type = lib.types.enum ["navbar" "menupanel"];
+              example = "navbar";
+              description = ''
+                Where to put this extension by default.
+                `navbar` means into the top-left bar as icon.
+                `menupanel` means hidden behind a “all extensions” button.
+              '';
+            };
+            pname = lib.mkOption {
+              type = lib.types.str;
+              example = "darkreader";
+              description = "The package name of this extension";
+            };
+            sha256 = lib.mkOption {
+              type = lib.types.str;
+              example = "sha256:f565b2263a71626a0310380915b7aef90be8cc6fe16ea43ac1a0846efedc2e4c";
+              description = "The fetchurl copatible hash of this extension";
+            };
+            url = lib.mkOption {
+              type = lib.types.str;
+              example = "https://addons.mozilla.org/firefox/downloads/file/4439735/darkreader-4.9.103.xpi";
+              description = "The download url of this extension.";
+            };
+            version = lib.mkOption {
+              type = lib.types.str;
+              example = "4.9.103";
+              description = "The version of this extension";
+            };
+          };
+        }
+      );
+
+      default = builtins.fromJSON (builtins.readFile ./extensions.json);
+
+      description = ''
+        A list of the extensions that should be installed.
+        You can use a tool like `generate_extensions` to generate this config.
+      '';
+    };
+  };
+
+  config = lib.mkIf cfg.enable {
+    programs.firefox = {
+      enable = true;
+      preferencesStatus = "locked";
+
+      languagePacks = ["en-CA" "de" "sv-SE"];
+
+      nativeMessagingHosts.packages = [
+        pkgs.tridactyl-native
+        pkgs.keepassxc
+      ];
+
+      # NOTE: See https://mozilla.github.io/policy-templates for documentation <2023-10-21>
+      policies = {
+        # NixOS manages this already
+        DisableAppUpdate = true;
+
+        DisableFirefoxAccounts = true;
+        DisableFirefoxScreenshots = true;
+
+        # KeepassXC does this for me
+        DisableMasterPasswordCreation = true;
+
+        # I use a self-hosted services for that
+        DisablePocket = true;
+
+        # I don't want to lose my data
+        DisableProfileRefresh = true;
+
+        DisableDeveloperTools = false;
+
+        DisplayBookmarksToolbar = "newtab";
+        DisplayMenuBar = "default-off";
+
+        DNSOverHTTPS = {
+          Enabled = true;
+          Locked = false;
+        };
+        # The concept of a "default browser" does not apply to my NixOS config
+        DontCheckDefaultBrowser = true;
+
+        ExtensionSettings =
+          {
+            "*" = {
+              # Blocking the extension install here, also blocks the 'about:debugging' page
+
+              # blocked_install_message = ''
+              #   You can't install a extension manually,
+              #   please specify it in your NixOS configuration
+              # '';
+              installation_mode = "allowed";
+            };
+          }
+          // allowedExtensions
+          // blockedExtensions;
+        RequestedLocales = config.programs.firefox.languagePacks;
+
+        ExtensionUpdate = false;
+
+        HardwareAcceleration = true;
+
+        # KeepassXC and such things
+        OfferToSaveLogins = false;
+        PasswordManagerEnabled = false;
+
+        PDFjs = {
+          Enabled = true;
+          # Don't honor documents right to be un-copy-able
+          EnablePermissions = false;
+        };
+
+        SearchBar = "unified";
+      };
+
+      # Beware, that we already set them per-profile in the home-manager config.
+      preferences = {};
+    };
+
+    home-manager.users.soispha = {
+      home.sessionVariables = {
+        # Improve touch input and make scrolling smother
+        MOZ_USE_XINPUT2 = "1";
+
+        # Tell Firefox to use Wayland
+        MOZ_ENABLE_WAYLAND = 1;
+
+        # Tell GTK to use portals
+        GTK_USE_PORTAL = 1;
+
+        BROWSER = "firefox";
+      };
+
+      programs.firefox = {
+        enable = true;
+        arkenfox = {
+          enable = true;
+          version = "133.0";
+        };
+
+        # We use the NixOS module to provide us a package.
+        # HACK: Extract the package from the system-path to get a version for
+        # arkenfox-nixos to compare to. <2025-04-02>
+        package = lib.lists.findSingle (x: builtins.hasAttr "pname" x && x.pname == "firefox") "none" "multiple" config.environment.systemPackages;
+
+        profiles =
+          {
+            default = mkProfile {
+              isDefault = true;
+              id = 0;
+              name = "default";
+            };
+          }
+          // cfg.profiles;
+      };
+    };
+  };
+}
diff --git a/modules/by-name/fi/firefox/profile.nix b/modules/by-name/fi/firefox/profile.nix
new file mode 100644
index 00000000..195c2075
--- /dev/null
+++ b/modules/by-name/fi/firefox/profile.nix
@@ -0,0 +1,180 @@
+{
+  config,
+  pkgs,
+}: preConfig: ({
+    userChrome = ./userChrome.css;
+
+    bookmarks = {
+      force = true;
+      settings = [];
+    };
+
+    search = {
+      default = "brave-search";
+      privateDefault = "brave-search";
+      force = true;
+      engines = import ./search_engines {inherit pkgs;};
+
+      order = [
+        # DEFAULT
+        "brave-search"
+
+        # NIX
+        "nix-packages"
+        "nix-options"
+        "nixpkgs-issues"
+        "homemanager-options"
+        "nixos-wiki"
+        "nixpkgs-pull-request-tracker"
+
+        # RUST
+        "rust-std"
+        "rust-tokio"
+
+        # OTHER
+        "google-scholar"
+        "wikipedia"
+        "arch-wiki"
+      ];
+    };
+
+    settings = {
+      "browser.download.dir" = "${config.home-manager.users.soispha.xdg.userDirs.download}";
+      # "browser.download.useDownloadDir" = true;
+      # "browser.download.folderList" = 2;
+
+      # QoL
+      "general.autoScroll" = false;
+      "browser.tabs.insertAfterCurrent" = true;
+      "browser.tabs.loadInBackground" = true;
+      "browser.ctrlTab.recentlyUsedOrder" = false;
+      "browser.search.widget.inNavBar" = true;
+      "findbar.highlightAll" = true;
+
+      "devtools.toolbox.host" = "right";
+      "devtools.toolsidebar-width.inspector" = 700;
+
+      # Keep translations useful
+      "browser.translations.automaticallyPopup" = true;
+      "browser.translations.neverTranslateLanguages" = "de";
+
+      # Improve Tab UI
+      "browser.tabs.inTitlebar" = 1;
+      "browser.toolbars.bookmarks.visibility" = "never";
+      "browser.places.importBookmarksHTML" = true;
+
+      # Theme
+      "extensions.activeThemeID" = "firefox-alpenglow@mozilla.org";
+      "extensions.extensions.activeThemeID" = "firefox-alpenglow@mozilla.org";
+
+      # disable updates (pretty pointless with nix)
+      "extensions.update.autoUpdateDefault" = false;
+      "extensions.update.enabled" = false;
+      "app.update.channel" = "default";
+      "browser.shell.checkDefaultBrowser" = false;
+
+      # Allow my custom css
+      "toolkit.legacyUserProfileCustomizations.stylesheets" = true;
+    };
+
+    arkenfox = {
+      enable = true;
+      "0000".enable = true;
+      "0100" = {
+        enable = true;
+        "0102"."browser.startup.page".value = 3;
+        "0103"."browser.startup.homepage".value = "file:///home/dt/home.html";
+        "0104"."browser.newtabpage.enabled".value = true;
+      };
+      "0200" = {
+        enable = true;
+      };
+      "0300" = {
+        enable = true;
+      };
+      "0400" = {
+        enable = false;
+      };
+      "0600" = {
+        enable = true;
+      };
+      "0700" = {
+        enable = true;
+        "0710"."network.trr.mode" = {
+          enable = true;
+          value = 3;
+        };
+      };
+      "0800" = {
+        enable = true;
+      };
+      "0900" = {
+        enable = true;
+      };
+      "1000" = {
+        enable = true;
+        "1001"."browser.cache.disk.enable".value = true;
+        "1003"."browser.sessionstore.privacy_level".value = 0;
+      };
+      "1200" = {
+        enable = true;
+        "1241"."security.mixed_content.block_display_content".enable = true;
+      };
+      "1600" = {
+        enable = true;
+      };
+      "1700" = {
+        enable = true;
+      };
+      "2000" = {
+        enable = true;
+      };
+      "2400" = {
+        enable = true;
+      };
+      "2600" = {
+        enable = true;
+        "2603" = {
+          "browser.download.start_downloads_in_tmp_dir".value = false;
+          "browser.helperApps.deleteTempFileOnExit".value = false;
+        };
+        "2615"."permissions.default.shortcuts" = {
+          value = 2;
+          enable = true;
+        };
+      };
+      "2700" = {
+        enable = true;
+      };
+      "2800" = {
+        enable = false;
+        "2810"."privacy.sanitize.sanitizeOnShutdown".value = false;
+      };
+      "4000" = {
+        enable = true;
+      };
+      "4500" = {
+        enable = true;
+      };
+      "5000" = {
+        enable = true;
+        "5003"."signon.rememberSignons" = {
+          enable = true;
+          value = false;
+        };
+      };
+      "6000" = {
+        enable = true;
+      };
+      "7000" = {
+        enable = true;
+      };
+      "8000" = {
+        enable = true;
+      };
+      "9000" = {
+        enable = true;
+      };
+    };
+  }
+  // preConfig)
diff --git a/modules/home.legacy/conf/firefox/config/search/engines/default.nix b/modules/by-name/fi/firefox/search_engines/default.nix
index a47c77df..51a447e1 100644
--- a/modules/home.legacy/conf/firefox/config/search/engines/default.nix
+++ b/modules/by-name/fi/firefox/search_engines/default.nix
@@ -1,84 +1,104 @@
 {pkgs, ...}: {
   # DEFAULT
-  "Brave Search" = {
+  brave-search = {
+    name = "Brave Search";
     urls = [{template = "https://search.brave.com/search?q={searchTerms}";}];
     icon = ./logos/brave.svg;
     definedAliases = ["@bs"];
   };
 
   # NIX
-  "Nix Packages" = {
+  nix-packages = {
+    name = "Nix packages";
     urls = [{template = "https://search.nixos.org/packages?type=packages&query={searchTerms}";}];
     icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg";
     definedAliases = ["@np"];
   };
 
-  "NixOS Options" = {
+  nix-functions = {
+    name = "Nix functions";
+    urls = [{template = "https://noogle.dev/q?term={searchTerms}";}];
+    icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg";
+    definedAliases = ["@ng"];
+  };
+
+  nixos-options = {
+    name = "NixOS options";
     urls = [{template = "https://search.nixos.org/options?type=options&query={searchTerms}";}];
     icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg";
     definedAliases = ["@no"];
   };
-  "HomeManager Options" = {
+  homemanager-options = {
+    name = "Home-Manager options";
     urls = [{template = "https://home-manager-options.extranix.com/?query={searchTerms}&release=master";}];
     icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg";
     definedAliases = ["@nh"];
   };
 
-  "Nixpkgs issues" = {
+  nixpkgs-issues = {
+    name = "Nixpkgs issues";
     urls = [{template = "https://github.com/NixOS/nixpkgs/issues?q=is%3Aissue+is%3Aopen+{searchTerms}";}];
     icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg";
     definedAliases = ["@ni"];
   };
-  "Nixpkgs pull requests" = {
+  nixpkgs-pull-requests = {
+    name = "Nixpkgs pull requests";
     urls = [{template = "https://github.com/NixOS/nixpkgs/pulls?q=is%3Apr+is%3Aopen+{searchTerms}";}];
     icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg";
     definedAliases = ["@nr"];
   };
 
-  "Nixpkgs pull requests tracker" = {
+  nixpkgs-pull-requests-tracker = {
+    name = "Nixpkgs pull requests tracker";
     urls = [{template = "https://nixpk.gs/pr-tracker.html?pr={searchTerms}";}];
     icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg";
     definedAliases = ["@nt"];
   };
-  "NixOS Wiki" = {
+  nixos-wiki = {
+    name = "NixOS Wiki";
     urls = [{template = "https://wiki.nixos.org/w/index.php?search={searchTerms}";}];
     icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg";
     definedAliases = ["@nw"];
   };
 
   # RUST
-  "Rust std" = {
+  rust-std = {
+    name = "Rust std";
     urls = [{template = "https://doc.rust-lang.org/std/?search={searchTerms}";}];
     icon = ./logos/rust_std.svg;
     definedAliases = ["@rs"];
   };
-  "Rust tokio" = {
+  rust-tokio = {
+    name = "Rust tokio";
     urls = [{template = "https://docs.rs/tokio/latest/tokio/index.html?search={searchTerms}";}];
     icon = ./logos/rust_tokio.png;
     definedAliases = ["@rt"];
   };
 
   # OTHER
-  "Google Scholar" = {
+  google-scholar = {
+    name = "Google Scholar";
     urls = [{template = "https://scholar.google.com/scholar?hl=en&q={searchTerms}";}];
     icon = ./logos/google_scholar.ico;
     definedAliases = ["@gs"];
   };
-  "Wikipedia" = {
+  wikipedia = {
+    name = "Wikipedia";
     urls = [{template = "https://en.wikipedia.org/wiki/{searchTerms}";}];
     icon = ./logos/wikipedia.svg;
     definedAliases = ["@wp"];
   };
-  "Arch Wiki" = {
+  arch-wiki = {
+    name = "Arch Wiki";
     urls = [{template = "https://wiki.archlinux.org/index.php?search={searchTerms}";}];
     icon = ./logos/arch_linux.svg;
     definedAliases = ["@aw"];
   };
 
-  "Wikipedia (en)".metaData.hidden = true;
-  "DuckDuckGo".metaData.hidden = true;
-  "Bing".metaData.hidden = true;
-  "Google".metaData.hidden = true;
+  "wikipedia".metaData.hidden = true;
+  "ddg".metaData.hidden = true;
+  "bing".metaData.hidden = true;
+  "google".metaData.hidden = true;
   "Amazon.de".metaData.hidden = true;
-  "eBay".metaData.hidden = true;
+  "ebay".metaData.hidden = true;
 }
diff --git a/modules/home.legacy/conf/firefox/config/search/engines/logos/arch_linux.svg b/modules/by-name/fi/firefox/search_engines/logos/arch_linux.svg
index 949b5c5f..949b5c5f 100644
--- a/modules/home.legacy/conf/firefox/config/search/engines/logos/arch_linux.svg
+++ b/modules/by-name/fi/firefox/search_engines/logos/arch_linux.svg
diff --git a/modules/home.legacy/conf/firefox/config/search/engines/logos/brave.svg b/modules/by-name/fi/firefox/search_engines/logos/brave.svg
index 09dd2e42..09dd2e42 100644
--- a/modules/home.legacy/conf/firefox/config/search/engines/logos/brave.svg
+++ b/modules/by-name/fi/firefox/search_engines/logos/brave.svg
diff --git a/modules/home.legacy/conf/firefox/config/search/engines/logos/google_scholar.ico b/modules/by-name/fi/firefox/search_engines/logos/google_scholar.ico
index 85d0c664..85d0c664 100644
--- a/modules/home.legacy/conf/firefox/config/search/engines/logos/google_scholar.ico
+++ b/modules/by-name/fi/firefox/search_engines/logos/google_scholar.ico
Binary files differdiff --git a/modules/home.legacy/conf/firefox/config/search/engines/logos/rust_std.svg b/modules/by-name/fi/firefox/search_engines/logos/rust_std.svg
index 0091b5a8..0091b5a8 100644
--- a/modules/home.legacy/conf/firefox/config/search/engines/logos/rust_std.svg
+++ b/modules/by-name/fi/firefox/search_engines/logos/rust_std.svg
diff --git a/modules/home.legacy/conf/firefox/config/search/engines/logos/rust_tokio.png b/modules/by-name/fi/firefox/search_engines/logos/rust_tokio.png
index f1de55ff..f1de55ff 100644
--- a/modules/home.legacy/conf/firefox/config/search/engines/logos/rust_tokio.png
+++ b/modules/by-name/fi/firefox/search_engines/logos/rust_tokio.png
Binary files differdiff --git a/modules/home.legacy/conf/firefox/config/search/engines/logos/wikipedia.svg b/modules/by-name/fi/firefox/search_engines/logos/wikipedia.svg
index dc32f984..dc32f984 100644
--- a/modules/home.legacy/conf/firefox/config/search/engines/logos/wikipedia.svg
+++ b/modules/by-name/fi/firefox/search_engines/logos/wikipedia.svg
diff --git a/modules/by-name/fi/firefox/update_extensions.sh b/modules/by-name/fi/firefox/update_extensions.sh
new file mode 100755
index 00000000..efcc83c6
--- /dev/null
+++ b/modules/by-name/fi/firefox/update_extensions.sh
@@ -0,0 +1,12 @@
+#!/usr/bin/env sh
+
+# The `generate_extensions` binary is provided in the devshell.
+
+generate_extensions \
+    darkreader:navbar \
+    keepassxc-browser:navbar \
+    vhack-libredirect:navbar \
+    torproject-snowflake:navbar \
+    tridactyl-vim:menupanel \
+    ublock-origin:menupanel \
+    >"$(dirname "$0")"/extensions.json
diff --git a/modules/home.legacy/conf/firefox/config/chrome/userChrome.css b/modules/by-name/fi/firefox/userChrome.css
index 0b3aff77..0b3aff77 100644
--- a/modules/home.legacy/conf/firefox/config/chrome/userChrome.css
+++ b/modules/by-name/fi/firefox/userChrome.css
diff --git a/modules/by-name/ho/home-manager/module.nix b/modules/by-name/ho/home-manager/module.nix
index f5304170..5da40834 100644
--- a/modules/by-name/ho/home-manager/module.nix
+++ b/modules/by-name/ho/home-manager/module.nix
@@ -8,7 +8,6 @@
   system,
   # bins
   # TODO: Integrate these <2024-05-22>
-  river_init_lesser,
   shell_library,
   qmk_firmware,
   # external deps
@@ -17,6 +16,7 @@
   impermanence,
   nix-index-database,
   nixVim,
+  arkenfox-nixos,
   ...
 }: let
   cfg = config.soispha.home-manager;
@@ -42,7 +42,6 @@ in {
           # extra information
           system
           # bins
-          river_init_lesser
           shell_library
           qmk_firmware
           # external deps
@@ -51,6 +50,7 @@ in {
           impermanence
           nixVim
           nix-index-database
+          arkenfox-nixos
           ;
       };
     };
diff --git a/modules/by-name/im/impermanence/module.nix b/modules/by-name/im/impermanence/module.nix
index 9c289346..94789755 100644
--- a/modules/by-name/im/impermanence/module.nix
+++ b/modules/by-name/im/impermanence/module.nix
@@ -43,7 +43,7 @@ in {
             ".config/iamb/profiles"
 
             ".cache"
-            ".mozilla"
+            ".mozilla/firefox"
 
             "media"
             "repos"
diff --git a/modules/by-name/lf/lf/colors b/modules/by-name/lf/lf/colors
index 1c2853ec..17201e64 100644
--- a/modules/by-name/lf/lf/colors
+++ b/modules/by-name/lf/lf/colors
@@ -60,11 +60,6 @@ fi      00          # FILE
 # links to hide
 ~/.mozilla       01;08;30
 ~/.ssh           01;08;30
-~/.zshenv        01;08;30
-
-~/.steampid      01;08;30
-~/.steam         01;08;30
-~/.steampath     01;08;30
 
 # archives or compressed (dircolors defaults)
 *.tar   01;31
diff --git a/modules/by-name/lf/lf/commands/base.sh b/modules/by-name/lf/lf/commands/base.sh
new file mode 100755
index 00000000..61b59a7b
--- /dev/null
+++ b/modules/by-name/lf/lf/commands/base.sh
@@ -0,0 +1,78 @@
+#!/usr/bin/env sh
+
+# shellcheck disable=SC2269
+id="$id"
+
+# Prompt the user for input.
+# This will just _print_ the prompt, you still need to `read -r` the user's answer.
+#
+# # Type
+# prompt :: String
+#
+# # Arguments
+# $1
+# : The prompt to print for the user.
+prompt() {
+    printf "=> %s" "$1"
+}
+
+# Reads its Stdin into a temporary file and returns the path of the temporary file.
+# This is only really useful, if you want to pipe something into an while read loop that
+# should modify global variables. Piping directly into it will not work, because the shell
+# would just run it in a subshell, so you need this workaround.
+#
+# # Type
+# tmp :: <stdin> -> Path
+#
+# # Arguments
+#
+# # Examples
+# while read -r file; do
+#   set -- "$@" "$file"
+# done < "$(echo "$fx" | tmp)"
+tmp() {
+    __base_tmp_temporary_file="$(mktemp --tmpdir="$__base_tmp_temporary_directory")"
+    cat >"$__base_tmp_temporary_file"
+    echo "$__base_tmp_temporary_file"
+}
+__base_tmp_temporary_directory="$(mktemp --directory)"
+trap 'rm --recursive "$__base_tmp_temporary_directory"' EXIT
+
+# Run a lf command on the current lf client
+# All arguments will run in like they were typed directly into lf.
+# # TODO(@bpeetz): Escape the single quotes in the input arguments. <2025-02-02>
+#
+# # Type
+# lf_cmd :: [String]
+#
+# # Arguments
+# $1..$@
+# : The arguments composing the command to run.
+lf_cmd() {
+    arguments=""
+    for arg in "$@"; do
+        if [ -z "$arguments" ]; then
+            arguments="'$arg'"
+        else
+            arguments="$arguments '$arg'"
+        fi
+    done
+
+    lf -remote "send $id $arguments"
+}
+
+# Print an error message and exit with error code 1.
+# The error message will be printed to lf.
+#
+# # Type
+# die :: String
+#
+# # Arguments
+# $1
+# : The error message
+die() {
+    lf_cmd echo "Error: $1"
+    exit 1
+}
+
+# vim: ft=sh
diff --git a/modules/by-name/lf/lf/commands/default.nix b/modules/by-name/lf/lf/commands/default.nix
index b3c9acab..0c42607b 100644
--- a/modules/by-name/lf/lf/commands/default.nix
+++ b/modules/by-name/lf/lf/commands/default.nix
@@ -1,231 +1,150 @@
-{
-  pkgs,
-  sysLib,
-  shell_library,
-  system,
-  ...
-}: let
+{pkgs, ...}: let
   functionCall = {
     name,
     dependencies,
-    replacementStrings,
-    ...
+    keepPath ? false,
   }:
-    sysLib.writeShellScript {
+    pkgs.writeShellApplication {
       inherit name;
-      src = ./scripts/${name}.sh;
-      keepPath = true;
-      dependencies = dependencies ++ (builtins.attrValues {inherit (pkgs) dash coreutils;});
-      inherit replacementStrings;
+      text = builtins.readFile ./base.sh + builtins.readFile ./scripts/${name}.sh;
+      runtimeInputs = [pkgs.lf pkgs.mktemp pkgs.coreutils] ++ dependencies;
+      inheritPath = keepPath;
     }
     + "/bin/${name}";
 
-  shell = {
-    name,
-    dependencies,
-    replacementStrings ? null,
-    ...
-  }: ''
+  # closes the lf tui
+  shell = args: ''
     ''${{
-      ${functionCall {inherit name dependencies replacementStrings;}}
+      ${functionCall args}
     }}
-  ''; # closes the lf tui
-  pipe = {
-    name,
-    dependencies,
-    replacementStrings ? null,
-    ...
-  }: ''
+  '';
+  # runs the command in the ui/term bar
+  pipe = args: ''
     %{{
-      ${functionCall {inherit name dependencies replacementStrings;}}
+      ${functionCall args}
     }}
-  ''; # runs the command in the ui/term bar
-  async = {
-    name,
-    dependencies,
-    replacementStrings ? null,
-    ...
-  }: ''
+  '';
+  # runs the command in the background
+  async = args: ''
     &{{
-      ${functionCall {inherit name dependencies replacementStrings;}}
+      ${functionCall args}
     }}
-  ''; # runs the command in the background
-  wait = {
-    name,
-    dependencies,
-    replacementStrings ? null,
-    ...
-  }: ''
+  '';
+  # adds a prompt after the command has run
+  wait = args: ''
     !{{
-      ${functionCall {inherit name dependencies replacementStrings;}}
+      ${functionCall args}
     }}
-  ''; # adds a prompt after the command has run
+  '';
 in {
-  archive = shell {
-    name = "archive";
-    dependencies = builtins.attrValues {
-      inherit
-        (pkgs)
-        fzf
-        gnutar
-        xz
-        p7zip
-        zip
-        ;
-    };
-  };
-  broot_jump = shell {
-    name = "broot_jump";
-    dependencies = builtins.attrValues {
-      inherit (pkgs) broot;
-    };
+  archive_compress = shell {
+    name = "archive_compress";
+    dependencies = with pkgs; [
+      fzf
+      gnutar
+      xz
+      p7zip
+      zip
+    ];
+  };
+  archive_decompress = pipe {
+    name = "archive_decompress";
+    dependencies = with pkgs; [
+      gnutar
+      unzip
+      p7zip
+    ];
+  };
+
+  cd_project_root = async {
+    name = "cd_project_root";
+    dependencies = [pkgs.git];
   };
+
   chmod = pipe {
     name = "chmod";
     dependencies = [];
   };
-  clear_trash = shell {
-    name = "clear_trash";
-    dependencies = builtins.attrValues {
-      inherit
-        (pkgs)
-        fzf
-        trashy
-        ;
-    };
-  };
-  dl_file = pipe {
-    name = "dl_file";
-    dependencies = builtins.attrValues {
-      inherit
-        (pkgs)
-        xdragon
-        curl
-        ;
-    };
-  };
+
   dragon = pipe {
     name = "dragon";
-    dependencies = builtins.attrValues {
-      inherit
-        (pkgs)
-        xdragon
-        ;
-    };
+    dependencies = [pkgs.dragon-drop];
   };
   dragon_individual = pipe {
     name = "dragon_individual";
-    dependencies = builtins.attrValues {
-      inherit
-        (pkgs)
-        xdragon
-        ;
-    };
+    dependencies = [pkgs.dragon-drop];
   };
   dragon_stay = pipe {
     name = "dragon_stay";
-    dependencies = builtins.attrValues {
-      inherit
-        (pkgs)
-        xdragon
-        ;
-    };
+    dependencies = [pkgs.dragon-drop];
   };
+
   execute = shell {
     name = "execute";
     dependencies = [];
+    keepPath = true;
   };
   follow_link = pipe {
     name = "follow_link";
-    dependencies = with pkgs; [lf];
-  };
-  fzf_jump = shell {
-    name = "fzf_jump";
-    dependencies = builtins.attrValues {
-      inherit (pkgs) fzf lf gnused;
-    };
+    dependencies = [];
   };
-  mk_dir = pipe {
-    name = "mk_dir";
+
+  mk_directory = pipe {
+    name = "mk_directory";
     dependencies = [];
   };
   mk_file = shell {
     name = "mk_file";
     dependencies = [];
   };
-  mk_file_and_edit = shell {
-    name = "mk_file_and_edit";
+  mk_link = pipe {
+    name = "mk_link";
     dependencies = [];
   };
-  mk_ln = pipe {
-    name = "mk_ln";
+  mk_script = shell {
+    name = "mk_script";
     dependencies = [];
+    keepPath = true;
   };
-  mk_scr_default = shell {
-    name = "mk_scr_default";
-    dependencies = builtins.attrValues {};
-    replacementStrings = {
-      SHELL_LIBRARY_TEMPLATE = "${shell_library.rawTemplate."${system}"}";
-    };
-  };
-  mk_scr_temp = shell {
-    name = "mk_scr_temp";
-    dependencies = builtins.attrValues {};
-    replacementStrings = {
-      SHELL_LIBRARY_TEMPLATE = "${shell_library.rawTemplate."${system}"}";
-      TO_BE_SHELL_LIBRARY_PATH = "%SHELL_LIBRARY_PATH"; # replacement is not recursive
-    };
-  };
-  view_file = async {
-    name = "view_file";
-    dependencies = builtins.attrValues {inherit (pkgs) file;};
-  };
-  go_project_base_directory = async {
-    name = "go_project_root";
-    dependencies = [];
-  };
-  restore_trash = shell {
-    name = "restore_trash";
-    dependencies = builtins.attrValues {
-      inherit
-        (pkgs)
-        fzf
-        trashy
-        ;
-    };
-  };
+
   set_clipboard_path = async {
     name = "set_clipboard_path";
     dependencies = [pkgs.wl-clipboard];
   };
-  set_wall_paper = pipe {
-    name = "set_wall_paper";
-    dependencies = [];
+  set_wallpaper = pipe {
+    name = "set_wallpaper";
+    dependencies = with pkgs; [
+      river # for `riverctl`
+      swaybg
+    ];
   };
+
   stripspace = pipe {
     name = "stripspace";
-    dependencies = [];
+    dependencies = [pkgs.gnused];
   };
+
+  open = async {
+    name = "open";
+    dependencies = [pkgs.handlr-regex];
+  };
+
   trash = pipe {
     name = "trash";
-    dependencies = builtins.attrValues {
-      inherit
-        (pkgs)
-        trashy
-        trash-cli
-        findutils
-        ;
-    };
-  };
-  unarchive = pipe {
-    name = "unarchive";
-    dependencies = builtins.attrValues {
-      inherit
-        (pkgs)
-        gnutar
-        unzip
-        p7zip
-        ;
-    };
+    dependencies = [pkgs.trash-cli];
+  };
+  trash_clear = shell {
+    name = "trash_clear";
+    dependencies = with pkgs; [conceal fzf gawk trashy];
+  };
+  trash_restore = shell {
+    name = "trash_restore";
+    dependencies = with pkgs; [conceal fzf gawk trashy];
+  };
+
+  view_file = async {
+    name = "view_file";
+    dependencies = with pkgs; [file];
+    keepPath = true;
   };
 }
diff --git a/modules/by-name/lf/lf/commands/run.sh b/modules/by-name/lf/lf/commands/run.sh
new file mode 100755
index 00000000..6a9b8cab
--- /dev/null
+++ b/modules/by-name/lf/lf/commands/run.sh
@@ -0,0 +1,30 @@
+#!/usr/bin/env sh
+
+# Run one of the commands for debugging purposes.
+
+[ "$#" -gt 1 ] || {
+    echo "Usage: $0 <script_name> <input_files>.."
+    exit 2
+}
+
+script_name="./scripts/$1"
+shift 1
+
+fx=""
+for arg in "$@"; do
+    if [ -z "$fx" ]; then
+        fx="$arg"
+    else
+        fx="$(printf "%s\n%s" "$fx" "$arg")"
+    fi
+done
+
+export f="$1"
+set --
+
+# shellcheck source=/dev/null
+. ./base.sh
+# shellcheck source=/dev/null
+. "$script_name"
+
+# vim: ft=sh
diff --git a/modules/by-name/lf/lf/commands/scripts/archive.sh b/modules/by-name/lf/lf/commands/scripts/archive.sh
deleted file mode 100755
index 25f40534..00000000
--- a/modules/by-name/lf/lf/commands/scripts/archive.sh
+++ /dev/null
@@ -1,77 +0,0 @@
-#! /usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
-# Option '-f' disables pathname expansion which can be useful when $f, $fs, and
-# $fx variables contain names with '*' or '?' characters. However, this option
-# is used selectively within individual commands as it can be limiting at
-# times.
-set -f
-
-# shellcheck disable=SC2269
-f="$f"
-# shellcheck disable=SC2269
-fx="$fx"
-# shellcheck disable=SC2269
-fs="$fs"
-
-archivers="$(tmp echo gzip xz 7z zip)"
-archiver="$(awk '{for (i=1; i<=NF; i++) print $i}' "$archivers" | fzf)"
-
-case "$archiver" in
-"gzip")
-    ext=tar.gz
-    ;;
-"xz")
-    ext=tar.xz
-    ;;
-"7z")
-    ext=7z
-    ;;
-"zip")
-    ext=zip
-    ;;
-esac
-
-prompt "Archive name: "
-name=""
-while [ -z "$name" ] || [ -e "$name" ]; do
-    read -r name_base
-    name="$name_base.$ext"
-    if [ -e "$name" ]; then
-        prompt "Archive already exists, overwrite [y|N]: "
-        read -r ans
-
-        if [ "$ans" = "y" ]; then
-            break
-        else
-            prompt "Archive name: "
-        fi
-    fi
-done
-
-root="$(if [ "$(pwd)" = "/" ]; then pwd; else echo "$(pwd)/"; fi)"
-
-# fx contains all selected file name separated by a newline
-while read -r raw_file; do
-    file="$(echo "$raw_file" | sed "s|$root||")"
-    set -- "$@" "$file"
-done <"$(tmp echo "$fx")"
-
-case "$archiver" in
-"gzip")
-    tar --create --gzip -file="$name" "$@"
-    ;;
-"xz")
-    tar --create --file="$name" "$@"
-    xz --compress -9 --extreme --threads=0 "$name"
-    ;;
-"7z")
-    7z a "$name" "$@"
-    ;;
-"zip")
-    zip --symlinks -9 -r "$name" "$@"
-    ;;
-esac
-# vim: ft=sh
diff --git a/modules/by-name/lf/lf/commands/scripts/archive_compress.sh b/modules/by-name/lf/lf/commands/scripts/archive_compress.sh
new file mode 100755
index 00000000..c3776a80
--- /dev/null
+++ b/modules/by-name/lf/lf/commands/scripts/archive_compress.sh
@@ -0,0 +1,63 @@
+# shellcheck shell=sh
+
+# shellcheck disable=SC2269
+f="$f"
+# shellcheck disable=SC2269
+fx="$fx"
+# shellcheck disable=SC2269
+fs="$fs"
+
+archiver="$(printf "%s\n" gzip xz 7z zip | fzf)"
+
+case "$archiver" in
+"gzip")
+    ext=tar.gz
+    ;;
+"xz")
+    ext=tar.xz
+    ;;
+"7z")
+    ext=7z
+    ;;
+"zip")
+    ext=zip
+    ;;
+esac
+
+prompt "Archive name: "
+name=""
+while [ -z "$name" ] || [ -e "$name" ]; do
+    read -r name_base
+    name="$name_base.$ext"
+    if [ -e "$name" ]; then
+        prompt "Archive already exists, overwrite [y|N]: "
+        read -r ans
+
+        if [ "$ans" = "y" ]; then
+            break
+        else
+            prompt "New Archive name: "
+        fi
+    fi
+done
+
+# fx contains all selected file name separated by a newline
+while read -r file; do
+    set -- "$@" "$(realpath --relative-to="$(pwd)" "$file")"
+done <"$(echo "$fx" | tmp)"
+
+case "$archiver" in
+"gzip")
+    tar --create --gzip --file="$name" "$@"
+    ;;
+"xz")
+    tar --create "$@" | xz --compress -9 --format=xz --extreme --threads=0 --stdout >"$name"
+    ;;
+"7z")
+    7z a "$name" "$@"
+    ;;
+"zip")
+    zip --symlinks -9 --recurse-paths "$name" "$@"
+    ;;
+esac
+# vim: ft=sh
diff --git a/modules/by-name/lf/lf/commands/scripts/archive_decompress.sh b/modules/by-name/lf/lf/commands/scripts/archive_decompress.sh
new file mode 100755
index 00000000..08374176
--- /dev/null
+++ b/modules/by-name/lf/lf/commands/scripts/archive_decompress.sh
@@ -0,0 +1,23 @@
+# shellcheck shell=sh
+
+# shellcheck disable=SC2269
+f="$f"
+# shellcheck disable=SC2269
+fx="$fx"
+# shellcheck disable=SC2269
+fs="$fs"
+# shellcheck disable=SC2269
+id="$id"
+
+echo "$fx" | while read -r file; do
+    case "$file" in
+    *.tar.bz | *.tar.bz2 | *.tbz | *.tbz2) tar --extract --bzip2 --verbose --file="$file" ;;
+    *.tar.gz | *.tgz) tar --extract --gzip --verbose --file="$file" ;;
+    *.tar.xz | *.txz) tar --extract --xz --verbose --file="$file" ;;
+    *.tar*) tar --extract --verbose --file="$file" ;;
+    *.zip) unzip "$file" ;;
+    *.7z) 7z x "$file" ;;
+    *) die "'$file' is not a supported file for unarchiving." ;;
+    esac
+done
+# vim: ft=sh
diff --git a/modules/by-name/lf/lf/commands/scripts/broot_jump.sh b/modules/by-name/lf/lf/commands/scripts/broot_jump.sh
deleted file mode 100755
index 8f40ba01..00000000
--- a/modules/by-name/lf/lf/commands/scripts/broot_jump.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#! /usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
-# shellcheck disable=SC2269
-f="$f"
-# shellcheck disable=SC2269
-fx="$fx"
-# shellcheck disable=SC2269
-fs="$fs"
-# shellcheck disable=SC2269
-id="$id"
-
-tmp=$(mktmp)
-res="$(broot --outcmd "$tmp" && sed 's/cd //' "$tmp")"
-
-if [ -f "$res" ]; then
-    cmd="select"
-elif [ -d "$res" ]; then
-    cmd="cd"
-fi
-
-lf -remote "send '$id' '$cmd' '$res'"
-# vim: ft=sh
diff --git a/modules/by-name/lf/lf/commands/scripts/cd_project_root.sh b/modules/by-name/lf/lf/commands/scripts/cd_project_root.sh
new file mode 100755
index 00000000..19100947
--- /dev/null
+++ b/modules/by-name/lf/lf/commands/scripts/cd_project_root.sh
@@ -0,0 +1,19 @@
+# shellcheck shell=sh
+
+# shellcheck disable=SC2269
+f="$f"
+# shellcheck disable=SC2269
+fx="$fx"
+# shellcheck disable=SC2269
+fs="$fs"
+# shellcheck disable=SC2269
+id="$id"
+
+root="$(git rev-parse --show-toplevel)"
+if [ "$root" ]; then
+    lf_cmd cd "$root" || die "Bug: Failed to cd to project root at '$root'"
+else
+    die "Unable to locate base dir"
+fi
+
+# vim: ft=sh
diff --git a/modules/by-name/lf/lf/commands/scripts/chmod.sh b/modules/by-name/lf/lf/commands/scripts/chmod.sh
index 9859127b..3dc5f19c 100755
--- a/modules/by-name/lf/lf/commands/scripts/chmod.sh
+++ b/modules/by-name/lf/lf/commands/scripts/chmod.sh
@@ -1,7 +1,4 @@
-#! /usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+# shellcheck shell=sh
 
 # shellcheck disable=SC2269
 f="$f"
@@ -12,13 +9,12 @@ fs="$fs"
 # shellcheck disable=SC2269
 id="$id"
 
-readp "Mode bits: " bits
-# shellcheck disable=SC2269
-bits="$bits"
+prompt "Mode bits: "
+read -r bits
 
-while read -r file; do
+echo "$fx" | while read -r file; do
     chmod "$bits" "$file"
-done <"$(tmp echo "$fx")"
+done
 
-lf -remote 'send reload'
+lf_cmd reload
 # vim: ft=sh
diff --git a/modules/by-name/lf/lf/commands/scripts/clear_trash.sh b/modules/by-name/lf/lf/commands/scripts/clear_trash.sh
deleted file mode 100755
index 9052bb5f..00000000
--- a/modules/by-name/lf/lf/commands/scripts/clear_trash.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#! /usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
-# could also use --force, for instand removal
-trash list | fzf --multi | awk '{print $NF}' | xargs trash empty --match=exact
-# vim: ft=sh
diff --git a/modules/by-name/lf/lf/commands/scripts/dl_file.sh b/modules/by-name/lf/lf/commands/scripts/dl_file.sh
deleted file mode 100755
index c7e3d8b2..00000000
--- a/modules/by-name/lf/lf/commands/scripts/dl_file.sh
+++ /dev/null
@@ -1,43 +0,0 @@
-#! /usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
-# shellcheck disable=SC2269
-f="$f"
-# shellcheck disable=SC2269
-fx="$fx"
-# shellcheck disable=SC2269
-fs="$fs"
-# shellcheck disable=SC2269
-id="$id"
-
-# Provides the ability to download a file by dropping it into a window
-
-url="$(dragon -t -x)"
-
-if [ -n "$url" ]; then
-    prompt "File Name: "
-    name=""
-    while [ -z "$name" ] || [ -e "$name" ]; do
-        read -r name
-        if [ -e "$name" ]; then
-            prompt "File already exists, overwrite [y|N]: "
-            read -r ans
-
-            if [ "$ans" = "y" ]; then
-                break
-            else
-                prompt "File Name: "
-            fi
-        fi
-    done
-
-    # Download the file with curl
-    if [ -n "$name" ]; then
-        curl -o "$name" "$url" || die "curl failed"
-    fi
-else
-    die "URL is null!"
-fi
-# vim: ft=sh
diff --git a/modules/by-name/lf/lf/commands/scripts/dragon.sh b/modules/by-name/lf/lf/commands/scripts/dragon.sh
index cf3c3176..916c09ee 100755
--- a/modules/by-name/lf/lf/commands/scripts/dragon.sh
+++ b/modules/by-name/lf/lf/commands/scripts/dragon.sh
@@ -1,7 +1,4 @@
-#! /usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+# shellcheck shell=sh
 
 # shellcheck disable=SC2269
 f="$f"
@@ -14,7 +11,7 @@ id="$id"
 
 while read -r file; do
     set -- "$@" "$file"
-done <"$(tmp echo "$fx")"
+done <"$(echo "$fx" | tmp)"
 
-dragon -a -x "$@"
+dragon-drop --all --and-exit "$@"
 # vim: ft=sh
diff --git a/modules/by-name/lf/lf/commands/scripts/dragon_individual.sh b/modules/by-name/lf/lf/commands/scripts/dragon_individual.sh
index 2465cdfa..c6b3b2a6 100755
--- a/modules/by-name/lf/lf/commands/scripts/dragon_individual.sh
+++ b/modules/by-name/lf/lf/commands/scripts/dragon_individual.sh
@@ -1,7 +1,4 @@
-#! /usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+# shellcheck shell=sh
 
 # shellcheck disable=SC2269
 f="$f"
@@ -14,7 +11,7 @@ id="$id"
 
 while read -r file; do
     set -- "$@" "$file"
-done <"$(tmp echo "$fx")"
+done <"$(echo "$fx" | tmp)"
 
-dragon "$@"
+dragon-drop "$@"
 # vim: ft=sh
diff --git a/modules/by-name/lf/lf/commands/scripts/dragon_stay.sh b/modules/by-name/lf/lf/commands/scripts/dragon_stay.sh
index 066b4c75..7296a6b9 100755
--- a/modules/by-name/lf/lf/commands/scripts/dragon_stay.sh
+++ b/modules/by-name/lf/lf/commands/scripts/dragon_stay.sh
@@ -1,7 +1,4 @@
-#! /usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+# shellcheck shell=sh
 
 # shellcheck disable=SC2269
 f="$f"
@@ -14,7 +11,7 @@ id="$id"
 
 while read -r file; do
     set -- "$@" "$file"
-done <"$(tmp echo "$fx")"
+done <"$(echo "$fx" | tmp)"
 
-dragon -a "$@"
+dragon-drop --all "$@"
 # vim: ft=sh
diff --git a/modules/by-name/lf/lf/commands/scripts/execute.sh b/modules/by-name/lf/lf/commands/scripts/execute.sh
index aa97fd7f..1d5dc87f 100755
--- a/modules/by-name/lf/lf/commands/scripts/execute.sh
+++ b/modules/by-name/lf/lf/commands/scripts/execute.sh
@@ -1,7 +1,4 @@
-#!/usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+# shellcheck shell=sh
 
 # shellcheck disable=SC2269
 f="$f"
diff --git a/modules/by-name/lf/lf/commands/scripts/follow_link.sh b/modules/by-name/lf/lf/commands/scripts/follow_link.sh
index 80413990..509fc2e0 100755
--- a/modules/by-name/lf/lf/commands/scripts/follow_link.sh
+++ b/modules/by-name/lf/lf/commands/scripts/follow_link.sh
@@ -1,7 +1,4 @@
-#!/usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+# shellcheck shell=sh
 
 # shellcheck disable=SC2269
 f="$f"
@@ -14,6 +11,12 @@ id="$id"
 
 dir="$(realpath "$f")"
 
-lf -remote "send $id cd \"$dir\""
+if [ -f "$dir" ]; then
+    cmd="select"
+elif [ -d "$dir" ]; then
+    cmd="cd"
+fi
+
+lf_cmd "$cmd" "$dir"
 
 # vim: ft=sh
diff --git a/modules/by-name/lf/lf/commands/scripts/fzf_jump.sh b/modules/by-name/lf/lf/commands/scripts/fzf_jump.sh
deleted file mode 100755
index ad1633fb..00000000
--- a/modules/by-name/lf/lf/commands/scripts/fzf_jump.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-#! /usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
-res="$(fd . --maxdepth 3 | fzf --header='Jump to location')"
-
-# shellcheck disable=SC2269
-f="$f"
-# shellcheck disable=SC2269
-fx="$fx"
-# shellcheck disable=SC2269
-fs="$fs"
-# shellcheck disable=SC2269
-id="$id"
-
-if [ -f "$res" ]; then
-    cmd="select"
-elif [ -d "$res" ]; then
-    cmd="cd"
-fi
-
-lf -remote "send $id $cmd \"$res\""
-# vim: ft=sh
diff --git a/modules/by-name/lf/lf/commands/scripts/go_project_root.sh b/modules/by-name/lf/lf/commands/scripts/go_project_root.sh
deleted file mode 100755
index 5f7746d3..00000000
--- a/modules/by-name/lf/lf/commands/scripts/go_project_root.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
-# shellcheck disable=SC2269
-f="$f"
-# shellcheck disable=SC2269
-fx="$fx"
-# shellcheck disable=SC2269
-fs="$fs"
-# shellcheck disable=SC2269
-id="$id"
-
-flake_base_dir="$(search_flake_base_dir)"
-if [ "$flake_base_dir" ]; then
-    lf -remote "send $id cd $flake_base_dir" || die "Bug: No base dir ($flake_base_dir)"
-else
-    die "Unable to locate base dir"
-fi
-
-# vim: ft=sh
diff --git a/modules/by-name/lf/lf/commands/scripts/mk_dir.sh b/modules/by-name/lf/lf/commands/scripts/mk_directory.sh
index 150f7eed..58921ccd 100755
--- a/modules/by-name/lf/lf/commands/scripts/mk_dir.sh
+++ b/modules/by-name/lf/lf/commands/scripts/mk_directory.sh
@@ -1,7 +1,4 @@
-#! /usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+# shellcheck shell=sh
 
 # shellcheck disable=SC2269
 f="$f"
@@ -23,7 +20,7 @@ while [ -z "$name" ] || [ -e "$name" ]; do
         if [ "$ans" = "y" ]; then
             break
         else
-            prompt "Directory Name: "
+            prompt "New Directory Name: "
         fi
     fi
 done
diff --git a/modules/by-name/lf/lf/commands/scripts/mk_file.sh b/modules/by-name/lf/lf/commands/scripts/mk_file.sh
index 41d5cf1a..5dafe30d 100755
--- a/modules/by-name/lf/lf/commands/scripts/mk_file.sh
+++ b/modules/by-name/lf/lf/commands/scripts/mk_file.sh
@@ -1,7 +1,4 @@
-#! /usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+# shellcheck shell=sh
 
 # shellcheck disable=SC2269
 f="$f"
@@ -23,7 +20,7 @@ while [ -z "$name" ] || [ -e "$name" ]; do
         if [ "$ans" = "y" ]; then
             break
         else
-            prompt "File name: "
+            prompt "New File name: "
         fi
     fi
 done
diff --git a/modules/by-name/lf/lf/commands/scripts/mk_file_and_edit.sh b/modules/by-name/lf/lf/commands/scripts/mk_file_and_edit.sh
deleted file mode 100755
index 19fc51db..00000000
--- a/modules/by-name/lf/lf/commands/scripts/mk_file_and_edit.sh
+++ /dev/null
@@ -1,33 +0,0 @@
-#! /usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
-# shellcheck disable=SC2269
-f="$f"
-# shellcheck disable=SC2269
-fx="$fx"
-# shellcheck disable=SC2269
-fs="$fs"
-# shellcheck disable=SC2269
-id="$id"
-
-prompt "File name: "
-name=""
-while [ -z "$name" ] || [ -e "$name" ]; do
-    read -r name
-    if [ -e "$name" ]; then
-        prompt "File already exists, overwrite [y|N]: "
-        read -r ans
-
-        if [ "$ans" = "y" ]; then
-            break
-        else
-            prompt "File name: "
-        fi
-    fi
-done
-
-touch "$name"
-"$EDITOR" "$name"
-# vim: ft=sh
diff --git a/modules/by-name/lf/lf/commands/scripts/mk_ln.sh b/modules/by-name/lf/lf/commands/scripts/mk_link.sh
index 7fab8e22..40b2099d 100755
--- a/modules/by-name/lf/lf/commands/scripts/mk_ln.sh
+++ b/modules/by-name/lf/lf/commands/scripts/mk_link.sh
@@ -1,7 +1,4 @@
-#! /usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+# shellcheck shell=sh
 
 # shellcheck disable=SC2269
 f="$f"
@@ -14,20 +11,19 @@ id="$id"
 
 while IFS= read -r i; do
     set -- "$@" "$i"
-done <"$HOME"/.local/share/lf/files
+done <"$HOME/.local/share/lf/files"
 
 mode="$1"
 shift
 
 if [ "$#" -eq 0 ]; then
-    msg "no files to link"
+    lf_cmd echo "No files to link."
     exit 0
 fi
 
 case "$mode" in
 copy)
-    while [ "$#" -gt 0 ]; do
-        file="$1"
+    for file in "$@"; do
         ans="$(basename "$file")"
 
         while [ -e "$ans" ]; do
@@ -36,10 +32,10 @@ copy)
         done
 
         ln --symbolic --relative "$file" "$(pwd)/$ans"
-        shift
     done
     ;;
 esac
-rm ~/.local/share/lf/files
+rm "$HOME/.local/share/lf/files"
 # lf -remote "send clear"
+
 # vim: ft=sh
diff --git a/modules/by-name/lf/lf/commands/scripts/mk_scr_temp.sh b/modules/by-name/lf/lf/commands/scripts/mk_scr_temp.sh
deleted file mode 100755
index 512b5d0b..00000000
--- a/modules/by-name/lf/lf/commands/scripts/mk_scr_temp.sh
+++ /dev/null
@@ -1,38 +0,0 @@
-#! /usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
-# shellcheck disable=SC2269
-f="$f"
-# shellcheck disable=SC2269
-fx="$fx"
-# shellcheck disable=SC2269
-fs="$fs"
-# shellcheck disable=SC2269
-id="$id"
-
-prompt "Script name: "
-name=""
-while [ -z "$name" ] || [ -e "$name" ]; do
-    read -r name
-    if [ -e "$name" ]; then
-        prompt "Script already exists, overwrite [y|N]: "
-        read -r ans
-
-        if [ "$ans" = "y" ]; then
-            break
-        else
-            prompt "Script Name: "
-        fi
-    fi
-done
-
-script="$(pwd)"/"$name"
-
-sed 's|%TO_BE_SHELL_LIBRARY_PATH|%SHELL_LIBRARY_PATH|' "%SHELL_LIBRARY_TEMPLATE" >"$script"
-sed -i 's|dash|sh|' "$script"
-chmod +x "$script"
-"$VISUAL" "$script"
-
-# vim: ft=sh
diff --git a/modules/by-name/lf/lf/commands/scripts/mk_scr_default.sh b/modules/by-name/lf/lf/commands/scripts/mk_script.sh
index 47d05080..bbdf6d39 100755
--- a/modules/by-name/lf/lf/commands/scripts/mk_scr_default.sh
+++ b/modules/by-name/lf/lf/commands/scripts/mk_script.sh
@@ -1,7 +1,4 @@
-#! /usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+# shellcheck shell=sh
 
 # shellcheck disable=SC2269
 f="$f"
@@ -15,8 +12,7 @@ id="$id"
 prompt "Script name: "
 name=""
 while [ -z "$name" ] || [ -e "$name" ]; do
-    read -r name_base
-    name="$name_base.sh"
+    read -r name
     if [ -e "$name" ]; then
         prompt "Script already exists, overwrite [y|N]: "
         read -r ans
@@ -24,14 +20,21 @@ while [ -z "$name" ] || [ -e "$name" ]; do
         if [ "$ans" = "y" ]; then
             break
         else
-            prompt "Script Name: "
+            prompt "New Script Name: "
         fi
     fi
 done
 
-script="$(pwd)"/"$name"
+script="$(pwd)/$name"
+
+cat <<SCRIPT >"$script"
+#! /usr/bin/env sh
+
+
+
+# vim: ft=sh
+SCRIPT
 
-cat "%SHELL_LIBRARY_TEMPLATE" >"$script"
 chmod +x "$script"
 "$VISUAL" "$script"
 
diff --git a/modules/by-name/lf/lf/commands/scripts/open.sh b/modules/by-name/lf/lf/commands/scripts/open.sh
new file mode 100755
index 00000000..b494074f
--- /dev/null
+++ b/modules/by-name/lf/lf/commands/scripts/open.sh
@@ -0,0 +1,15 @@
+# shellcheck shell=sh
+
+# shellcheck disable=SC2269
+f="$f"
+# shellcheck disable=SC2269
+fx="$fx"
+# shellcheck disable=SC2269
+fs="$fs"
+# shellcheck disable=SC2269
+id="$id"
+
+# TODO: For some reason, `xdg-utils` tries to open firefox with it's default profile for
+# _everything_. Using `handlr-regex` sort-of solves this. <2025-04-04>
+handlr open "$f"
+# vim: ft=sh
diff --git a/modules/by-name/lf/lf/commands/scripts/restore_trash.sh b/modules/by-name/lf/lf/commands/scripts/restore_trash.sh
deleted file mode 100755
index b4ef492f..00000000
--- a/modules/by-name/lf/lf/commands/scripts/restore_trash.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#! /usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
-# shellcheck disable=SC2269
-f="$f"
-# shellcheck disable=SC2269
-fx="$fx"
-# shellcheck disable=SC2269
-fs="$fs"
-# shellcheck disable=SC2269
-id="$id"
-
-trash list | fzf --multi | awk '{print $NF}' | xargs trash restore --match=exact
-# vim: ft=sh
diff --git a/modules/by-name/lf/lf/commands/scripts/set_clipboard_path.sh b/modules/by-name/lf/lf/commands/scripts/set_clipboard_path.sh
index ff5f3c01..893452e1 100755
--- a/modules/by-name/lf/lf/commands/scripts/set_clipboard_path.sh
+++ b/modules/by-name/lf/lf/commands/scripts/set_clipboard_path.sh
@@ -1,7 +1,4 @@
-#! /usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+# shellcheck shell=sh
 
 # shellcheck disable=SC2269
 f="$f"
@@ -17,10 +14,10 @@ if [ -n "$fx" ]; then
 elif [ -n "$f" ]; then
     echo "$f" | wl-copy --trim-newline
 else
-    lf -remote "send $id echo 'No file selected.'"
+    lf_cmd echo "No file selected."
     exit 1
 fi
 
-lf -remote "send $id echo 'Path copied'"
+lf_cmd echo "Path copied to clipboard."
 
 # vim: ft=sh
diff --git a/modules/by-name/lf/lf/commands/scripts/set_wall_paper.sh b/modules/by-name/lf/lf/commands/scripts/set_wall_paper.sh
deleted file mode 100755
index 2e607d33..00000000
--- a/modules/by-name/lf/lf/commands/scripts/set_wall_paper.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#! /usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
-# shellcheck disable=SC2269
-f="$f"
-# shellcheck disable=SC2269
-fx="$fx"
-# shellcheck disable=SC2269
-fs="$fs"
-# shellcheck disable=SC2269
-id="$id"
-
-die "No yet implemented" # TODO: do what the 'die' says
-#sed -i "s,export AWMWALLPAPER='.*',export AWMWALLPAPER='${f}'," ${ZDOTDIR}/.zshenv
-#nohub swaybg -i "$f"
-#feh --bg-max --no-fehbg "$f"
-# vim: ft=sh
diff --git a/modules/by-name/lf/lf/commands/scripts/set_wallpaper.sh b/modules/by-name/lf/lf/commands/scripts/set_wallpaper.sh
new file mode 100755
index 00000000..4387cd9a
--- /dev/null
+++ b/modules/by-name/lf/lf/commands/scripts/set_wallpaper.sh
@@ -0,0 +1,19 @@
+# shellcheck shell=sh
+
+# shellcheck disable=SC2269
+f="$f"
+# shellcheck disable=SC2269
+fx="$fx"
+# shellcheck disable=SC2269
+fs="$fs"
+# shellcheck disable=SC2269
+id="$id"
+
+pid="$(pgrep swaybg)"
+[ -n "$pid" ] && kill "$pid"
+
+# We cannot control the available commands for river.
+# Thus we ensure that it can correctly start `swaybg`
+swaybg="$(command -v swaybg)"
+riverctl spawn "$swaybg --image \"$f\"" && lf_cmd echo "Temporary background image set."
+# vim: ft=sh
diff --git a/modules/by-name/lf/lf/commands/scripts/stripspace.sh b/modules/by-name/lf/lf/commands/scripts/stripspace.sh
index 33b1cbcf..95f8f742 100755
--- a/modules/by-name/lf/lf/commands/scripts/stripspace.sh
+++ b/modules/by-name/lf/lf/commands/scripts/stripspace.sh
@@ -1,7 +1,4 @@
-#! /usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+# shellcheck shell=sh
 
 # shellcheck disable=SC2269
 f="$f"
@@ -12,29 +9,14 @@ fs="$fs"
 # shellcheck disable=SC2269
 id="$id"
 
-files=$(mktmp)
-echo "$fx" >"$files"
-
-awk_source=$(mktmp)
-cat <<OFT >"$awk_source"
-BEGIN {FS=" "}
-{for (i=1; i != NF + 1; i++)
-    if (i == NF) {
-        parts[i]=tolower(\$i);
-    } else {
-        parts[i]=tolower(\$i"_");
-    }
-}
-END {for (i in parts) printf parts[i]}
-OFT
+echo "$fx" | while read -r file; do
+    dirty_name=$(basename "$file")
+    clean_name=$(echo "$dirty_name" | sed 's/[[:blank:]]\+/_/g' | sed 's/\(.*\)/\L\1/')
 
-while read -r file; do
-    dirty_name=$(mktmp)
-    basename "$file" >"$dirty_name"
-    clean_name=$(awk -f "$awk_source" "$dirty_name")
+    [ -e "$clean_name" ] && die "file '$clean_name' already exists!"
+    mv "$dirty_name" "$clean_name" || die "Move failed"
 
-    [ -e "$clean_name" ] && die "file \"$clean_name\" already exists!"
-    mv "$(cat "$dirty_name")" "$clean_name" || die "Move failed"
-    lf -remote 'send reload'
-done <"$files"
+    lf_cmd reload
+    lf_cmd select "$clean_name"
+done
 # vim: ft=sh
diff --git a/modules/by-name/lf/lf/commands/scripts/trash.sh b/modules/by-name/lf/lf/commands/scripts/trash.sh
index f4878c49..958bc3f9 100755
--- a/modules/by-name/lf/lf/commands/scripts/trash.sh
+++ b/modules/by-name/lf/lf/commands/scripts/trash.sh
@@ -1,7 +1,4 @@
-#! /usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+# shellcheck shell=sh
 
 # shellcheck disable=SC2269
 f="$f"
@@ -12,26 +9,9 @@ fs="$fs"
 # shellcheck disable=SC2269
 id="$id"
 
-trash_output=$(mktmp)
-expected_error_output=$(mktmp)
-
 while read -r file; do
     set -- "$@" "$file"
-done <"$(tmp echo "$fx")"
-
-# TODO: why are we using trashy at all, when trash-cli can do everything?
-#
-# try trashy first, through nix because both trashy and trash-cli provide a trash command, which conflicts
-nix run nixpkgs#trashy -- put "$@" 2>"$trash_output"
-
-# FIXME: Find a way, that does not depend on parsing an error message <2023-08-29>
-cat <<EOF >"$expected_error_output"
-error: Error during a \`trash\` operation: Unknown { description: "Path: '\"/.Trash-1000\"'. Message: Permission denied (os error 13)" }
-EOF
+done <"$(echo "$fx" | tmp)"
 
-if [ "$(cat "$expected_error_output")" = "$(cat "$trash_output")" ]; then
-    warning "Deleting with trash-cli to the /.Trash folder"
-    # this file could not be trashed because it is on the tempfs volume, trash-cli can do this this
-    trash-put "$@"
-fi
+trash-put -- "$@"
 # vim: ft=sh
diff --git a/modules/by-name/lf/lf/commands/scripts/trash_clear.sh b/modules/by-name/lf/lf/commands/scripts/trash_clear.sh
new file mode 100755
index 00000000..a41dce27
--- /dev/null
+++ b/modules/by-name/lf/lf/commands/scripts/trash_clear.sh
@@ -0,0 +1,9 @@
+# shellcheck shell=sh
+
+while IFS="$(printf '\n')" read -r file; do
+    set -- "$@" "$(pwd)/$file"
+done <"$(conceal list | fzf --multi --ansi | awk '{$1="";$2=""; print $0}' | sed 's/^\s*//' | tmp)"
+
+[ "$#" -ne 0 ] && trash empty --match=exact "$@"
+
+# vim: ft=sh
diff --git a/modules/by-name/lf/lf/commands/scripts/trash_restore.sh b/modules/by-name/lf/lf/commands/scripts/trash_restore.sh
new file mode 100755
index 00000000..cc2d4890
--- /dev/null
+++ b/modules/by-name/lf/lf/commands/scripts/trash_restore.sh
@@ -0,0 +1,17 @@
+# shellcheck shell=sh
+
+# shellcheck disable=SC2269
+f="$f"
+# shellcheck disable=SC2269
+fx="$fx"
+# shellcheck disable=SC2269
+fs="$fs"
+# shellcheck disable=SC2269
+id="$id"
+
+while IFS="$(printf '\n')" read -r file; do
+    set -- "$@" "$(pwd)/$file"
+done <"$(conceal list | fzf --multi --ansi | awk '{$1="";$2=""; print $0}' | sed 's/^\s*//' | tmp)"
+
+[ "$#" -ne 0 ] && trash restore --match=exact "$@"
+# vim: ft=sh
diff --git a/modules/by-name/lf/lf/commands/scripts/unarchive.sh b/modules/by-name/lf/lf/commands/scripts/unarchive.sh
deleted file mode 100755
index d4835f6b..00000000
--- a/modules/by-name/lf/lf/commands/scripts/unarchive.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#! /usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
-# shellcheck disable=SC2269
-f="$f"
-# shellcheck disable=SC2269
-fx="$fx"
-# shellcheck disable=SC2269
-fs="$fs"
-# shellcheck disable=SC2269
-id="$id"
-
-# extract the current file with the right command
-# (xkcd link: https://xkcd.com/1168/)
-set -f
-
-unarchive() {
-    case "$1" in
-    *.tar.bz | *.tar.bz2 | *.tbz | *.tbz2) tar xjvf "$1" ;;
-    *.tar.gz | *.tgz) tar xzvf "$1" ;;
-    *.tar.xz | *.txz) tar xJvf "$1" ;;
-    *.zip) unzip "$1" ;;
-    *.rar)
-        die "rar is a unfree format!"
-        ;;
-    *.7z) 7z x "$1" ;;
-    *) die "Unsupported format" ;;
-    esac
-}
-
-while read -r file; do
-    unarchive "$file"
-done <"$fx"
-# vim: ft=sh
diff --git a/modules/by-name/lf/lf/commands/scripts/view_file.sh b/modules/by-name/lf/lf/commands/scripts/view_file.sh
index 6258d755..38e6b778 100755
--- a/modules/by-name/lf/lf/commands/scripts/view_file.sh
+++ b/modules/by-name/lf/lf/commands/scripts/view_file.sh
@@ -1,7 +1,4 @@
-#!/usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+# shellcheck shell=sh
 
 # shellcheck disable=SC2269
 f="$f"
@@ -12,7 +9,7 @@ fs="$fs"
 
 mime_type="$(file --mime-type --brief --dereference "$f")"
 case "$mime_type" in
-application/pdf)
+application/pdf | application/epub*)
     "$READER" "$f"
     ;;
 image/*)
diff --git a/modules/by-name/lf/lf/ctpv/default.nix b/modules/by-name/lf/lf/ctpv/default.nix
index 3748eca4..98438fba 100644
--- a/modules/by-name/lf/lf/ctpv/default.nix
+++ b/modules/by-name/lf/lf/ctpv/default.nix
@@ -1,5 +1,4 @@
 {
-  sysLib,
   lib,
   config,
   pkgs,
@@ -8,15 +7,15 @@
   functionCall = {
     name,
     dependencies,
-    replacementStrings,
     scriptPath,
-    ...
+    environment,
   }:
-    sysLib.writeShellScript {
+    pkgs.writeShellApplication {
       inherit name;
-      src = scriptPath;
-      keepPath = false;
-      inherit replacementStrings dependencies;
+      text = builtins.readFile ./helpers.sh + builtins.readFile scriptPath;
+      inheritPath = false;
+      runtimeInputs = dependencies;
+      runtimeEnv = environment;
     }
     + "/bin/${name}";
 
@@ -24,8 +23,8 @@
     matches,
     priority,
     dependencies,
-    replacementStrings,
     previewer,
+    environment,
   }: let
     mkMimePath = val: let
       split = lib.strings.splitString "/" val;
@@ -49,7 +48,7 @@
       inherit
         name
         dependencies
-        replacementStrings
+        environment
         ;
       scriptPath = previewer;
     };
@@ -93,6 +92,12 @@
         };
       };
 
+      environment = lib.mkOption {
+        type = lib.types.attrsOf lib.types.str;
+        default = {};
+        description = "Environment variables to set for the script";
+      };
+
       previewer = lib.mkOption {
         type = lib.types.pathInStore;
         description = "The path to the preview script or binary";
@@ -104,13 +109,6 @@
         default = 0;
         description = "The priority to use this previewer.";
       };
-      replacementStrings = lib.mkOption {
-        type = lib.types.attrsOf (lib.types.either lib.types.str lib.types.pathInStore);
-        default = {
-          HELPERS = ./helpers.sh;
-        };
-        description = "Arbitrary strings to replace in the shell script.";
-      };
       dependencies = lib.mkOption {
         type = lib.types.listOf lib.types.package;
         default = [];
@@ -153,17 +151,6 @@ in {
 
     package = lib.mkPackageOption pkgs "ctpv-64-types" {};
 
-    # TODO: This is necessary, as the `./prev` dir is imported separately and as such
-    # cannot access the `./helpers.sh` file in it's parent directory.
-    # This separate import should ideally be removed. <2024-12-15>
-    helpers = lib.mkOption {
-      default = ./helpers.sh;
-      type = lib.types.pathInStore;
-
-      internal = true;
-      readOnly = true;
-    };
-
     previewers = lib.mkOption {
       description = ''
         The previewers to add to the config file.
diff --git a/modules/by-name/lf/lf/ctpv/helpers.sh b/modules/by-name/lf/lf/ctpv/helpers.sh
index 6dc7fee6..30e4483a 100644
--- a/modules/by-name/lf/lf/ctpv/helpers.sh
+++ b/modules/by-name/lf/lf/ctpv/helpers.sh
@@ -59,7 +59,7 @@ preview_xxd() {
     # This has been derived mathematically.
     octet_columns=$(((2 * w - 22) / 7))
 
-    if [ -n "$CTPV_LESS_PREVIEWER" ]; then
+    if [ "${CTPV_LESS_PREVIEWER:-unset}" != "-unset" ]; then
         __base_xxd_preview "$1"
     else
         __base_xxd_preview "$1" -len "$((h * octet_columns))"
diff --git a/modules/by-name/lf/lf/ctpv/prev/any.sh b/modules/by-name/lf/lf/ctpv/prev/any.sh
index 38dfd538..7ce72dcd 100644
--- a/modules/by-name/lf/lf/ctpv/prev/any.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/any.sh
@@ -1,16 +1,13 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 # shellcheck disable=SC2269
 w="$w"
 # shellcheck disable=SC2269
-e="$e"
+e="${e:-[missing extension]}"
 # shellcheck disable=SC2269
-m="$m"
+m="${m:-[missing mime type]}"
 # shellcheck disable=SC2269
 h="$h"
 
@@ -19,8 +16,6 @@ extension="$e"
 # shellcheck disable=SC2269
 mime="$m"
 
-. %HELPERS
-
 is_not_printable() {
     grep --text --quiet '[^[:print:]]' "$1"
 }
@@ -33,8 +28,8 @@ case "$mime" in
 *)
     echo "(ctpv did not recognize this file, with extension: '$extension' and mime: '$mime')"
 
-    directory_storage="%STORAGE_DIRECTORY/$mime"
-    mkdir --parents "$(dirname "%STORAGE_DIRECTORY/$mime")"
+    directory_storage="$STORAGE_DIRECTORY/$mime"
+    mkdir --parents "$(dirname "$STORAGE_DIRECTORY/$mime")"
 
     printf "%s -- %s\n" "$f" "$extension" >>"$directory_storage"
     ;;
diff --git a/modules/by-name/lf/lf/ctpv/prev/application/archive/atool.sh b/modules/by-name/lf/lf/ctpv/prev/application/archive/atool.sh
index 5f4baac7..3aebfbb3 100644
--- a/modules/by-name/lf/lf/ctpv/prev/application/archive/atool.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/application/archive/atool.sh
@@ -1,11 +1,6 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 
-. %HELPERS
-
 atool --list -- "$f"
diff --git a/modules/by-name/lf/lf/ctpv/prev/application/archive/default.nix b/modules/by-name/lf/lf/ctpv/prev/application/archive/default.nix
index 9370bf14..febacb7d 100644
--- a/modules/by-name/lf/lf/ctpv/prev/application/archive/default.nix
+++ b/modules/by-name/lf/lf/ctpv/prev/application/archive/default.nix
@@ -64,7 +64,7 @@
         pkgs.atool
 
         # archive tools
-        pkgs.archiver # for arc
+        # pkgs.archiver # for arc # Unmaintained and insecure
         # pkgs.arj # NOTE: Fails to build since: 2024-12-28
         pkgs.cpio
         pkgs.dpkg
diff --git a/modules/by-name/lf/lf/ctpv/prev/application/dll/dll.sh b/modules/by-name/lf/lf/ctpv/prev/application/dll/dll.sh
index 678506eb..5237ecec 100644
--- a/modules/by-name/lf/lf/ctpv/prev/application/dll/dll.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/application/dll/dll.sh
@@ -1,19 +1,14 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 # shellcheck disable=SC2269
 w="$w"
 # shellcheck disable=SC2269
-e="$e"
+e="${e:-[missing extension]}"
 # shellcheck disable=SC2269
-m="$m"
+m="${m:-[missing mime type]}"
 # shellcheck disable=SC2269
 h="$h"
 
-. %HELPERS
-
 preview_xxd "$f"
diff --git a/modules/by-name/lf/lf/ctpv/prev/application/epub/default.nix b/modules/by-name/lf/lf/ctpv/prev/application/epub/default.nix
index 40510a78..b4df845a 100644
--- a/modules/by-name/lf/lf/ctpv/prev/application/epub/default.nix
+++ b/modules/by-name/lf/lf/ctpv/prev/application/epub/default.nix
@@ -5,11 +5,11 @@
       matches.mime = ["application/epub+zip"];
       matches.extension = ["epub"];
       priority = 1;
-      dependencies = with pkgs; [
-        bk
-        epub-thumbnailer
-        chafa
-        gnused
+      dependencies = [
+        pkgs.bk
+        pkgs.epub-thumbnailer
+        pkgs.chafa
+        pkgs.gnused
       ];
     };
   };
diff --git a/modules/by-name/lf/lf/ctpv/prev/application/epub/epub.sh b/modules/by-name/lf/lf/ctpv/prev/application/epub/epub.sh
index 703e7dad..3bec0dd1 100644
--- a/modules/by-name/lf/lf/ctpv/prev/application/epub/epub.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/application/epub/epub.sh
@@ -1,23 +1,18 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 # shellcheck disable=SC2269
 w="$w"
 # shellcheck disable=SC2269
-e="$e"
+e="${e:-[missing extension]}"
 # shellcheck disable=SC2269
-m="$m"
+m="${m:-[missing mime type]}"
 # shellcheck disable=SC2269
 h="$h"
 # shellcheck disable=SC2269
 cache_f="$cache_f"
 
-. %HELPERS
-
 epub() {
     epub-thumbnailer "$f" "$cache_f" 20000
 }
diff --git a/modules/by-name/lf/lf/ctpv/prev/application/pdf/default.nix b/modules/by-name/lf/lf/ctpv/prev/application/pdf/default.nix
index d3061ea8..24112737 100644
--- a/modules/by-name/lf/lf/ctpv/prev/application/pdf/default.nix
+++ b/modules/by-name/lf/lf/ctpv/prev/application/pdf/default.nix
@@ -8,6 +8,7 @@
         pkgs.poppler_utils # for `pdftoppm`
         pkgs.chafa
         pkgs.gnused
+        pkgs.coreutils
       ];
     };
   };
diff --git a/modules/by-name/lf/lf/ctpv/prev/application/pdf/pdf.sh b/modules/by-name/lf/lf/ctpv/prev/application/pdf/pdf.sh
index 2f807b1a..4d99f4b0 100644
--- a/modules/by-name/lf/lf/ctpv/prev/application/pdf/pdf.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/application/pdf/pdf.sh
@@ -1,15 +1,10 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 # shellcheck disable=SC2269
 cache_f="$cache_f"
 
-. %HELPERS
-
 pdf() {
     pdftoppm -f 1 -l 1 \
         -scale-to-x 1920 \
diff --git a/modules/by-name/lf/lf/ctpv/prev/application/pgp/pgp.sh b/modules/by-name/lf/lf/ctpv/prev/application/pgp/pgp.sh
index a4eefd96..4747a8c4 100644
--- a/modules/by-name/lf/lf/ctpv/prev/application/pgp/pgp.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/application/pgp/pgp.sh
@@ -1,13 +1,8 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 # shellcheck disable=SC2269
 w="$w"
 
-. %HELPERS
-
 hide_script_env sq inspect --certifications -- "$f"
diff --git a/modules/by-name/lf/lf/ctpv/prev/application/sqlite/sqlite.sh b/modules/by-name/lf/lf/ctpv/prev/application/sqlite/sqlite.sh
index 07e77a93..62c1abec 100644
--- a/modules/by-name/lf/lf/ctpv/prev/application/sqlite/sqlite.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/application/sqlite/sqlite.sh
@@ -1,15 +1,10 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 # shellcheck disable=SC2269
 w="$w"
 
-. %HELPERS
-
 echo "SQLite database. Schema:"
 echo
 
diff --git a/modules/by-name/lf/lf/ctpv/prev/application/x-bittorrent/torrent.sh b/modules/by-name/lf/lf/ctpv/prev/application/x-bittorrent/torrent.sh
index 16cfcbcd..f1da355a 100644
--- a/modules/by-name/lf/lf/ctpv/prev/application/x-bittorrent/torrent.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/application/x-bittorrent/torrent.sh
@@ -1,13 +1,8 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 # shellcheck disable=SC2269
 cache_f="$cache_f"
 
-. %HELPERS
-
 transmission-show -- "$f"
diff --git a/modules/by-name/lf/lf/ctpv/prev/application/x-pem-file/default.nix b/modules/by-name/lf/lf/ctpv/prev/application/x-pem-file/default.nix
new file mode 100644
index 00000000..a6a32808
--- /dev/null
+++ b/modules/by-name/lf/lf/ctpv/prev/application/x-pem-file/default.nix
@@ -0,0 +1,11 @@
+{pkgs, ...}: {
+  soispha.programs.lf.ctpv.previewers = {
+    pem = {
+      previewer = ./pem.sh;
+      matches.mime = ["application/x-pem-file"];
+      dependencies = [
+        pkgs.openssl
+      ];
+    };
+  };
+}
diff --git a/modules/by-name/lf/lf/ctpv/prev/application/x-pem-file/pem.sh b/modules/by-name/lf/lf/ctpv/prev/application/x-pem-file/pem.sh
new file mode 100644
index 00000000..76ee3002
--- /dev/null
+++ b/modules/by-name/lf/lf/ctpv/prev/application/x-pem-file/pem.sh
@@ -0,0 +1,8 @@
+#! /usr/bin/env dash
+
+# shellcheck disable=SC2269
+f="$f"
+# shellcheck disable=SC2269
+cache_f="$cache_f"
+
+openssl x509 -in "$f" -text -noout
diff --git a/modules/by-name/lf/lf/ctpv/prev/audio/audio.sh b/modules/by-name/lf/lf/ctpv/prev/audio/audio.sh
index c5abc646..2e9e147c 100644
--- a/modules/by-name/lf/lf/ctpv/prev/audio/audio.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/audio/audio.sh
@@ -1,15 +1,10 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 # shellcheck disable=SC2269
 cache_f="$cache_f"
 
-. %HELPERS
-
 audio() {
     ffmpegthumbnailer -i "$f" -s 0 -q 5 -t 10 -o "$cache_f" 2>/dev/null
 }
diff --git a/modules/by-name/lf/lf/ctpv/prev/audio/default.nix b/modules/by-name/lf/lf/ctpv/prev/audio/default.nix
index 0c60e9d5..20df04b3 100644
--- a/modules/by-name/lf/lf/ctpv/prev/audio/default.nix
+++ b/modules/by-name/lf/lf/ctpv/prev/audio/default.nix
@@ -9,6 +9,7 @@
 
         pkgs.chafa
         pkgs.gnused
+        pkgs.coreutils
       ];
     };
   };
diff --git a/modules/by-name/lf/lf/ctpv/prev/default.nix b/modules/by-name/lf/lf/ctpv/prev/default.nix
index b59430f8..3e54e88a 100644
--- a/modules/by-name/lf/lf/ctpv/prev/default.nix
+++ b/modules/by-name/lf/lf/ctpv/prev/default.nix
@@ -10,18 +10,15 @@ in {
       previewer = ./any.sh;
       priority = -1;
       matches.mime = ["*/*"];
-      replacementStrings = {
-        # FIXME: This declaration replaces the default (although it should be merged with
-        # the default value.) There must be a way, so that repeating the default values is
-        # not needed. <2024-12-15>
-        HELPERS = cfg.ctpv.helpers;
-
+      environment = {
         STORAGE_DIRECTORY = "${cfg.ctpv.xdgDataHome}/ctpv/missing_previews";
       };
 
       dependencies = [
         pkgs.tinyxxd # For xxd
         pkgs.bat
+        pkgs.gnugrep
+        pkgs.coreutils
       ];
     };
   };
diff --git a/modules/by-name/lf/lf/ctpv/prev/font/default.nix b/modules/by-name/lf/lf/ctpv/prev/font/default.nix
index 306e7892..48bcb7ad 100644
--- a/modules/by-name/lf/lf/ctpv/prev/font/default.nix
+++ b/modules/by-name/lf/lf/ctpv/prev/font/default.nix
@@ -13,6 +13,7 @@
         pkgs.fontforge # for `fontimage`
         pkgs.chafa
         pkgs.gnused
+        pkgs.coreutils
       ];
     };
   };
diff --git a/modules/by-name/lf/lf/ctpv/prev/font/font.sh b/modules/by-name/lf/lf/ctpv/prev/font/font.sh
index 4065557e..9e5ef3c1 100644
--- a/modules/by-name/lf/lf/ctpv/prev/font/font.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/font/font.sh
@@ -1,15 +1,10 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 # shellcheck disable=SC2269
 cache_f="$cache_f"
 
-. %HELPERS
-
 font() {
     fontimage -o "$cache_f.png" "$f" 2>/dev/null &&
         mv -- "$cache_f.png" "$cache_f"
diff --git a/modules/by-name/lf/lf/ctpv/prev/image/image.sh b/modules/by-name/lf/lf/ctpv/prev/image/image.sh
index b5b97668..42c99c23 100644
--- a/modules/by-name/lf/lf/ctpv/prev/image/image.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/image/image.sh
@@ -1,11 +1,6 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 
-. %HELPERS
-
 send_image "$f"
diff --git a/modules/by-name/lf/lf/ctpv/prev/image/svg+xml/svg.sh b/modules/by-name/lf/lf/ctpv/prev/image/svg+xml/svg.sh
index 04a06f56..ce588ada 100644
--- a/modules/by-name/lf/lf/ctpv/prev/image/svg+xml/svg.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/image/svg+xml/svg.sh
@@ -1,15 +1,10 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 # shellcheck disable=SC2269
 cache_f="$cache_f"
 
-. %HELPERS
-
 svg() {
     magick "$f" "jpg:$cache_f"
 }
diff --git a/modules/by-name/lf/lf/ctpv/prev/image/x-xcf/xcf.sh b/modules/by-name/lf/lf/ctpv/prev/image/x-xcf/xcf.sh
index 1603e337..abb83a89 100644
--- a/modules/by-name/lf/lf/ctpv/prev/image/x-xcf/xcf.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/image/x-xcf/xcf.sh
@@ -1,15 +1,10 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 # shellcheck disable=SC2269
 cache_f="$cache_f"
 
-. %HELPERS
-
 xcf() {
     # TODO: Add this (currently it fails, as gimp lacks the `python-fu` evaluator) <2024-11-25>
     true
diff --git a/modules/by-name/lf/lf/ctpv/prev/inode/ls.sh b/modules/by-name/lf/lf/ctpv/prev/inode/ls.sh
index f73bd1c2..f5b95d13 100644
--- a/modules/by-name/lf/lf/ctpv/prev/inode/ls.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/inode/ls.sh
@@ -1,8 +1,5 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 # shellcheck disable=SC2269
@@ -10,6 +7,4 @@ cache_d="$cache_d"
 # shellcheck disable=SC2269
 cache_f="$cache_f"
 
-. %HELPERS
-
 ls --color --group-directories-first -- "$f"
diff --git a/modules/by-name/lf/lf/ctpv/prev/inode/symlink.sh b/modules/by-name/lf/lf/ctpv/prev/inode/symlink.sh
index b30957d0..fb0dea8f 100644
--- a/modules/by-name/lf/lf/ctpv/prev/inode/symlink.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/inode/symlink.sh
@@ -1,13 +1,8 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 
-. %HELPERS
-
 #
 # do nothing because in src/ctpv.c some kind of a "preview"
 # is already printed
diff --git a/modules/by-name/lf/lf/ctpv/prev/libreoffice.sh b/modules/by-name/lf/lf/ctpv/prev/libreoffice.sh
index ec57da0b..9407aade 100644
--- a/modules/by-name/lf/lf/ctpv/prev/libreoffice.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/libreoffice.sh
@@ -1,8 +1,5 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 # shellcheck disable=SC2269
@@ -10,8 +7,6 @@ cache_d="$cache_d"
 # shellcheck disable=SC2269
 cache_f="$cache_f"
 
-. %HELPERS
-
 doc() {
     # File produced by libreoffice
     jpg="$(printf '%s\n' "$f" | sed 's|^.*/||; s|\..*$||')"
diff --git a/modules/by-name/lf/lf/ctpv/prev/text/bat.sh b/modules/by-name/lf/lf/ctpv/prev/text/bat.sh
index be952aea..a466c9c7 100644
--- a/modules/by-name/lf/lf/ctpv/prev/text/bat.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/text/bat.sh
@@ -1,13 +1,8 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 # shellcheck disable=SC2269
 w="$w"
 
-. %HELPERS
-
 preview_bat "$f"
diff --git a/modules/by-name/lf/lf/ctpv/prev/text/diff/delta.sh b/modules/by-name/lf/lf/ctpv/prev/text/diff/delta.sh
index 6a4e9a4e..3f8b5631 100644
--- a/modules/by-name/lf/lf/ctpv/prev/text/diff/delta.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/text/diff/delta.sh
@@ -1,11 +1,6 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 
-. %HELPERS
-
 delta <"$f"
diff --git a/modules/by-name/lf/lf/ctpv/prev/text/glow.sh b/modules/by-name/lf/lf/ctpv/prev/text/glow.sh
index 301fe675..30f2af78 100644
--- a/modules/by-name/lf/lf/ctpv/prev/text/glow.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/text/glow.sh
@@ -1,15 +1,10 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 # shellcheck disable=SC2269
 w="$w"
 
-. %HELPERS
-
 # Specify the style, to force `glow` to output colors.
 # tracking issue: https://github.com/charmbracelet/glow/issues/654
 # We can't use `hide_script_env` because of some bespoke reason. (It just forces glow to
diff --git a/modules/by-name/lf/lf/ctpv/prev/text/html/default.nix b/modules/by-name/lf/lf/ctpv/prev/text/html/default.nix
deleted file mode 100644
index 2a7a9a9f..00000000
--- a/modules/by-name/lf/lf/ctpv/prev/text/html/default.nix
+++ /dev/null
@@ -1,13 +0,0 @@
-{pkgs, ...}: {
-  # TODO: I might want to use lynx/w3m instead <2024-11-24>
-  soispha.programs.lf.ctpv.previewers = {
-    elinks = {
-      previewer = ./elinks.sh;
-      priority = 1;
-      matches.mime = ["text/html"];
-      dependencies = [
-        pkgs.elinks
-      ];
-    };
-  };
-}
diff --git a/modules/by-name/lf/lf/ctpv/prev/text/html/elinks.sh b/modules/by-name/lf/lf/ctpv/prev/text/html/elinks.sh
deleted file mode 100644
index ca0de22e..00000000
--- a/modules/by-name/lf/lf/ctpv/prev/text/html/elinks.sh
+++ /dev/null
@@ -1,18 +0,0 @@
-#! /usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
-# shellcheck disable=SC2269
-f="$f"
-# shellcheck disable=SC2269
-w="$w"
-
-. %HELPERS
-
-elinks \
-    -dump 1 -dump-width "$w" \
-    -no-references -no-numbering <"$f"
-
-# lynx -dump -nonumbers -nolist -width="$w" -- "$f"
-# w3m -dump "$f"
diff --git a/modules/by-name/lf/lf/ctpv/prev/text/json/jq.sh b/modules/by-name/lf/lf/ctpv/prev/text/json/jq.sh
index bf807d1d..c7090ccb 100644
--- a/modules/by-name/lf/lf/ctpv/prev/text/json/jq.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/text/json/jq.sh
@@ -1,11 +1,6 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 
-. %HELPERS
-
 jq --color-output . <"$f"
diff --git a/modules/by-name/lf/lf/ctpv/prev/video/video.sh b/modules/by-name/lf/lf/ctpv/prev/video/video.sh
index e42e3612..d1972187 100644
--- a/modules/by-name/lf/lf/ctpv/prev/video/video.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/video/video.sh
@@ -1,15 +1,10 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 # shellcheck disable=SC2269
 cache_f="$cache_f"
 
-. %HELPERS
-
 video() {
     ffmpegthumbnailer -i "$f" -o "$cache_f" -s 0 -t 50% 2>/dev/null
 }
diff --git a/modules/by-name/lf/lf/keybindings/default.nix b/modules/by-name/lf/lf/keybindings/default.nix
index f624719f..c5d6427d 100644
--- a/modules/by-name/lf/lf/keybindings/default.nix
+++ b/modules/by-name/lf/lf/keybindings/default.nix
@@ -36,21 +36,18 @@
   cp = "set_clipboard_path";
 
   # Archive Mappings
-  au = "unarchive";
-  aa = "archive";
+  au = "archive_decompress";
+  aa = "archive_compress";
 
   # Trash Mappings
   dd = "trash";
-  jc = "clear_trash";
-  jr = "restore_trash";
+  jc = "trash_clear";
+  jr = "trash_restore";
 
   # Dragon Mapping
   dr = "dragon";
-  ds = "dragon-stay";
-  di = "dragon-individual";
-  #dm = "mvdragon";
-  #dc = "cpdragon";
-  dl = "dlfile";
+  ds = "dragon_stay";
+  di = "dragon_individual";
 
   cs = "stripspace";
 
@@ -68,17 +65,15 @@
   y = "copy";
   "<enter>" = "open";
 
-  mk = "mk_ln";
+  mk = "mk_link";
   mf = "mk_file";
-  me = "mk_file_and_edit";
-  md = "mk_dir";
-  ms = "mk_scr_default";
-  mt = "mk_scr_temp";
+  md = "mk_directory";
+  ms = "mk_script";
 
   ch = "chmod";
-  bg = "set_wall_paper";
+  bg = "set_wallpaper";
   r = ":rename; cmd-end";
-  H = "go_project_base_directory";
+  H = "cd_project_root";
   R = "reload";
   C = "clear";
   U = "unselect";
diff --git a/modules/by-name/li/libvirtd/module.nix b/modules/by-name/li/libvirtd/module.nix
index 5c519550..3481ef3b 100644
--- a/modules/by-name/li/libvirtd/module.nix
+++ b/modules/by-name/li/libvirtd/module.nix
@@ -1,4 +1,6 @@
-{pkgs, ...}: {
+{...}: {
+  # FIXME(@bpeetz): Do something with this module. <2025-04-04>
+
   # virtualisation = {
   # spiceUSBRedirection.enable = true; # TODO: this allows usb access to any user, which shouldn't be that bad
   #    cores = 8;
diff --git a/modules/by-name/lo/locale/keymaps/us_modified.xkb b/modules/by-name/lo/locale/keymaps/us_modified.xkb
deleted file mode 100644
index 6299a5e9..00000000
--- a/modules/by-name/lo/locale/keymaps/us_modified.xkb
+++ /dev/null
@@ -1,9 +0,0 @@
-partial alphanumeric_keys
-xkb_symbols "us-modified" {
-    name[Group1]= "US English with caps lock key as compose key";
-
-
-    include "us(basic)"
-    include "compose(caps)"
-};
-// vim: ft=xkb
diff --git a/modules/by-name/lo/locale/module.nix b/modules/by-name/lo/locale/module.nix
index 10569216..eda707af 100644
--- a/modules/by-name/lo/locale/module.nix
+++ b/modules/by-name/lo/locale/module.nix
@@ -42,11 +42,6 @@ in {
     };
 
     services.xserver.xkb.extraLayouts = {
-      "us-modified" = {
-        description = "standard us with caps as compose key.";
-        languages = ["eng" "swe" "deu"];
-        symbolsFile = ./keymaps/us_modified.xkb;
-      };
       "dvorak-modified" = {
         description = "standard dvorak english with german and swedish extra chars.";
         languages = ["eng" "swe" "deu"];
diff --git a/modules/by-name/mp/mpv/module.nix b/modules/by-name/mp/mpv/module.nix
new file mode 100644
index 00000000..49a97c3c
--- /dev/null
+++ b/modules/by-name/mp/mpv/module.nix
@@ -0,0 +1,315 @@
+{
+  config,
+  lib,
+  pkgs,
+  ...
+}: let
+  cfg = config.soispha.programs.mpv;
+in {
+  options.soispha.programs.mpv = {
+    enable = lib.mkEnableOption "mpv";
+  };
+
+  config.home-manager.users.soispha = lib.mkIf cfg.enable {
+    programs.mpv = {
+      enable = true;
+
+      bindings = {
+        q = "quit 0";
+        "Ctrl+c" = "quit 1";
+        "Shift+q" = "quit-watch-later 1";
+      };
+      config = {
+        # uosc provides seeking & volume indicators (via flash-timeline and flash-volume commands)
+        # if you decide to use them, you don't need osd-bar
+        osd-bar = false;
+
+        # uosc will draw its own window controls and border if you disable window border
+        border = false;
+      };
+      scriptOpts = {
+        osc = {
+          scalewindowed = 0.8;
+          hidetimeout = 300;
+        };
+        uosc = {
+          # Display style of current position. available: line, bar
+          timeline_style = "line";
+
+          # Line display style config
+          timeline_line_width = 2;
+
+          # Timeline size when fully expanded, in pixels, 0 to disable
+          timeline_size = 40;
+
+          # Comma separated states when element should always be fully visible.
+          # Available: paused, audio, image, video, idle, windowed, fullscreen
+          timeline_persistency = "";
+
+          # Top border of background color to help visually separate timeline from video
+          timeline_border = 1;
+
+          # When scrolling above timeline, wheel will seek by this amount of seconds.
+          # Default uses fast seeking. Add `!` suffix to enable exact seeks. Example: `5!`
+          timeline_step = 5;
+
+          # Render cache indicators for streaming content
+          timeline_cache = true;
+
+          # When to display an always visible progress bar (minimized timeline). Can be: windowed, fullscreen, always, never
+          # Can also be toggled on demand with `toggle-progress` command.
+          progress = "windowed";
+          progress_size = 2;
+          progress_line_width = 20;
+
+          # A comma delimited list of controls above the timeline. Set to `never` to disable.
+          # Parameter spec: enclosed in `{}` means value, enclosed in `[]` means optional
+          # Full item syntax: `[<[!]{disposition1}[,[!]{dispositionN}]>]{element}[:{paramN}][#{badge}[>{limit}]][?{tooltip}]`
+          # Common properties:
+          #   `{icon}` - parameter used to specify an icon name (example: `face`)
+          #            - pick here: https://fonts.google.com/icons?icon.platform=web&icon.set=Material+Icons&icon.style=Rounded
+          # `{element}`s and their parameters:
+          #   `{shorthand}` - preconfigured shorthands:
+          #        `play-pause`, `menu`, `subtitles`, `audio`, `video`, `playlist`,
+          #        `chapters`, `editions`, `stream-quality`, `open-file`, `items`,
+          #        `next`, `prev`, `first`, `last`, `audio-device`, `fullscreen`,
+          #        `loop-playlist`, `loop-file`, `shuffle`, `autoload`
+          #   `speed[:{scale}]` - display speed slider, [{scale}] - factor of controls_size, default: 1.3
+          #   `command:{icon}:{command}` - button that executes a {command} when pressed
+          #   `toggle:{icon}:{prop}[@{owner}]` - button that toggles mpv property. shorthand for yes/no cycle below
+          #   `cycle:{default_icon}:{prop}[@{owner}]:{value1}[={icon1}][!]/{valueN}[={iconN}][!]`
+          #       - button that cycles mpv property between values, each optionally having different icon and active flag
+          #       - presence of `!` at the end will style the button as active
+          #       - `{owner}` is the name of a script that manages this property if any. Set to `uosc` to tap into uosc options.
+          #   `gap[:{scale}]` - display an empty gap
+          #       {scale} - factor of controls_size, default: 0.3
+          #   `space` - fills all available space between previous and next item, useful to align items to the right
+          #           - multiple spaces divide the available space among themselves, which can be used for centering
+          #   `button:{name}` - button whose state, look, and click action are managed by external script
+          # Item visibility control:
+          #   `<[!]{disposition1}[,[!]{dispositionN}]>` - optional prefix to control element's visibility
+          #   - `{disposition}` can be one of:
+          #     - `idle` - true if mpv is in idle mode (no file loaded)
+          #     - `image` - true if current file is a single image
+          #     - `audio` - true for audio only files
+          #     - `video` - true for files with a video track
+          #     - `has_many_video` - true for files with more than one video track
+          #     - `has_image` - true for files with a cover or other image track
+          #     - `has_audio` - true for files with an audio track
+          #     - `has_many_audio` - true for files with more than one audio track
+          #     - `has_sub` - true for files with an subtitle track
+          #     - `has_many_sub` - true for files with more than one subtitle track
+          #     - `has_many_edition` - true for files with more than one edition
+          #     - `has_chapter` - true for files with chapter list
+          #     - `stream` - true if current file is read from a stream
+          #     - `has_playlist` - true if current playlist has 2 or more items in it
+          #   - prefix with `!` to negate the required disposition
+          #   Examples:
+          #     - `<stream>stream-quality` - show stream quality button only for streams
+          #     - `<has_audio,!audio>audio` - show audio tracks button for all files that have
+          #                                   an audio track, but are not exclusively audio only files
+          # Place `#{badge}[>{limit}]` after the element params to give it a badge. Available badges:
+          #   `sub`, `audio`, `video` - track type counters
+          #   `{mpv_prop}` - any mpv prop that makes sense to you: https://mpv.io/manual/master/#property-list
+          #                - if prop value is an array it'll display its size
+          #   `>{limit}` will display the badge only if it's numerical value is above this threshold.
+          #   Example: `#audio>1`
+          # Place `?{tooltip}` after the element config to give it a tooltip.
+          # Example implementations:
+          #   menu = command:menu:script-binding uosc/menu-blurred?Menu
+          #   subtitles = command:subtitles:script-binding uosc/subtitles#sub?Subtitles
+          #   fullscreen = cycle:crop_free:fullscreen:no/yes=fullscreen_exit!?Fullscreen
+          #   loop-playlist = cycle:repeat:loop-playlist:no/inf!?Loop playlist
+          #   toggle:{icon}:{prop} = cycle:{icon}:{prop}:no/yes!
+          controls = "menu,gap,subtitles,<has_many_audio>audio,<has_many_video>video,<has_many_edition>editions,<stream>stream-quality,gap,space,speed,space,shuffle,loop-playlist,loop-file,gap,prev,items,next,gap,fullscreen";
+          controls_size = 32;
+          controls_margin = 8;
+          controls_spacing = 2;
+          controls_persistency = "";
+
+          # Where to display volume controls: none, left, right
+          volume = "right";
+          volume_size = 40;
+          volume_border = 1;
+          volume_step = 1;
+          volume_persistency = "";
+
+          # Playback speed widget: mouse drag or wheel to change, click to reset
+          speed_step = 0.1;
+          speed_step_is_factor = false;
+          speed_persistency = "";
+
+          # Controls all menus, such as context menu, subtitle loader/selector, etc
+          menu_item_height = 36;
+          menu_min_width = 260;
+          menu_padding = 4;
+
+          # Determines if `/` or `ctrl+f` is required to activate the search, or if typing
+          # any text is sufficient.
+          # When enabled, you can no longer toggle a menu off with the same key that opened it, if the key is a unicode character.
+          menu_type_to_search = true;
+
+          # Top bar with window controls and media title
+          # Can be: never, no-border, always
+          top_bar = "never";
+          top_bar_size = 40;
+          # Can be: `no` (hide), left or right
+          top_bar_controls = false;
+          # Can be: `no` (hide), `yes` (inherit title from mpv.conf), or a custom template string
+          top_bar_title = false;
+          # Template string to enable alternative top bar title. If alt title matches main title,
+          # it'll be hidden. Tip: use `${media-title}` for main, and `${filename}` for alt title.
+          top_bar_alt_title = "";
+          # Can be:
+          #   `below`  => display alt title below the main one
+          #   `toggle` => toggle the top bar title text between main and alt by clicking
+          #               the top bar, or calling `toggle-title` binding
+          top_bar_alt_title_place = "below";
+          # Flash top bar when any of these file types is loaded. Available: audio,video,image,chapter
+          top_bar_flash_on = "video,audio";
+          top_bar_persistency = "";
+
+          # Window border drawn in no-border mode
+          window_border_size = 1;
+
+          # If there's no playlist and file ends, load next file in directory
+          # Uses `load_types` config below to determine what type of file to load next.
+          # When enabled, usoc will set mpv config `keep-open` to `yes`, and `keep-open-pause` to `no`.
+          autoload = false;
+          # Enable uosc's playlist/directory shuffle mode
+          # This simply makes the next selected playlist or directory item be random, just
+          # like any other player in the world. It also has an easily togglable control button.
+          shuffle = false;
+
+          # Scale the interface by this factor
+          scale = 1;
+          # Scale in fullscreen
+          scale_fullscreen = 1.3;
+          # Adjust the text scaling to fit your font
+          font_scale = 1;
+          # Border of text and icons when drawn directly on top of video
+          text_border = 1.2;
+          # Border radius of buttons, menus, and all other rectangles
+          border_radius = 4;
+          # A comma delimited list of color overrides in RGB HEX format. Defaults:
+          # foreground=ffffff,foreground_text=000000,background=000000,background_text=ffffff,curtain=111111,success=a5e075,error=ff616e
+          color = "";
+          # A comma delimited list of opacity overrides for various UI element backgrounds and shapes.
+          # This does not affect any text, which is always rendered fully opaque. Defaults:
+          # timeline=0.9,position=1,chapters=0.8,slider=0.9,slider_gauge=1,controls=0,speed=0.6,menu=1,submenu=0.4,border=1,title=1,tooltip=1,thumbnail=1,curtain=0.8,idle_indicator=0.8,audio_indicator=0.5,buffering_indicator=0.3,playlist_position=0.8
+          opacity = "";
+
+          # A comma delimited list of features to refine at a cost of some performance impact.
+          # text_width - Use a more accurate text width measurement that measures each text string individually
+          #              instead of just measuring the width of known letters once and adding them up.
+          # sorting    - Use filename sorting that handles non-english languages better, especially asian ones.
+          #              At the moment, this is only available on windows, and has no effect on other platforms.
+          refine = "";
+
+          # Duration of animations in milliseconds
+          animation_duration = 100;
+
+          # Execute command for background clicks shorter than this number of milliseconds, 0 to disable
+          # Execution always waits for `input-doubleclick-time` to filter out double-clicks
+          click_threshold = 0;
+          click_command = "cycle pause; script-binding uosc/flash-pause-indicator";
+
+          # Flash duration in milliseconds used by `flash-{element}` commands
+          flash_duration = 1000;
+
+          # Distances in pixels below which elements are fully faded in/out
+          proximity_in = 40;
+          proximity_out = 120;
+
+          # Use only bold font weight throughout the whole UI
+          font_bold = false;
+
+          # One of `total`, `playtime-remaining` (scaled by the current speed), `time-remaining` (remaining length of file)
+          destination_time = "playtime-remaining";
+
+          # Display sub second fraction in timestamps up to this precision
+          time_precision = 0;
+
+          # Display stream's buffered time in timeline if it's lower than this amount of seconds, 0 to disable
+          buffered_time_threshold = 60;
+
+          # Hide UI when mpv autohides the cursor. Timing is controlled by `cursor-autohide` in `mpv.conf` (in milliseconds).
+          autohide = true;
+
+          # Can be: flash, static, manual (controlled by flash-pause-indicator and decide-pause-indicator commands)
+          pause_indicator = "static";
+
+          # Sizes to list in stream quality menu
+          stream_quality_options = "4320,2160,1440,1080,720,480,360,240,144";
+
+          # Types to identify media files
+          video_types = "3g2,3gp,asf,avi,f4v,flv,h264,h265,m2ts,m4v,mkv,mov,mp4,mp4v,mpeg,mpg,ogm,ogv,rm,rmvb,ts,vob,webm,wmv,y4m";
+          audio_types = "aac,ac3,aiff,ape,au,cue,dsf,dts,flac,m4a,mid,midi,mka,mp3,mp4a,oga,ogg,opus,spx,tak,tta,wav,weba,wma,wv";
+          image_types = "apng,avif,bmp,gif,j2k,jp2,jfif,jpeg,jpg,jxl,mj2,png,svg,tga,tif,tiff,webp";
+          subtitle_types = "aqt,ass,gsub,idx,jss,lrc,mks,pgs,pjs,psb,rt,sbv,slt,smi,sub,sup,srt,ssa,ssf,ttxt,txt,usf,vt,vtt";
+          playlist_types = "m3u,m3u8,pls,url,cue";
+
+          # Type pools used by file navigation and `autoload` to determine what type of file to load next
+          # Available: video,audio,image,playlist,same. `same` means the same type pool (not just extension) as currently open file.
+          load_types = "video,audio,image";
+
+          # Default open-file menu directory. Use `{drives}` to open drives menu on windows (defaults to `/` on unix).
+          default_directory = "~/";
+
+          # List hidden files when reading directories. Due to environment limitations, this currently only hides
+          # files starting with a dot. Doesn't hide hidden files on windows (we have no way to tell they're hidden).
+          show_hidden_files = false;
+
+          # Move files to trash (recycle bin) when deleting files. Dependencies:
+          # - Linux: `sudo apt install trash-cli`
+          # - MacOS: `brew install trash`
+          use_trash = false;
+
+          # Adjusted osd margins based on the visibility of UI elements
+          adjust_osd_margins = true;
+
+          # Adds chapter range indicators to some common chapter types.
+          # Additionally to displaying the start of the chapter as a diamond icon on top of the timeline,
+          # the portion of the timeline of that chapter range is also colored based on the config below.
+          #
+          # The syntax is a comma-delimited list of `{type}:{color}` pairs, where:
+          # `{type}` => range type. Currently supported ones are:
+          #   - `openings`, `endings` => anime openings/endings
+          #   - `intros`, `outros` => video intros/outros
+          #   - `ads` => segments created by sponsor-block software like https://github.com/po5/mpv_sponsorblock
+          # `{color}` => an RGB(A) HEX color code (`rrggbb`, or `rrggbbaa`)
+          #
+          # To exclude marking any of the range types, simply remove them from the list.
+          chapter_ranges = "openings:30abf964,endings:30abf964,ads:c54e4e80";
+
+          # Add alternative lua patterns to identify beginnings of simple chapter ranges (except for `ads`)
+          # Syntax: `{type}:{pattern}[,{patternN}][;{type}:{pattern}[,{patternN}]]`
+          chapter_range_patterns = "openings:オープニング;endings:エンディング";
+
+          # Localization language priority from highest to lowest.
+          # Also controls what languages are fetched by `download-subtitles` menu.
+          # Built in languages can be found in `uosc/intl`.
+          # `slang` is a keyword to inherit values from `--slang` mpv config.
+          # Supports paths to custom json files: `languages=~~/custom.json,slang,en`
+          languages = "slang,en";
+
+          # A comma separated list of element IDs to disable. Available IDs:
+          #   window_border, top_bar, timeline, controls, volume,
+          #   idle_indicator, audio_indicator, buffering_indicator, pause_indicator
+          disable_elements = "";
+        };
+        thumbfast = {
+          hwdec = true;
+          network = false;
+          spawn_first = false;
+          max_height = 250;
+          max_width = 250;
+        };
+      };
+      scripts = with pkgs.mpvScripts; [
+        uosc
+        thumbfast
+      ];
+    };
+  };
+}
diff --git a/modules/by-name/ni/nix/module.nix b/modules/by-name/ni/nix/module.nix
index 767ab076..48834b2d 100644
--- a/modules/by-name/ni/nix/module.nix
+++ b/modules/by-name/ni/nix/module.nix
@@ -7,6 +7,8 @@
   system,
   ...
 }: {
+  # TODO(@bpeetz): Modularize <2025-02-08>
+
   nix = {
     package = pkgs.lix;
 
@@ -52,7 +54,7 @@
 
       fallback = true; # Build from source, if binary can't be substituted
 
-      keep-failed = true; # keep failed tmp build dirs
+      keep-failed = false; # keep failed tmp build dirs
       pure-eval = true; # restrict file system and network access to hash
 
       sandbox-fallback = false; # Don't disable the sandbox, if the kernel doesn't support it
diff --git a/modules/by-name/nv/nvim/module.nix b/modules/by-name/nv/nvim/module.nix
index 69e417bb..0eb416f6 100644
--- a/modules/by-name/nv/nvim/module.nix
+++ b/modules/by-name/nv/nvim/module.nix
@@ -32,6 +32,9 @@ in {
       programs.nixvim = {
         enable = true;
 
+        # Use my global nixpkgs set, instead of constructing a separate one.
+        nixpkgs.useGlobalPackages = true;
+
         # source: https://www.patorjk.com/software/taag/#p=display&f=ANSI%20Shadow&t=Neovim
         extraConfigLuaPre = lib.mkBefore ''
           ---------------------------------------------------------------------------
diff --git a/modules/by-name/nv/nvim/plgs/flatten-nvim/default.nix b/modules/by-name/nv/nvim/plgs/flatten-nvim/default.nix
index c1ace4ac..48fcd8a6 100644
--- a/modules/by-name/nv/nvim/plgs/flatten-nvim/default.nix
+++ b/modules/by-name/nv/nvim/plgs/flatten-nvim/default.nix
@@ -6,7 +6,8 @@
 }: let
   cfg = config.soispha.programs.nvim;
 in {
-  home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable {
+  # TODO: Get this plugin working again <2025-01-29>
+  home-manager.users.soispha.programs.nixvim = lib.mkIf false {
     # TODO: package flatten-nvim though a module
 
     extraConfigLuaPre = ''
diff --git a/modules/by-name/nv/nvim/plgs/lf-nvim/default.nix b/modules/by-name/nv/nvim/plgs/lf-nvim/default.nix
index 5e2836b0..1e7c91e3 100644
--- a/modules/by-name/nv/nvim/plgs/lf-nvim/default.nix
+++ b/modules/by-name/nv/nvim/plgs/lf-nvim/default.nix
@@ -2,6 +2,8 @@
   pkgs,
   lib,
   config,
+  nixpkgs_open_prs,
+  system,
   ...
 }: let
   cfg = config.soispha.programs.nvim;
@@ -13,7 +15,7 @@ in {
       ${lib.strings.fileContents ./lua/lf-nvim.lua}
     '';
     extraPlugins = [
-      pkgs.vimExtraPlugins.lf-nvim
+      nixpkgs_open_prs.nixpkgs-lf.legacyPackages."${system}".vimPlugins.lf-nvim
 
       pkgs.vimPlugins.toggleterm-nvim # required by lf-nvim
     ];
diff --git a/modules/by-name/nv/nvim/plgs/telescope/extensions/bibtex/default.nix b/modules/by-name/nv/nvim/plgs/telescope/extensions/bibtex/default.nix
index 818aa18e..8eee9a27 100644
--- a/modules/by-name/nv/nvim/plgs/telescope/extensions/bibtex/default.nix
+++ b/modules/by-name/nv/nvim/plgs/telescope/extensions/bibtex/default.nix
@@ -1,32 +1,27 @@
-{
-  pkgs,
-  config,
-  lib,
-  ...
-}: let
+{config, ...}: let
   cfg = config.soispha.programs.nvim;
 in {
-  home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable {
-    extraPlugins = [
-      pkgs.vimExtraPlugins.telescope-bibtex-nvim
-    ];
-
-    # Only activate this in tex files.
-    # TODO: Why? <2024-11-23>
-    extraFiles = {
-      "ftplugin/tex.lua".text = ''
-        ${lib.strings.fileContents ./tex.lua}
-      '';
-    };
-
-    keymaps = [
-      {
-        key = "<space>ib";
-        # This is registered in the ftplugin file, so we set this to null here
-        action = "<Nop>";
-        mode = "n";
-        options.desc = "[i]nsert a [b]atex citation";
-      }
-    ];
-  };
+  # TODO: Re-enable this, once the plugin is merged into nixpkgs <2025-03-29>
+  # home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable {
+  #   extraPlugins = [
+  #     pkgs.vimExtraPlugins.telescope-bibtex-nvim
+  #   ];
+  #
+  #   # Only activate this in tex files.
+  #   extraFiles = {
+  #     "ftplugin/tex.lua".text = ''
+  #       ${lib.strings.fileContents ./tex.lua}
+  #     '';
+  #   };
+  #
+  #   keymaps = [
+  #     {
+  #       key = "<space>ib";
+  #       # This is registered in the ftplugin file, so we set this to null here
+  #       action = "<Nop>";
+  #       mode = "n";
+  #       options.desc = "[i]nsert a [b]atex citation";
+  #     }
+  #   ];
+  # };
 }
diff --git a/modules/by-name/ol/ollama/module.nix b/modules/by-name/ol/ollama/module.nix
index bd0baaa6..7a4e8038 100644
--- a/modules/by-name/ol/ollama/module.nix
+++ b/modules/by-name/ol/ollama/module.nix
@@ -28,6 +28,16 @@ in {
     services.ollama = {
       enable = true;
       acceleration = false;
+
+      # TODO: This could work for GPU acceleration. <2024-12-20>
+      # acceleration = "rocm";
+      # host = "127.0.0.1";
+      # port = 11434;
+      # environmentVariables = {
+      #   HCC_AMDGPU_TARGET = "gfx1032"; # used to be necessary, but doesn't seem to anymore
+      # };
+      #
+      # rocmOverrideGfx = "10.3.2";
     };
   };
 }
diff --git a/modules/by-name/ri/river/init_base.sh b/modules/by-name/ri/river/init_base.sh
new file mode 100755
index 00000000..938b46b1
--- /dev/null
+++ b/modules/by-name/ri/river/init_base.sh
@@ -0,0 +1,22 @@
+#!/usr/bin/env sh
+
+# NOTE: Keep this in sync with the file from `river-start` <2025-02-03>
+RIVER_LOG_FILE="$HOME/.local/share/river/log"
+
+err_fail() {
+    if ! "$@"; then
+        output=""
+        for arg in "$@"; do
+            if [ -z "$output" ]; then
+                output="'$arg'"
+            else
+                output="$output '$arg'"
+            fi
+        done
+        printf "%s failed!\n" "$output" >>"$RIVER_LOG_FILE"
+    fi
+}
+exec 1>>"$RIVER_LOG_FILE"
+exec 2>>"$RIVER_LOG_FILE"
+
+# Start of the generated stuff.
diff --git a/modules/by-name/ri/river/module.nix b/modules/by-name/ri/river/module.nix
index a059da4d..139e8b66 100644
--- a/modules/by-name/ri/river/module.nix
+++ b/modules/by-name/ri/river/module.nix
@@ -3,19 +3,216 @@
   lib,
   qmk_firmware,
   system,
+  pkgs,
   ...
 }: let
   cfg = config.soispha.programs.river;
+  esa = lib.strings.escapeShellArg;
+  riverctl = lib.getExe' pkgs.river "riverctl";
+
+  mkOutputFlags = output: flags: let
+    expandedFlags = builtins.concatStringsSep " " (lib.attrsets.mapAttrsToList (flag: value: "--${esa flag} ${esa value}") flags);
+  in ''
+    err_fail ${lib.getExe pkgs.wlr-randr} --output ${esa output} ${expandedFlags}
+  '';
+  screenSetupCode = builtins.concatStringsSep "" (lib.attrsets.mapAttrsToList mkOutputFlags cfg.init.screenSetupCode);
+
+  mkLrProgram = input: let
+    program = builtins.concatStringsSep " " (
+      if lib.isDerivation input
+      then [(lib.getExe input)]
+      else builtins.map esa input
+    );
+  in "err_fail ${program} &";
+  longRunningPrograms = builtins.concatStringsSep "\n" (builtins.map mkLrProgram cfg.init.backgroundStart);
+
+  keymapFormat = pkgs.formats.json {};
+
+  keymappings = ''
+    err_fail ${riverctl} keyboard-layout ${esa cfg.init.mappings.layout}
+    err_fail ${lib.getExe pkgs.river-mk-keymap} ${keymapFormat.generate "keys.json" cfg.init.mappings.keymap}
+  '';
+
+  mkRule = {
+    app-id,
+    title,
+    action,
+  }: ''
+    err_fail ${riverctl} rule-add -app-id ${esa app-id} -title ${esa title} ${esa action}
+  '';
+  ruleSetup = builtins.concatStringsSep "" (builtins.map mkRule cfg.init.rules);
+
+  mkSetting = name: maybe_values: let
+    rawValues =
+      if builtins.isString maybe_values
+      then [maybe_values]
+      else maybe_values;
+    values = builtins.concatStringsSep " " (builtins.map esa rawValues);
+  in ''
+    err_fail ${riverctl} ${esa name} ${values}
+  '';
+  generalSettings =
+    builtins.concatStringsSep "" (lib.attrsets.mapAttrsToList mkSetting
+      cfg.init.generalSettings);
+
+  mkInput = name: arguments:
+    builtins.concatStringsSep "" (builtins.map (argumentLine: mkSetting "input" ([name] ++ argumentLine)) arguments);
+  inputs =
+    builtins.concatStringsSep "" (lib.attrsets.mapAttrsToList mkInput cfg.init.inputs);
 in {
   options.soispha.programs.river = {
     enable = lib.mkEnableOption "river";
+
     unicodeInput = {
       enable = lib.mkEnableOption "udev rules for rawhid based unicode input";
     };
+
+    init = {
+      mappings = {
+        layout = lib.mkOption {
+          type = lib.types.str;
+          description = "The keymap to use";
+          default = "dvorak-modified";
+        };
+
+        keymap = lib.mkOption {
+          type = lib.types.submodule {
+            freeformType = keymapFormat.type;
+
+            options = {};
+          };
+          default = {};
+
+          description = ''
+            Configuration for river-mk-keymap via `keys.json`.
+          '';
+        };
+      };
+
+      rules = lib.mkOption {
+        type = lib.types.listOf (lib.types.attrsOf lib.types.str);
+        default = [];
+
+        example = ''
+          [
+            {
+              app-id = "*";
+              title = "floating please";
+              action = "float";
+            }
+            {
+              app-id = "*";
+              title = "*";
+              action = "ssd";
+            }
+          ]
+        '';
+
+        description = ''
+          Configuration for river's rules.
+        '';
+      };
+
+      generalSettings = lib.mkOption {
+        type = lib.types.attrsOf (lib.types.either (lib.types.listOf lib.types.str) lib.types.str);
+        description = "Simple key value settings.";
+        default = {};
+        example = ''
+          {
+            background-color = "0x002b36";
+            set-repeat = ["50" "300"];
+            hide-cursor = ["when-typing" "enabled"];
+          }
+        '';
+      };
+
+      inputs = lib.mkOption {
+        type = lib.types.attrsOf (lib.types.listOf (lib.types.listOf lib.types.str));
+        description = "Options to set per input device";
+        default = {};
+        example = ''
+          {
+            pointer-1133-49970-Logitech_Gaming_Mouse_G502 = [["pointer-accel" "0"] ["accel-profile" "none"]];
+            pointer-12951-6505-ZSA_Technology_Labs_Moonlander_Mark_I = [["pointer-accel" "0"] ["accel-profile" "none"]];
+          }
+        '';
+      };
+
+      backgroundStart = lib.mkOption {
+        type = lib.types.listOf (lib.types.either lib.types.package (lib.types.listOf lib.types.str));
+        description = "List of programs to start in the background";
+        example = ''
+          [
+            pkgs.gammastep
+          ]
+        '';
+      };
+
+      screenSetupCode = lib.mkOption {
+        type = lib.types.attrsOf (lib.types.attrsOf lib.types.str);
+        default = {};
+        description = ''
+          `wlr-randr` flags to set up outputs. The attribute names are the `--output` keys
+          and the attrs are flag value pairs to setup.
+        '';
+        example = ''
+          {
+            "Virtual-1" = {mode = "1920x1080";};
+            "DP-2" = {pos = "2560,0";};
+            "DP-1" = {scale = "1.5"; pos = "0,0";};
+          }
+        '';
+      };
+    };
   };
 
   config = lib.mkIf cfg.enable {
-    # TODO: Migrate the complete river module <2024-12-30>
     services.udev.packages = lib.mkIf cfg.unicodeInput.enable [qmk_firmware.packages.${system}.qmk_unicode_type];
+
+    home-manager.users.soispha = {
+      home.sessionVariables = {
+        WM = "river";
+        XDG_CURRENT_DESKTOP = "river";
+        DESKTOP_SESSION = "river";
+
+        # Export Wayland env Vars {{{
+        QT_QPA_PLATFORM = "wayland";
+        QT_QPA_PLATFORMTHEME = "qt5ct"; # needs qt5ct
+        CLUTTER_BACKEND = "wayland";
+        SDL_VIDEODRIVER = "wayland"; # might brake some things
+        # }}}
+      };
+
+      home.packages = [
+        pkgs.river-start
+      ];
+
+      xdg.configFile."river/init" = {
+        executable = true;
+        text = let
+          mkHeading = text: other_stuff: ''
+            # ${text}
+            ${other_stuff}
+          '';
+        in
+          builtins.readFile ./init_base.sh
+          +
+          # bash
+          mkHeading "Environment variables" ''
+            err_fail ${riverctl} spawn "${lib.getExe' pkgs.dbus "dbus-update-activation-environment"} --verbose --systemd SEATD_SOCK DISPLAY WAYLAND_DISPLAY DESKTOP_SESSION=river XDG_CURRENT_DESKTOP=river"
+            export XDG_CURRENT_DESKTOP=river DESKTOP_SESSION=river;
+          ''
+          + mkHeading "Key Mappings" keymappings
+          + mkHeading "Rules" ruleSetup
+          + mkHeading "General Settings" generalSettings
+          + mkHeading "Input Section" inputs
+          + mkHeading "Screen setup code" screenSetupCode
+          + mkHeading "Background services" longRunningPrograms
+          + mkHeading "Layout Setup" ''
+            err_fail ${riverctl} default-layout rivertile
+            ${lib.getExe' pkgs.river "rivertile"} -main-ratio 0.5 -view-padding 1 -outer-padding 0
+          '';
+      };
+    };
   };
 }
diff --git a/modules/by-name/so/sound/module.nix b/modules/by-name/so/sound/module.nix
index f3120a67..8b519f09 100644
--- a/modules/by-name/so/sound/module.nix
+++ b/modules/by-name/so/sound/module.nix
@@ -10,7 +10,7 @@ in {
   };
 
   config = lib.mkIf cfg.enable {
-    hardware.pulseaudio.enable = false;
+    services.pulseaudio.enable = false;
     security.rtkit.enable = true;
 
     services.pipewire = {
diff --git a/modules/home.legacy/conf/swaylock/GTDcanonical.png b/modules/by-name/sw/swaylock/images/GTDcanonical.png
index ef41d79d..ef41d79d 100644
--- a/modules/home.legacy/conf/swaylock/GTDcanonical.png
+++ b/modules/by-name/sw/swaylock/images/GTDcanonical.png
Binary files differdiff --git a/modules/home.legacy/conf/swaylock/commands.jpg b/modules/by-name/sw/swaylock/images/commands.jpg
index 54016503..54016503 100644
--- a/modules/home.legacy/conf/swaylock/commands.jpg
+++ b/modules/by-name/sw/swaylock/images/commands.jpg
Binary files differdiff --git a/modules/by-name/sw/swaylock/images/duwon-lee-tempano-port.jpg b/modules/by-name/sw/swaylock/images/duwon-lee-tempano-port.jpg
new file mode 100644
index 00000000..d72f32d1
--- /dev/null
+++ b/modules/by-name/sw/swaylock/images/duwon-lee-tempano-port.jpg
Binary files differdiff --git a/modules/home.legacy/conf/swaylock/gnu.png b/modules/by-name/sw/swaylock/images/gnu.png
index d07dee3e..d07dee3e 100644
--- a/modules/home.legacy/conf/swaylock/gnu.png
+++ b/modules/by-name/sw/swaylock/images/gnu.png
Binary files differdiff --git a/modules/by-name/sw/swaylock/module.nix b/modules/by-name/sw/swaylock/module.nix
index 6cbcef28..fc296de7 100644
--- a/modules/by-name/sw/swaylock/module.nix
+++ b/modules/by-name/sw/swaylock/module.nix
@@ -1,4 +1,25 @@
-{...}: {
-  # otherwise swaylock can't access the user password.
-  security.pam.services.swaylock = {};
+{
+  config,
+  lib,
+  ...
+}: let
+  cfg = config.soispha.programs.swaylock;
+in {
+  options.soispha.programs.swaylock = {
+    enable = lib.mkEnableOption "swaylock";
+  };
+
+  config = lib.mkIf cfg.enable {
+    # otherwise swaylock can't access the user password.
+    security.pam.services.swaylock = {};
+
+    home-manager.users.soispha.programs.swaylock = {
+      enable = true;
+      settings = {
+        image = "${./images/duwon-lee-tempano-port.jpg}";
+        scaling = "stretch";
+        color = "000000";
+      };
+    };
+  };
 }
diff --git a/modules/by-name/ta/taskwarrior/module.nix b/modules/by-name/ta/taskwarrior/module.nix
index 0a942820..2c1f91c2 100644
--- a/modules/by-name/ta/taskwarrior/module.nix
+++ b/modules/by-name/ta/taskwarrior/module.nix
@@ -1,44 +1,148 @@
 {
   lib,
   config,
+  pkgs,
   ...
 }: let
   cfg = config.soispha.programs.taskwarrior;
+
+  hooksDir =
+    pkgs.runCommandNoCCLocal "mk-taskwarrior-hooks" {}
+    (''
+        mkdir "$out"
+      ''
+      + (builtins.concatStringsSep "\n"
+        (lib.attrsets.mapAttrsToList
+          (name: value: ''
+            ln --symbolic "${lib.getExe value.executable}" "$out/${value.mode}_${name}"
+          '')
+          cfg.hooks)));
+
+  mkHook = mode: deps: path: {
+    inherit mode;
+
+    executable = pkgs.writeShellApplication {
+      name = "add-hook-${builtins.baseNameOf path}";
+      runtimeInputs = [pkgs.taskwarrior3 pkgs.coreutils pkgs.gnugrep] ++ deps;
+      inheritPath = false;
+      text =
+        # bash
+        ''
+          die() {
+            echo "$@">&2
+            exit 1
+          }
+
+          enable_hook_dbg() {
+              # TODO: We should probably be smarter with the debug detection <2025-04-04>
+              if echo "$2" | grep --quiet 'rc.debug.hooks='; then
+                set -x
+                mkdir --parents "$HOME/.cache/task"
+                exec >>"$HOME/.cache/task/hook.log.$1"
+                exec 2>>"$HOME/.cache/task/hook.log.$1"
+              fi
+          }
+
+          addedCall() {
+           ${builtins.readFile path}
+          }
+
+          ${
+            if mode == "on-modify"
+            then "read -r old_task"
+            else "old_task=NULL"
+          }
+          read -r new_task
+          # We don't change the task, thus immediately return the JSON
+          echo "$new_task"
+
+          enable_hook_dbg "$@"
+          addedCall "$new_task" "$old_task"
+
+          exit 0
+        '';
+    };
+  };
 in {
   options.soispha.programs.taskwarrior = {
-    enable = lib.mkEnableOption "taskwarrior-secrets";
+    enable = lib.mkEnableOption "taskwarrior";
+
+    includeFiles = lib.mkOption {
+      type = lib.types.attrsOf lib.types.path;
+      description = "Extra files to include in the taskwarrior config";
+      default = {};
+      apply = value:
+        builtins.concatStringsSep "\n"
+        (builtins.map (path: "include ${path}")
+          (builtins.attrValues value));
+    };
+
+    hooks = lib.mkOption {
+      description = "Map hook names to their values";
+      type = lib.types.attrsOf (lib.types.submodule {
+        options = {
+          mode = lib.mkOption {
+            type = lib.types.enum ["on-add" "on-modify"];
+            description = "The type of the hook";
+          };
+          executable = lib.mkOption {
+            type = lib.types.package;
+            description = "The executable to call.";
+          };
+        };
+      });
+    };
   };
 
-  # HACK: Migrating the whole `taskwarrior` setup is right now unrealistic, as the module is
-  # tightly coupled with the `firefox` module, and `neorg` script.
-  # But to work around the  fact that setting the `age` secrets in the legacy module is
-  # impossible, this module was created as work-around until the `taskwarrior` module can
-  # be fully migrated. <2024-10-18>
-  config = lib.mkIf cfg.enable {
-    age.secrets = {
-      taskserverPrivate = {
-        file = ./secrets/private.key;
-        mode = "700";
-        owner = "soispha";
-        group = "users";
-      };
-      taskserverPublic = {
-        file = ./secrets/public.cert;
-        mode = "700";
-        owner = "soispha";
-        group = "users";
-      };
-      taskserverCA = {
-        file = ./secrets/ca.cert;
-        mode = "700";
-        owner = "soispha";
-        group = "users";
+  config = {
+    lib.taskwarrior = {
+      inherit mkHook;
+    };
+
+    home-manager.users.soispha = lib.mkIf cfg.enable {
+      services.taskwarrior-sync = {
+        enable = true;
+        package = pkgs.taskwarrior3;
       };
-      taskserverCredentials = {
-        file = ./secrets/credentials;
-        mode = "700";
-        owner = "soispha";
-        group = "users";
+
+      programs.taskwarrior = {
+        enable = true;
+        colorTheme = ./nord.theme;
+        package = pkgs.taskwarrior3;
+        extraConfig = cfg.includeFiles;
+
+        config = {
+          complete.all.tags = true;
+          list.all = {
+            projects = true;
+            tags = true;
+          };
+
+          news.version = "3.4.1";
+
+          regex = true;
+          weekstart = "Monday";
+
+          uda = {
+            total_active_time = {
+              type = "duration";
+              label = "Total active time";
+            };
+          };
+
+          alias = {
+            mod = "modify";
+          };
+          color = true;
+
+          hooks.location = "${hooksDir}";
+
+          urgency.uda.priority = {
+            H.coefficient = 6.0;
+            M.coefficient = 0;
+            L.coefficient = -1.8;
+          };
+        };
       };
     };
   };
diff --git a/modules/home.legacy/conf/taskwarrior/nord.theme b/modules/by-name/ta/taskwarrior/nord.theme
index 2897418f..2897418f 100644
--- a/modules/home.legacy/conf/taskwarrior/nord.theme
+++ b/modules/by-name/ta/taskwarrior/nord.theme
diff --git a/modules/by-name/ta/taskwarrior/secrets/ca.cert b/modules/by-name/ta/taskwarrior/secrets/ca.cert
deleted file mode 100644
index 81528a2a..00000000
--- a/modules/by-name/ta/taskwarrior/secrets/ca.cert
+++ /dev/null
@@ -1,161 +0,0 @@
------BEGIN AGE ENCRYPTED FILE-----
-YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4dVVkOWlYNjJQSFZYbExM
-bENvUTFzbmdPQ0ljR2V1TlJXYUZFVnNMS3owCjNmaE5pNnZqN0FXRUtFQzZYR0xQ
-NWh0L0NLVDlEeWlvdlB1T2dwRmkybXcKLT4gc3NoLWVkMjU1MTkgelpFb25nIHR3
-TmJzS2Q4WDN4KzVkVXgyMzhiYmdId0wwSzJndmZJQUlzYm9MTW5zR3cKRmswT3RN
-QTR2VjYvVXY4TnJCNEVrY0V1c3FEK3hGMkppeWh0bEUzdEdMRQotPiBzc2gtZWQy
-NTUxOSA3SGZGVXcgY2R5WUVpdlJCVjBxR0lTMmFnY0plV0J4NUFWTk1XWnllbjlt
-OS8xS3FIVQo4MytXd054Rm5neTFsREpWTFdJc2xzLzdDckZ5M2tOelNhakMxanlY
-cTQ4Ci0+IE1Dci1ncmVhc2UgfSYwZlg0YlcKQUlENkdEalVMZ0VzTXFlUHB1Yzhr
-VWZwb1FMZFdtbm1HU01VMWtLVnB4MmlyUQotLS0gUTh6RGZ4NVRaQXppQ1ozbmlS
-U1FqSVRDOEQzZDc0NUtyN3JMMmhER1U3TQrE19bvLibjcNcMzhiPZxX9K38Lr4Xo
-TXxkclMNX1EKveHCqG8rzkkquPJar5M5PAo7UL+zXBaB63XCbuscUv1jTiTFYN7V
-hVEAoj1rpcsDslhchpra3TZWuQZuhDJw+2Ig0qaCQWCzqi+e0j6oTAwZWyo3lIB1
-jt1xik+2QAxdMae2i3CBpPdwlyWGN5rpX+CgFQg3SKpOtaE5T924GJTBdm6jSfR6
-91tNoU+8cR82tHlR1NrhoKFPqw4xKZhrIhe+WW5IqK2SB7IRsnS7hiYz+UzDQu/9
-Bvfd2RO07JH1wCphnH7l+YmTVyZSydm1gPzBwGnRtWrxZa4B6xYatTWT8CQZyg0k
-suKe9EVYb6A9+UzrfjwNKIm+1aTyy7NUPTtbJ0Qjn3NoNMZIdONXqPQnT2iSFy4G
-ym4ZvkIRoyjh3dzd3csVvHIAsdWyyUL3uvri+HeHuaTtiSpyUl5hzHnjQyKgubI4
-rIfrSYtqsA76scj8HsMQ9DaQsGnEtIbvUAHemTKKVDnozY1vrO2RNg4CtAyRRfbl
-DnITU9S5V5CzMZdnUnq0qeVyKG/amPnDuEhk/IyaaLOM7T7Zl2PuT6T+Dckmj6GV
-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
------END AGE ENCRYPTED FILE-----
diff --git a/modules/by-name/ta/taskwarrior/secrets/credentials b/modules/by-name/ta/taskwarrior/secrets/credentials
deleted file mode 100644
index f3aaf502..00000000
--- a/modules/by-name/ta/taskwarrior/secrets/credentials
+++ /dev/null
@@ -1,15 +0,0 @@
------BEGIN AGE ENCRYPTED FILE-----
-YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqdGQ3a0pWb3lvZXFWbTFQ
-UG1JbGREZW9SS3ZuWXJhbTdvTTBqZUdhN0Q0CjF1cnJFM1d2ZFNyRW44Rzlvamlz
-VWQycXhmWnB4L1hiSE5qbFozWFlGMU0KLT4gc3NoLWVkMjU1MTkgelpFb25nIEFk
-bVQ3U3BsU1FkeWxBY0sySTV2UkxocXJpVXMyd1FrMXA3YUR0NWtTR1kKeUtHODVy
-aXE3aXh4WkFmYTJtdlZyZ1A1QlhYZGZuTUYxYVVlblRUV1BqOAotPiBzc2gtZWQy
-NTUxOSA3SGZGVXcgdGR4cFMya3p6TEx5cnhYcWNXR2FlVEk3UTBEcHQ3Y3RmK0lY
-YlpwRXJGcwpwZUVqODB3SUZUdTlQVW4yaWlZaTE0RE9OT1dLanZlSGV6cnlJRElQ
-UjBBCi0+ICFALWdyZWFzZSB0MFU2IDZoIEJPWUZIP1sKN1l2dzdWN1JDbEhEeXBq
-THV0cWJIV1RLalVsVVp3RCtwbk5NS2pnd3kxS1RhNTNaa3pqWXZFVm9FM2N2cFp5
-TQpYR2MKLS0tIEhLQWdwL0VoT1ZGNU5UUWs0SVVqK0ZQTndkTURPb0VtNEtJN3or
-S0Q0K1UKRfhyrcVb0EbsKj9gL5kqaIpfrsWd2cizrVQ67y9ZOwWilWgk/gkoXadf
-q7QeYjnWsHeIVtSZIaHSa8+9pvKAwiYW+B6DjRi7EXkCYz8zGeanMuoKA4by5Q9x
-VMKJlWk7c0WIzSuviw==
------END AGE ENCRYPTED FILE-----
diff --git a/modules/by-name/ta/taskwarrior/secrets/private.key b/modules/by-name/ta/taskwarrior/secrets/private.key
deleted file mode 100644
index 64f925fb..00000000
--- a/modules/by-name/ta/taskwarrior/secrets/private.key
+++ /dev/null
@@ -1,449 +0,0 @@
------BEGIN AGE ENCRYPTED FILE-----
-YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBncVlhL2RhS3JNaWFIKzl5
-VFV2Y3dZRkE2SlFvV25wd2NRU0NVN1Z0T2pBCmpRM2FJSUpPMGpQRE5EZHR5NElu
-UlBLcE9EWVBRSHA4eTRTNHpDaDdIOHMKLT4gc3NoLWVkMjU1MTkgelpFb25nIGlC
-cGR2aytobjcxV0xJMUc4d1VseUN2K3NoMEx4UnIzRGZvOTZoNHJVaGMKYWV3TVAw
-RWJzN3NnOHo3QnZSL3JvbTFxWG9zQmtISzRIMDJXVXg4U1kvZwotPiBzc2gtZWQy
-NTUxOSA3SGZGVXcgV0E4b05Kc3FwRXdFT3Y4c1VmTi83QXFxSXViVVVORTRMMms0
-cVpzMEd6ZwphazBuREVxSWxMcFJUYUplQXFOQkVjM2hUSytMUmN0d1dsM21lOGE1
-SkhNCi0+IE57XS1ncmVhc2UKN0RPSGRMOG5YSUZNblphWXg3MUxyNVVyS2RocnAw
-SFlsbG5PZzlWNndtL016WnFraXhWNHhaV1hwK3F1NCtDVQpSMm5vcjk5M282UUk1
-c1BjMHdCSjlkdmxQM1NKdzFVUG53Ci0tLSBlbE9TSUV2Tmxlc1FhaWZZU0hWQVdX
-SnNnWFUvWEcwSmppdCsvQUxWVGlvCqDjHDzuQfNWNpnVCLFdErXs5Xp1tedq+HIK
-/os5NEoGXikwdJTi0QMbBJwe/jKtf6WNEz/CX/sNCRg2qHGLZFFOuTZ+daIhfx3U
-kO3rA0pZzN1nyVwZhWSs63SOnooAUjfMzIcnDnu0qfGKXUAf1VmKxrqx5r/g4Sk3
-pYj383uWylTkrCo1OA4Hq02ynCosS+rDtyMb+mO8v2MxhG/r5noMO9YbBA7DOKtv
-Rp2Ji8vdrvUnsLMBWBZsdFr0mpg7adoraCRIerpbJAG5LpA3QsHS8rjymn9RDLH3
-CogNs5NcYEjIj2sf+1/pLUqlUb6BEog/4QLD9aRIoQECwNTIMHRtwq09V3YkOEB+
-UXCTnfdDyqj+DlADFfRmu82P32E/VcS9MH0WHSKuVCiNa6Vzljowrt9JUXVxXKbs
-+ae8+qnQA/rOInWMG94ypFBH+fcYuso0rFSLU40MSUZtZmBHa1TYJ0md4U5V7Fnp
-0OpL7PNnoxh1fdlTwDJ7zGOUyijTl15dPbAdzSiqm0mYmXms0BzPkubOMbAsiKmu
-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
-Mfoar9/TM+perLNXW3/cOII8+LiNVz8y+Vc=
------END AGE ENCRYPTED FILE-----
diff --git a/modules/by-name/ta/taskwarrior/secrets/public.cert b/modules/by-name/ta/taskwarrior/secrets/public.cert
deleted file mode 100644
index d20ef291..00000000
--- a/modules/by-name/ta/taskwarrior/secrets/public.cert
+++ /dev/null
@@ -1,83 +0,0 @@
------BEGIN AGE ENCRYPTED FILE-----
-YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkQVJNM1RDMEp0NkM1dzlF
-UE42amNBaERmanAyUDNFSlFlUWszb3hiMWtVCllKSml4QVBGT293U3lmaEo2YVVn
-TGdRcllMOFI5WXJsL3ZvdnpIeS9UZjgKLT4gc3NoLWVkMjU1MTkgelpFb25nIEVE
-WnJYU28wdThLWEJlYlpSeDM5eklZR05aR0dpVnN0QjFCU3hueW9NR0UKSXhlV2oy
-b3BWaDQ0K1R2YVZhbjVjZHkyWTQwNGZ6K09QcHJwcFN2S2doRQotPiBzc2gtZWQy
-NTUxOSA3SGZGVXcgemg3dWV3emhNSjdIOVRqYk1mSHdMUnk4bnpBUWZZTkZlY0tG
-aUVkWUt6bwpDRmhKNlU3NGNCQzdNQmsvUndQQ3c2VHRab0h2NDl6MVdlb1BncnRo
-ME1NCi0+ID0tZ3JlYXNlCk9OOVlwMmlONmN1aUNScmNwT3drVHBUc1dqb0FuNUU3
-UWoxNy9SRUp3NDFXRFh6WE0zdUVJMnVCemVkUmtpamcKd3BEb1VtajcxUQotLS0g
-YVo1S1JLQmQrZkIzMmE1YlFCMGlHNElaSXdCR0VBU3pNYS8xSGtFRlpwWQp2we4U
-b9JZk9snxRROCHh9w0nfIDwqGsR8+mFScXDHZAT5pji2nlJncjOToUUf6kqDY3EH
-+UzfvxUZrzF0LZxhlJEApmeo5ObuexQqtm6M4mg8Sx+3XoTHM/07xWB464eKSyGw
-4xBzR0Lj21XUBdfbM3gBAY2J4kvZwPyD0ygun+x+JesJFWgkezh5Vn/oY7bCtgE5
-VjFKR7+kSltBeK7PiqafiukuF/0KRsTDg02FryCCH4nGcjeZeqhs5k2B/56Mxd89
-MD1K/tw4lkvrZ09gLdCN7bY8d72WMQ+Qbilrf5InJsLaUn3dloeyQgJiR9LUkwP0
-b1jZWsUgWOeHfwKUhFoPW4b8VVT8PV3SaLgeoCtoW3ZME+Yv3T7NJZupq57KGcYo
-XgDl8XOG2GjL2UIqp7i7cQFt8KuZxRs2259e8Jf1shyHr34Qw18UpL01++DkZbS3
-f6SucDAbak57CS+qHxLzTqtZT6kLQhfY3yF8QTXcdVC7hMbGNar8TaqIe6SQ1HCT
-HHFRHZ4hj/VVdVlaOLHBvIokFkZE85tTiyjW/llkyfQWH2z+Dwctou6nUBzPgNNF
-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
-dw==
------END AGE ENCRYPTED FILE-----
diff --git a/modules/by-name/ti/timewarrior/module.nix b/modules/by-name/ti/timewarrior/module.nix
new file mode 100644
index 00000000..f33d02be
--- /dev/null
+++ b/modules/by-name/ti/timewarrior/module.nix
@@ -0,0 +1,88 @@
+{
+  config,
+  lib,
+  pkgs,
+  ...
+}: let
+  cfg = config.soispha.programs.timewarrior;
+
+  track_timewarrior = pkgs.stdenv.mkDerivation {
+    name = "track-timewarrior";
+    nativeBuildInputs = [
+      pkgs.makeWrapper
+    ];
+    buildInputs = [
+      pkgs.timewarrior
+      pkgs.taskwarrior3
+      pkgs.python3
+    ];
+    dontUnpack = true;
+    installPhase = ''
+      install -Dm755 ${./taskwarrior_hooks/on-modify.track-timewarrior.py} $out/bin/track-timewarrior
+      wrapProgram $out/bin/track-timewarrior \
+      --set PATH ${lib.makeBinPath [pkgs.taskwarrior3 pkgs.timewarrior]}
+    '';
+
+    meta.mainProgram = "track-timewarrior";
+  };
+  track_total_active_time = pkgs.stdenv.mkDerivation {
+    name = "track-total-active-time";
+    nativeBuildInputs = [
+      pkgs.makeWrapper
+    ];
+    buildInputs = [
+      pkgs.taskwarrior3
+      pkgs.python3
+    ];
+    dontUnpack = true;
+    installPhase = ''
+      install -Dm755 ${./taskwarrior_hooks/on-modify.track-total-active-time.py} $out/bin/track-total-active-time
+      wrapProgram $out/bin/track-total-active-time \
+      --set PATH ${lib.makeBinPath [pkgs.taskwarrior3]}
+    '';
+
+    meta.mainProgram = "track-total-active-time";
+  };
+in {
+  options.soispha.programs.timewarrior = {
+    enable = lib.mkEnableOption "timewarrior";
+  };
+  config = lib.mkIf cfg.enable {
+    soispha.programs.taskwarrior = {
+      hooks = {
+        track-timewarrior = {
+          mode = "on-modify";
+          executable = track_timewarrior;
+        };
+        track-total-active-time = {
+          mode = "on-modify";
+          executable = track_total_active_time;
+        };
+      };
+    };
+
+    home-manager.users.soispha = {
+      home.packages = [
+        pkgs.timewarrior
+      ];
+
+      xdg.configFile."timewarrior/timewarrior.cfg".text = ''
+        # source: https://github.com/arcticicestudio/igloo
+        #+----+
+        #+ UI +
+        #+----+
+        import ${./nord.theme}
+        color = true
+
+        #+---------+
+        #+ Reports +
+        #+---------+
+        define reports:
+          day:
+            lines = 10
+            month = true
+            week = true
+      '';
+    };
+  };
+}
diff --git a/modules/home.legacy/conf/timewarrior/nord.theme b/modules/by-name/ti/timewarrior/nord.theme
index da3c387a..da3c387a 100644
--- a/modules/home.legacy/conf/timewarrior/nord.theme
+++ b/modules/by-name/ti/timewarrior/nord.theme
diff --git a/modules/by-name/ti/timewarrior/taskwarrior_hooks/on-modify.track-timewarrior.py b/modules/by-name/ti/timewarrior/taskwarrior_hooks/on-modify.track-timewarrior.py
new file mode 100755
index 00000000..0bef8bc2
--- /dev/null
+++ b/modules/by-name/ti/timewarrior/taskwarrior_hooks/on-modify.track-timewarrior.py
@@ -0,0 +1,124 @@
+#!/usr/bin/env python3
+
+###############################################################################
+#
+# Copyright 2016 - 2021, 2023, Gothenburg Bit Factory
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+# https://www.opensource.org/licenses/mit-license.php
+#
+###############################################################################
+
+import json
+import subprocess
+import sys
+
+# Hook should extract all the following for use as Timewarrior tags:
+#   UUID
+#   Project
+#   Tags
+#   Description
+#   UDAs
+
+try:
+    input_stream = sys.stdin.buffer
+except AttributeError:
+    input_stream = sys.stdin
+
+
+MAX_ACTIVE = 1
+
+
+def extract_tags_from(json_obj) -> [str]:
+    # Extract attributes for use as tags.
+    tags = [json_obj["description"]]
+
+    if "project" in json_obj:
+        tags.append(json_obj["project"])
+
+    if "tags" in json_obj:
+        if type(json_obj["tags"]) is str:
+            # Usage of tasklib (e.g. in taskpirate) converts the tag list into a string
+            # If this is the case, convert it back into a list first
+            # See https://github.com/tbabej/taskpirate/issues/11
+            tags.extend(json_obj["tags"].split(","))
+        else:
+            tags.extend(json_obj["tags"])
+
+    return tags
+
+
+def extract_annotation_from(json_obj):
+    if "annotations" not in json_obj:
+        return "''"
+
+    return json_obj["annotations"][0]["description"]
+
+
+def main(old, new):
+    start_or_stop = ""
+
+    # Started task.
+    if "start" in new and "start" not in old:
+        # Prevent this task from starting if "task +ACTIVE count" is greater than "MAX_ACTIVE".
+        p = subprocess.Popen(
+            ["task", "+ACTIVE", "status:pending", "count", "rc.verbose:off"],
+            stdout=subprocess.PIPE,
+        )
+        out, err = p.communicate()
+        count = int(out.rstrip())
+        if count >= MAX_ACTIVE:
+            print(
+                f"Only {MAX_ACTIVE} task(s) can be active at a time.",
+            )
+            sys.exit(1)
+        else:
+            start_or_stop = "start"
+
+    # Stopped task.
+    elif ("start" not in new or "end" in new) and "start" in old:
+        start_or_stop = "stop"
+
+    if start_or_stop:
+        tags = extract_tags_from(new)
+
+        subprocess.call(["timew", start_or_stop] + tags + [":yes"])
+
+    # Modifications to task other than start/stop
+    elif "start" in new and "start" in old:
+        old_tags = extract_tags_from(old)
+        new_tags = extract_tags_from(new)
+
+        if old_tags != new_tags:
+            subprocess.call(["timew", "untag", "@1"] + old_tags + [":yes"])
+            subprocess.call(["timew", "tag", "@1"] + new_tags + [":yes"])
+
+        old_annotation = extract_annotation_from(old)
+        new_annotation = extract_annotation_from(new)
+
+        if old_annotation != new_annotation:
+            subprocess.call(["timew", "annotate", "@1", new_annotation])
+
+
+if __name__ == "__main__":
+    old = json.loads(input_stream.readline().decode("utf-8", errors="replace"))
+    new = json.loads(input_stream.readline().decode("utf-8", errors="replace"))
+    print(json.dumps(new))
+    main(old, new)
diff --git a/modules/home.legacy/conf/taskwarrior/hooks/scripts/on-modify_track-total-active-time.py b/modules/by-name/ti/timewarrior/taskwarrior_hooks/on-modify.track-total-active-time.py
index d5b380d0..0b6be082 100755
--- a/modules/home.legacy/conf/taskwarrior/hooks/scripts/on-modify_track-total-active-time.py
+++ b/modules/by-name/ti/timewarrior/taskwarrior_hooks/on-modify.track-total-active-time.py
@@ -20,37 +20,24 @@ By default, this plugin allows to have one task active at a time. This can be ch
 ``1``.
 
 Note:
-    This hook requires Python 3 and the `taskw`_ package to be installed which provides the python bindings for Taskwarrior!
-    Also note that this hook is only compatible with Taskwarrior version greater or equal to 2.4!
+    Note that this hook is only compatible with Taskwarrior version greater or equal to 2.4!
 
 This hook is a fork from `kostajh/taskwarrior-time-tracking-hook`_
 
-.. _taskw:
-   https://pypi.python.org/pypi/taskw
 .. _kostajh/taskwarrior-time-tracking-hook:
    https://github.com/kostajh/taskwarrior-time-tracking-hook
 """
 
 import datetime
 import json
-import re
 import sys
 import subprocess
-from taskw import TaskWarrior
 from typing import TypeVar
 
 TIME_FORMAT = "%Y%m%dT%H%M%SZ"
 UDA_KEY = "total_active_time"
 
-w = TaskWarrior(config_filename=sys.argv[4].replace("rc:", ""))
-config = w.load_config(config_filename=sys.argv[4].replace("rc:", ""))
-if "max_active_tasks" in config:
-    MAX_ACTIVE = int(config["max_active_tasks"])
-else:
-    MAX_ACTIVE = 1
-
-"""Compiled regular expression for the duration as ISO-8601 formatted string."""
-ISO8601DURATION = re.compile("P((\d*)Y)?((\d*)M)?((\d*)D)?T((\d*)H)?((\d*)M)?((\d*)S)?")
+MAX_ACTIVE = 1
 
 """The duration type either as integer (in seconds), as ISO-8601 formatted string ("PT1H10M31S") or the seconds suffixed with "seconds"."""
 DurationType = TypeVar("DurationType", str, int)
@@ -63,31 +50,7 @@ def duration_str_to_time_delta(duration_str: DurationType) -> datetime.timedelta
     :return: The duration as timedelta object
     """
     if duration_str.startswith("P"):
-        match = ISO8601DURATION.match(duration_str)
-        if match:
-            year = match.group(2)
-            month = match.group(4)
-            day = match.group(6)
-            hour = match.group(8)
-            minute = match.group(10)
-            second = match.group(12)
-            value = 0
-            if second:
-                value += int(second)
-            if minute:
-                value += int(minute) * 60
-            if hour:
-                value += int(hour) * 3600
-            if day:
-                value += int(day) * 3600 * 24
-            if month:
-                # Assume a month is 30 days for now.
-                value += int(month) * 3600 * 24 * 30
-            if year:
-                # Assume a year is 365 days for now.
-                value += int(year) * 3600 * 24 * 365
-        else:
-            value = int(duration_str)
+        value = datetime.fromisoformat(duration_str)
     elif duration_str.endswith("seconds"):
         value = int(duration_str.rstrip("seconds"))
     else:
diff --git a/modules/by-name/ts/tskm/module.nix b/modules/by-name/ts/tskm/module.nix
new file mode 100644
index 00000000..51be48fe
--- /dev/null
+++ b/modules/by-name/ts/tskm/module.nix
@@ -0,0 +1,127 @@
+{
+  lib,
+  config,
+  pkgs,
+  ...
+}: let
+  cfg = config.soispha.programs.tskm;
+
+  allProjectNames = lib.lists.flatten (lib.attrsets.mapAttrsToList mkProject cfg.projects);
+
+  projectList = builtins.concatStringsSep "\n" allProjectNames;
+  mkProject = name: value: let
+    subprojects = lib.attrsets.mapAttrsToList (newName: mkProject "${name}.${newName}") value.subprojects;
+  in
+    [name] ++ subprojects;
+
+  firefoxProfiles = builtins.listToAttrs (lib.imap0 (index: name:
+    lib.attrsets.nameValuePair name {
+      inherit name;
+      # Add one here, so that we can have the default profile at id 0.
+      id = index + 1;
+    })
+  allProjectNames);
+
+  contexts =
+    builtins.concatStringsSep "\n"
+    (lib.lists.flatten
+      (lib.attrsets.mapAttrsToList mkContext cfg.projects));
+  mkContext = name: value: let
+    subprojects =
+      lib.attrsets.mapAttrsToList
+      (newName: newValue: let
+        finalValue =
+          if newValue.prefix == ""
+          then newValue // {inherit (value) prefix;}
+          else newValue;
+      in
+        mkContext "${name}.${newName}" finalValue)
+      value.subprojects;
+    contextName = builtins.replaceStrings ["."] ["_"] name;
+  in
+    [
+      ''
+        context.${contextName}.rc.neorg_path=${value.prefix}/index.norg
+        context.${contextName}.read=project:${name}
+        context.${contextName}.write=project:${name}
+      ''
+    ]
+    ++ subprojects;
+
+  contextsFile =
+    pkgs.writeText "contexts-file" contexts;
+
+  projectType = lib.types.submodule {
+    options = {
+      name = lib.mkOption {
+        type = lib.types.str;
+        example = "timesinks";
+        description = "The name of this project";
+      };
+
+      prefix = lib.mkOption {
+        type = lib.types.str;
+        default = "";
+        example = "programming/zig";
+        description = ''
+          A prefix to append to the project neorg path.
+          This can be used to group similar project's neorg directories together. '
+        '';
+      };
+
+      subprojects = lib.mkOption {
+        type = lib.types.attrsOf projectType;
+        description = ''
+          A list of subprojects.
+          These can also contain subprojects.
+        '';
+        default = {};
+      };
+    };
+  };
+in {
+  options.soispha.programs.tskm = {
+    enable = lib.mkEnableOption "tskm";
+
+    projects = lib.mkOption {
+      type = lib.types.attrsOf projectType;
+    };
+  };
+
+  config = lib.mkIf cfg.enable {
+    soispha.programs = {
+      firefox.profiles = firefoxProfiles;
+      taskwarrior = {
+        includeFiles = {
+          tskm-contexts = contextsFile;
+        };
+        hooks = {
+          enforce-projects =
+            config.lib.taskwarrior.mkHook "on-add" [
+              pkgs.jq
+              pkgs.gnugrep
+              pkgs.tskm
+            ]
+            ./taskwarrior_hooks/enforce-projects.sh;
+        };
+      };
+    };
+
+    home-manager.users.soispha = {
+      home.sessionVariables = {
+        # TODO: Remove this hard-coded path with a reference. <2025-04-04>
+        "TSKM_PROJECT_FILE" = "/home/soispha/repos/nix/config/modules/common/projects.json";
+      };
+
+      programs.nixvim = {
+        plugins.neorg.settings.load."core.dirman".config.workspaces = {
+          tskm = "~/.local/share/tskm/notes";
+        };
+      };
+
+      xdg.configFile."tskm/projects.list" = {
+        text = projectList;
+      };
+    };
+  };
+}
diff --git a/modules/by-name/ts/tskm/taskwarrior_hooks/enforce-projects.sh b/modules/by-name/ts/tskm/taskwarrior_hooks/enforce-projects.sh
new file mode 100755
index 00000000..217e6052
--- /dev/null
+++ b/modules/by-name/ts/tskm/taskwarrior_hooks/enforce-projects.sh
@@ -0,0 +1,12 @@
+#!/usr/bin/env sh
+
+new_task="$1"
+
+project="$(echo "$new_task" | jq '.project' --raw-output)"
+[ "$project" = "null" ] && die "No project supplied!"
+
+if ! tskm projects list | grep -q "^$project$"; then
+    die "The project '$project' is not (yet) registered, registered projects: $(tskm projects list | tr '\n' ',')"
+fi
+
+# vim: ft=sh
diff --git a/modules/by-name/wa/water-reminder/module.nix b/modules/by-name/wa/water-reminder/module.nix
new file mode 100644
index 00000000..39e63771
--- /dev/null
+++ b/modules/by-name/wa/water-reminder/module.nix
@@ -0,0 +1,57 @@
+{
+  config,
+  lib,
+  pkgs,
+  ...
+}: let
+  cfg = config.soispha.services.water-reminder;
+in {
+  options.soispha.services.water-reminder = {
+    enable = lib.mkEnableOption "periodic reminder for water intake";
+
+    frequency = lib.mkOption {
+      type = lib.types.str;
+      default = "*-*-* *:00/30:00"; # Every 30 minutes
+      description = ''
+        How often to remind. This value is passed to the systemd
+        timer configuration as the `OnCalendar` option. See
+        {manpage}`systemd.time(7)` for more information about the format.
+      '';
+    };
+  };
+
+  config = lib.mkIf cfg.enable {
+    home-manager.users.soispha = {
+      systemd.user.services.water-reminder = {
+        Unit = {Description = "Water reminder";};
+        Service = {
+          CPUSchedulingPolicy = "idle";
+          IOSchedulingClass = "idle";
+          ExecStart = lib.getExe (
+            pkgs.writeShellApplication {
+              name = "water-reminder";
+
+              inheritPath = false;
+              runtimeInputs = [pkgs.libnotify];
+
+              text =
+                # bash
+                ''
+                  notify-send 'Seek fluid intake' 'Water intake required' --wait --expire-time=0 --urgency=critical
+                '';
+            }
+          );
+        };
+      };
+
+      systemd.user.timers.water-reminder = {
+        Unit = {Description = "periodic reminder for water intake";};
+        Timer = {
+          Unit = "water-reminder.service";
+          OnCalendar = cfg.frequency;
+        };
+        Install = {WantedBy = ["timers.target"];};
+      };
+    };
+  };
+}
diff --git a/modules/by-name/xd/xdg/module.nix b/modules/by-name/xd/xdg/module.nix
index 5140a832..f1781d86 100644
--- a/modules/by-name/xd/xdg/module.nix
+++ b/modules/by-name/xd/xdg/module.nix
@@ -1,58 +1,119 @@
 {
   pkgs,
-  nixpkgs_open_prs,
-  sysLib,
-  system,
+  lib,
+  config,
   ...
 }: let
-  pkgs_tfc = nixpkgs_open_prs.nixpkgs-tfc.legacyPackages."${system}";
+  lf-wrapper = pkgs.writeShellApplication {
+    name = "lf-wrapper";
+
+    runtimeInputs = [pkgs.lf pkgs.alacritty];
+    inheritPath = true;
+
+    text = builtins.readFile ./scripts/lf-wrapper.sh;
+  };
+
+  url-handler = pkgs.writeShellApplication {
+    name = "url-handler";
+
+    runtimeInputs = [pkgs.rofi pkgs.libnotify pkgs.zathura pkgs.tskm];
+    inheritPath = false;
+
+    text = builtins.readFile ./scripts/url-handler.sh;
+  };
+
+  tfcConfigFile = (pkgs.formats.ini {}).generate "xdg-desktop-portal-termfilechooser.ini" {
+    filechooser = {
+      default_dir = "/tmp";
+      cmd = "${lib.getExe lf-wrapper}";
+    };
+  };
+
+  cfg = config.soispha.xdg;
 in {
-  services.dbus.enable = true;
-  xdg = {
-    portal = {
-      enable = true;
-      termfilechooser = {
-        enable = true;
-        logLevel = "TRACE";
-        package = pkgs_tfc.xdg-desktop-portal-termfilechooser;
-        settings = {
-          filechooser = {
-            default_dir = "/tmp";
-            cmd = "${sysLib.writeShellScript {
-              src = ./scripts/lf_wrapper.sh;
-              name = "lf_wrapper";
-              keepPath = true;
-              dependencies = with pkgs; [
-                lf
-                alacritty
-                bash
-              ];
-            }}/bin/lf_wrapper";
+  options.soispha.xdg = {
+    enable = lib.mkEnableOption "xdg";
+  };
+
+  config = lib.mkIf cfg.enable {
+    home-manager.users.soispha = {
+      xdg = {
+        desktopEntries = {
+          url-handler = {
+            name = "url-handler";
+            genericName = "Web Browser";
+            exec = "${lib.getExe url-handler} %u";
+            terminal = false;
+            categories = [
+              "Application"
+              "Network"
+              "WebBrowser"
+            ];
+            mimeType = [
+              "text/html"
+              "text/xml"
+              "x-scheme-handler/http"
+              "x-scheme-handler/https"
+              "x-scheme-handler/about"
+              "x-scheme-handler/unknown"
+            ];
           };
         };
       };
-      wlr = {
+    };
+
+    services.dbus.enable = true;
+
+    xdg = {
+      mime = {
         enable = true;
+        defaultApplications = {
+          "application/pdf" = ["url-handler.desktop"];
+          "application/x-pdf" = ["url-handler.desktop"];
+
+          "text/html" = ["url-handler.desktop"];
+          "text/xml" = ["url-handler.desktop"];
+          "x-scheme-handler/http" = ["url-handler.desktop"];
+          "x-scheme-handler/https" = ["url-handler.desktop"];
+          "x-scheme-handler/about" = ["url-handler.desktop"];
+          "x-scheme-handler/unknown" = ["url-handler.desktop"];
+        };
       };
-      config = {
-        common = {
-          # NOTE: The next entry is supposedly needed for gtk based apps <2023-08-31>
-          default = ["wlr" "gtk"];
-          "org.freedesktop.impl.portal.FileChooser" = ["termfilechooser"];
+
+      portal = {
+        enable = true;
+        wlr = {
+          enable = true;
         };
+        config = {
+          common = {
+            # NOTE: The next entry is supposedly needed for gtk based apps <2023-08-31>
+            default = ["wlr" "gtk"];
+            "org.freedesktop.impl.portal.FileChooser" = ["termfilechooser"];
+          };
 
-        # TODO: Also activate, when on another wlr-based compositor <2023-11-25>
-        river = {
-          default = ["wlr" "gtk"];
-          "org.freedesktop.impl.portal.FileChooser" = ["termfilechooser"];
+          # TODO: Also activate, when on another wlr-based compositor <2023-11-25>
+          river = {
+            default = ["wlr" "gtk"];
+            "org.freedesktop.impl.portal.FileChooser" = ["termfilechooser"];
+          };
         };
+
+        extraPortals = [
+          pkgs.xdg-desktop-portal-gtk
+          pkgs.xdg-desktop-portal-wlr
+          pkgs.xdg-desktop-portal-termfilechooser
+        ];
       };
-      extraPortals = [
-        pkgs.xdg-desktop-portal-gtk
-        pkgs.xdg-desktop-portal-wlr
-        pkgs_tfc.xdg-desktop-portal-termfilechooser
+    };
+
+    environment.etc."xdg/xdg-desktop-portal-termfilechooser/config".source = tfcConfigFile;
+
+    systemd.user.services.xdg-desktop-portal-termfilechooser = {
+      serviceConfig.ExecStart = [
+        ""
+        "${pkgs.xdg-desktop-portal-termfilechooser}/libexec/xdg-desktop-portal-termfilechooser --loglevel=TRACE"
       ];
     };
   };
-  # TODO: mime = {};
 }
diff --git a/modules/by-name/xd/xdg/scripts/lf-wrapper.sh b/modules/by-name/xd/xdg/scripts/lf-wrapper.sh
new file mode 100755
index 00000000..f85f7bac
--- /dev/null
+++ b/modules/by-name/xd/xdg/scripts/lf-wrapper.sh
@@ -0,0 +1,39 @@
+#!/usr/bin/env sh
+# This wrapper script is invoked by xdg-desktop-portal-termfilechooser.
+#
+# For more information about input/output arguments read `xdg-desktop-portal-termfilechooser(5)`
+
+set -ex
+
+multiple="$1"
+directory="$2"
+save="$3"
+path="$4"
+out="$5"
+
+# echo > /tmp/stdout
+# echo > /tmp/stderr
+#
+# exec 1>> /tmp/stdout
+# exec 2>> /tmp/stderr
+
+if [ "$save" = "1" ]; then
+    # save a file
+    set -- -selection-path="$out" -command='set promptfmt "Select the file to write to %S \033[32;1m%u@%h\033[0m:\033[34;1m%d\033[0m\033[1m%f\033[0m"' "$path"
+elif [ "$directory" = "1" ]; then
+    # upload files from a directory
+    set -- -last-dir-path="$out" -command='set dironly' -command='set promptfmt "Select directory (quit in dir to select it) %S \033[32;1m%u@%h\033[0m:\033[34;1m%d\033[0m\033[1m%f\033[0m"' "$path"
+elif [ "$multiple" = "1" ]; then
+    # upload multiple files
+    set -- -selection-path="$out" -command='set promptfmt "Select file(s) (open file to select it; <Space> to select multiple) %S \033[32;1m%u@%h\033[0m:\033[34;1m%d\033[0m\033[1m%f\033[0m"' "$path"
+else
+    # upload only 1 file
+    set -- -selection-path="$out" -command='set promptfmt "Select file (open file to select it) %S \033[32;1m%u@%h\033[0m:\033[34;1m%d\033[0m\033[1m%f\033[0m"' "$path"
+fi
+
+alacritty --title 'floating please' -e lf "$@"
+
+# Delete the left recommended file, if we did not actually save anything.
+if [ "$save" = "1" ] && ! [ -s "$out" ]; then
+    rm "$path"
+fi
diff --git a/modules/by-name/xd/xdg/scripts/lf_wrapper.sh b/modules/by-name/xd/xdg/scripts/lf_wrapper.sh
deleted file mode 100755
index 16603fe4..00000000
--- a/modules/by-name/xd/xdg/scripts/lf_wrapper.sh
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
-# This wrapper script is invoked by xdg-desktop-portal-termfilechooser.
-#
-# Inputs:
-# 1. "1" if multiple files can be chosen, "0" otherwise.
-# 2. "1" if a directory should be chosen, "0" otherwise.
-# 3. "0" if opening files was requested, "1" if writing to a file was
-#    requested. For example, when uploading files in Firefox, this will be "0".
-#    When saving a web page in Firefox, this will be "1".
-# 4. If writing to a file, this is recommended path provided by the caller. For
-#    example, when saving a web page in Firefox, this will be the recommended
-#    path Firefox provided, such as "~/Downloads/webpage_title.html".
-#    Note that if the path already exists, we keep appending "_" to it until we
-#    get a path that does not exist.
-# 5. The output path, to which results should be written.
-#
-# Output:
-# The script should print the selected paths to the output path (argument #5),
-# one path per line.
-# If nothing is printed, then the operation is assumed to have been canceled.
-
-multiple="$1"
-directory="$2"
-save="$3"
-recommended_path="$4"
-out="$5"
-
-# echo > /tmp/stdout
-# echo > /tmp/stderr
-#
-# exec 1>> /tmp/stdout
-# exec 2>> /tmp/stderr
-
-cmd="$(command -v lf)"
-termcmd="${TERMINAL:-$(command -v alacritty)}"
-
-if [ "$save" = "1" ]; then
-    set -- -selection-path="$out" -command='set promptfmt "Select the file to write to %S \033[32;1m%u@%h\033[0m:\033[34;1m%d\033[0m\033[1m%f\033[0m"' "$recommended_path"
-    cat <<EOF >"$recommended_path"
-xdg-desktop-portal-termfilechooser saving files tutorial
-
-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-!!!                 === WARNING! ===                 !!!
-!!! The contents of *whatever* file you open last in !!!
-!!!            lf will be *overwritten*!             !!!
-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-Instructions:
-1) Move this file wherever you want.
-2) Rename the file if needed.
-3) Confirm your selection by opening the file, for
-   example by pressing <Enter>.
-
-Notes:
-1) This file is provided for your convenience. You
-   could delete it and choose another file to overwrite
-   that, for example.
-2) If you quit lf without opening a file, this file
-   will be removed and the save operation aborted.
-EOF
-
-elif [ "$directory" = "1" ]; then
-    set -- -selection-path="$out" -command='set dironly' -command='set promptfmt "Select directory (quit in dir to select it) %S \033[32;1m%u@%h\033[0m:\033[34;1m%d\033[0m\033[1m%f\033[0m"'
-elif [ "$multiple" = "1" ]; then
-    set -- -selection-path="$out" -command='set promptfmt "Select file(s) (open file to select it; <Space> to select multiple) %S \033[32;1m%u@%h\033[0m:\033[34;1m%d\033[0m\033[1m%f\033[0m"'
-else
-    set -- -selection-path="$out" -command='set promptfmt "Select file (open file to select it) %S \033[32;1m%u@%h\033[0m:\033[34;1m%d\033[0m\033[1m%f\033[0m"'
-fi
-
-"$termcmd" --title 'floating please' -e "$cmd" "$@"
-
-if [ "$save" = "1" ] && [ ! -s "$out" ]; then
-    rm "$recommended_path"
-fi
-# vim: ft=sh
diff --git a/modules/by-name/xd/xdg/scripts/ranger_wrapper.sh b/modules/by-name/xd/xdg/scripts/ranger_wrapper.sh
deleted file mode 100755
index e148bf19..00000000
--- a/modules/by-name/xd/xdg/scripts/ranger_wrapper.sh
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-# This wrapper script is invoked by xdg-desktop-portal-termfilechooser.
-#
-# Inputs:
-# 1. "1" if multiple files can be chosen, "0" otherwise.
-# 2. "1" if a directory should be chosen, "0" otherwise.
-# 3. "0" if opening files was requested, "1" if writing to a file was
-#    requested. For example, when uploading files in Firefox, this will be "0".
-#    When saving a web page in Firefox, this will be "1".
-# 4. If writing to a file, this is recommended path provided by the caller. For
-#    example, when saving a web page in Firefox, this will be the recommended
-#    path Firefox provided, such as "~/Downloads/webpage_title.html".
-#    Note that if the path already exists, we keep appending "_" to it until we
-#    get a path that does not exist.
-# 5. The output path, to which results should be written.
-#
-# Output:
-# The script should print the selected paths to the output path (argument #5),
-# one path per line.
-# If nothing is printed, then the operation is assumed to have been canceled.
-
-multiple="$1"
-directory="$2"
-save="$3"
-path="$4"
-out="$5"
-
-cmd="$(command -v ranger)"
-termcmd="${TERMCMD:-$(command -v kitty)}"
-
-if [ "$save" = "1" ]; then
-    set -- --choosefile="$out" --cmd='echo Select save path (see tutorial in preview pane; try pressing zv or zp if no preview)' "$path"
-    printf '%s' 'xdg-desktop-portal-termfilechooser saving files tutorial
-
-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-!!!                 === WARNING! ===                 !!!
-!!! The contents of *whatever* file you open last in !!!
-!!! ranger will be *overwritten*!                    !!!
-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-Instructions:
-1) Move this file wherever you want.
-2) Rename the file if needed.
-3) Confirm your selection by opening the file, for
-   example by pressing <Enter>.
-
-Notes:
-1) This file is provided for your convenience. You
-   could delete it and choose another file to overwrite
-   that, for example.
-2) If you quit ranger without opening a file, this file
-   will be removed and the save operation aborted.
-' >"$path"
-elif [ "$directory" = "1" ]; then
-    set -- --choosedir="$out" --show-only-dirs --cmd="echo Select directory (quit in dir to select it)"
-elif [ "$multiple" = "1" ]; then
-    set -- --choosefiles="$out" --cmd="echo Select file(s) (open file to select it; <Space> to select multiple)"
-else
-    set -- --choosefile="$out" --cmd="echo Select file (open file to select it)"
-fi
-
-"$termcmd" -- "$cmd" "$@"
-if [ "$save" = "1" ] && [ ! -s "$out" ]; then
-    rm "$path"
-fi
diff --git a/modules/by-name/xd/xdg/scripts/url-handler.sh b/modules/by-name/xd/xdg/scripts/url-handler.sh
new file mode 100755
index 00000000..804a0450
--- /dev/null
+++ b/modules/by-name/xd/xdg/scripts/url-handler.sh
@@ -0,0 +1,18 @@
+#!/usr/bin/env sh
+
+project="$({
+    tskm projects list
+    echo nvim zathura
+} | rofi -sep "$(printf "\n")" -dmenu)"
+
+if [ "$project" = "nvim" ]; then
+    "$TERMINAL" -e nvim "$1"
+elif [ "$project" = "zathura" ]; then
+    zathura "$1"
+elif [ "$project" ]; then
+    tskm open project "$project" "$1"
+else
+    notify-send "(URL HANDLER) No project selected"; exit 1
+fi
+
+# vim: ft=sh
diff --git a/modules/by-name/yt/yt/input.conf b/modules/by-name/yt/yt/input.conf
index 10e453a1..68dad824 100644
--- a/modules/by-name/yt/yt/input.conf
+++ b/modules/by-name/yt/yt/input.conf
@@ -7,8 +7,8 @@ D script-message yt-description-local
 WHEEL_LEFT playlist-prev
 WHEEL_RIGHT playlist-next
 
-q script-message yt-mark-done-and-go-next
-Q script-message yt-mark-watch-later
+q script-message yt-mark-watched
+Q script-message yt-mark-picked
 r script-message yt-check-new-videos
 
 P quit
diff --git a/modules/by-name/yt/yt/mpv.conf b/modules/by-name/yt/yt/mpv.conf
index b6d2501f..52a40823 100644
--- a/modules/by-name/yt/yt/mpv.conf
+++ b/modules/by-name/yt/yt/mpv.conf
@@ -1,2 +1 @@
-speed=2.7
 volume=75
diff --git a/modules/by-name/zs/zsh/module.nix b/modules/by-name/zs/zsh/module.nix
index 833da126..b50e72ac 100644
--- a/modules/by-name/zs/zsh/module.nix
+++ b/modules/by-name/zs/zsh/module.nix
@@ -6,106 +6,136 @@
   ...
 }: let
   cfg = config.soispha.programs.zsh;
-  homeConfig = config.home-manager.users.soispha;
+
+  zDotDir = ".config/zsh";
 
   sourceFile = path: "source ${path}\n";
+
+  extraFiles = builtins.concatStringsSep "\n" (
+    builtins.map sourceFile (
+      builtins.attrValues cfg.integrations
+    )
+  );
 in {
   options.soispha.programs.zsh = {
     enable = lib.mkEnableOption "zsh";
-  };
-
-  config.home-manager.users.soispha = lib.mkIf cfg.enable {
-    home.sessionPath = [];
-
-    programs.zsh = {
-      enable = true;
-      enableCompletion = true;
-      autosuggestion = {
-        enable = true;
-        strategy = [];
-      };
-      syntaxHighlighting.enable = true;
 
-      autocd = true;
+    integrations = lib.mkOption {
+      type = lib.types.attrsOf lib.types.path;
+      example = ''
+        {
+          atuin = ./integrations/atuin.zsh;
+        }
+      '';
+      default = {};
+    };
+  };
 
-      # Must be relative to the users home directory (for whatever reason)
-      # Thus no `${homeConfig.xdg.configHome}`
-      dotDir = ".config/zsh";
+  config = lib.mkIf cfg.enable {
+    environment.variables = {
+      ZDOTDIR = "${config.home-manager.users.soispha.home.homeDirectory}/${zDotDir}";
+    };
 
-      # TODO: Remove the whole history and replace it completely with `atuin` <2024-10-21>
-      history = {
-        path = "/dev/null";
-        # save = 0; # number of lines to save
-        # size = 0; # number of lines to keep
-        # share = false; # share between sessions
-      };
+    home-manager.users.soispha = {
+      home.sessionPath = lib.mkForce [];
 
-      loginExtra =
-        # bash
-        ''
-          setopt AUTO_CD
-          setopt AUTO_PUSHD
-          setopt CHASE_DOTS
-
-          setopt ALWAYS_TO_END
-
-          setopt EXTENDED_HISTORY
-          setopt HIST_ALLOW_CLOBBER
-          setopt HIST_VERIFY
-          setopt HIST_FCNTL_LOCK
-          setopt APPEND_HISTORY
-
-          setopt DVORAK
-          setopt CORRECT
-
-          setopt PROMPT_SUBST
-          setopt TRANSIENT_RPROMPT # maybe?
-
-          setopt COMBINING_CHARS
-          setopt VI
-        '';
-
-      initExtraFirst =
-        sourceFile ./config/zsh-init.zsh
-        + ''
-          SHELL_LIBRARY_VERSION="2.1.2" source ${shell_library.rawLib.${system}}
-        '';
-
-      initExtra = let
-        start = lib.modules.mkBefore (
-          # NOTE: This must be before the insult, as we otherwise override the previous handler <2024-02-28>
-          sourceFile ./config/command_not_found/command_not_found.sh
-          + sourceFile ./config/command_not_found/command_not_found_insult.sh
-          + sourceFile ./config/custom_cursor.zsh
-          + sourceFile ./config/edit_command_line.zsh
-          + sourceFile ./plugins/zsh-history-substring-search.zsh
-        );
-        end = lib.modules.mkAfter (
-          sourceFile ./config/keymaps_start.zsh
-          + sourceFile ./config/keymaps/command.zsh
-          + sourceFile ./config/keymaps/emacs.zsh
-          + sourceFile ./config/keymaps/isearch.zsh
-          + sourceFile ./config/keymaps/vicmd.zsh
-          + sourceFile ./config/keymaps/viins.zsh
-          + sourceFile ./config/keymaps/viopp.zsh
-          + sourceFile ./config/keymaps/visual.zsh
-          + sourceFile ./config/keymaps_end.zsh
-        );
-      in
-        lib.modules.mkMerge
-        [
-          start
-          end
-        ];
-
-      localVariables = {
-        HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND = "bg=cyan,fg=white";
-        HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND = "fg=red,underline,standout,bold";
-      };
+      # This just includes a `source ~/.config/zsh/.zshenv`, because home-manger by-default
+      # can't access the root `/etc/zshenv`. We can and thus, we can remove this file.
+      home.file.".zshenv".enable = false;
 
-      shellAliases = {
-        ll = ". ll";
-        lm = ". lm";
+      programs.zsh = {
+        enable = true;
+        enableCompletion = true;
+        autosuggestion = {
+          enable = true;
+          strategy = [];
+        };
+        syntaxHighlighting.enable = true;
+
+        autocd = true;
+
+        # Must be relative to the users home directory (for whatever reason)
+        # Thus no `${homeConfig.xdg.configHome}`
+        dotDir = zDotDir;
+
+        # TODO: Remove the whole history and replace it completely with `atuin` <2024-10-21>
+        history = {
+          path = "/dev/null";
+          # save = 0; # number of lines to save
+          # size = 0; # number of lines to keep
+          # share = false; # share between sessions
+        };
+
+        loginExtra =
+          # bash
+          ''
+            setopt AUTO_CD
+            setopt AUTO_PUSHD
+            setopt CHASE_DOTS
+
+            setopt ALWAYS_TO_END
+
+            setopt EXTENDED_HISTORY
+            setopt HIST_ALLOW_CLOBBER
+            setopt HIST_VERIFY
+            setopt HIST_FCNTL_LOCK
+            setopt APPEND_HISTORY
+
+            setopt DVORAK
+            setopt CORRECT
+
+            setopt PROMPT_SUBST
+            setopt TRANSIENT_RPROMPT # maybe?
+
+            setopt COMBINING_CHARS
+            setopt VI
+          '';
+
+        initExtraFirst =
+          sourceFile ./config/zsh-init.zsh
+          + ''
+            SHELL_LIBRARY_VERSION="2.1.2" source ${shell_library.rawLib.${system}}
+          '';
+
+        initExtra = let
+          start = lib.modules.mkBefore (
+            # NOTE: This must be before the insult, as we otherwise override the previous handler <2024-02-28>
+            sourceFile ./config/command_not_found/command_not_found.sh
+            + sourceFile ./config/command_not_found/command_not_found_insult.sh
+            + sourceFile ./config/custom_cursor.zsh
+            + sourceFile ./config/edit_command_line.zsh
+            + sourceFile ./plugins/zsh-history-substring-search.zsh
+          );
+          end = lib.modules.mkAfter (
+            sourceFile ./config/keymaps_start.zsh
+            + sourceFile ./config/keymaps/command.zsh
+            + sourceFile ./config/keymaps/emacs.zsh
+            + sourceFile ./config/keymaps/isearch.zsh
+            + sourceFile ./config/keymaps/vicmd.zsh
+            + sourceFile ./config/keymaps/viins.zsh
+            + sourceFile ./config/keymaps/viopp.zsh
+            + sourceFile ./config/keymaps/visual.zsh
+            + sourceFile ./config/keymaps_end.zsh
+          );
+        in
+          lib.modules.mkMerge
+          [
+            start
+
+            extraFiles
+
+            end
+          ];
+
+        localVariables = {
+          HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND = "bg=cyan,fg=white";
+          HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND = "fg=red,underline,standout,bold";
+        };
+
+        shellAliases = {
+          ll = ". ll";
+          lm = ". lm";
+        };
       };
     };
   };
diff --git a/modules/home.legacy/files/wallpaper/abstract-nord.png b/modules/common/abstract-nord.png
index 5ef498bf..5ef498bf 100644
--- a/modules/home.legacy/files/wallpaper/abstract-nord.png
+++ b/modules/common/abstract-nord.png
Binary files differdiff --git a/flake/nixosConfigurations/common.nix b/modules/common/default.nix
index b8601c75..1c00c710 100644
--- a/flake/nixosConfigurations/common.nix
+++ b/modules/common/default.nix
@@ -3,6 +3,7 @@
 {
   config,
   pkgs,
+  lib,
   ...
 }: {
   soispha = {
@@ -28,6 +29,7 @@
     };
     polkit.enable = true;
     power.enable = true;
+    xdg.enable = true;
 
     services = {
       adb = {
@@ -55,6 +57,7 @@
       printing.enable = true;
       scanning.enable = true;
       snapper.enable = true;
+      water-reminder.enable = true;
       steam.enable = false;
       systemDiff.enable = true;
       unison = {
@@ -88,7 +91,6 @@
           "~/.local/share"
           "~/.local/.Trash-1000"
 
-          "~/.mozilla/.Trash-1000"
           "~/.mozilla/firefox"
 
           "~/media"
@@ -104,12 +106,97 @@
         shell = pkgs.zsh;
       };
       atuin.enable = true;
+      cargo.enable = true;
+      direnv.enable = true;
       git.enable = true;
       imv.enable = true;
       less.enable = true;
       lf.enable = true;
-      river.enable = true;
-      taskwarrior.enable = true;
+      river = {
+        enable = true;
+        init = {
+          rules = [
+            {
+              app-id = "float";
+              title = "*";
+              action = "float";
+            }
+            {
+              app-id = "mpv";
+              title = "*";
+              action = "float";
+            }
+            {
+              app-id = "ModernGL";
+              title = "*";
+              action = "float";
+            }
+            {
+              app-id = "*";
+              title = "Manim Slides";
+              action = "float";
+            }
+            {
+              app-id = "*";
+              title = "floating please";
+              action = "float";
+            }
+
+            {
+              app-id = "*";
+              title = "*";
+              action = "ssd";
+            }
+            # This remove the focus border around Firefox (which is useful because the Firefox is nearly always in its own tag.)
+            {
+              app-id = "firefox";
+              title = "*";
+              action = "csd";
+            }
+          ];
+          generalSettings = {
+            # background
+            background-color = "0x002b36";
+            border-color-focused = "0x93a1a1";
+            border-color-unfocused = "0x586e75";
+
+            # keyboard repeat rate
+            set-repeat = ["50" "300"];
+
+            # Cursor
+            focus-follows-cursor = "normal";
+            # hide-cursor = ["timeout" "2000"];
+            hide-cursor = ["when-typing" "enabled"];
+            set-cursor-warp = "on-output-change";
+            xcursor-theme = ["Nordzy-cursors" "24"];
+          };
+          inputs = {
+            pointer-1133-49970-Logitech_Gaming_Mouse_G502 = [["pointer-accel" "0"] ["accel-profile" "none"]];
+            pointer-12951-6505-ZSA_Technology_Labs_Moonlander_Mark_I = [["pointer-accel" "0"] ["accel-profile" "none"]];
+          };
+          backgroundStart = [
+            pkgs.gammastep
+            pkgs.yambar
+
+            pkgs.mako
+            ["${lib.getExe pkgs.swaybg}" "--image" "${./abstract-nord.png}"]
+            pkgs.swayidle
+            pkgs.alacritty
+          ];
+        };
+      };
+      firefox.enable = true;
+      mpv.enable = true;
+      swaylock.enable = true;
+      timewarrior.enable = true;
+      taskwarrior = {
+        enable = true;
+        hooks = import ./hooks {inherit pkgs lib config;};
+      };
+      tskm = {
+        enable = true;
+        projects = builtins.fromJSON (builtins.readFile ./projects.json);
+      };
       yambar.enable = true;
       yt.enable = true;
       zathura.enable = true;
diff --git a/modules/common/hooks/default.nix b/modules/common/hooks/default.nix
new file mode 100644
index 00000000..e2d12807
--- /dev/null
+++ b/modules/common/hooks/default.nix
@@ -0,0 +1,8 @@
+{
+  pkgs,
+  lib,
+  config,
+}: {
+  sync-git-repos = config.lib.taskwarrior.mkHook "on-add" [pkgs.git] ./scripts/sync-git-repo.sh;
+  sync-git-repos-mod = config.lib.taskwarrior.mkHook "on-modify" [pkgs.git] ./scripts/sync-git-repo.sh;
+}
diff --git a/modules/common/hooks/scripts/sync-git-repo.sh b/modules/common/hooks/scripts/sync-git-repo.sh
new file mode 100755
index 00000000..ad7368f3
--- /dev/null
+++ b/modules/common/hooks/scripts/sync-git-repo.sh
@@ -0,0 +1,13 @@
+#!/usr/bin/env sh
+
+task_data="$(task _get rc.data.location)"
+[ "$task_data" ] || die "Taskwarrior should have a location set"
+
+cd "$task_data" || die "(BUG?): Your data.location path is not accessable"
+
+[ -d ./.git/ ] || git init
+
+git add .
+git commit --message="chore: Update" --no-gpg-sign
+
+# vim: ft=sh
diff --git a/modules/common/projects.json b/modules/common/projects.json
new file mode 100644
index 00000000..48a10f03
--- /dev/null
+++ b/modules/common/projects.json
@@ -0,0 +1,132 @@
+{
+  "3d-printer": {
+    "prefix": "hardware"
+  },
+  "aoc": {
+    "prefix": "programming/advent_of_code"
+  },
+  "book": {
+    "prefix": "book"
+  },
+  "buy": {
+    "prefix": "buy",
+    "subprojects": {
+      "books": {},
+      "pc": {}
+    }
+  },
+  "camera": {
+    "prefix": "programming/zig"
+  },
+  "hardware": {
+    "prefix": "research"
+  },
+  "input": {
+    "prefix": "research",
+    "subprojects": {
+      "dotfiles": {},
+      "read-things": {}
+    }
+  },
+  "latex": {
+    "prefix": "programming/latex"
+  },
+  "me": {
+    "subprojects": {
+      "bank": {},
+      "google": {},
+      "health": {},
+      "sweden": {}
+    }
+  },
+  "possible-projects": {
+    "prefix": "research"
+  },
+  "presentation": {
+    "prefix": "research"
+  },
+  "school": {
+    "prefix": "research",
+    "subprojects": {
+      "biologie": {},
+      "chemie": {
+        "subprojects": {
+          "facharbeit": {}
+        }
+      },
+      "deutsch": {},
+      "english": {},
+      "extern": {
+        "subprojects": {
+          "bwinf": {},
+          "dsa": {}
+        }
+      },
+      "geographie": {},
+      "geschichte": {},
+      "infomatik": {},
+      "klausuren": {},
+      "latein": {},
+      "mathematik": {},
+      "musik": {},
+      "philosophie": {},
+      "physik": {},
+      "sozialkunde": {},
+      "sport": {}
+    }
+  },
+  "server": {
+    "prefix": "config",
+    "subprojects": {
+      "b-peetz": {},
+      "blog": {},
+      "ci": {},
+      "email": {},
+      "nix-sync": {},
+      "sudo-less": {}
+    }
+  },
+  "serverphone": {
+    "prefix": "programming/rust"
+  },
+  "smartphone": {
+    "prefix": "hardware",
+    "subprojects": {
+      "airdrop": {},
+      "airplay": {}
+    }
+  },
+  "system": {
+    "prefix": "config",
+    "subprojects": {
+      "backup": {},
+      "bar": {},
+      "email": {},
+      "firefox": {},
+      "gpg": {},
+      "keyboard": {},
+      "laptop": {},
+      "nvim": {},
+      "rss": {},
+      "shell": {},
+      "task": {},
+      "wm": {},
+      "youtube": {}
+    }
+  },
+  "timesinks": {
+    "subprojects": {
+      "games": {},
+      "music": {},
+      "netflix": {},
+      "youtube": {}
+    }
+  },
+  "trinitrix": {
+    "prefix": "programming/rust",
+    "subprojects": {
+      "documentation": {},
+      "testing": {}
+    }
+  }
+}
diff --git a/modules/default.nix b/modules/default.nix
index 1df511a1..a34e807f 100644
--- a/modules/default.nix
+++ b/modules/default.nix
@@ -7,14 +7,6 @@
       baseDirectory = ./by-name;
       fileName = "module.nix";
       finalizeFunction = name: value: value;
-
-      # TODO: Re-activate, when/if most modules have tests.  <2024-11-23>
-      # coImportsNameFunction = {
-      #   shard,
-      #   name,
-      # }:
-      #   ../tests/by-name + "/${shard}" + "/${name}" + "/test.nix";
-      # coImportsWarnMessageObject = "test";
     });
 in {
   imports = files;
diff --git a/modules/home.legacy/conf/beets/default.nix b/modules/home.legacy/conf/beets/default.nix
index 8d6277b7..e0421a9d 100644
--- a/modules/home.legacy/conf/beets/default.nix
+++ b/modules/home.legacy/conf/beets/default.nix
@@ -5,6 +5,16 @@
   ...
 }: let
   plugins = import ./plugins.nix {};
+
+  # TODO: Enable xtractor again <2025-03-29>
+  # package = pkgs.beets.override {
+  #   pluginOverrides = {
+  #     xtractor = {
+  #       enable = true;
+  #       propagatedBuildInputs = [pkgs.beetsExtraPlugins.xtractor];
+  #     };
+  #   };
+  package = pkgs.beets;
 in {
   imports = [
     ./plugins
@@ -12,14 +22,7 @@ in {
 
   programs.beets = {
     enable = true;
-    package = pkgs.beets.override {
-      pluginOverrides = {
-        xtractor = {
-          enable = true;
-          propagatedBuildInputs = [pkgs.beetsExtraPlugins.xtractor];
-        };
-      };
-    };
+    inherit package;
 
     settings = {
       library = "${config.xdg.dataHome}/beets/library.db";
diff --git a/modules/home.legacy/conf/beets/plugins.nix b/modules/home.legacy/conf/beets/plugins.nix
index bea2fefe..9500364b 100644
--- a/modules/home.legacy/conf/beets/plugins.nix
+++ b/modules/home.legacy/conf/beets/plugins.nix
@@ -12,7 +12,7 @@
   "mbsubmit"
 
   # Extract things from the music file
-  "xtractor"
+  # "xtractor"
 
   # Calculate replay gain
   "replaygain"
diff --git a/modules/home.legacy/conf/beets/plugins/default.nix b/modules/home.legacy/conf/beets/plugins/default.nix
index 3bea5ea8..a0b44e3c 100644
--- a/modules/home.legacy/conf/beets/plugins/default.nix
+++ b/modules/home.legacy/conf/beets/plugins/default.nix
@@ -11,6 +11,6 @@
     ./play
     ./replaygain
     ./smartplaylist
-    ./xtractor
+    # ./xtractor
   ];
 }
diff --git a/modules/home.legacy/conf/btop/default.nix b/modules/home.legacy/conf/btop/default.nix
index 06b56ea7..48572568 100644
--- a/modules/home.legacy/conf/btop/default.nix
+++ b/modules/home.legacy/conf/btop/default.nix
@@ -1,4 +1,4 @@
-{config, ...}: {
+{...}: {
   programs.btop = {
     enable = true;
   };
diff --git a/modules/home.legacy/conf/default.nix b/modules/home.legacy/conf/default.nix
index 328f4dab..767039c6 100644
--- a/modules/home.legacy/conf/default.nix
+++ b/modules/home.legacy/conf/default.nix
@@ -4,8 +4,6 @@
     ./beets
     ./btop
     ./dconf
-    ./direnv
-    ./firefox
     ./gammastep
     ./gpg
     ./gtk
@@ -17,7 +15,6 @@
     ./mail
     ./mako
     ./mbsync
-    ./mpv
     ./mumble
     ./neomutt
     ./nix-index
@@ -29,11 +26,6 @@
     ./ssh
     ./starship
     ./swayidle
-    ./swaylock
-    ./taskwarrior
-    ./timewarrior
     ./tridactyl
-    ./xdg
-    ./ytcc
   ];
 }
diff --git a/modules/home.legacy/conf/direnv/default.nix b/modules/home.legacy/conf/direnv/default.nix
deleted file mode 100644
index 3a7b8add..00000000
--- a/modules/home.legacy/conf/direnv/default.nix
+++ /dev/null
@@ -1,6 +0,0 @@
-{...}: {
-  programs.direnv = {
-    enable = true;
-    nix-direnv.enable = true;
-  };
-}
diff --git a/modules/home.legacy/conf/firefox/config/bookmarks/default.nix b/modules/home.legacy/conf/firefox/config/bookmarks/default.nix
deleted file mode 100644
index c612bf4d..00000000
--- a/modules/home.legacy/conf/firefox/config/bookmarks/default.nix
+++ /dev/null
@@ -1,31 +0,0 @@
-{
-  lib,
-  pkgs,
-  ...
-}: let
-  bookmarks = [
-    {
-      name = "Feed - Piped";
-      url = "https://piped.video/feed";
-    }
-
-    {
-      name = "DeepL Translate";
-      url = "https://www.deepl.com/translator";
-    }
-
-    {
-      name = "Nix lib";
-      url = "https://teu5us.github.io/nix-lib.html";
-    }
-
-    {
-      name = "Nixpkgs manual";
-      url = "https://ryantm.github.io/nixpkgs/";
-    }
-  ];
-
-  mkBookmarksFile = (import ./lib.nix) {inherit lib pkgs;};
-  bookmarks_file = mkBookmarksFile bookmarks;
-in
-  bookmarks_file
diff --git a/modules/home.legacy/conf/firefox/config/bookmarks/lib.nix b/modules/home.legacy/conf/firefox/config/bookmarks/lib.nix
deleted file mode 100644
index d1d89dd2..00000000
--- a/modules/home.legacy/conf/firefox/config/bookmarks/lib.nix
+++ /dev/null
@@ -1,49 +0,0 @@
-{
-  lib,
-  pkgs,
-}: bookmarks: let
-  indent = level:
-    lib.concatStringsSep "" (map (lib.const "  ") (lib.range 1 level));
-
-  bookmarkToHTML = indentLevel: bookmark: ''
-    ${indent indentLevel}<DT><A HREF="${
-      lib.escapeXML bookmark.url
-    }" ADD_DATE="0" LAST_MODIFIED="0">${lib.escapeXML bookmark.name}</A>'';
-
-  directoryToHTML = indentLevel: directory: ''
-    ${indent indentLevel}<DT>${
-      if directory.toolbar
-      then ''<H3 PERSONAL_TOOLBAR_FOLDER="true">Bookmarks Toolbar''
-      else "<H3>${lib.escapeXML directory.name}"
-    }</H3>
-    ${indent indentLevel}<DL><p>
-    ${allItemsToHTML (indentLevel + 1) directory.bookmarks}
-    ${indent indentLevel}</p></DL>'';
-
-  itemToHTMLOrRecurse = indentLevel: item:
-    if item ? "url"
-    then bookmarkToHTML indentLevel item
-    else directoryToHTML indentLevel item;
-
-  allItemsToHTML = indentLevel: bookmarks:
-    lib.concatStringsSep "\n"
-    (map (itemToHTMLOrRecurse indentLevel) bookmarks);
-
-  bookmarkEntries = allItemsToHTML 1 bookmarks;
-in
-  pkgs.writeText "firefox-bookmarks.html" ''
-    <!DOCTYPE NETSCAPE-Bookmark-file-1>
-    <!-- This is an automatically generated file.
-      It will be read and overwritten.
-      DO NOT EDIT! -->
-    <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
-    <TITLE>Bookmarks</TITLE>
-    <H1>Bookmarks Menu</H1>
-
-    <DL><p>
-        <DT><H3 ADD_DATE="0" LAST_MODIFIED="0" PERSONAL_TOOLBAR_FOLDER="true">Bookmarks Toolbar</H3>
-        <DL><p>
-        ${bookmarkEntries}
-        </DL><p>
-    </p></DL>
-  ''
diff --git a/modules/home.legacy/conf/firefox/config/extensions/native_messaging_hosts/default.nix b/modules/home.legacy/conf/firefox/config/extensions/native_messaging_hosts/default.nix
deleted file mode 100644
index 9aaa1682..00000000
--- a/modules/home.legacy/conf/firefox/config/extensions/native_messaging_hosts/default.nix
+++ /dev/null
@@ -1,15 +0,0 @@
-{pkgs, ...}:
-/*
-++ lib.optional (cfg.enableBrowserpass or false) (lib.getBin browserpass)
-++ lib.optional (cfg.enableBukubrow or false) bukubrow
-++ lib.optional (cfg.enableTridactylNative or false) tridactyl-native
-++ lib.optional (cfg.enableGnomeExtensions or false) gnome-browser-connector
-++ lib.optional (cfg.enableUgetIntegrator or false) uget-integrator
-++ lib.optional (cfg.enablePlasmaBrowserIntegration or false) plasma5Packages.plasma-browser-integration
-++ lib.optional (cfg.enableFXCastBridge or false) fx-cast-bridge
-++ lib.optional (cfg.enableKeePassXC or false) keepassxc
-*/
-with pkgs; [
-  tridactyl-native
-  keepassxc
-]
diff --git a/modules/home.legacy/conf/firefox/config/policies/default.nix b/modules/home.legacy/conf/firefox/config/policies/default.nix
deleted file mode 100644
index 02c740f6..00000000
--- a/modules/home.legacy/conf/firefox/config/policies/default.nix
+++ /dev/null
@@ -1,146 +0,0 @@
-{
-  config,
-  extensions,
-  ...
-}: let
-  locals = [
-    "en-CA"
-    "de"
-    "sv-SE"
-  ];
-  mkAllowedExtension = extension: {
-    name = extension.addonId;
-    value = {
-      installation_mode = "normal_installed";
-      updates_disabled = true;
-      inherit (extension) default_area;
-      install_url = "file://${builtins.fetchurl {
-        inherit
-          (extension)
-          url
-          sha256
-          ;
-      }}";
-    };
-  };
-  allowedExtensions =
-    builtins.listToAttrs
-    (builtins.map mkAllowedExtension (builtins.attrValues
-        extensions));
-
-  mkBlockedExtension = id: {
-    name = id;
-    value = {
-      install_mode = "blocked";
-    };
-  };
-  blockedExtensions = builtins.listToAttrs (builtins.map mkBlockedExtension [
-    # these are the default search engines
-    "addons-search-detection@mozilla.com"
-    "amazon@search.mozilla.org"
-    "bing@search.mozilla.org"
-    "ddg@search.mozilla.org"
-    "google@search.mozilla.org"
-    "wikipedia@search.mozilla.org"
-  ]);
-
-  language_packs = builtins.listToAttrs (builtins.map
-    (
-      lang: {
-        name = "langpack-${lang}@firefox.mozilla.org";
-        value = {
-          installation_mode = "normal_installed";
-          updates_disabled = true;
-          install_url = "https://releases.mozilla.org/pub/firefox/releases/${config.soispha.firefox.package_version}/linux-x86_64/xpi/${lang}.xpi";
-        };
-      }
-    )
-    locals);
-in {
-  # NOTE: See https://mozilla.github.io/policy-templates for documentation <2023-10-21>
-  policies = {
-    # NixOS manages this already
-    DisableAppUpdate = true;
-
-    DisableFirefoxAccounts = true;
-    DisableFirefoxScreenshots = true;
-
-    # KeepassXC does this for me
-    DisableMasterPasswordCreation = true;
-
-    # I use a self-hosted services for that
-    DisablePocket = true;
-
-    # I don't want to lose my data
-    DisableProfileRefresh = true;
-
-    DisableDeveloperTools = false;
-
-    DisplayBookmarksToolbar = "newtab";
-    DisplayMenuBar = "default-off";
-
-    DNSOverHTTPS = {
-      Enabled = true;
-      Locked = false;
-    };
-    # The concept of a "default browser" does not apply to my NixOS config
-    DontCheckDefaultBrowser = true;
-
-    EnableTrackingProtection = {
-      Value = true;
-      Locked = false;
-      Cryptomining = true;
-      Fingerprinting = true;
-      EmailTracking = true;
-    };
-
-    EncryptedMediaExtensions = {
-      # I want a _free_ config (and I can always just run another browser)
-      Enabled = false;
-      Locked = true;
-    };
-
-    ExtensionSettings =
-      {
-        "*" = {
-          # Blocking the extension install here, also blocks the 'about:debugging' page
-
-          # blocked_install_message = ''
-          #   You can't install a extension manually,
-          #   please specify it in your NixOS configuration
-          # '';
-          installation_mode = "allowed";
-        };
-      }
-      // allowedExtensions
-      // blockedExtensions
-      // language_packs;
-
-    ExtensionUpdate = false;
-
-    # TODO: Add handlers for the default file types <2023-10-21>
-    # Handlers = {
-    # };
-
-    HardwareAcceleration = true;
-
-    # Blocking the extension install here, also blocks the 'about:debugging' page
-    # InstallAddonsPermission = {
-    #   Allowed = [];
-    #   Default = false;
-    # };
-
-    # KeepassXC and such things
-    OfferToSaveLogins = false;
-    PasswordManagerEnabled = false;
-
-    PDFjs = {
-      Enabled = true;
-      # Don't honor documents right to be un-copy-able
-      EnablePermissions = false;
-    };
-
-    SearchBar = "unified";
-    RequestedLocales = locals;
-  };
-}
diff --git a/modules/home.legacy/conf/firefox/config/prefs/default.nix b/modules/home.legacy/conf/firefox/config/prefs/default.nix
deleted file mode 100644
index 80c6d274..00000000
--- a/modules/home.legacy/conf/firefox/config/prefs/default.nix
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-  pkgs,
-  config,
-  user_js,
-  bookmarks,
-  ...
-}: let
-  user_js_override = pkgs.writeText "user.override.js" (builtins.readFile ./override.js);
-in
-  pkgs.runCommand "user.js" {} ''
-    mkdir $out;
-    cat "${user_js}/user.js" > $out/user.js;
-    cat "${user_js_override}" >> $out/user.js;
-
-    cat << EOF >> $out/user.js;
-    // My bookmarks
-    user_pref("browser.bookmarks.file", "${toString bookmarks}");
-    user_pref("browser.startup.homepage", "file:///home/dt/home.html"); // 0103 // TODO: add this from a flake
-    user_pref("browser.download.dir", "${config.xdg.userDirs.download}");
-    EOF
-  ''
diff --git a/modules/home.legacy/conf/firefox/config/prefs/override.js b/modules/home.legacy/conf/firefox/config/prefs/override.js
deleted file mode 100644
index bf874b33..00000000
--- a/modules/home.legacy/conf/firefox/config/prefs/override.js
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
-  0100: STARTUP
-  0200: GEOLOCATION / LANGUAGE / LOCALE
-  0300: QUIETER FOX
-  0400: SAFE BROWSING
-  0600: BLOCK IMPLICIT OUTBOUND
-  0700: DNS / DoH / PROXY / SOCKS / IPv6
-  0800: LOCATION BAR / SEARCH BAR / SUGGESTIONS / HISTORY / FORMS
-  0900: PASSWORDS
-  1000: DISK AVOIDANCE
-  1200: HTTPS (SSL/TLS / OCSP / CERTS / HPKP)
-  1400: FONTS
-  1600: HEADERS / REFERERS
-  1700: CONTAINERS
-  2000: PLUGINS / MEDIA / WEBRTC
-  2400: DOM (DOCUMENT OBJECT MODEL)
-  2600: MISCELLANEOUS
-  2700: ETP (ENHANCED TRACKING PROTECTION)
-  2800: SHUTDOWN & SANITIZING
-  4500: RFP (RESIST FINGERPRINTING)
-  5000: OPTIONAL OPSEC
-  5500: OPTIONAL HARDENING
-  6000: DON'T TOUCH
-  7000: DON'T BOTHER
-  8000: DON'T BOTHER: FINGERPRINTING
-  9000: NON-PROJECT RELATED
-  9999: DEPRECATED / REMOVED / LEGACY / RENAMED
-*/
-
-
-// restore session
-user_pref("browser.startup.page", 3); // 0102
-
-user_pref("browser.newtabpage.enabled", true); // 0104
-
-// disable the geoservice, TODO: don't know if I want this
-//user_pref("geo.provider.use_geoclue", false); // 0202
-
-// TODO: is this something useful?
-user_pref("datareporting.policy.dataSubmissionEnabled", true); // 0330
-
-// enable health reports
-user_pref("datareporting.healthreport.uploadEnabled", true); // 0331
-
-// Do I want to opt-out?
-user_pref("toolkit.telemetry.coverage.opt-out", false); // 0333
-
-// enables studies
-user_pref("app.shield.optoutstudies.enabled", true); // 0340
-
-// I guess that browsing protection is useful
-user_pref("browser.safebrowsing.downloads.remote.enabled", true); // 0403
-
-// TODO: does this (-> set to false) make things slower?
-user_pref("network.prefetch-next", true); // 0601
-
-// enable ipv6 because the rest of the system uses it
-user_pref("network.dns.disableIPv6", false); // 0701
-
-// TRR only
-user_pref("network.trr.mode", 3); // 0710
-
-// I trust my search engine
-user_pref("keyword.enabled", true); // 801
-user_pref("browser.search.suggest.enabled", true); // 0804
-user_pref("browser.urlbar.suggest.searches", true); // 0804
-// TODO: no idea what this does, enabling it
-user_pref("browser.urlbar.showSearchTerms.enabled", true); // 9004
-
-// prefetch urls, if the get auto completed
-user_pref("browser.urlbar.speculativeConnect.enabled", true); // 0805
-
-// Disable autoScrolling (clicking with the mouse wheel)
-user_pref("general.autoScroll", false);
-
-// add new tabs after the current one
-user_pref("browser.tabs.insertAfterCurrent", true);
-
-// TODO: I might want to enable this
-//user_pref("browser.urlbar.suggest.quicksuggest.nonsponsored", false); // 0807
-
-// TODO: enable form and search history?
-//user_pref("browser.formfill.enable", false); // 0810
-
-// disk cache should help performance
-user_pref("browser.cache.disk.enable", true); // 1001
-
-// store extra session data (form content, cookies and POST data) 0: everywhere
-user_pref("browser.sessionstore.privacy_level", 0); // 1003
-
-// Disable unsafe passive content (images) on https sites
-user_pref("security.mixed_content.block_display_content", true); // 1241
-
-// Disable the eme banner
-user_pref("browser.eme.ui.enabled", false); // 2022
-
-// Don't delete my precious temp files
-user_pref("browser.helperApps.deleteTempFileOnExit", false); // 2603
-
-// Download to the download dir
-user_pref("browser.download.useDownloadDir", true); // 2651
-
-// Open the download panel
-user_pref("browser.download.alwaysOpenPanel", true); // 2652
-
-// Block after custom ruleset
-user_pref("browser.contentblocking.category", "custom"); // 2701
-
-// set the custom settings // 7016
-user_pref("network.cookie.cookieBehavior", 1);
-user_pref("network.http.referer.disallowCrossSiteRelaxingDefault", true);
-user_pref("network.http.referer.disallowCrossSiteRelaxingDefault.top_navigation", true);
-user_pref("privacy.partition.network_state.ocsp_cache", true);
-user_pref("privacy.query_stripping.enabled", true);
-user_pref("privacy.trackingprotection.enabled", true);
-user_pref("privacy.trackingprotection.socialtracking.enabled", true);
-user_pref("privacy.trackingprotection.cryptomining.enabled", true);
-user_pref("privacy.trackingprotection.fingerprinting.enabled", true);
-
-
-// I might want to change that, when it hinders session restore
-//user_pref("privacy.partition.always_partition_third_party_non_cookie_storage.exempt_sessionstorage", false); // 2720
-
-// I like my history very much!
-user_pref("privacy.sanitize.sanitizeOnShutdown", false); // 2810
-
-// The downsides (light theme + potential breakages):
-//user_pref("privacy.resistFingerprinting", true); // 4501
-user_pref("privacy.resistFingerprinting.letterboxing", false); // 4504
-
-// I would like to keep my gl, even in the web
-user_pref("webgl.disabled", false); // 4520
-
-// I like my service workers and am using a service using them.
-user_pref("dom.serviceWorkers.enabled", true); // 7017
-
-// I've got a password manager already
-user_pref("signon.rememberSignons", false); // 5003
-
-// Do not track header
-user_pref("privacy.donottrackheader.enabled", true); // 7015
-
-// Allow my custom css
-user_pref("toolkit.legacyUserProfileCustomizations.stylesheets", true);
-
-// might improve performance TODO:
-user_pref("gfx.webrender.all", true);
-
-// disable updates (pretty pointless with nix)
-user_pref("extensions.update.autoUpdateDefault", false);
-user_pref("extensions.update.enabled", false);
-user_pref("app.update.channel", "default");
-
-user_pref("browser.ctrlTab.recentlyUsedOrder", false);
-
-user_pref("browser.download.useDownloadDir", true);
-user_pref("browser.download.folderList", 2); // TODO:
-user_pref("browser.download.viewableInternally.typeWasRegistered.svg", true);
-user_pref("browser.download.viewableInternally.typeWasRegistered.webp", true);
-user_pref("browser.download.viewableInternally.typeWasRegistered.xml", true);
-
-// TODO: what does this do?
-user_pref("browser.search.widget.inNavBar", true);
-
-user_pref("browser.shell.checkDefaultBrowser", false);
-user_pref("browser.tabs.loadInBackground", true);
-user_pref("browser.urlbar.placeholderName", "Brave");
-
-// Set the tabs and bookmarks
-user_pref("browser.tabs.inTitlebar", 1);
-user_pref("browser.toolbars.bookmarks.visibility", "always");
-user_pref("browser.places.importBookmarksHTML", true);
-
-// Theme
-user_pref("extensions.activeThemeID", "firefox-alpenglow@mozilla.org");
-user_pref("extensions.extensions.activeThemeID", "firefox-alpenglow@mozilla.org");
-
-// highlight all entries when searching
-user_pref("findbar.highlightAll", true);
-
-// Set the default position for the developer toolbox
-user_pref("devtools,toolbox.host", "right");
-user_pref("devtools,toolsidebar-width.inspector", 700);
-
-// Don't bother me with translations
-user_pref("browser.translations.automaticallyPopup", true);
-user_pref("browser.translations.neverTranslateLanguages", "de");
-
-// Put all downloads into the downloads directory
-user_pref("browser.download.start_downloads_in_tmp_dir", false);
-
-// TODO:
-//user_pref("extensions.webcompat.enable_picture_in_picture_overrides", true);
-//user_pref("extensions.webcompat.enable_shims", true);
-//user_pref("extensions.webcompat.perform_injections", true);
-//user_pref("extensions.webcompat.perform_ua_overrides", true);
-
-// onlykey / copied from a yubikey config
-//user_pref("security.webauth.u2f", true);
-//user_pref("security.webauth.webauthn", true);
-//user_pref("security.webauth.webauthn_enable_softtoken", true);
-//user_pref("security.webauth.webauthn_enable_usbtoken", true);
diff --git a/modules/home.legacy/conf/firefox/default.nix b/modules/home.legacy/conf/firefox/default.nix
deleted file mode 100644
index 663c4978..00000000
--- a/modules/home.legacy/conf/firefox/default.nix
+++ /dev/null
@@ -1,133 +0,0 @@
-{
-  config,
-  pkgs,
-  lib,
-  user_js,
-  ...
-}: let
-  extensions =
-    builtins.fromJSON (builtins.readFile ./config/extensions/extensions.json);
-
-  userChrome = builtins.readFile ./config/chrome/userChrome.css;
-  bookmarks = (import ./config/bookmarks/default.nix) {
-    inherit
-      pkgs
-      lib
-      ;
-  };
-  engines = (import ./config/search/engines) {inherit pkgs;};
-
-  native_messaging_hosts = (import ./config/extensions/native_messaging_hosts/default.nix) {inherit pkgs;};
-
-  policies = (import ./config/policies) {inherit config extensions;};
-
-  search = {
-    default = "Brave Search";
-    privateDefault = "Brave Search";
-    force = true;
-    order = [
-      # DEFAULT
-      "Brave Search"
-
-      # NIX
-      "Nix Packages"
-      "Nix Options"
-      "Nixpkgs issues"
-      "Homemanager Options"
-      "NixOS Wiki"
-      "Nixpkgs Pull Request Tracker"
-
-      # RUST
-      "Rust std"
-      "Rust tokio"
-
-      # OTHER
-      "Google Scholar"
-      "Wikipedia"
-      "Arch Wiki"
-    ];
-
-    inherit engines;
-  };
-
-  prefConfig = builtins.readFile "${
-    (import ./config/prefs) {inherit pkgs lib config bookmarks user_js;}
-  }/user.js";
-
-  # Package {{{
-  package = import ./package.nix {
-    inherit config lib pkgs;
-    extraPolicies = policies;
-    extraNativeMessagingHosts = native_messaging_hosts;
-  };
-  # }}}
-
-  # Profiles {{{
-  profiles = {
-    "default" = {
-      inherit search userChrome;
-      isDefault = true;
-      id = 0;
-      name = "default";
-      extraConfig = prefConfig;
-    };
-  };
-
-  taskwarriorProfiles = import ../taskwarrior/firefox {
-    inherit
-      config
-      lib
-      # options
-      prefConfig
-      search
-      userChrome
-      ;
-    profile_size = builtins.length (builtins.attrNames profiles);
-  };
-  # }}}
-in {
-  options.soispha.firefox = {
-    package = lib.mkOption {
-      type = lib.types.package;
-      default = pkgs.firefox;
-      description = "Firefox package to use.";
-      defaultText = lib.literalExpression "pkgs.firefox";
-      relatedPackages = [
-        "firefox"
-        "firefox-beta-bin"
-        "firefox-bin"
-        "firefox-devedition-bin"
-        "firefox-esr"
-      ];
-    };
-    package_version = lib.mkOption {
-      type = lib.types.str;
-      default = pkgs.firefox.version;
-      description = "Firefox version to use";
-    };
-  };
-
-  config = {
-    soispha.firefox.package = package;
-    soispha.firefox.package_version = pkgs.firefox.version;
-    home.sessionVariables = {
-      # improve touch input & make scrolling smother
-      MOZ_USE_XINPUT2 = "1";
-
-      # improve wayland support
-      MOZ_ENABLE_WAYLAND = 1;
-
-      # tell gtk to use portals
-      GTK_USE_PORTAL = 1;
-
-      BROWSER = "firefox";
-    };
-    programs.firefox = {
-      enable = true;
-      inherit (config.soispha.firefox) package;
-      profiles =
-        profiles
-        // taskwarriorProfiles;
-    };
-  };
-}
diff --git a/modules/home.legacy/conf/firefox/package.nix b/modules/home.legacy/conf/firefox/package.nix
deleted file mode 100644
index f7e4319b..00000000
--- a/modules/home.legacy/conf/firefox/package.nix
+++ /dev/null
@@ -1,30 +0,0 @@
-# taken from the NixOS Firefox module: https://github.com/NixOS/nixpkgs/blob/7c9cc5a6e5d38010801741ac830a3f8fd667a7a0/nixos/modules/programs/firefox.nix
-{
-  config,
-  lib,
-  pkgs,
-  # options
-  autoConfig ? "",
-  extraNativeMessagingHosts ? [],
-  wrapperConfig ? {},
-  extraPolicies ? {},
-  base_package ? pkgs.firefox,
-}: let
-  pkg = base_package.override (old: {
-    extraPrefsFiles =
-      (old.extraPrefsFiles or [])
-      ++ [
-        (pkgs.writeText "autoConfig.js" autoConfig)
-      ];
-    nativeMessagingHosts = old.nativeMessagingHosts or [] ++ extraNativeMessagingHosts;
-    cfg = (old.cfg or {}) // wrapperConfig;
-    extraPoliciesFiles =
-      (old.extraPoliciesFiles or [])
-      ++ [
-        (
-          pkgs.writeText "policies.json" (builtins.toJSON extraPolicies)
-        )
-      ];
-  });
-in
-  pkg
diff --git a/modules/home.legacy/conf/firefox/scripts/default.nix b/modules/home.legacy/conf/firefox/scripts/default.nix
deleted file mode 100644
index 1127662b..00000000
--- a/modules/home.legacy/conf/firefox/scripts/default.nix
+++ /dev/null
@@ -1,29 +0,0 @@
-{
-  pkgs,
-  sysLib,
-  ...
-}: let
-  unzip_mozlz4 = pkgs.stdenv.mkDerivation {
-    name = "unzip_mozlz4";
-    propagatedBuildInputs = [
-      (pkgs.python3.withPackages (pythonPackages:
-        with pythonPackages; [
-          lz4
-        ]))
-    ];
-    dontUnpack = true;
-    installPhase = "install -Dm755 ${./unzip_mozlz4.py} $out/bin/unzip_mozlz4";
-  };
-  extract_cookies = sysLib.writeShellScript {
-    name = "extract_cookies";
-    src = ./extract_cookies.sh;
-    dependencies = with pkgs; [
-      bash
-      sqlite
-      mktemp
-      coreutils
-    ];
-  };
-in {
-  inherit unzip_mozlz4 extract_cookies;
-}
diff --git a/modules/home.legacy/conf/firefox/scripts/extract_cookies.sh b/modules/home.legacy/conf/firefox/scripts/extract_cookies.sh
deleted file mode 100755
index e3d50d43..00000000
--- a/modules/home.legacy/conf/firefox/scripts/extract_cookies.sh
+++ /dev/null
@@ -1,77 +0,0 @@
-#!/usr/bin/env bash
-# copied from https://superuser.com/a/1239036
-# extract_cookies.sh:
-#
-# Convert from Firefox's cookies.sqlite format to Netscape cookies,
-# which can then be used by wget and curl. (Why don't wget and curl
-# just use libsqlite if it's installed? Mysteries abound.)
-#
-# Note: This script reads directly from the standard cookie jar file,
-# which means cookies which are kept only in memory ("session cookies")
-# will not be extracted. You will need an extension to do that.
-
-# USAGE:
-#
-# $ extract_cookies.sh > /tmp/cookies.txt
-# or
-# $ extract_cookies.sh ~/.mozilla/firefox/*default*/cookies.sqlite > /tmp/cookies.txt
-
-# USING WITH WGET:
-# $ wget --load-cookies=/tmp/cookies.txt http://example.com
-
-# USING WITH CURL:
-# $ curl --cookie /tmp/cookies.txt http://example.com
-
-# Note: If you do not specify an SQLite filename, this script will
-# intelligently find it for you.
-#
-# A) Usually it will check all profiles under ~/.mozilla/firefox/ and
-# use the cookies.sqlite that was updated most recently.
-#
-# B) If you've redirected stdin (with < or |) , then that will be used.
-
-# HISTORY: I believe this is circa 2010 from:
-# http://slacy.com/blog/2010/02/using-cookies-sqlite-in-wget-or-curl/
-# However, that site is down now.
-
-# Cleaned up by Hackerb9 (2017) to be more robust and require less typing.
-
-cleanup() {
-    rm -f "$TMPFILE"
-    exit 0
-}
-trap cleanup EXIT INT QUIT TERM
-
-if [ "$#" -ge 1 ]; then
-    SQLFILE="$1"
-else
-    SQLFILE="$HOME/.mozilla/firefox/default/cookies.sqlite"
-fi
-
-if ! [ -r "$SQLFILE" ]; then
-    echo "Error. File $SQLFILE is not readable." >&2
-    exit 1
-fi
-
-# We have to copy cookies.sqlite, because FireFox has a lock on it
-TMPFILE=$(mktemp /tmp/cookies.sqlite.XXXXXXXXXX)
-cat "$SQLFILE" >>"$TMPFILE"
-
-# This is the format of the sqlite database:
-# CREATE TABLE moz_cookies (id INTEGER PRIMARY KEY, name TEXT, value TEXT, host TEXT, path TEXT,expiry INTEGER, lastAccessed INTEGER, isSecure INTEGER, isHttpOnly INTEGER);
-
-echo "# Netscape HTTP Cookie File"
-sqlite3 -separator $'\t' "$TMPFILE" <<EOF
-.mode tabs
-.header off
-select host,
-case substr(host,1,1)='.' when 0 then 'FALSE' else 'TRUE' end,
-path,
-case isSecure when 0 then 'FALSE' else 'TRUE' end,
-expiry,
-name,
-value
-from moz_cookies;
-EOF
-
-cleanup
diff --git a/modules/home.legacy/conf/firefox/scripts/unzip_mozlz4.py b/modules/home.legacy/conf/firefox/scripts/unzip_mozlz4.py
deleted file mode 100755
index 71e4e6bc..00000000
--- a/modules/home.legacy/conf/firefox/scripts/unzip_mozlz4.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env python
-# source: https://unix.stackexchange.com/a/497861
-# Command-line tool to decompress mozLz4 files used for example by Firefox to store various kinds of session backup information.
-# Works in both Python 2.7.15 and 3.6.7, as of version 2.1.6 of the LZ4 Python bindings at pypi.org/project/lz4.
-# To use in another script, simply cut and paste the import statement and the mozlz4_to_text() function (lines 8 to 17).
-
-import lz4.block  # pip install lz4 --user
-
-
-def mozlz4_to_text(filepath):
-    # Given the path to a "mozlz4", "jsonlz4", "baklz4" etc. file,
-    # return the uncompressed text.
-    bytestream = open(filepath, "rb")
-    bytestream.read(8)  # skip past the b"mozLz40\0" header
-    valid_bytes = bytestream.read()
-    text = lz4.block.decompress(valid_bytes)
-    return text
-
-
-def main(args):
-    # Given command-line arguments of an input filepath for a ".mozlz4" file
-    # and optionally an output filepath, write the decompressed text to the
-    # output filepath.
-    # Default output filepath is the input filepath minus the last three characters
-    # (e.g. "foo.jsonlz4" becomes "foo.json")
-    filepath_in = args[0]
-    if len(args) < 2:
-        filepath_out = filepath_in[:-3]
-    else:
-        filepath_out = args[1]
-    text = mozlz4_to_text(filepath_in)
-    with open(filepath_out, "wb") as outfile:
-        outfile.write(text)
-    if filepath_out != "/dev/stdout":
-        print("Wrote decompressed text to {}".format(filepath_out))
-
-
-if __name__ == "__main__":
-    import sys
-
-    args = sys.argv[1:]
-    if args and args[0] not in ("--help", "-h"):
-        main(args)
-    else:
-        print("Usage: mozlz4.py <mozlz4 file to read> <location to write>")
diff --git a/modules/home.legacy/conf/firefox/scripts/update_extensions.sh b/modules/home.legacy/conf/firefox/scripts/update_extensions.sh
deleted file mode 100755
index 86bd843c..00000000
--- a/modules/home.legacy/conf/firefox/scripts/update_extensions.sh
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/bin/sh
-
-tmp=$(mktemp)
-cat <<EOF | awk '!/^\s*#/' >"$tmp"
-    darkreader:navbar
-    keepassxc-browser:navbar
-    vhack-libredirect:navbar
-    torproject-snowflake:navbar
-    tridactyl-vim:menupanel
-    ublock-origin:menupanel
-EOF
-
-# The bin is provided in the devshell;
-# The cat execution should be unquoted;
-# shellcheck disable=SC2046
-generate_extensions $(cat "$tmp") >"$(dirname "$0")"/../config/extensions/extensions.json
-
-rm "$tmp"
diff --git a/modules/home.legacy/conf/gtk/default.nix b/modules/home.legacy/conf/gtk/default.nix
index f5411369..b19ef3a9 100644
--- a/modules/home.legacy/conf/gtk/default.nix
+++ b/modules/home.legacy/conf/gtk/default.nix
@@ -1,8 +1,6 @@
 {
   config,
-  lib,
   pkgs,
-  stdenv,
   ...
 }: {
   gtk = {
diff --git a/modules/home.legacy/conf/keepassxc/default.nix b/modules/home.legacy/conf/keepassxc/default.nix
index 3ac82812..38df9055 100644
--- a/modules/home.legacy/conf/keepassxc/default.nix
+++ b/modules/home.legacy/conf/keepassxc/default.nix
@@ -1,7 +1,3 @@
-{
-  config,
-  pkgs,
-  ...
-}: {
+{...}: {
   xdg.configFile."keepassxc/keepassxc.ini".source = ./keepassxc.ini;
 }
diff --git a/modules/home.legacy/conf/latexindent/default.nix b/modules/home.legacy/conf/latexindent/default.nix
index 0d776e14..8dccc73e 100644
--- a/modules/home.legacy/conf/latexindent/default.nix
+++ b/modules/home.legacy/conf/latexindent/default.nix
@@ -1,8 +1,4 @@
-{
-  config,
-  pkgs,
-  ...
-}: {
+{...}: {
   xdg.configFile."latexindent/indentconfig.yaml".source = ./indentconfig.yaml;
   xdg.configFile."latexindent/mysettings.yaml".source = ./mysettings.yaml;
 }
diff --git a/modules/home.legacy/conf/mail/accounts/benedikt.nix b/modules/home.legacy/conf/mail/accounts/benedikt.nix
index 87ede61b..2fe72fca 100644
--- a/modules/home.legacy/conf/mail/accounts/benedikt.nix
+++ b/modules/home.legacy/conf/mail/accounts/benedikt.nix
@@ -32,11 +32,11 @@
   #   };
   # };
   smtp = {
-    host = "server1.vhack.eu";
+    host = "mail.foss-syndicate.org";
     port = 465;
   };
   imap = {
-    host = "server1.vhack.eu";
+    host = "mail.foss-syndicate.org";
     port = 993;
   };
   jmap = {
diff --git a/modules/home.legacy/conf/mail/accounts/soispha.nix b/modules/home.legacy/conf/mail/accounts/soispha.nix
index 012e84d6..11634ab3 100644
--- a/modules/home.legacy/conf/mail/accounts/soispha.nix
+++ b/modules/home.legacy/conf/mail/accounts/soispha.nix
@@ -33,11 +33,11 @@
   #   };
   # };
   smtp = {
-    host = "server1.vhack.eu";
+    host = "mail.vhack.eu";
     port = 465;
   };
   imap = {
-    host = "server1.vhack.eu";
+    host = "mail.vhack.eu";
     port = 993;
   };
   jmap = {
diff --git a/modules/home.legacy/conf/mail/default.nix b/modules/home.legacy/conf/mail/default.nix
index 0ecbe40a..46526173 100644
--- a/modules/home.legacy/conf/mail/default.nix
+++ b/modules/home.legacy/conf/mail/default.nix
@@ -1,15 +1,53 @@
 {
   config,
   pkgs,
+  lib,
   ...
 }: let
   benedikt = import ./accounts/benedikt.nix {inherit pkgs;};
   soispha = import ./accounts/soispha.nix {inherit pkgs;};
 
   accounts = {inherit soispha benedikt;};
+
+  mkHelper = {
+    userName,
+    passwordCommand,
+    ...
+  }:
+    builtins.toString (pkgs.writeShellScript "git-credential-keepassxc-libsecret"
+      # bash
+      ''
+        [ "$1" = "get" ] || {
+          exit 1
+        }
+        output="$(cat)"
+        if echo "$output" | grep "username=${userName}" -q; then
+          if password="$(${passwordCommand})"; then
+            printf "%s\npassword=%s\n\n" "$output" "$password"
+          else
+            # The password command failed (for whatever reason)
+            exit 1
+          fi
+        else
+          # Not our business.
+          exit 1
+        fi
+      '');
+  accountCredentials =
+    # TODO: This will result in only one of them being defined, as we duplicate the
+    # attribute key <2025-02-03>
+    lib.mapAttrs' (_: value: {
+      name = "credential.smtp://${value.smtp.host}:${builtins.toString value.smtp.port}";
+      value = {
+        "helper" = mkHelper value;
+      };
+    })
+    accounts;
 in {
   accounts.email = {
     maildirBasePath = "${config.xdg.dataHome}/maildir";
     inherit accounts;
   };
+
+  programs.git.extraConfig = accountCredentials;
 }
diff --git a/modules/home.legacy/conf/mako/default.nix b/modules/home.legacy/conf/mako/default.nix
index 711457f2..6acf0afe 100644
--- a/modules/home.legacy/conf/mako/default.nix
+++ b/modules/home.legacy/conf/mako/default.nix
@@ -1,8 +1,4 @@
-{
-  config,
-  pkgs,
-  ...
-}: {
+{...}: {
   services.mako = {
     enable = true;
     backgroundColor = "#2e3440";
diff --git a/modules/home.legacy/conf/mbsync/default.nix b/modules/home.legacy/conf/mbsync/default.nix
index ac9808c9..8418d92d 100644
--- a/modules/home.legacy/conf/mbsync/default.nix
+++ b/modules/home.legacy/conf/mbsync/default.nix
@@ -1,17 +1,16 @@
-{
-  config,
-  lib,
-  ...
-}: {
-  # TODO: I have no clue if both are needed, but it looks neat, right?
+{lib, ...}: {
+  # This configures the program in itself (i.e., sets-up a config file, etc.)
   programs.mbsync = {
     enable = true;
   };
+
+  # This starts a systemd service to periodically sync mail
   services.mbsync = {
     enable = true;
-    # TODO: enable after isync 1.5 drops
-    #configFile = "${config.xdg.configHome}/mbsync/mbsync.conf";
   };
-  # Disable the timer, and only activate it on neomutt start
+
+  # Disable the timer, and only activate the service when neomutt starts
+  # Otherwise, the password command would prompt me to unlock the keepassxc database every
+  # time.
   systemd.user.timers.mbsync = lib.mkForce {};
 }
diff --git a/modules/home.legacy/conf/mpv/default.nix b/modules/home.legacy/conf/mpv/default.nix
deleted file mode 100644
index 6b252a38..00000000
--- a/modules/home.legacy/conf/mpv/default.nix
+++ /dev/null
@@ -1,10 +0,0 @@
-{...}: {
-  programs.mpv = {
-    enable = true;
-    bindings = {
-      q = "quit 0";
-      "Ctrl+c" = "quit 1";
-      "Shift+q" = "quit-watch-later 1";
-    };
-  };
-}
diff --git a/modules/home.legacy/conf/neomutt/default.nix b/modules/home.legacy/conf/neomutt/default.nix
index e4fbcb39..10da8f0e 100644
--- a/modules/home.legacy/conf/neomutt/default.nix
+++ b/modules/home.legacy/conf/neomutt/default.nix
@@ -2,8 +2,13 @@
   programs.neomutt = {
     enable = true;
     package = pkgs.writeShellScriptBin "neomutt" ''
+      # Download newest mail
       systemctl --user start mbsync.service;
+
       ${pkgs.neomutt}/bin/neomutt;
+
+      # Upload changed things (e.g., new mail in Sent)
+      systemctl --user start mbsync.service;
     '';
     vimKeys = false; # see the modified ones below
     checkStatsInterval = 60;
diff --git a/modules/home.legacy/conf/npm/default.nix b/modules/home.legacy/conf/npm/default.nix
index 7b4bb6a1..d836e89c 100644
--- a/modules/home.legacy/conf/npm/default.nix
+++ b/modules/home.legacy/conf/npm/default.nix
@@ -1,7 +1,3 @@
-{
-  config,
-  pkgs,
-  ...
-}: {
+{...}: {
   xdg.configFile."npm/.npmrc".source = ./.npmrc;
 }
diff --git a/modules/home.legacy/conf/rclone/default.nix b/modules/home.legacy/conf/rclone/default.nix
index bd0c1ac2..caae4c9e 100644
--- a/modules/home.legacy/conf/rclone/default.nix
+++ b/modules/home.legacy/conf/rclone/default.nix
@@ -1,7 +1,3 @@
-{
-  config,
-  pkgs,
-  ...
-}: {
+{...}: {
   xdg.configFile."rclone/rclone.conf".source = ./rclone.conf;
 }
diff --git a/modules/home.legacy/conf/starship/default.nix b/modules/home.legacy/conf/starship/default.nix
index 5db6eb8b..5255ba66 100644
--- a/modules/home.legacy/conf/starship/default.nix
+++ b/modules/home.legacy/conf/starship/default.nix
@@ -1,7 +1,6 @@
 {
   lib,
   nixosConfig,
-  pkgs,
   ...
 }: {
   programs.starship = {
diff --git a/modules/home.legacy/conf/swayidle/default.nix b/modules/home.legacy/conf/swayidle/default.nix
index 6b8a7d80..e0106cbf 100644
--- a/modules/home.legacy/conf/swayidle/default.nix
+++ b/modules/home.legacy/conf/swayidle/default.nix
@@ -1,8 +1,5 @@
-{
-  config,
-  pkgs,
-  ...
-}: {
+{...}: {
+  # TODO: This fails to hibernate when the hardware swap was not previously activated. <2025-04-04>
   xdg.configFile."swayidle/config".source = ./config;
 
   #  services.swayidle = {
diff --git a/modules/home.legacy/conf/swaylock/default.nix b/modules/home.legacy/conf/swaylock/default.nix
deleted file mode 100644
index 9e5eabac..00000000
--- a/modules/home.legacy/conf/swaylock/default.nix
+++ /dev/null
@@ -1,10 +0,0 @@
-{...}: {
-  programs.swaylock = {
-    enable = true;
-    settings = {
-      image = "${./GTDcanonical.png}";
-      scaling = "center";
-      color = "000000";
-    };
-  };
-}
diff --git a/modules/home.legacy/conf/taskwarrior/default.nix b/modules/home.legacy/conf/taskwarrior/default.nix
deleted file mode 100644
index d7aec156..00000000
--- a/modules/home.legacy/conf/taskwarrior/default.nix
+++ /dev/null
@@ -1,125 +0,0 @@
-{
-  nixosConfig,
-  lib,
-  config,
-  ...
-}: {
-  imports = [
-    ./hooks
-  ];
-
-  services.taskwarrior-sync = {
-    enable = true;
-  };
-
-  programs.taskwarrior = let
-    projects = import ./projects {};
-
-    mkContext = project:
-      if builtins.hasAttr "subprojects" project
-      then
-        lib.lists.flatten (
-          (builtins.map mkContext (builtins.map (mkProject project) project.subprojects))
-          ++ (mkContext (builtins.removeAttrs project ["subprojects"]))
-        )
-      else [
-        {
-          inherit (project) name;
-          value = let
-            name =
-              if builtins.hasAttr "pname" project
-              then project.pname
-              else project.name;
-          in {
-            read = "project:${name}";
-            write = "project:${name}";
-            rc = {
-              neorg_path =
-                if builtins.hasAttr "neorg_path" project
-                then project.neorg_path
-                else "${project.prefix}/${project.name}/index.norg";
-            };
-          };
-        }
-      ];
-    mkProject = project: subproject: let
-      pname =
-        if builtins.hasAttr "pname" project
-        then project.pname
-        else project.name;
-    in
-      if builtins.isString subproject
-      then {
-        name = "${project.name}_${subproject}";
-        pname = "${pname}.${subproject}";
-        neorg_path =
-          if builtins.hasAttr "neorg_path_prefix" project
-          then "${project.neorg_path_prefix}/${subproject}/index.norg"
-          else "${project.prefix}/${project.name}/${subproject}/index.norg";
-      }
-      else if builtins.isAttrs subproject
-      then let
-        name = builtins.elemAt (builtins.attrNames subproject) 0;
-      in {
-        name = "${project.name}_${name}";
-        pname = "${pname}.${name}";
-        prefix = "${project.prefix}/${project.name}";
-        neorg_path_prefix = "${project.prefix}/${project.name}/${name}";
-        subprojects = builtins.elemAt (builtins.attrValues subproject) 0;
-      }
-      else builtins.throw "Subproject not a string or a attrs: ${subproject}";
-
-    context =
-      builtins.listToAttrs (lib.lists.flatten (builtins.map mkContext projects));
-  in {
-    enable = true;
-    colorTheme = ./nord.theme;
-    extraConfig = ''
-      # This include just contains my taskd user credentials
-      include ${nixosConfig.age.secrets.taskserverCredentials.path}
-    '';
-    config = {
-      news.version = "2.6.0";
-      complete.all.tags = true;
-      list.all = {
-        projects = true;
-        tags = true;
-      };
-      regex = true;
-      weekstart = "Monday";
-      uda = {
-        total_active_time = {
-          type = "duration";
-          label = "Total active time";
-        };
-      };
-      alias = {
-        mod = "modify";
-        n = "execute neorg --task";
-        fstart = "execute neorg fstart";
-      };
-      color = true;
-
-      hooks.location = "${config.xdg.configHome}/task/hooks";
-
-      urgency.uda.priority = {
-        H.coefficient = 6.0;
-        M.coefficient = 0;
-        L.coefficient = -1.8;
-      };
-
-      inherit context;
-
-      taskd = {
-        server = "taskserver.vhack.eu:53589";
-        trust = "strict";
-        ca =
-          nixosConfig.age.secrets.taskserverCA.path;
-        key =
-          nixosConfig.age.secrets.taskserverPrivate.path;
-        certificate =
-          nixosConfig.age.secrets.taskserverPublic.path;
-      };
-    };
-  };
-}
diff --git a/modules/home.legacy/conf/taskwarrior/firefox/default.nix b/modules/home.legacy/conf/taskwarrior/firefox/default.nix
deleted file mode 100644
index fb5daaa8..00000000
--- a/modules/home.legacy/conf/taskwarrior/firefox/default.nix
+++ /dev/null
@@ -1,32 +0,0 @@
-{
-  config,
-  lib,
-  # options
-  prefConfig,
-  profile_size,
-  search,
-  userChrome,
-  ...
-}: let
-  inherit (config.soispha.taskwarrior.projects) projects;
-
-  mkFirefoxProfile = {
-    name,
-    id,
-  }: {
-    inherit name;
-    value = {
-      isDefault = false;
-      extraConfig = prefConfig;
-      inherit id name search userChrome;
-    };
-  };
-  projects_id =
-    lib.imap0 (id: project: {
-      name = project;
-      id = id + profile_size;
-    })
-    projects;
-  firefoxProfiles = builtins.listToAttrs (builtins.map mkFirefoxProfile projects_id);
-in
-  firefoxProfiles
diff --git a/modules/home.legacy/conf/taskwarrior/hooks/default.nix b/modules/home.legacy/conf/taskwarrior/hooks/default.nix
deleted file mode 100644
index ef97e1b5..00000000
--- a/modules/home.legacy/conf/taskwarrior/hooks/default.nix
+++ /dev/null
@@ -1,114 +0,0 @@
-{
-  sysLib,
-  pkgs,
-  lib,
-  config,
-  ...
-}: let
-  mkProject = project: subproject:
-    if builtins.isString subproject
-    then {
-      name = "${project.name}.${subproject}";
-      prefix = null;
-    }
-    else let
-      name = builtins.elemAt (builtins.attrNames subproject) 0;
-    in {
-      name = "${project.name}.${name}";
-      subprojects = builtins.elemAt (builtins.attrValues subproject) 0;
-      prefix = null;
-    };
-
-  mkProjectName = project:
-    if builtins.hasAttr "subprojects" project
-    then
-      lib.lists.flatten ([project.name]
-        ++ (builtins.map mkProjectName
-          (builtins.map (mkProject project) project.subprojects)))
-    else [project.name];
-  projects = lib.lists.unique (lib.lists.naturalSort (lib.lists.flatten (builtins.map mkProjectName (import ../projects {}))));
-  projects_newline = builtins.concatStringsSep "\n" projects;
-  projects_comma = builtins.concatStringsSep ", " projects;
-  projects_pipe = builtins.concatStringsSep "|" projects;
-
-  enforce_policies = sysLib.writeShellScript {
-    name = "bin";
-    src = ./scripts/on-add_enforce-policies.sh;
-    dependencies = with pkgs; [dash jq taskwarrior gnused gnugrep];
-    replacementStrings = {
-      PROJECTS_NEWLINE = projects_newline;
-      PROJECTS_COMMA = projects_comma;
-    };
-  };
-  track_timewarrior = pkgs.stdenv.mkDerivation {
-    name = "track_timewarrior.taskwarrior-hook";
-    nativeBuildInputs = [
-      pkgs.makeWrapper
-    ];
-    buildInputs = [
-      pkgs.timewarrior
-      pkgs.taskwarrior
-      # TODO: Use a `taskw` package, that actually supports newer python variants <2024-07-13>
-      (pkgs.python311.withPackages (pythonPackages:
-        with pythonPackages; [
-          taskw
-        ]))
-    ];
-    dontUnpack = true;
-    installPhase = ''
-      install -Dm755 ${./scripts/on-modify_track-timewarrior.py} $out/bin/bin
-      wrapProgram $out/bin/bin \
-      --prefix PATH : ${lib.makeBinPath [pkgs.taskwarrior pkgs.timewarrior]}
-    '';
-  };
-  track_total_active_time = pkgs.stdenv.mkDerivation {
-    name = "track_total_active_time.taskwarrior-hook";
-    nativeBuildInputs = [
-      pkgs.makeWrapper
-    ];
-    buildInputs = [
-      pkgs.taskwarrior
-      # TODO: Use a `taskw` package, that actually supports newer python variants <2024-07-13>
-      (pkgs.python311.withPackages (pythonPackages:
-        with pythonPackages; [
-          taskw
-        ]))
-    ];
-    dontUnpack = true;
-    installPhase = ''
-      install -Dm755 ${./scripts/on-modify_track-total-active-time.py} $out/bin/bin
-      wrapProgram $out/bin/bin \
-      --prefix PATH : ${lib.makeBinPath [pkgs.taskwarrior]}
-    '';
-  };
-
-  mkSyncGitRepo = type: {
-    name = "${hookPath}/${type}_sync-git-repo";
-    value = {
-      source = "${sysLib.writeShellScript {
-        name = "bin";
-        src = ./scripts + "/${type}_sync-git-repo.sh";
-        dependencies = with pkgs; [dash taskwarrior git];
-      }}/bin/bin";
-    };
-  };
-  sync_git_repos =
-    builtins.listToAttrs (builtins.map mkSyncGitRepo ["on-add" "on-modify"]);
-  hookPath = config.programs.taskwarrior.config.hooks.location;
-in {
-  options.soispha.taskwarrior.projects = lib.mkOption {
-    type = lib.types.attrs;
-  };
-  config = {
-    soispha.taskwarrior.projects = {
-      inherit projects_newline projects_comma projects projects_pipe;
-    };
-    home.file =
-      {
-        "${hookPath}/on-add_enforce-policies".source = "${enforce_policies}/bin/bin";
-        "${hookPath}/on-modify_track-timewarrior".source = "${track_timewarrior}/bin/bin";
-        "${hookPath}/on-modify_track-total-active-time".source = "${track_total_active_time}/bin/bin";
-      }
-      // sync_git_repos;
-  };
-}
diff --git a/modules/home.legacy/conf/taskwarrior/hooks/scripts/on-add_enforce-policies.sh b/modules/home.legacy/conf/taskwarrior/hooks/scripts/on-add_enforce-policies.sh
deleted file mode 100755
index eaf7f30c..00000000
--- a/modules/home.legacy/conf/taskwarrior/hooks/scripts/on-add_enforce-policies.sh
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
-# override shell lib output to stdout
-eprint() {
-    # shellcheck disable=SC2317
-    print "$@"
-}
-eprintln() {
-    # shellcheck disable=SC2317
-    println "$@"
-}
-
-enable_hook_dbg() {
-    debug_hooks="$(task _get rc.debug.hooks)"
-    [ "$debug_hooks" ] && [ "$debug_hooks" -ge 1 ] && dbg_enable
-}
-
-enforce_project() {
-    project="$(jq '.project' "$(ptmp "$1")")"
-    [ "$project" = "null" ] && die "No project supplied!"
-
-    if grep -q "^$(echo "$project" | sed 's|"\(.*\)"|\1|')\$" "$(ptmp "%PROJECTS_NEWLINE")"; then
-        dbg "project('$project') is a valid part of %PROJECTS_COMMA"
-    else
-        die "The project '$(echo "$project" | sed 's|"||g')' is not registered with the nix config, registered projects: %PROJECTS_COMMA"
-    fi
-}
-
-read -r new_task
-# We don't change the task, thus immediately return the json
-echo "$new_task"
-
-enable_hook_dbg
-enforce_project "$new_task"
-
-exit 0
-
-# vim: ft=sh
diff --git a/modules/home.legacy/conf/taskwarrior/hooks/scripts/on-add_sync-git-repo.sh b/modules/home.legacy/conf/taskwarrior/hooks/scripts/on-add_sync-git-repo.sh
deleted file mode 100755
index dadc96b0..00000000
--- a/modules/home.legacy/conf/taskwarrior/hooks/scripts/on-add_sync-git-repo.sh
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
-# override shell lib output to stdout
-eprint() {
-    # shellcheck disable=SC2317
-    print "$@"
-}
-eprintln() {
-    # shellcheck disable=SC2317
-    println "$@"
-}
-
-enable_hook_dbg() {
-    debug_hooks="$(task _get rc.debug.hooks)"
-    [ "$debug_hooks" ] && [ "$debug_hooks" -ge 1 ] && dbg_enable
-}
-
-update_git_repo() {
-    task_data="$(task _get rc.data.location)"
-    [ "$task_data" ] || die "Taskwarrior should have a location set"
-
-    cd "$task_data" || die "(BUG?): Your data.location path is not accessable"
-
-    [ -d ./.git/ ] || git init
-
-    git add .
-    git commit --message="chore: Update" --no-gpg-sign
-}
-
-read -r new_task
-# We don't change the task, thus immediately return the json
-echo "$new_task"
-
-enable_hook_dbg
-update_git_repo
-
-exit 0
-
-# vim: ft=sh
diff --git a/modules/home.legacy/conf/taskwarrior/hooks/scripts/on-modify_sync-git-repo.sh b/modules/home.legacy/conf/taskwarrior/hooks/scripts/on-modify_sync-git-repo.sh
deleted file mode 100755
index 25813e46..00000000
--- a/modules/home.legacy/conf/taskwarrior/hooks/scripts/on-modify_sync-git-repo.sh
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
-# override shell lib output to stdout
-eprint() {
-    # shellcheck disable=SC2317
-    print "$@"
-}
-eprintln() {
-    # shellcheck disable=SC2317
-    println "$@"
-}
-
-enable_hook_dbg() {
-    debug_hooks="$(task _get rc.debug.hooks)"
-    [ "$debug_hooks" ] && [ "$debug_hooks" -ge 1 ] && dbg_enable
-}
-
-update_git_repo() {
-    task_data="$(task _get rc.data.location)"
-    [ "$task_data" ] || die "Taskwarrior should have a location set"
-
-    cd "$task_data" || die "(BUG?): Your data.location path is not accessable"
-
-    [ -d ./.git/ ] || git init
-
-    git add .
-    git commit --message="chore: Update" --no-gpg-sign
-}
-
-read -r _old_task
-read -r new_task
-# We don't change the task, thus immediately return the json
-echo "$new_task"
-
-enable_hook_dbg
-update_git_repo
-
-exit 0
-
-# vim: ft=sh
diff --git a/modules/home.legacy/conf/taskwarrior/hooks/scripts/on-modify_track-timewarrior.py b/modules/home.legacy/conf/taskwarrior/hooks/scripts/on-modify_track-timewarrior.py
deleted file mode 100755
index b482af6a..00000000
--- a/modules/home.legacy/conf/taskwarrior/hooks/scripts/on-modify_track-timewarrior.py
+++ /dev/null
@@ -1,94 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-# Copyright (C) 2016-present Arctic Ice Studio <development@arcticicestudio.com>
-# Copyright (C) 2016-present Sven Greb <development@svengreb.de>
-
-# Project:    igloo
-# Repository: https://github.com/arcticicestudio/igloo
-# License:    MIT
-# References:
-#   https://taskwarrior.org/docs
-#   https://taskwarrior.org/docs/timewarrior
-#   timew(1)
-#   task(1)
-
-"""A Taskwarrior hook to track the time of a active task with Taskwarrior.
-
-This hook will extract all of the following for use as Timewarrior tags:
-
-* UUID
-* Project
-* Tags
-* Description
-* UDAs
-
-Note:
-    This hook requires Python 3 and is only compatible with Taskwarrior version greater or equal to 2.4!
-
-This hook is a fork from the `official on-modify.timewarrior hook`_.
-
-.. _`official on-modify.timewarrior hook`:
-   https://github.com/GothenburgBitFactory/timewarrior/blob/dev/ext/on-modify.timewarrior
-"""
-
-import subprocess
-import sys
-from json import loads, dumps
-from os import system
-from sys import stdin
-from taskw import TaskWarrior
-
-# Make no changes to the task, simply observe.
-old = loads(stdin.readline())
-new = loads(stdin.readline())
-print(dumps(new))
-
-
-w = TaskWarrior(config_filename=sys.argv[4].replace("rc:", ""))
-config = w.load_config(config_filename=sys.argv[4].replace("rc:", ""))
-if "max_active_tasks" in config:
-    MAX_ACTIVE = int(config["max_active_tasks"])
-else:
-    MAX_ACTIVE = 1
-
-
-# Extract attributes for use as tags.
-tags = [new["description"]]
-
-if "project" in new:
-    project = new["project"]
-    tags.append(project)
-    if "." in project:
-        tags.extend([tag for tag in project.split(".")])
-
-if "tags" in new:
-    tags.extend(new["tags"])
-
-combined = " ".join(["'%s'" % tag for tag in tags]).encode("utf-8").strip()
-
-# Task has been started.
-if "start" in new and "start" not in old:
-    # Prevent this task from starting if "task +ACTIVE count" is greater than "MAX_ACTIVE".
-    p = subprocess.Popen(
-        ["task", "+ACTIVE", "status:pending", "count", "rc.verbose:off"],
-        stdout=subprocess.PIPE,
-    )
-    out, err = p.communicate()
-    count = int(out.rstrip())
-    if count >= MAX_ACTIVE:
-        print(
-            "Only %d task(s) can be active at a time. "
-            "See 'max_active_tasks' in .taskrc." % MAX_ACTIVE
-        )
-        sys.exit(1)
-
-    system("timew start " + combined.decode() + " :yes")
-
-# Task has been stopped.
-elif "start" not in new and "start" in old:
-    system("timew stop " + combined.decode() + " :yes")
-
-# Any task that is active, with a non-pending status should not be tracked.
-elif "start" in new and new["status"] != "pending":
-    system("timew stop " + combined.decode() + " :yes")
diff --git a/modules/home.legacy/conf/taskwarrior/projects/default.nix b/modules/home.legacy/conf/taskwarrior/projects/default.nix
deleted file mode 100644
index c5c55059..00000000
--- a/modules/home.legacy/conf/taskwarrior/projects/default.nix
+++ /dev/null
@@ -1,123 +0,0 @@
-{}: [
-  {
-    name = "me";
-    prefix = "";
-    subprojects = ["health" "sweden" "bank" "google"];
-  }
-  {
-    name = "timesinks";
-    prefix = "";
-    subprojects = ["youtube" "games" "netflix" "music"];
-  }
-  {
-    name = "input";
-    prefix = "research";
-    subprojects = ["read-things" "dotfiles"];
-  }
-  {
-    name = "book";
-    prefix = "book";
-  }
-  {
-    name = "aoc";
-    prefix = "programming/advent_of_code";
-  }
-  {
-    name = "camera";
-    prefix = "programming/zig";
-    subprojects = [];
-  }
-  {
-    name = "trinitrix";
-    prefix = "programming/rust";
-    subprojects = ["testing" "documentation"];
-  }
-  {
-    name = "serverphone";
-    prefix = "programming/rust";
-  }
-  {
-    name = "latex";
-    prefix = "programming/latex";
-  }
-  {
-    name = "presentation";
-    prefix = "research";
-  }
-  {
-    name = "possible-projects";
-    prefix = "research";
-  }
-  {
-    name = "school";
-    prefix = "research";
-    subprojects = [
-      "biologie"
-      "chemie"
-      "deutsch"
-      "english"
-      "geographie"
-      "geschichte"
-      "infomatik"
-      "klausuren"
-      "latein"
-      "mathematik"
-      "musik"
-      "philosophie"
-      "physik"
-      "sozialkunde"
-      "sport"
-      {extern = ["bwinf" "dsa"];}
-      {chemie = ["facharbeit"];} # TODO: Remove once the ff tabs are cleared <2024-05-10>
-    ];
-  }
-  {
-    name = "hardware";
-    prefix = "research";
-  }
-  {
-    name = "buy";
-    prefix = "buy";
-    subprojects = ["books" "pc"];
-  }
-  {
-    name = "system";
-    prefix = "config";
-    subprojects = [
-      "youtube"
-      "backup"
-      "bar"
-      "email"
-      "firefox"
-      "gpg"
-      "keyboard"
-      "laptop"
-      "nvim"
-      "rss"
-      "shell"
-      "task"
-      "wm"
-    ];
-  }
-  {
-    name = "server";
-    prefix = "config";
-    subprojects = [
-      "b-peetz"
-      "email"
-      "blog"
-      "nix-sync"
-      "sudo-less"
-      "ci"
-    ];
-  }
-  {
-    name = "3d-printer";
-    prefix = "hardware";
-  }
-  {
-    name = "smartphone";
-    prefix = "hardware";
-    subprojects = ["airplay" "airdrop"];
-  }
-]
diff --git a/modules/home.legacy/conf/timewarrior/default.nix b/modules/home.legacy/conf/timewarrior/default.nix
deleted file mode 100644
index bcb627f5..00000000
--- a/modules/home.legacy/conf/timewarrior/default.nix
+++ /dev/null
@@ -1,22 +0,0 @@
-{pkgs, ...}: {
-  home.packages = [
-    pkgs.timewarrior
-  ];
-  xdg.configFile."timewarrior/timewarrior.cfg".text = ''
-    # source: https://github.com/arcticicestudio/igloo
-    #+----+
-    #+ UI +
-    #+----+
-    import ${./nord.theme}
-    color = true
-
-    #+---------+
-    #+ Reports +
-    #+---------+
-    define reports:
-      day:
-        lines = 10
-        month = true
-        week = true
-  '';
-}
diff --git a/modules/home.legacy/conf/xdg/default.nix b/modules/home.legacy/conf/xdg/default.nix
deleted file mode 100644
index 4099720d..00000000
--- a/modules/home.legacy/conf/xdg/default.nix
+++ /dev/null
@@ -1,63 +0,0 @@
-{
-  sysLib,
-  pkgs,
-  config,
-  ...
-}: let
-  url_handler = sysLib.writeShellScript {
-    name = "url_handler";
-    src = ./url_handler.sh;
-    keepPath = true;
-    # Naming dependencies for this will be difficult, as it depend on overridden packages.
-    dependencies = with pkgs; [
-      rofi
-      libnotify
-      zathura
-    ];
-    replacementStrings = {
-      ALL_PROJECTS_PIPE = "${config.soispha.taskwarrior.projects.projects_pipe}";
-    };
-  };
-in {
-  imports = [
-    ./xdg_vars.nix
-  ];
-
-  xdg = {
-    mimeApps = {
-      enable = true;
-      defaultApplications = {
-        "application/pdf" = ["url_handler.desktop"];
-        "application/x-pdf" = ["url_handler.desktop"];
-
-        "text/html" = ["url_handler.desktop"];
-        "text/xml" = ["url_handler.desktop"];
-        "x-scheme-handler/http" = ["url_handler.desktop"];
-        "x-scheme-handler/https" = ["url_handler.desktop"];
-        "x-scheme-handler/about" = ["url_handler.desktop"];
-        "x-scheme-handler/unknown" = ["url_handler.desktop"];
-      };
-    };
-    desktopEntries = {
-      url_handler = {
-        name = "url_handler";
-        genericName = "Web Browser";
-        exec = "${url_handler}/bin/url_handler %u";
-        terminal = false;
-        categories = [
-          "Application"
-          "Network"
-          "WebBrowser"
-        ];
-        mimeType = [
-          "text/html"
-          "text/xml"
-          "x-scheme-handler/http"
-          "x-scheme-handler/https"
-          "x-scheme-handler/about"
-          "x-scheme-handler/unknown"
-        ];
-      };
-    };
-  };
-}
diff --git a/modules/home.legacy/conf/xdg/url_handler.sh b/modules/home.legacy/conf/xdg/url_handler.sh
deleted file mode 100755
index 95eedffb..00000000
--- a/modules/home.legacy/conf/xdg/url_handler.sh
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
-project="$(echo "%ALL_PROJECTS_PIPE|nvim|zathura|" | rofi -sep "|" -dmenu)"
-
-if [ "$project" = "nvim" ]; then
-    "$TERMINAL" -e nvim "$1"
-elif [ "$project" = "zathura" ]; then
-    zathura "$1"
-elif [ "$project" ]; then
-    firefox -P "$project" "$1"
-else
-    notify-send "(URL HANDLER) No project selected" && exit 1
-fi
-
-# vim: ft=sh
diff --git a/modules/home.legacy/conf/xdg/xdg_vars.nix b/modules/home.legacy/conf/xdg/xdg_vars.nix
deleted file mode 100644
index aa2f30d4..00000000
--- a/modules/home.legacy/conf/xdg/xdg_vars.nix
+++ /dev/null
@@ -1,29 +0,0 @@
-{config, ...}: let
-  inherit (config.xdg) dataHome;
-in {
-  # FIXME: Move these options in relevant modules, that are connected to their software.
-  #        <2024-10-21>
-
-  # Variables that only have to be set because special applications fail to set reasonable
-  # defaults (mostly understandable because of backwards-compatibility, but yeah)
-  home.sessionVariables = {
-    CARGO_HOME = "${dataHome}/cargo";
-    GRADLE_USER_HOME = "${dataHome}/gradle";
-
-    #_JAVA_OPTIONS = lib.concatStringsSep " " [
-    #        ''-Djava.util.prefs.userRoot="${config.xdg.configHome}/java"''
-    #        ''-Djavafx.cachedir="${config.xdg.cacheHome}/openjfx"''
-    #      ];
-    #GOPATH = "${config.xdg.dataHome}/go";
-    #GTK2_RC_FILES = "${config.xdg.configHome}/gtk-2.0/gtkrc";
-    #RUSTUP_HOME = "${config.xdg.dataHome}/rustup";
-    #NPM_CONFIG_USERCONFIG = "${config.xdg.configHome}/npm/npmrc";
-    #NUGET_PACKAGES = "${config.xdg.cacheHome}/NuGetPackages";
-    #XAUTHORITY = "${config.xdg.stateHome}/Xauthority";
-    #COMPDUMPFILE = "${config.xdg.dataHome}/zsh/.zcompdump}";
-    #IPYTHONDIR = "${config.xdg.configHome}/ipython";
-    #PARALLEL_HOME = "${config.xdg.configHome}/parallel";
-    #STACK_XDG = "1";
-    #WINEPREFIX = "${config.xdg.dataHome}/wine";
-  };
-}
diff --git a/modules/home.legacy/conf/ytcc/default.nix b/modules/home.legacy/conf/ytcc/default.nix
deleted file mode 100644
index 87300ec1..00000000
--- a/modules/home.legacy/conf/ytcc/default.nix
+++ /dev/null
@@ -1,11 +0,0 @@
-{
-  config,
-  pkgs,
-  ...
-}: {
-  xdg.configFile."ytcc/ytcc.conf".source = pkgs.substituteAll {
-    src = ./ytcc.conf;
-    download_dir = "${config.xdg.userDirs.download}/ytcc";
-    xdg_data_home = config.xdg.dataHome;
-  };
-}
diff --git a/modules/home.legacy/conf/ytcc/ytcc.conf b/modules/home.legacy/conf/ytcc/ytcc.conf
deleted file mode 100644
index 289843ad..00000000
--- a/modules/home.legacy/conf/ytcc/ytcc.conf
+++ /dev/null
@@ -1,37 +0,0 @@
-[ytcc]
-download_dir = @download_dir@
-mpv_flags = --really-quiet --ytdl --ytdl-format=bestvideo[height<=?1080]+bestaudio/best --speed=2.7
-download_subdirs = true
-order_by = playlists:asc, publish_date:desc
-video_attrs = id, title, publish_date, duration, playlists
-playlist_attrs = name, url, tags, reverse
-db_path = @xdg_data_home@/ytcc/ytcc.db
-date_format = %Y-%m-%d
-max_update_fail = 5
-max_update_backlog = 20
-age_limit = 0
-
-[tui]
-alphabet = sdfervghnuiojkl
-default_action = play_video
-
-[theme]
-prompt_download_audio = 2
-prompt_download_video = 4
-prompt_play_audio = 2
-prompt_play_video = 4
-prompt_mark_watched = 1
-table_alternate_background = 245
-plain_label_text = 244
-
-[youtube_dl]
-format = bestvideo[height<=?1080]+bestaudio/best
-output_template = %(title)s.%(ext)s
-ratelimit = 0
-retries = 0
-subtitles = off
-thumbnail = true
-skip_live_stream = true
-merge_output_format = mkv
-max_duration = 0
-restrict_filenames = false
diff --git a/modules/home.legacy/default.nix b/modules/home.legacy/default.nix
index de6fec25..706e2045 100644
--- a/modules/home.legacy/default.nix
+++ b/modules/home.legacy/default.nix
@@ -1,6 +1,7 @@
 {
   nixVim,
   nix-index-database,
+  arkenfox-nixos,
   ...
 }: let
   username = "soispha";
@@ -18,10 +19,10 @@ in {
     ./conf
     ./files
     ./pkgs
-    ./wms
 
     nixVim.homeManagerModules.nixvim
     nix-index-database.hmModules.nix-index
+    arkenfox-nixos.hmModules.arkenfox
   ];
 
   # I don't know what this does, but I've seen it a lot online, so it should be good, right?
diff --git a/modules/home.legacy/files/default.nix b/modules/home.legacy/files/default.nix
index 16fe9afe..50b340b8 100644
--- a/modules/home.legacy/files/default.nix
+++ b/modules/home.legacy/files/default.nix
@@ -1,6 +1,5 @@
 {...}: {
   imports = [
-    ./wallpaper
     ./manifest_json
   ];
 }
diff --git a/modules/home.legacy/files/wallpaper/default.nix b/modules/home.legacy/files/wallpaper/default.nix
deleted file mode 100644
index 119df225..00000000
--- a/modules/home.legacy/files/wallpaper/default.nix
+++ /dev/null
@@ -1,14 +0,0 @@
-{config, ...}: {
-  home = {
-    sessionVariables = {
-      WALLPAPER = "${config.home.homeDirectory}/media/pictures/wallpaper";
-    };
-
-    file = {
-      wallpaper = {
-        source = ./abstract-nord.png;
-        target = "media/pictures/wallpaper";
-      };
-    };
-  };
-}
diff --git a/modules/home.legacy/pkgs/default.nix b/modules/home.legacy/pkgs/default.nix
index 1a4c4a1b..31942f0d 100644
--- a/modules/home.legacy/pkgs/default.nix
+++ b/modules/home.legacy/pkgs/default.nix
@@ -1,51 +1,22 @@
 {
   pkgs,
   lib,
-  config,
   nixosConfig,
   ...
 }:
-# TODO: Remove this whole file, and move each pkgs to a separate module. <2024-11-16>
+# TODO: Remove this whole file, and move each package to a separate module. <2024-11-16>
 with pkgs; let
   Gui = {
     Terminals = [
-      # foot # wayland native terminal
       alacritty # default terminal
     ];
-    Browsers = [
-      #ungoogled-chromium # web browser (only for web programming)
-      #brave
-    ];
-
-    ImageManipulation = [
-      #krita # new, and better (KDE)
-      #gimp # conservative, and old (GNOME)
-    ];
-
-    Social = [
-      mumble # voice chat software (client)
-      # lutris # multiple game store clients
-
-      # nheko # best matrix client (as of today)
-      # element-desktop  # nheko didn't work
-      signal-desktop # to avoid encryption problems with signal-bridge
-    ];
 
     Misc = [
-      #kalzium # Periodic Table of Elements (`element` is [sort of] better)
       keepassxc # password manager
-      #onlykey # OnlyKey Chrome Desktop App
-      anki-bin # spaced repetition
     ];
   };
 
   TuiCli = {
-    EyeCandy = [
-      #banner # Print large banners to ASCII terminals
-      cmatrix # A curses-based scrolling 'Matrix'-like screen
-      hyfetch # Neofetch with LGBTQ pride flags.
-    ];
-
     Social = [
       iamb # best tui matrix client (as of today)
     ];
@@ -55,16 +26,10 @@ with pkgs; let
     ];
 
     Misc = [
-      android-file-transfer # Android MTP client with minimalistic UI
-      #xdg-ninja # A shell script which checks your $HOME for unwanted files and directories.
-      xdg-utils # open urls and such things
-      yokadi # Command line oriented, sqlite powered, todo list
       killall # kill a application by name
       snap-sync-forked # A btrfs based backup solution
       bc # Smart calculator
       aumo # Automatic mount
-      nato # Encodes a string in the standardized spelling alphabet
-      virsh-del # Delete a libvirt virtual machine (not really used anymore).
       jq # Json parser
     ];
 
@@ -75,58 +40,30 @@ with pkgs; let
       ];
 
       Firefox = [
-        # `neorg` handles the integration between Firefox profiles and task
+        # `tskm` handles the integration between Firefox profiles and task
         # contexts
-        (neorg.override
-          {
-            defaultNeorgProjectDir = config.programs.nixvim.plugins.neorg.settings.load."core.dirman".config.workspaces.projects;
-            allProjectsNewline = config.soispha.taskwarrior.projects.projects_newline;
-            allProjectsComma = config.soispha.taskwarrior.projects.projects_comma;
-            allProjectsPipe = config.soispha.taskwarrior.projects.projects_pipe;
-            allWorkspaces = config.programs.nixvim.plugins.neorg.settings.load."core.dirman".config.workspaces;
-            xdgConfigHome = config.xdg.configHome;
-            xdgDataHome = config.xdg.dataHome;
-          })
+        pkgs.tskm
       ];
     };
 
     WM = {
-      river = [river]; # A dynamic tiling wayland compositor
-
       CLITools = [
-        lswt # List Wayland toplevels.
         wl-clipboard # Command-line copy/paste utilities.
-        swaylock # My current lockscreen implementation.
-      ];
-
-      Media = [
-        wf-recorder # Screen recorder.
-        libnotify # a command to send a notification.
-        screenshot_persistent # Creates a persisting screenshot.
-        screenshot_temporary # Takes a screenshot and stores it in the clipboard.
       ];
     };
 
     Media = {
       View = [
-        imv # Image viewer
         zathura # PDF viewer
       ];
 
       YouTube = [
-        yti # Wrapper around `yt-dlp`.
         yt # A command line YouTube client
       ];
-
-      Listen = [
-        spodi # Wrapper around `spotdl`.
-        sort_song # Sorts songs in the current directory.
-      ];
     };
 
     Hardware = {
       Storage = [
-        #compsize # Calculate compression ratio of a set of files on Btrfs
         # TODO: smartmontools # Control and monitor S.M.A.R.T. enabled ATA and SCSI Hard Drives
       ];
 
@@ -144,10 +81,6 @@ with pkgs; let
             backlightName = nixosConfig.soispha.laptop.backlight;
           }
         );
-
-      Input = [
-        #piper # GTK application to configure gaming mice
-      ];
     };
 
     SystemUpdate = [
@@ -159,33 +92,21 @@ with pkgs; let
       tree # A directory listing program displaying a depth indented list of files
       fd # Simple, fast and user-friendly alternative to find
       ripgrep # A search tool that combines the usability of ag with the raw speed of grep
-      fzf # used to quickly move around with its keybindings
       file # Show information about a file
       ll # Wrapper around `lf` to automatically change the path
       lm # Wrapper around `ll` to automatically cd to the last accessed path
     ];
 
-    Editors = [
-      ed # A POSIX-compliant line-oriented text editor
-      #sed # GNU stream editor
-      vim # The original ex/vi text editor (this is `vim` and not `vi`, as `vi` is unfree)
-      #neovim # Fork of Vim aiming to improve user experience, plugins, and GUIs
-    ];
-
     Programming = {
       GeneralTools = [
         stamp # Add a license header to a file
         git # the fast distributed version control system
-        git-absorb # git commit --fixup, but automatic
         git-edit-index # Allows you to edit the indexed version of a file
         git-cm # A wrapper that re-adds the last commit's subject
-        git-cleanup # An automatic merged branch deleter
         glow # Command-line markdown renderer
       ];
     };
   };
-  # TODO: unmaintained, find sth else:
-  # handlr # Powerful alternative to xdg-utils written in Rust
   mapFun = x:
     if builtins.isAttrs x
     then
@@ -194,7 +115,7 @@ with pkgs; let
       else builtins.attrValues x
     else [x];
 in {
-  home.packages =
+  config.home.packages =
     []
     ++ (with builtins;
       concatLists
diff --git a/modules/home.legacy/wms/default.nix b/modules/home.legacy/wms/default.nix
deleted file mode 100644
index 610ea2f4..00000000
--- a/modules/home.legacy/wms/default.nix
+++ /dev/null
@@ -1,7 +0,0 @@
-{config, ...}: {
-  imports = [
-    # ./sway
-    ./river
-    # ./plasma
-  ];
-}
diff --git a/modules/home.legacy/wms/plasma/default.nix b/modules/home.legacy/wms/plasma/default.nix
deleted file mode 100644
index f68ee272..00000000
--- a/modules/home.legacy/wms/plasma/default.nix
+++ /dev/null
@@ -1,5 +0,0 @@
-{config, ...}: {
-  services.xserver.enable = true;
-  services.xserver.displayManager.sddm.enable = true;
-  services.xserver.desktopManager.plasma5.enable = true;
-}
diff --git a/modules/home.legacy/wms/river/default.nix b/modules/home.legacy/wms/river/default.nix
deleted file mode 100644
index 9463e94e..00000000
--- a/modules/home.legacy/wms/river/default.nix
+++ /dev/null
@@ -1,91 +0,0 @@
-{
-  pkgs,
-  sysLib,
-  river_init_lesser,
-  nixosConfig,
-  system,
-  qmk_firmware,
-  ...
-}: let
-  inherit (nixosConfig.networking) hostName;
-  mappings =
-    if hostName == "tiamat"
-    then ''
-      err_fail riverctl keyboard-layout 'us-modified'
-      err_fail river_init_lesser ~/.config/river/res/moonlander.ron
-    ''
-    else if hostName == "lahmu" || hostName == "apzu" || hostName == "mammun" || hostName == "isimud"
-    then ''
-      err_fail riverctl keyboard-layout 'dvorak-modified'
-      err_fail river_init_lesser ~/.config/river/res/keys.ron
-    ''
-    else builtins.throw "Host not covered in river mappings";
-  screen_setup =
-    if hostName == "lahmu"
-    then ''
-      err_fail wlr-randr --output Virtual-1 --mode 1920x1080
-    ''
-    else if hostName == "tiamat"
-    then ''
-      err_fail wlr-randr --output DP-2 --pos 2560,0
-      err_fail wlr-randr --output DP-1 --scale 1.5 --pos 0,0
-      err_fail gammastep &
-    ''
-    else if hostName == "apzu" || hostName == "mammun" || hostName == "isimud"
-    then ''
-      err_fail gammastep &
-    ''
-    else builtins.throw "Host not covered in river screen setup";
-  env_vars = "XDG_CURRENT_DESKTOP=river DESKTOP_SESSION=river";
-  init_scr = pkgs.substituteAll {
-    src = ./init.sh;
-    inherit mappings screen_setup env_vars;
-  };
-in {
-  home.sessionVariables = {
-    WM = "river";
-    XDG_CURRENT_DESKTOP = "river";
-    DESKTOP_SESSION = "river";
-
-    # Export Wayland env Vars {{{
-    QT_QPA_PLATFORM = "wayland";
-    QT_QPA_PLATFORMTHEME = "qt5ct"; # needs qt5ct
-    CLUTTER_BACKEND = "wayland";
-    SDL_VIDEODRIVER = "wayland"; # might brake some things
-    # }}}
-  };
-
-  xdg.configFile."river/init".source =
-    sysLib.writeShellScript {
-      name = "river_init";
-      src = init_scr;
-      keepPath = true;
-      dependencies = builtins.attrValues {
-        river_init_lesser = river_init_lesser.packages.${system}.default;
-        inherit (qmk_firmware.packages.${system}) qmk_unicode_type;
-
-        inherit
-          (pkgs)
-          dash
-          river
-          glib # gnome lib
-          gammastep
-          wlr-randr
-          yambar
-          mako
-          swaybg
-          swayidle
-          swaylock
-          alacritty
-          ;
-      };
-    }
-    + /bin/river_init;
-
-  # TODO: These mappings should be generated in nix. (Which would allow to replace the
-  # `mpc` pat adding.) <2024-11-16>
-
-  # Needed for the key-mappings.
-  home.packages = [pkgs.mpc];
-  xdg.configFile."river/res".source = ./res;
-}
diff --git a/modules/home.legacy/wms/river/init.sh b/modules/home.legacy/wms/river/init.sh
deleted file mode 100755
index 06a2e2f4..00000000
--- a/modules/home.legacy/wms/river/init.sh
+++ /dev/null
@@ -1,80 +0,0 @@
-#!/usr/bin/env bash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
-err_fail() {
-    if ! "$@"; then
-        warning "\"$*\" failed!\n" >>~/river_log
-        # msg "Executing the safe init!"
-        # exec ~/.config/river/res/safe_init.sh
-    fi
-}
-err_fail rm ~/river_log
-exec 1>>"$HOME"/river_log
-exec 2>>"$HOME"/river_log
-
-#trap err_fail ERR
-
-#Setup of environment variables {{{
-err_fail riverctl spawn "exec dbus-update-activation-environment --systemd SEATD_SOCK DISPLAY WAYLAND_DISPLAY DESKTOP_SESSION=river XDG_CURRENT_DESKTOP=river"
-export @env_vars@
-#}}}
-
-# Setup of mappings {{{
-@mappings@
-# }}}
-
-# Setup of Rules {{{
-err_fail riverctl rule-add -app-id float -title '*' float
-err_fail riverctl rule-add -app-id mpv -title '*' float
-err_fail riverctl rule-add -app-id ModernGL -title '*' float
-err_fail riverctl rule-add -app-id '*' -title 'Manim Slides' float
-err_fail riverctl rule-add -app-id '*' -title 'floating please' float
-
-err_fail riverctl rule-add -app-id '*' -title '*' ssd
-err_fail riverctl rule-add -app-id firefox -title '*' csd # This remove the focus border around Firefox (which is useful because the Firefox is nearly always in its own tag.)
-# }}}
-
-# Set riverctl settings {{{
-# background
-err_fail riverctl background-color 0x002b36
-err_fail riverctl border-color-focused 0x93a1a1
-err_fail riverctl border-color-unfocused 0x586e75
-
-# keyboard repeat rate
-err_fail riverctl set-repeat 50 300
-
-# Cursor
-err_fail riverctl focus-follows-cursor normal
-#riverctl hide-cursor timeout 2000
-err_fail riverctl hide-cursor when-typing enabled
-err_fail riverctl set-cursor-warp on-output-change
-err_fail riverctl xcursor-theme Nordzy-cursors 24
-
-err_fail riverctl input pointer-1133-49970-Logitech_Gaming_Mouse_G502 pointer-accel 0
-err_fail riverctl input pointer-1133-49970-Logitech_Gaming_Mouse_G502 accel-profile none
-
-err_fail riverctl input pointer-12951-6505-ZSA_Technology_Labs_Moonlander_Mark_I pointer-accel 0
-err_fail riverctl input pointer-12951-6505-ZSA_Technology_Labs_Moonlander_Mark_I accel-profile none
-# }}}
-
-# Setup of general apps {{{
-@screen_setup@
-
-err_fail yambar &
-
-err_fail mako &
-err_fail swaybg -i "$WALLPAPER" &
-err_fail swayidle &
-err_fail alacritty &
-# }}}
-
-# Setup of layout [acts as exec!] {{{
-err_fail riverctl default-layout rivertile
-@env_vars@ rivertile -main-ratio 0.5 -view-padding 1 -outer-padding 0
-
-#riverctl default-layout luatile
-#river-luatile
-# }}}
-# vim: ft=sh
diff --git a/modules/home.legacy/wms/river/res/keys.ron b/modules/home.legacy/wms/river/res/keys.ron
deleted file mode 100644
index a2bc0fa1..00000000
--- a/modules/home.legacy/wms/river/res/keys.ron
+++ /dev/null
@@ -1,58 +0,0 @@
-#![enable(implicit_some)]
-RiverctlCommandArray(
-    commands: [
-    // Focus change
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "T",                       mods: "Super",          command: "focus-view",          command_args: "next",),
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "N",                       mods: "Super",          command: "focus-view",          command_args: "previous",),
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "T",                       mods: "Super+Control",  command: "focus-output",        command_args: "next",),
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "N",                       mods: "Super+Control",  command: "focus-output",        command_args: "previous",),
-
-    // Standard program
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "Return",                  mods: "Super",          command: "spawn",               command_args: "alacritty",),
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "q",                       mods: "Super+Shift",    command: "exit",                command_args: None,),
-
-    // Screenshot
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "Print",                   mods: "None",           command: "spawn",               command_args: "screenshot_persistent",),
-
-    // Audio
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "XF86AudioRaiseVolume",    mods: "None",           command: "spawn",               command_args: "pactl set-sink-volume 1 +5%",),
-    RiverctlCommand( map_mode: Map,         mode: ["normal", "locked"], key: "XF86AudioLowerVolume",    mods: "None",           command: "spawn",               command_args: "pactl set-sink-volume 1 -5%",),
-    RiverctlCommand( map_mode: Map,         mode: ["normal", "locked"], key: "XF86AudioMute",           mods: "None",           command: "spawn",               command_args: "mpc toggle",),
-
-    // Launcher
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "R",                       mods: "Super",          command: "spawn",               command_args: "rofi -show combi -modes combi -combi-modes 'window,drun,run' -show-icons",),
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "F1",                      mods: "Super",          command: "spawn",               command_args: "neorg dmenu",),
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "F2",                      mods: "Super",          command: "spawn",               command_args: "keepassxc",),
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "F3",                      mods: "Super",          command: "spawn",               command_args: "signal-desktop",),
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "F4",                      mods: "Super",          command: "spawn",               command_args: "steam",),
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "L",                       mods: "Super",          command: "spawn",               command_args: "lock",),
-
-    // Client
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "f",                       mods: "Super",          command: "toggle-fullscreen",   command_args: None,),
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "c",                       mods: "Super+Shift",    command: "close",               command_args: None,),
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "space",                   mods: "Super+Control",  command: "toggle-float",        command_args: None,),
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "Return",                  mods: "Super+Control",  command: "zoom",                command_args: None,),
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "o",                       mods: "Super",          command: "send-to-output",      command_args: "next",),
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "T",                       mods: "Super+Shift",    command: "swap",                command_args: "next",),
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "N",                       mods: "Super+Shift",    command: "swap",                command_args: "previous",),
-
-    // Toggle all tags
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "0",                       mods: "Super",          command: "set-focused-tags",    command_args: "4294967295"),
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "0",                       mods: "Super+Shift",    command: "set-view-tags",       command_args: "4294967295"),
-
-    // Mouse
-    RiverctlCommand( map_mode: MapMouse,    mode: ["normal"],           key: "BTN_LEFT",                mods: "Super",          command: "move-view",           command_args: None,),
-    RiverctlCommand( map_mode: MapMouse,    mode: ["normal"],           key: "BTN_RIGHT",               mods: "Super",          command: "resize-view",         command_args: None,),
-
-    ],
-    // Set these mappings for the tags 0-8 with key [1-9]
-    tags_number: 9,
-    tag_commands: [
-    RiverctlTagCommand( map_mode: Map, mode: ["normal"], mods: "Super",                 command: "set-focused-tags",),
-    RiverctlTagCommand( map_mode: Map, mode: ["normal"], mods: "Super+Shift",           command: "set-view-tags",),
-    RiverctlTagCommand( map_mode: Map, mode: ["normal"], mods: "Super+Control",         command: "toggle-focused-tags",),
-    RiverctlTagCommand( map_mode: Map, mode: ["normal"], mods: "Super+Shift+Control",   command: "toggle-view-tags",),
-    ],
-)
-
-// vim: nolinebreak nowrap textwidth=0
diff --git a/modules/home.legacy/wms/river/res/moonlander.ron b/modules/home.legacy/wms/river/res/moonlander.ron
deleted file mode 100644
index 247c1697..00000000
--- a/modules/home.legacy/wms/river/res/moonlander.ron
+++ /dev/null
@@ -1,66 +0,0 @@
-#![enable(implicit_some)]
-RiverctlCommandArray(
-    // TODO: add toggle-focus mapping
-    commands: [
-    // Movement
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "A", mods: "Alt+Control+Super+Shift", command: "exit",                 command_args: None,),
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "B", mods: "Alt+Control+Super+Shift", command: "close",                command_args: None,),
-
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "C", mods: "Alt+Control+Super+Shift", command: "focus-view",           command_args: "previous",),
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "D", mods: "Alt+Control+Super+Shift", command: "focus-view",           command_args: "next",),
-
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "E", mods: "Alt+Control+Super+Shift", command: "swap",                 command_args: "previous",),
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "F", mods: "Alt+Control+Super+Shift", command: "swap",                 command_args: "next",),
-
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "G", mods: "Alt+Control+Super+Shift", command: "zoom",                 command_args: None,),
-
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "H", mods: "Alt+Control+Super+Shift", command: "toggle-fullscreen",    command_args: None,),
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "I", mods: "Alt+Control+Super+Shift", command: "toggle-float",         command_args: None,),
-
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "J", mods: "Alt+Control+Super+Shift", command: "send-to-output",       command_args: "next",),
-
-
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "K", mods: "Alt+Control+Super+Shift", command: "spawn",                command_args: "alacritty",),
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "L", mods: "Alt+Control+Super+Shift", command: "spawn",                command_args: "screenshot_persistent",),
-
-    // Audio
-    // RiverctlCommand( map_mode: Map,         mode: ["normal", "locked"], key: "M", mods: "Alt+Control+Super+Shift", command: "spawn",                command_args: "video-pause toggle",),
-    RiverctlCommand( map_mode: Map,         mode: ["normal", "locked"], key: "N", mods: "Alt+Control+Super+Shift", command: "spawn",                command_args: "mpc toggle",),
-
-    // Launcher
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "O", mods: "Alt+Control+Super+Shift", command: "spawn",                command_args: "rofi -show combi -modes combi -combi-modes 'window,drun,run' -show-icons",),
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "P", mods: "Alt+Control+Super+Shift", command: "spawn",                command_args: "neorg dmenu",),
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "Q", mods: "Alt+Control+Super+Shift", command: "spawn",                command_args: "keepassxc",),
-    // RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "R", mods: "Alt+Control+Super+Shift", command: "spawn",                command_args: "nheko",),
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "S", mods: "Alt+Control+Super+Shift", command: "spawn",                command_args: "signal-desktop",),
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "T", mods: "Alt+Control+Super+Shift", command: "spawn",                command_args: "lock",),
-
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "U", mods: "Alt+Control+Super+Shift", command: "focus-output",         command_args: "next",),
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "V", mods: "Alt+Control+Super+Shift", command: "focus-previous-tags",  command_args: None,),
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "W", mods: "Alt+Control+Super+Shift", command: "send-to-previous-tags",command_args: None,),
-    //RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "X", mods: "Alt+Control+Super+Shift", command: "spawn",               command_args: "bemenu-run",),
-    //RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "Y", mods: "Alt+Control+Super+Shift", command: "spawn",               command_args: "bemenu-run",),
-
-
-    // Toggle all tags
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "0", mods: "Alt+Control+Super+Shift", command: "set-focused-tags",    command_args: "4294967295"),
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "0", mods: "Alt+Control+Shift",       command: "set-view-tags",       command_args: "4294967295"),
-
-    // Support Unicode input
-    RiverctlCommand( map_mode: Map,         mode: ["normal"],           key: "Z", mods: "Alt+Control+Super+Shift", command: "spawn",               command_args: "qmk-unicode-type 106 65377",),
-
-    // Mouse
-    RiverctlCommand( map_mode: MapMouse,    mode: ["normal"],           key: "BTN_LEFT",                mods: "Super",          command: "move-view",           command_args: None,),
-    RiverctlCommand( map_mode: MapMouse,    mode: ["normal"],           key: "BTN_RIGHT",               mods: "Super",          command: "resize-view",         command_args: None,),
-    ],
-
-    // Set these mappings for the tags 0-8 with key [1-9]
-    tags_number: 9,
-    tag_commands: [
-        RiverctlTagCommand( map_mode: Map, mode: ["normal"], mods: "Alt+Control+Super+Shift", command: "set-focused-tags",),
-        RiverctlTagCommand( map_mode: Map, mode: ["normal"], mods: "Alt+Control+Shift",       command: "set-view-tags",),
-        // TODO: RiverctlTagCommand( map_mode: Map, mode: ["normal"], mods: "Super+Control",         command: "toggle-focused-tags",),
-        // TODO: RiverctlTagCommand( map_mode: Map, mode: ["normal"], mods: "Super+Shift+Control",   command: "toggle-view-tags",),
-    ],
-)
-// vim: nolinebreak nowrap textwidth=0
diff --git a/modules/home.legacy/wms/sway/default.nix b/modules/home.legacy/wms/sway/default.nix
deleted file mode 100644
index bb3ddb49..00000000
--- a/modules/home.legacy/wms/sway/default.nix
+++ /dev/null
@@ -1,16 +0,0 @@
-# also requires:
-# security.polkit.enable = true;
-{lib, ...}: {
-  wayland.windowManager.sway = {
-    enable = true;
-    config = {
-      modifier = "Mod4";
-      # Use kitty as default terminal
-      terminal = "kitty";
-      startup = [
-        # Launch Firefox on start
-        {command = "firefox";}
-      ];
-    };
-  };
-}
diff --git a/pkgs/by-name/be/beetsExtraPlugins/package.nix b/pkgs/by-name/be/beetsExtraPlugins/package.nix
index 0da472fa..f019922e 100644
--- a/pkgs/by-name/be/beetsExtraPlugins/package.nix
+++ b/pkgs/by-name/be/beetsExtraPlugins/package.nix
@@ -1,3 +1,3 @@
-{pkgs, ...}: {
-  xtractor = pkgs.callPackage ./xtractor.nix {beets = pkgs.beetsPackages.beets-minimal;};
+{...}: {
+  # xtractor = pkgs.callPackage ./xtractor.nix {beets = pkgs.beetsPackages.beets-minimal;};
 }
diff --git a/pkgs/by-name/be/beetsExtraPlugins/xtractor.nix b/pkgs/by-name/be/beetsExtraPlugins/xtractor.nix
index 01c6207a..17981cdb 100644
--- a/pkgs/by-name/be/beetsExtraPlugins/xtractor.nix
+++ b/pkgs/by-name/be/beetsExtraPlugins/xtractor.nix
@@ -3,52 +3,56 @@
   fetchFromGitHub,
   python3Packages,
   beets,
-}:
-# FIXME: Find a way to update this derivation <2024-08-11>
-let
-  version = "0.4.2";
-  models = builtins.fetchTarball {
-    url = "https://essentia.upf.edu/svm_models/essentia-extractor-svm_models-v2.1_beta5.tar.gz";
-    sha256 = "11ps1l4h8bl4l9rlvkhjs61908l18dh7mpq65brm8ki99hnp9g64";
-  };
-in
-  python3Packages.buildPythonApplication {
-    inherit version;
-    pname = "beets-xtractor";
-    pyproject = true;
+}: {}
+# # NOTE: This fails to build now. It didn't work anyways. See
+# https://git.sr.ht/~johnhamelink/nix/tree/master/item/home/hosts/sun/beets/beets-plugin-xtractor.nix
+# for a possibly working version. <2025-03-29>
+# # FIXME: Find a way to update this derivation <2024-08-11>
+# let
+#   version = "0.4.2";
+#   models = builtins.fetchTarball {
+#     url = "https://essentia.upf.edu/svm_models/essentia-extractor-svm_models-v2.1_beta5.tar.gz";
+#     sha256 = "11ps1l4h8bl4l9rlvkhjs61908l18dh7mpq65brm8ki99hnp9g64";
+#   };
+# in
+#   python3Packages.buildPythonApplication {
+#     inherit version;
+#     pname = "beets-xtractor";
+#     pyproject = true;
+#
+#     src = fetchFromGitHub {
+#       repo = "BeetsPluginXtractor";
+#       owner = "adamjakab";
+#       rev = "v${version}";
+#       hash = "sha256-it4qQ2OS4qBEaGLJK8FVGpjlvg0MQICazV7TAM8lH9s=";
+#     };
+#
+#     nativeBuildInputs = [
+#       beets
+#       python3Packages.setuptools
+#     ];
+#
+#     passthru = {inherit models;};
+#
+#     nativeCheckInputs = with python3Packages; [
+#       pytestCheckHook
+#       pytest-cov
+#       mock
+#       typeguard
+#     ];
+#
+#     preCheck = ''
+#       export HOME="$(mktemp -d)"
+#     '';
+#     postInstall = ''
+#       mkdir --parents $out/models
+#       cp ${models}/* $out/models
+#     '';
+#
+#     meta = {
+#       description = "Obtain low and high level musical information from your song";
+#       homepage = "https://github.com/adamjakab/BeetsPluginXtractor/releasesfhhhhh";
+#       license = lib.licenses.mit;
+#     };
+#   }
 
-    src = fetchFromGitHub {
-      repo = "BeetsPluginXtractor";
-      owner = "adamjakab";
-      rev = "v${version}";
-      hash = "sha256-it4qQ2OS4qBEaGLJK8FVGpjlvg0MQICazV7TAM8lH9s=";
-    };
-
-    nativeBuildInputs = [
-      beets
-      python3Packages.setuptools
-    ];
-
-    passthru = {inherit models;};
-
-    nativeCheckInputs = with python3Packages; [
-      pytestCheckHook
-      pytest-cov
-      mock
-      typeguard
-    ];
-
-    preCheck = ''
-      export HOME="$(mktemp -d)"
-    '';
-    postInstall = ''
-      mkdir --parents $out/models
-      cp ${models}/* $out/models
-    '';
-
-    meta = {
-      description = "Obtain low and high level musical information from your song";
-      homepage = "https://github.com/adamjakab/BeetsPluginXtractor/releasesfhhhhh";
-      license = lib.licenses.mit;
-    };
-  }
diff --git a/pkgs/by-name/bl/blake3/add_cargo_lock.patch b/pkgs/by-name/bl/blake3/add_cargo_lock.patch
deleted file mode 100644
index 19a5d1d0..00000000
--- a/pkgs/by-name/bl/blake3/add_cargo_lock.patch
+++ /dev/null
@@ -1,431 +0,0 @@
-From 45fd97400c01f39f841f84d43f1d28f8102cd927 Mon Sep 17 00:00:00 2001
-From: Benedikt Peetz <benedikt.peetz@b-peetz.de>
-Date: Thu, 22 Aug 2024 11:25:24 +0200
-Subject: [PATCH] build(cargo.lock): Add
-
----
- Cargo.lock | 412 +++++++++++++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 412 insertions(+)
- create mode 100644 Cargo.lock
-
-diff --git a/Cargo.lock b/Cargo.lock
-new file mode 100644
-index 0000000..98b4b7a
---- /dev/null
-+++ b/Cargo.lock
-@@ -0,0 +1,412 @@
-+# This file is automatically @generated by Cargo.
-+# It is not intended for manual editing.
-+version = 3
-+
-+[[package]]
-+name = "arrayref"
-+version = "0.3.8"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a"
-+
-+[[package]]
-+name = "arrayvec"
-+version = "0.7.6"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
-+
-+[[package]]
-+name = "autocfg"
-+version = "1.3.0"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
-+
-+[[package]]
-+name = "bitflags"
-+version = "2.6.0"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
-+
-+[[package]]
-+name = "blake3"
-+version = "0.4.1"
-+dependencies = [
-+ "blake3 1.5.4",
-+ "hex",
-+ "pyo3",
-+ "rayon",
-+]
-+
-+[[package]]
-+name = "blake3"
-+version = "1.5.4"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "d82033247fd8e890df8f740e407ad4d038debb9eb1f40533fffb32e7d17dc6f7"
-+dependencies = [
-+ "arrayref",
-+ "arrayvec",
-+ "cc",
-+ "cfg-if",
-+ "constant_time_eq",
-+ "memmap2",
-+ "rayon-core",
-+]
-+
-+[[package]]
-+name = "cc"
-+version = "1.1.13"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "72db2f7947ecee9b03b510377e8bb9077afa27176fdbff55c51027e976fdcc48"
-+dependencies = [
-+ "shlex",
-+]
-+
-+[[package]]
-+name = "cfg-if"
-+version = "1.0.0"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
-+
-+[[package]]
-+name = "constant_time_eq"
-+version = "0.3.0"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2"
-+
-+[[package]]
-+name = "crossbeam-deque"
-+version = "0.8.5"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d"
-+dependencies = [
-+ "crossbeam-epoch",
-+ "crossbeam-utils",
-+]
-+
-+[[package]]
-+name = "crossbeam-epoch"
-+version = "0.9.18"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
-+dependencies = [
-+ "crossbeam-utils",
-+]
-+
-+[[package]]
-+name = "crossbeam-utils"
-+version = "0.8.20"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
-+
-+[[package]]
-+name = "either"
-+version = "1.13.0"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
-+
-+[[package]]
-+name = "heck"
-+version = "0.4.1"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
-+
-+[[package]]
-+name = "hex"
-+version = "0.4.3"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
-+
-+[[package]]
-+name = "indoc"
-+version = "2.0.5"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5"
-+
-+[[package]]
-+name = "libc"
-+version = "0.2.158"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
-+
-+[[package]]
-+name = "lock_api"
-+version = "0.4.12"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
-+dependencies = [
-+ "autocfg",
-+ "scopeguard",
-+]
-+
-+[[package]]
-+name = "memmap2"
-+version = "0.9.4"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322"
-+dependencies = [
-+ "libc",
-+]
-+
-+[[package]]
-+name = "memoffset"
-+version = "0.9.1"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
-+dependencies = [
-+ "autocfg",
-+]
-+
-+[[package]]
-+name = "once_cell"
-+version = "1.19.0"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
-+
-+[[package]]
-+name = "parking_lot"
-+version = "0.12.3"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
-+dependencies = [
-+ "lock_api",
-+ "parking_lot_core",
-+]
-+
-+[[package]]
-+name = "parking_lot_core"
-+version = "0.9.10"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
-+dependencies = [
-+ "cfg-if",
-+ "libc",
-+ "redox_syscall",
-+ "smallvec",
-+ "windows-targets",
-+]
-+
-+[[package]]
-+name = "portable-atomic"
-+version = "1.7.0"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265"
-+
-+[[package]]
-+name = "proc-macro2"
-+version = "1.0.86"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
-+dependencies = [
-+ "unicode-ident",
-+]
-+
-+[[package]]
-+name = "pyo3"
-+version = "0.20.3"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "53bdbb96d49157e65d45cc287af5f32ffadd5f4761438b527b055fb0d4bb8233"
-+dependencies = [
-+ "cfg-if",
-+ "indoc",
-+ "libc",
-+ "memoffset",
-+ "parking_lot",
-+ "portable-atomic",
-+ "pyo3-build-config",
-+ "pyo3-ffi",
-+ "pyo3-macros",
-+ "unindent",
-+]
-+
-+[[package]]
-+name = "pyo3-build-config"
-+version = "0.20.3"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "deaa5745de3f5231ce10517a1f5dd97d53e5a2fd77aa6b5842292085831d48d7"
-+dependencies = [
-+ "once_cell",
-+ "target-lexicon",
-+]
-+
-+[[package]]
-+name = "pyo3-ffi"
-+version = "0.20.3"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "62b42531d03e08d4ef1f6e85a2ed422eb678b8cd62b762e53891c05faf0d4afa"
-+dependencies = [
-+ "libc",
-+ "pyo3-build-config",
-+]
-+
-+[[package]]
-+name = "pyo3-macros"
-+version = "0.20.3"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "7305c720fa01b8055ec95e484a6eca7a83c841267f0dd5280f0c8b8551d2c158"
-+dependencies = [
-+ "proc-macro2",
-+ "pyo3-macros-backend",
-+ "quote",
-+ "syn",
-+]
-+
-+[[package]]
-+name = "pyo3-macros-backend"
-+version = "0.20.3"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "7c7e9b68bb9c3149c5b0cade5d07f953d6d125eb4337723c4ccdb665f1f96185"
-+dependencies = [
-+ "heck",
-+ "proc-macro2",
-+ "pyo3-build-config",
-+ "quote",
-+ "syn",
-+]
-+
-+[[package]]
-+name = "quote"
-+version = "1.0.36"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
-+dependencies = [
-+ "proc-macro2",
-+]
-+
-+[[package]]
-+name = "rayon"
-+version = "1.10.0"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
-+dependencies = [
-+ "either",
-+ "rayon-core",
-+]
-+
-+[[package]]
-+name = "rayon-core"
-+version = "1.12.1"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
-+dependencies = [
-+ "crossbeam-deque",
-+ "crossbeam-utils",
-+]
-+
-+[[package]]
-+name = "redox_syscall"
-+version = "0.5.3"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4"
-+dependencies = [
-+ "bitflags",
-+]
-+
-+[[package]]
-+name = "scopeguard"
-+version = "1.2.0"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
-+
-+[[package]]
-+name = "shlex"
-+version = "1.3.0"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
-+
-+[[package]]
-+name = "smallvec"
-+version = "1.13.2"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
-+
-+[[package]]
-+name = "syn"
-+version = "2.0.75"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "f6af063034fc1935ede7be0122941bafa9bacb949334d090b77ca98b5817c7d9"
-+dependencies = [
-+ "proc-macro2",
-+ "quote",
-+ "unicode-ident",
-+]
-+
-+[[package]]
-+name = "target-lexicon"
-+version = "0.12.16"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
-+
-+[[package]]
-+name = "unicode-ident"
-+version = "1.0.12"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
-+
-+[[package]]
-+name = "unindent"
-+version = "0.2.3"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "c7de7d73e1754487cb58364ee906a499937a0dfabd86bcb980fa99ec8c8fa2ce"
-+
-+[[package]]
-+name = "windows-targets"
-+version = "0.52.6"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
-+dependencies = [
-+ "windows_aarch64_gnullvm",
-+ "windows_aarch64_msvc",
-+ "windows_i686_gnu",
-+ "windows_i686_gnullvm",
-+ "windows_i686_msvc",
-+ "windows_x86_64_gnu",
-+ "windows_x86_64_gnullvm",
-+ "windows_x86_64_msvc",
-+]
-+
-+[[package]]
-+name = "windows_aarch64_gnullvm"
-+version = "0.52.6"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
-+
-+[[package]]
-+name = "windows_aarch64_msvc"
-+version = "0.52.6"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
-+
-+[[package]]
-+name = "windows_i686_gnu"
-+version = "0.52.6"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
-+
-+[[package]]
-+name = "windows_i686_gnullvm"
-+version = "0.52.6"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
-+
-+[[package]]
-+name = "windows_i686_msvc"
-+version = "0.52.6"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
-+
-+[[package]]
-+name = "windows_x86_64_gnu"
-+version = "0.52.6"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
-+
-+[[package]]
-+name = "windows_x86_64_gnullvm"
-+version = "0.52.6"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
-+
-+[[package]]
-+name = "windows_x86_64_msvc"
-+version = "0.52.6"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
--- 
-2.45.2
-
diff --git a/pkgs/by-name/bl/blake3/package.nix b/pkgs/by-name/bl/blake3/package.nix
deleted file mode 100644
index d465e856..00000000
--- a/pkgs/by-name/bl/blake3/package.nix
+++ /dev/null
@@ -1,29 +0,0 @@
-{
-  python3Packages,
-  rustPlatform,
-  fetchFromGitHub,
-}:
-python3Packages.buildPythonPackage rec {
-  pname = "blake3";
-  version = "0.4.1";
-
-  src = fetchFromGitHub {
-    owner = "oconnor663";
-    repo = "blake3-py";
-    rev = version;
-    hash = "sha256-Ju40ea8IQMOPg9BiN47BMmr/WU8HptbqqzVI+jNGpA8=";
-  };
-
-  patches = [
-    ./add_cargo_lock.patch
-  ];
-
-  cargoDeps = rustPlatform.fetchCargoTarball {
-    inherit src patches;
-    hash = "sha256-GwyGSdmJTgsHWfcS2n2FCFrlwRcuANM8/WteYTTyY6o=";
-  };
-
-  format = "pyproject";
-
-  nativeBuildInputs = with rustPlatform; [cargoSetupHook maturinBuildHook];
-}
diff --git a/pkgs/by-name/ge/generate_moz_extension/Cargo.lock b/pkgs/by-name/ge/generate_moz_extension/Cargo.lock
index 020fcaec..10970fa6 100644
--- a/pkgs/by-name/ge/generate_moz_extension/Cargo.lock
+++ b/pkgs/by-name/ge/generate_moz_extension/Cargo.lock
@@ -19,9 +19,9 @@ checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
 
 [[package]]
 name = "anyhow"
-version = "1.0.95"
+version = "1.0.97"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
+checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
 
 [[package]]
 name = "atomic-waker"
@@ -47,7 +47,7 @@ dependencies = [
  "miniz_oxide",
  "object",
  "rustc-demangle",
- "windows-targets",
+ "windows-targets 0.52.6",
 ]
 
 [[package]]
@@ -58,27 +58,27 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
 
 [[package]]
 name = "bitflags"
-version = "2.6.0"
+version = "2.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
+checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
 
 [[package]]
 name = "bumpalo"
-version = "3.16.0"
+version = "3.17.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
+checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
 
 [[package]]
 name = "bytes"
-version = "1.9.0"
+version = "1.10.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b"
+checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
 
 [[package]]
 name = "cc"
-version = "1.2.6"
+version = "1.2.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8d6dbb628b8f8555f86d0323c2eb39e3ec81901f4b83e091db8a6a76d316a333"
+checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a"
 dependencies = [
  "shlex",
 ]
@@ -127,9 +127,9 @@ dependencies = [
 
 [[package]]
 name = "equivalent"
-version = "1.0.1"
+version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
+checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
 
 [[package]]
 name = "errno"
@@ -286,7 +286,19 @@ checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
 dependencies = [
  "cfg-if",
  "libc",
- "wasi",
+ "wasi 0.11.0+wasi-snapshot-preview1",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "r-efi",
+ "wasi 0.14.2+wasi-0.2.4",
 ]
 
 [[package]]
@@ -297,9 +309,9 @@ checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
 
 [[package]]
 name = "h2"
-version = "0.4.7"
+version = "0.4.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e"
+checksum = "5017294ff4bb30944501348f6f8e42e6ad28f42c8bbef7a74029aff064a4e3c2"
 dependencies = [
  "atomic-waker",
  "bytes",
@@ -322,9 +334,9 @@ checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
 
 [[package]]
 name = "http"
-version = "1.2.0"
+version = "1.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea"
+checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565"
 dependencies = [
  "bytes",
  "fnv",
@@ -343,12 +355,12 @@ dependencies = [
 
 [[package]]
 name = "http-body-util"
-version = "0.1.2"
+version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f"
+checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a"
 dependencies = [
  "bytes",
- "futures-util",
+ "futures-core",
  "http",
  "http-body",
  "pin-project-lite",
@@ -356,15 +368,15 @@ dependencies = [
 
 [[package]]
 name = "httparse"
-version = "1.9.5"
+version = "1.10.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946"
+checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
 
 [[package]]
 name = "hyper"
-version = "1.5.2"
+version = "1.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "256fb8d4bd6413123cc9d91832d78325c48ff41677595be797d90f42969beae0"
+checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80"
 dependencies = [
  "bytes",
  "futures-channel",
@@ -473,9 +485,9 @@ dependencies = [
 
 [[package]]
 name = "icu_locid_transform_data"
-version = "1.5.0"
+version = "1.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e"
+checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d"
 
 [[package]]
 name = "icu_normalizer"
@@ -497,9 +509,9 @@ dependencies = [
 
 [[package]]
 name = "icu_normalizer_data"
-version = "1.5.0"
+version = "1.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516"
+checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7"
 
 [[package]]
 name = "icu_properties"
@@ -518,9 +530,9 @@ dependencies = [
 
 [[package]]
 name = "icu_properties_data"
-version = "1.5.0"
+version = "1.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569"
+checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2"
 
 [[package]]
 name = "icu_provider"
@@ -573,9 +585,9 @@ dependencies = [
 
 [[package]]
 name = "indexmap"
-version = "2.7.0"
+version = "2.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f"
+checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058"
 dependencies = [
  "equivalent",
  "hashbrown",
@@ -583,21 +595,21 @@ dependencies = [
 
 [[package]]
 name = "ipnet"
-version = "2.10.1"
+version = "2.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708"
+checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
 
 [[package]]
 name = "itoa"
-version = "1.0.14"
+version = "1.0.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
+checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
 
 [[package]]
 name = "js-sys"
-version = "0.3.76"
+version = "0.3.77"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7"
+checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
 dependencies = [
  "once_cell",
  "wasm-bindgen",
@@ -605,27 +617,27 @@ dependencies = [
 
 [[package]]
 name = "libc"
-version = "0.2.169"
+version = "0.2.171"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
+checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
 
 [[package]]
 name = "linux-raw-sys"
-version = "0.4.14"
+version = "0.9.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
+checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413"
 
 [[package]]
 name = "litemap"
-version = "0.7.4"
+version = "0.7.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104"
+checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856"
 
 [[package]]
 name = "log"
-version = "0.4.22"
+version = "0.4.27"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
+checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
 
 [[package]]
 name = "memchr"
@@ -641,9 +653,9 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
 
 [[package]]
 name = "miniz_oxide"
-version = "0.8.2"
+version = "0.8.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394"
+checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5"
 dependencies = [
  "adler2",
 ]
@@ -655,15 +667,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd"
 dependencies = [
  "libc",
- "wasi",
+ "wasi 0.11.0+wasi-snapshot-preview1",
  "windows-sys 0.52.0",
 ]
 
 [[package]]
 name = "native-tls"
-version = "0.2.12"
+version = "0.2.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466"
+checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e"
 dependencies = [
  "libc",
  "log",
@@ -687,15 +699,15 @@ dependencies = [
 
 [[package]]
 name = "once_cell"
-version = "1.20.2"
+version = "1.21.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
+checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
 
 [[package]]
 name = "openssl"
-version = "0.10.68"
+version = "0.10.71"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5"
+checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd"
 dependencies = [
  "bitflags",
  "cfg-if",
@@ -719,15 +731,15 @@ dependencies = [
 
 [[package]]
 name = "openssl-probe"
-version = "0.1.5"
+version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
+checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
 
 [[package]]
 name = "openssl-sys"
-version = "0.9.104"
+version = "0.9.106"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741"
+checksum = "8bb61ea9811cc39e3c2069f40b8b8e2e70d8569b361f879786cc7ed48b777cdd"
 dependencies = [
  "cc",
  "libc",
@@ -743,9 +755,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
 
 [[package]]
 name = "pin-project-lite"
-version = "0.2.15"
+version = "0.2.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff"
+checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
 
 [[package]]
 name = "pin-utils"
@@ -755,33 +767,39 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
 
 [[package]]
 name = "pkg-config"
-version = "0.3.31"
+version = "0.3.32"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
+checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.92"
+version = "1.0.94"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
+checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
 dependencies = [
  "unicode-ident",
 ]
 
 [[package]]
 name = "quote"
-version = "1.0.38"
+version = "1.0.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
+checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
 dependencies = [
  "proc-macro2",
 ]
 
 [[package]]
+name = "r-efi"
+version = "5.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
+
+[[package]]
 name = "reqwest"
-version = "0.12.11"
+version = "0.12.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fe060fe50f524be480214aba758c71f99f90ee8c83c5a36b5e9e1d568eb4eb3"
+checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb"
 dependencies = [
  "base64",
  "bytes",
@@ -823,15 +841,14 @@ dependencies = [
 
 [[package]]
 name = "ring"
-version = "0.17.8"
+version = "0.17.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d"
+checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
 dependencies = [
  "cc",
  "cfg-if",
- "getrandom",
+ "getrandom 0.2.15",
  "libc",
- "spin",
  "untrusted",
  "windows-sys 0.52.0",
 ]
@@ -844,9 +861,9 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
 
 [[package]]
 name = "rustix"
-version = "0.38.42"
+version = "1.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85"
+checksum = "e56a18552996ac8d29ecc3b190b4fdbb2d91ca4ec396de7bbffaf43f3d637e96"
 dependencies = [
  "bitflags",
  "errno",
@@ -857,9 +874,9 @@ dependencies = [
 
 [[package]]
 name = "rustls"
-version = "0.23.20"
+version = "0.23.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b"
+checksum = "822ee9188ac4ec04a2f0531e55d035fb2de73f18b41a63c70c2712503b6fb13c"
 dependencies = [
  "once_cell",
  "rustls-pki-types",
@@ -879,15 +896,15 @@ dependencies = [
 
 [[package]]
 name = "rustls-pki-types"
-version = "1.10.1"
+version = "1.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2bf47e6ff922db3825eb750c4e2ff784c6ff8fb9e13046ef6a1d1c5401b0b37"
+checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c"
 
 [[package]]
 name = "rustls-webpki"
-version = "0.102.8"
+version = "0.103.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9"
+checksum = "fef8b8769aaccf73098557a87cd1816b4f9c7c16811c9c77142aa695c16f2c03"
 dependencies = [
  "ring",
  "rustls-pki-types",
@@ -895,10 +912,16 @@ dependencies = [
 ]
 
 [[package]]
+name = "rustversion"
+version = "1.0.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2"
+
+[[package]]
 name = "ryu"
-version = "1.0.18"
+version = "1.0.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
+checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
 
 [[package]]
 name = "schannel"
@@ -924,9 +947,9 @@ dependencies = [
 
 [[package]]
 name = "security-framework-sys"
-version = "2.13.0"
+version = "2.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1863fd3768cd83c56a7f60faa4dc0d403f1b6df0a38c3c25f44b7894e45370d5"
+checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32"
 dependencies = [
  "core-foundation-sys",
  "libc",
@@ -934,18 +957,18 @@ dependencies = [
 
 [[package]]
 name = "serde"
-version = "1.0.217"
+version = "1.0.219"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
+checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
 dependencies = [
  "serde_derive",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.217"
+version = "1.0.219"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
+checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -954,9 +977,9 @@ dependencies = [
 
 [[package]]
 name = "serde_json"
-version = "1.0.134"
+version = "1.0.140"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d"
+checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
 dependencies = [
  "itoa",
  "memchr",
@@ -993,9 +1016,9 @@ dependencies = [
 
 [[package]]
 name = "smallvec"
-version = "1.13.2"
+version = "1.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
+checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd"
 
 [[package]]
 name = "socket2"
@@ -1008,12 +1031,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "spin"
-version = "0.9.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
-
-[[package]]
 name = "stable_deref_trait"
 version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1027,9 +1044,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
 
 [[package]]
 name = "syn"
-version = "2.0.93"
+version = "2.0.100"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c786062daee0d6db1132800e623df74274a0a87322d8e183338e01b3d98d058"
+checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1079,12 +1096,12 @@ dependencies = [
 
 [[package]]
 name = "tempfile"
-version = "3.14.0"
+version = "3.19.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c"
+checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf"
 dependencies = [
- "cfg-if",
  "fastrand",
+ "getrandom 0.3.2",
  "once_cell",
  "rustix",
  "windows-sys 0.59.0",
@@ -1102,9 +1119,9 @@ dependencies = [
 
 [[package]]
 name = "tokio"
-version = "1.42.0"
+version = "1.44.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551"
+checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a"
 dependencies = [
  "backtrace",
  "bytes",
@@ -1118,9 +1135,9 @@ dependencies = [
 
 [[package]]
 name = "tokio-macros"
-version = "2.4.0"
+version = "2.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
+checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1139,9 +1156,9 @@ dependencies = [
 
 [[package]]
 name = "tokio-rustls"
-version = "0.26.1"
+version = "0.26.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37"
+checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b"
 dependencies = [
  "rustls",
  "tokio",
@@ -1149,9 +1166,9 @@ dependencies = [
 
 [[package]]
 name = "tokio-util"
-version = "0.7.13"
+version = "0.7.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078"
+checksum = "6b9590b93e6fcc1739458317cccd391ad3955e2bde8913edf6f95f9e65a8f034"
 dependencies = [
  "bytes",
  "futures-core",
@@ -1214,9 +1231,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
 
 [[package]]
 name = "unicode-ident"
-version = "1.0.14"
+version = "1.0.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
+checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
 
 [[package]]
 name = "untrusted"
@@ -1269,21 +1286,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
 
 [[package]]
+name = "wasi"
+version = "0.14.2+wasi-0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
+dependencies = [
+ "wit-bindgen-rt",
+]
+
+[[package]]
 name = "wasm-bindgen"
-version = "0.2.99"
+version = "0.2.100"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396"
+checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
 dependencies = [
  "cfg-if",
  "once_cell",
+ "rustversion",
  "wasm-bindgen-macro",
 ]
 
 [[package]]
 name = "wasm-bindgen-backend"
-version = "0.2.99"
+version = "0.2.100"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79"
+checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
 dependencies = [
  "bumpalo",
  "log",
@@ -1295,9 +1322,9 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-futures"
-version = "0.4.49"
+version = "0.4.50"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2"
+checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61"
 dependencies = [
  "cfg-if",
  "js-sys",
@@ -1308,9 +1335,9 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-macro"
-version = "0.2.99"
+version = "0.2.100"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe"
+checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
 dependencies = [
  "quote",
  "wasm-bindgen-macro-support",
@@ -1318,9 +1345,9 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-macro-support"
-version = "0.2.99"
+version = "0.2.100"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2"
+checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1331,48 +1358,56 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-shared"
-version = "0.2.99"
+version = "0.2.100"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6"
+checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
+dependencies = [
+ "unicode-ident",
+]
 
 [[package]]
 name = "web-sys"
-version = "0.3.76"
+version = "0.3.77"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc"
+checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2"
 dependencies = [
  "js-sys",
  "wasm-bindgen",
 ]
 
 [[package]]
+name = "windows-link"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
+
+[[package]]
 name = "windows-registry"
-version = "0.2.0"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0"
+checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3"
 dependencies = [
  "windows-result",
  "windows-strings",
- "windows-targets",
+ "windows-targets 0.53.0",
 ]
 
 [[package]]
 name = "windows-result"
-version = "0.2.0"
+version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e"
+checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252"
 dependencies = [
- "windows-targets",
+ "windows-link",
 ]
 
 [[package]]
 name = "windows-strings"
-version = "0.1.0"
+version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10"
+checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319"
 dependencies = [
- "windows-result",
- "windows-targets",
+ "windows-link",
 ]
 
 [[package]]
@@ -1381,7 +1416,7 @@ version = "0.52.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
 dependencies = [
- "windows-targets",
+ "windows-targets 0.52.6",
 ]
 
 [[package]]
@@ -1390,7 +1425,7 @@ version = "0.59.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
 dependencies = [
- "windows-targets",
+ "windows-targets 0.52.6",
 ]
 
 [[package]]
@@ -1399,14 +1434,30 @@ version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
 dependencies = [
- "windows_aarch64_gnullvm",
- "windows_aarch64_msvc",
- "windows_i686_gnu",
- "windows_i686_gnullvm",
- "windows_i686_msvc",
- "windows_x86_64_gnu",
- "windows_x86_64_gnullvm",
- "windows_x86_64_msvc",
+ "windows_aarch64_gnullvm 0.52.6",
+ "windows_aarch64_msvc 0.52.6",
+ "windows_i686_gnu 0.52.6",
+ "windows_i686_gnullvm 0.52.6",
+ "windows_i686_msvc 0.52.6",
+ "windows_x86_64_gnu 0.52.6",
+ "windows_x86_64_gnullvm 0.52.6",
+ "windows_x86_64_msvc 0.52.6",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b"
+dependencies = [
+ "windows_aarch64_gnullvm 0.53.0",
+ "windows_aarch64_msvc 0.53.0",
+ "windows_i686_gnu 0.53.0",
+ "windows_i686_gnullvm 0.53.0",
+ "windows_i686_msvc 0.53.0",
+ "windows_x86_64_gnu 0.53.0",
+ "windows_x86_64_gnullvm 0.53.0",
+ "windows_x86_64_msvc 0.53.0",
 ]
 
 [[package]]
@@ -1416,48 +1467,105 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
 
 [[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
+
+[[package]]
 name = "windows_aarch64_msvc"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
 
 [[package]]
+name = "windows_aarch64_msvc"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
+
+[[package]]
 name = "windows_i686_gnu"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
 
 [[package]]
+name = "windows_i686_gnu"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"
+
+[[package]]
 name = "windows_i686_gnullvm"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
 
 [[package]]
+name = "windows_i686_gnullvm"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
+
+[[package]]
 name = "windows_i686_msvc"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
 
 [[package]]
+name = "windows_i686_msvc"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
+
+[[package]]
 name = "windows_x86_64_gnu"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
 
 [[package]]
+name = "windows_x86_64_gnu"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
+
+[[package]]
 name = "windows_x86_64_gnullvm"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
 
 [[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
+
+[[package]]
 name = "windows_x86_64_msvc"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
 
 [[package]]
+name = "windows_x86_64_msvc"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
+
+[[package]]
+name = "wit-bindgen-rt"
+version = "0.39.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
 name = "write16"
 version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1495,18 +1603,18 @@ dependencies = [
 
 [[package]]
 name = "zerofrom"
-version = "0.1.5"
+version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e"
+checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5"
 dependencies = [
  "zerofrom-derive",
 ]
 
 [[package]]
 name = "zerofrom-derive"
-version = "0.1.5"
+version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808"
+checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
 dependencies = [
  "proc-macro2",
  "quote",
diff --git a/pkgs/by-name/ge/generate_moz_extension/Cargo.toml b/pkgs/by-name/ge/generate_moz_extension/Cargo.toml
index 8af88523..1b3ff4f0 100644
--- a/pkgs/by-name/ge/generate_moz_extension/Cargo.toml
+++ b/pkgs/by-name/ge/generate_moz_extension/Cargo.toml
@@ -6,9 +6,9 @@ edition = "2021"
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
-anyhow = "1.0.95"
+anyhow = "1.0.97"
 futures = "0.3.31"
-reqwest = "0.12.11"
-serde = { version = "1.0.217", features = ["derive"] }
-serde_json = "1.0.134"
-tokio = { version = "1.42.0", features = ["macros", "rt-multi-thread"] }
+reqwest = "0.12.15"
+serde = { version = "1.0.219", features = ["derive"] }
+serde_json = "1.0.140"
+tokio = { version = "1.44.1", features = ["macros", "rt-multi-thread"] }
diff --git a/pkgs/by-name/ge/generate_moz_extension/flake.lock b/pkgs/by-name/ge/generate_moz_extension/flake.lock
index 51976eff..9d72fb5b 100644
--- a/pkgs/by-name/ge/generate_moz_extension/flake.lock
+++ b/pkgs/by-name/ge/generate_moz_extension/flake.lock
@@ -2,11 +2,11 @@
   "nodes": {
     "crane": {
       "locked": {
-        "lastModified": 1734808813,
-        "narHash": "sha256-3aH/0Y6ajIlfy7j52FGZ+s4icVX0oHhqBzRdlOeztqg=",
+        "lastModified": 1742394900,
+        "narHash": "sha256-vVOAp9ahvnU+fQoKd4SEXB2JG2wbENkpqcwlkIXgUC0=",
         "owner": "ipetkov",
         "repo": "crane",
-        "rev": "72e2d02dbac80c8c86bf6bf3e785536acf8ee926",
+        "rev": "70947c1908108c0c551ddfd73d4f750ff2ea67cd",
         "type": "github"
       },
       "original": {
@@ -35,11 +35,11 @@
     },
     "nixpkgs": {
       "locked": {
-        "lastModified": 1735523292,
-        "narHash": "sha256-opBsbR/nrGxiiF6XzlVluiHYb6yN/hEwv+lBWTy9xoM=",
+        "lastModified": 1743076231,
+        "narHash": "sha256-yQugdVfi316qUfqzN8JMaA2vixl+45GxNm4oUfXlbgw=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "6d97d419e5a9b36e6293887a89a078cf85f5a61b",
+        "rev": "6c5963357f3c1c840201eda129a99d455074db04",
         "type": "github"
       },
       "original": {
@@ -64,11 +64,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1735525800,
-        "narHash": "sha256-pcN8LAL021zdC99a9F7iEiFCI1wmrE4DpIYUgKpB/jY=",
+        "lastModified": 1743215516,
+        "narHash": "sha256-52qbrkG65U1hyrQWltgHTgH4nm0SJL+9TWv2UDCEPNI=",
         "owner": "oxalica",
         "repo": "rust-overlay",
-        "rev": "10faa81b4c0135a04716cbd1649260d82b2890cd",
+        "rev": "524463199fdee49338006b049bc376b965a2cfed",
         "type": "github"
       },
       "original": {
diff --git a/pkgs/by-name/gi/git-cleanup/git-cleanup.sh b/pkgs/by-name/gi/git-cleanup/git-cleanup.sh
deleted file mode 100755
index f423a9d2..00000000
--- a/pkgs/by-name/gi/git-cleanup/git-cleanup.sh
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
-help() {
-    cat <<EOF
-Automatically remove merged branches (remote and local)
-
-USAGE:
-    git-cleanup [OPTIONS]
-
-OPTIONS:
-    --remote    | -r
-                            Act on remote branches
-
-    --help      | -h
-                            Display this help and exit.
-
-    --version   | -v
-                            Display version and copyright information and exit.
-EOF
-}
-
-# This should always be the correct answer.
-get_default_branch() {
-    # source: https://stackoverflow.com/a/50056710
-    # We assume, that 'origin' is the remote in use
-    git remote show origin | sed -n '/HEAD branch/s|.*: ||p'
-}
-
-cleanup() {
-    default_branch="$(get_default_branch)"
-
-    merged_branches="$(git branch --merged "$default_branch" --no-contains "$default_branch" --format='%(refname:short)')"
-
-    # shellcheck disable=2086
-    # We expect the branches to not contain spaces and want git to deal with them
-    # separately
-    [ "$merged_branches" ] && git branch --delete $merged_branches
-}
-cleanup_remote() {
-    default_branch="$(get_default_branch)"
-
-    merged_branches="$(git branch --remotes --merged "$default_branch" --no-contains "$default_branch" --format='%(refname:short)' | sed 's|origin/||')"
-
-    # shellcheck disable=2086
-    # We expect the branches to not contain spaces and want git to deal with them
-    # separately
-    [ "$merged_branches" ] && git push --delete origin $merged_branches
-}
-
-remote=false
-for arg in "$@"; do
-    case "$arg" in
-    "--help" | "-h")
-        help
-        exit 0
-        ;;
-    "--version" | "-v")
-        version
-        exit 0
-        ;;
-    "--remote" | "-r")
-        remote=true
-        ;;
-    esac
-done
-
-if [ "$remote" = "true" ]; then
-    cleanup_remote
-elif [ "$remote" = "false" ]; then
-    cleanup
-else
-    die "BUG: 'remote' is not true or false but: '$remote'"
-fi
-
-# vim: ft=sh
diff --git a/pkgs/by-name/gi/git-cleanup/package.nix b/pkgs/by-name/gi/git-cleanup/package.nix
deleted file mode 100644
index 54b3f2bd..00000000
--- a/pkgs/by-name/gi/git-cleanup/package.nix
+++ /dev/null
@@ -1,17 +0,0 @@
-{
-  sysLib,
-  git,
-  gnused,
-  openssh,
-}:
-sysLib.writeShellScript {
-  name = "git-cleanup";
-  src = ./git-cleanup.sh;
-  keepPath = false;
-  generateCompletions = true;
-  dependencies = [
-    git
-    gnused
-    openssh
-  ];
-}
diff --git a/pkgs/by-name/hi/hibernate/package.nix b/pkgs/by-name/hi/hibernate/package.nix
index 24754f09..54716606 100644
--- a/pkgs/by-name/hi/hibernate/package.nix
+++ b/pkgs/by-name/hi/hibernate/package.nix
@@ -1,7 +1,7 @@
 {
   sysLib,
   systemd,
-  taskwarrior,
+  taskwarrior3,
 }:
 sysLib.writeShellScript {
   name = "hibernate";
@@ -10,6 +10,6 @@ sysLib.writeShellScript {
   keepPath = false;
   dependencies = [
     systemd
-    taskwarrior
+    taskwarrior3
   ];
 }
diff --git a/pkgs/by-name/lf/lf-make-map/.envrc b/pkgs/by-name/lf/lf-make-map/.envrc
index eb4480a6..2b742cf6 100644
--- a/pkgs/by-name/lf/lf-make-map/.envrc
+++ b/pkgs/by-name/lf/lf-make-map/.envrc
@@ -7,6 +7,5 @@ PATH_add ./target/release
 PATH_add ./scripts
 
 if on_git_branch; then
-    echo && git status --short --branch &&
-        echo && git fetch --verbose
+    echo && git status --short --branch
 fi
diff --git a/pkgs/by-name/lf/lf-make-map/Cargo.lock b/pkgs/by-name/lf/lf-make-map/Cargo.lock
index 42b96f7e..d68f7492 100644
--- a/pkgs/by-name/lf/lf-make-map/Cargo.lock
+++ b/pkgs/by-name/lf/lf-make-map/Cargo.lock
@@ -53,24 +53,25 @@ version = "1.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
 dependencies = [
- "windows-sys 0.59.0",
+ "windows-sys",
 ]
 
 [[package]]
 name = "anstyle-wincon"
-version = "3.0.6"
+version = "3.0.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125"
+checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e"
 dependencies = [
  "anstyle",
- "windows-sys 0.59.0",
+ "once_cell",
+ "windows-sys",
 ]
 
 [[package]]
 name = "anyhow"
-version = "1.0.95"
+version = "1.0.97"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
+checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
 
 [[package]]
 name = "autocfg"
@@ -80,15 +81,15 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
 
 [[package]]
 name = "bumpalo"
-version = "3.16.0"
+version = "3.17.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
+checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
 
 [[package]]
 name = "cc"
-version = "1.2.6"
+version = "1.2.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8d6dbb628b8f8555f86d0323c2eb39e3ec81901f4b83e091db8a6a76d316a333"
+checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a"
 dependencies = [
  "shlex",
 ]
@@ -101,23 +102,23 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
 [[package]]
 name = "chrono"
-version = "0.4.39"
+version = "0.4.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825"
+checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c"
 dependencies = [
  "android-tzdata",
  "iana-time-zone",
  "js-sys",
  "num-traits",
  "wasm-bindgen",
- "windows-targets",
+ "windows-link",
 ]
 
 [[package]]
 name = "clap"
-version = "4.5.23"
+version = "4.5.34"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84"
+checksum = "e958897981290da2a852763fe9cdb89cd36977a5d729023127095fa94d95e2ff"
 dependencies = [
  "clap_builder",
  "clap_derive",
@@ -125,9 +126,9 @@ dependencies = [
 
 [[package]]
 name = "clap_builder"
-version = "4.5.23"
+version = "4.5.34"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838"
+checksum = "83b0f35019843db2160b5bb19ae09b4e6411ac33fc6a712003c33e03090e2489"
 dependencies = [
  "anstream",
  "anstyle",
@@ -137,9 +138,9 @@ dependencies = [
 
 [[package]]
 name = "clap_derive"
-version = "4.5.18"
+version = "4.5.32"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab"
+checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7"
 dependencies = [
  "heck",
  "proc-macro2",
@@ -173,20 +174,21 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
 
 [[package]]
 name = "hermit-abi"
-version = "0.4.0"
+version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc"
+checksum = "fbd780fe5cc30f81464441920d82ac8740e2e46b29a6fad543ddd075229ce37e"
 
 [[package]]
 name = "iana-time-zone"
-version = "0.1.61"
+version = "0.1.62"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220"
+checksum = "b2fd658b06e56721792c5df4475705b6cda790e9298d19d2f8af083457bcd127"
 dependencies = [
  "android_system_properties",
  "core-foundation-sys",
  "iana-time-zone-haiku",
  "js-sys",
+ "log",
  "wasm-bindgen",
  "windows-core",
 ]
@@ -202,13 +204,13 @@ dependencies = [
 
 [[package]]
 name = "is-terminal"
-version = "0.4.13"
+version = "0.4.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b"
+checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9"
 dependencies = [
  "hermit-abi",
  "libc",
- "windows-sys 0.52.0",
+ "windows-sys",
 ]
 
 [[package]]
@@ -219,9 +221,9 @@ checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
 
 [[package]]
 name = "js-sys"
-version = "0.3.76"
+version = "0.3.77"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7"
+checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
 dependencies = [
  "once_cell",
  "wasm-bindgen",
@@ -240,15 +242,15 @@ dependencies = [
 
 [[package]]
 name = "libc"
-version = "0.2.169"
+version = "0.2.171"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
+checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
 
 [[package]]
 name = "log"
-version = "0.4.22"
+version = "0.4.27"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
+checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
 
 [[package]]
 name = "num-traits"
@@ -261,29 +263,35 @@ dependencies = [
 
 [[package]]
 name = "once_cell"
-version = "1.20.2"
+version = "1.21.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
+checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.92"
+version = "1.0.94"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
+checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
 dependencies = [
  "unicode-ident",
 ]
 
 [[package]]
 name = "quote"
-version = "1.0.38"
+version = "1.0.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
+checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
 dependencies = [
  "proc-macro2",
 ]
 
 [[package]]
+name = "rustversion"
+version = "1.0.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2"
+
+[[package]]
 name = "same-file"
 version = "1.0.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -319,9 +327,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
 
 [[package]]
 name = "syn"
-version = "2.0.93"
+version = "2.0.100"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c786062daee0d6db1132800e623df74274a0a87322d8e183338e01b3d98d058"
+checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -349,9 +357,9 @@ dependencies = [
 
 [[package]]
 name = "unicode-ident"
-version = "1.0.14"
+version = "1.0.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
+checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
 
 [[package]]
 name = "utf8parse"
@@ -371,20 +379,21 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen"
-version = "0.2.99"
+version = "0.2.100"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396"
+checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
 dependencies = [
  "cfg-if",
  "once_cell",
+ "rustversion",
  "wasm-bindgen-macro",
 ]
 
 [[package]]
 name = "wasm-bindgen-backend"
-version = "0.2.99"
+version = "0.2.100"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79"
+checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
 dependencies = [
  "bumpalo",
  "log",
@@ -396,9 +405,9 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-macro"
-version = "0.2.99"
+version = "0.2.100"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe"
+checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
 dependencies = [
  "quote",
  "wasm-bindgen-macro-support",
@@ -406,9 +415,9 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-macro-support"
-version = "0.2.99"
+version = "0.2.100"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2"
+checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -419,9 +428,12 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-shared"
-version = "0.2.99"
+version = "0.2.100"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6"
+checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
+dependencies = [
+ "unicode-ident",
+]
 
 [[package]]
 name = "winapi-util"
@@ -429,7 +441,7 @@ version = "0.1.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
 dependencies = [
- "windows-sys 0.59.0",
+ "windows-sys",
 ]
 
 [[package]]
@@ -442,13 +454,10 @@ dependencies = [
 ]
 
 [[package]]
-name = "windows-sys"
-version = "0.52.0"
+name = "windows-link"
+version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
-dependencies = [
- "windows-targets",
-]
+checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
 
 [[package]]
 name = "windows-sys"
diff --git a/pkgs/by-name/lf/lf-make-map/Cargo.toml b/pkgs/by-name/lf/lf-make-map/Cargo.toml
index a73aa318..d2427d73 100644
--- a/pkgs/by-name/lf/lf-make-map/Cargo.toml
+++ b/pkgs/by-name/lf/lf-make-map/Cargo.toml
@@ -7,8 +7,8 @@ edition = "2021"
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
-anyhow = "1.0.95"
-clap = { version = "4.5.23", features = ["derive", "env"] }
-log = "0.4.22"
+anyhow = "1.0.97"
+clap = { version = "4.5.34", features = ["derive", "env"] }
+log = "0.4.27"
 stderrlog = "0.6.0"
 walkdir = "2.5.0"
diff --git a/pkgs/by-name/lf/lf-make-map/flake.lock b/pkgs/by-name/lf/lf-make-map/flake.lock
index 650e9b93..c9c523d9 100644
--- a/pkgs/by-name/lf/lf-make-map/flake.lock
+++ b/pkgs/by-name/lf/lf-make-map/flake.lock
@@ -2,11 +2,11 @@
   "nodes": {
     "crane": {
       "locked": {
-        "lastModified": 1734808813,
-        "narHash": "sha256-3aH/0Y6ajIlfy7j52FGZ+s4icVX0oHhqBzRdlOeztqg=",
+        "lastModified": 1742394900,
+        "narHash": "sha256-vVOAp9ahvnU+fQoKd4SEXB2JG2wbENkpqcwlkIXgUC0=",
         "owner": "ipetkov",
         "repo": "crane",
-        "rev": "72e2d02dbac80c8c86bf6bf3e785536acf8ee926",
+        "rev": "70947c1908108c0c551ddfd73d4f750ff2ea67cd",
         "type": "github"
       },
       "original": {
@@ -53,11 +53,11 @@
     },
     "nixpkgs": {
       "locked": {
-        "lastModified": 1735523292,
-        "narHash": "sha256-opBsbR/nrGxiiF6XzlVluiHYb6yN/hEwv+lBWTy9xoM=",
+        "lastModified": 1743076231,
+        "narHash": "sha256-yQugdVfi316qUfqzN8JMaA2vixl+45GxNm4oUfXlbgw=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "6d97d419e5a9b36e6293887a89a078cf85f5a61b",
+        "rev": "6c5963357f3c1c840201eda129a99d455074db04",
         "type": "github"
       },
       "original": {
@@ -85,11 +85,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1735525800,
-        "narHash": "sha256-pcN8LAL021zdC99a9F7iEiFCI1wmrE4DpIYUgKpB/jY=",
+        "lastModified": 1743215516,
+        "narHash": "sha256-52qbrkG65U1hyrQWltgHTgH4nm0SJL+9TWv2UDCEPNI=",
         "owner": "oxalica",
         "repo": "rust-overlay",
-        "rev": "10faa81b4c0135a04716cbd1649260d82b2890cd",
+        "rev": "524463199fdee49338006b049bc376b965a2cfed",
         "type": "github"
       },
       "original": {
@@ -120,11 +120,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1735135567,
-        "narHash": "sha256-8T3K5amndEavxnludPyfj3Z1IkcFdRpR23q+T0BVeZE=",
+        "lastModified": 1743081648,
+        "narHash": "sha256-WRAylyYptt6OX5eCEBWyTwOEqEtD6zt33rlUkr6u3cE=",
         "owner": "numtide",
         "repo": "treefmt-nix",
-        "rev": "9e09d30a644c57257715902efbb3adc56c79cf28",
+        "rev": "29a3d7b768c70addce17af0869f6e2bd8f5be4b7",
         "type": "github"
       },
       "original": {
diff --git a/pkgs/by-name/lo/lock/lock.sh b/pkgs/by-name/lo/lock/lock.sh
index 3101ef9a..4c5e1c01 100755
--- a/pkgs/by-name/lo/lock/lock.sh
+++ b/pkgs/by-name/lo/lock/lock.sh
@@ -1,18 +1,15 @@
-#!/usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+# shellcheck shell=bash
 
 context="$(task _get rc.context)"
-[ "$context" ] && task context none
+[ -n "$context" ] && task context none
 
 # We have ensured that only one task is active
 active="$(task +ACTIVE _ids)"
-[ "$active" ] && task stop "$active"
+[ -n "$active" ] && task stop "$active"
 
 swaylock
 
-[ "$active" ] && task start "$active"
+[ -n "$active" ] && task start "$active"
 
-[ "$context" ] && task context "$context"
+[ -n "$context" ] && task context "$context"
 # vim: ft=sh
diff --git a/pkgs/by-name/lo/lock/package.nix b/pkgs/by-name/lo/lock/package.nix
index 0e6e38d0..a59fbdd0 100644
--- a/pkgs/by-name/lo/lock/package.nix
+++ b/pkgs/by-name/lo/lock/package.nix
@@ -1,15 +1,16 @@
 {
-  sysLib,
-  taskwarrior,
+  writeShellApplication,
+  taskwarrior3,
   swaylock,
 }:
-sysLib.writeShellScript {
+writeShellApplication {
   name = "lock";
-  src = ./lock.sh;
-  generateCompletions = false;
-  keepPath = false;
-  dependencies = [
-    taskwarrior
+  text = builtins.readFile ./lock.sh;
+  runtimeInputs = [
+    taskwarrior3
     swaylock
   ];
+  meta = {
+    mainProgram = "lock";
+  };
 }
diff --git a/pkgs/by-name/na/nato/nato.py b/pkgs/by-name/na/nato/nato.py
deleted file mode 100755
index e9d15f56..00000000
--- a/pkgs/by-name/na/nato/nato.py
+++ /dev/null
@@ -1,106 +0,0 @@
-#!/usr/bin/env python3
-# originally from here: https://cgit.pacien.net/desktop-utilities/
-
-import sys
-
-alphabet = {
-    "nato": {
-        "A": "Alfa",  # No idea why this is not just 'Alpha' ..
-        "B": "Bravo",
-        "C": "Charlie",
-        "D": "Delta",
-        "E": "Echo",
-        "F": "Foxtrot",
-        "G": "Golf",
-        "H": "Hotel",
-        "I": "India",
-        "J": "Juliett",
-        "K": "Kilo",
-        "L": "Lima",
-        "M": "Mike",
-        "N": "November",
-        "O": "Oscar",
-        "P": "Papa",
-        "Q": "Quebec",
-        "R": "Romeo",
-        "S": "Sierra",
-        "T": "Tango",
-        "U": "Uniform",
-        "V": "Victor",
-        "W": "Whiskey",
-        "X": "X-ray",
-        "Y": "Yankee",
-        "Z": "Zulu",
-        "0": "Nadazero",
-        "1": "Unaone",
-        "2": "Bissotwo",
-        "3": "Terrathree",
-        "4": "Kartefour",
-        "5": "Pantafive",
-        "6": "Soxisix",
-        "7": "Setteseven",
-        "8": "Oktoeight",
-        "9": "Novenine",
-        ",": "Comma",
-        "/": "Forward slash",
-        ".": "Stop/Decimal",
-    },
-    "german": {
-        "A": "Aachen",
-        "Ä": "Umlaut Aachen",
-        "B": "Berlin",
-        "C": "Chemnitz",
-        "D": "Düsseldorf",
-        "E": "Essen",
-        "F": "Frankfurt",
-        "G": "Goslar",
-        "H": "Hamburg",
-        "I": "Ingelheim",
-        "J": "Jena",
-        "K": "Köln",
-        "L": "Leipzig",
-        "M": "München",
-        "N": "Nürnberg",
-        "O": "Offenbach",
-        "Ö": "Umlaut Offenbach",
-        "P": "Potsdam",
-        "Q": "Quickborn",
-        "R": "Rostock",
-        "S": "Salzwedel",
-        "ẞ": "Eszett",
-        "T": "Tübingen",
-        "U": "Unna",
-        "Ü": "Umlaut Unna",
-        "V": "Völklingen",
-        "W": "Wuppertal",
-        "X": "Xanten",
-        "Y": "Ypsilon",
-        "Z": "Zwickau",
-    },
-}
-
-
-def str_to_telephony(phrase, language):
-    language_alphabet = alphabet[language]
-
-    return [
-        language_alphabet[c] if c in language_alphabet else c for c in phrase.upper()
-    ]
-
-
-language = sys.argv[1]
-if language not in ["nato", "german"]:
-    print(
-        f"Langugae '{language}' is not a valid language, only 'nato' and 'german' are!",
-        file=sys.stderr,
-    )
-    exit(1)
-
-print(
-    "\n".join(
-        str_to_telephony(
-            " ".join(sys.argv[2:]),
-            language,
-        )
-    )
-)
diff --git a/pkgs/by-name/na/nato/package.nix b/pkgs/by-name/na/nato/package.nix
deleted file mode 100644
index 17fe7d1a..00000000
--- a/pkgs/by-name/na/nato/package.nix
+++ /dev/null
@@ -1,34 +0,0 @@
-{
-  lib,
-  python3,
-  runCommandLocal,
-  makeWrapper,
-}: let
-  write_python = {
-    name,
-    dependencies_system ? [],
-    dependencies_python ? _: [],
-    keepPath ? false,
-  }: let
-    src = ./${name}.py;
-    dependencies =
-      [(python3.withPackages dependencies_python)]
-      ++ dependencies_system;
-    path_setting =
-      if keepPath
-      then "--prefix PATH :"
-      else "--set PATH";
-  in
-    runCommandLocal name {
-      nativeBuildInputs = [makeWrapper] ++ dependencies;
-    }
-    ''
-      install -m755 ${src} -D "$out/bin/${name}"
-      patchShebangs "$out/bin/${name}"
-      wrapProgram "$out/bin/${name}" ${path_setting} ${lib.makeBinPath dependencies};
-    '';
-in
-  write_python {
-    name = "nato";
-    dependencies_python = ps: [];
-  }
diff --git a/pkgs/by-name/ne/neorg/functions/add.sh b/pkgs/by-name/ne/neorg/functions/add.sh
deleted file mode 100644
index 5a830a10..00000000
--- a/pkgs/by-name/ne/neorg/functions/add.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/env dash
-
-add0open_taskwarrior_project_file() {
-    task_project_file="%TASK_PROJECT_FILE"
-
-    cd "$(dirname $task_project_file)" || die "BUG: task_project_file ('$task_project_file') can't be accessed"
-
-    git_dir="$(search_flake_base_dir)"
-    [ "$git_dir" ] || die "(BUG): No git directory?"
-    cd "$git_dir" || die "Unreachable, this MUST exists"
-
-    nvim "$task_project_file"
-    git add "$task_project_file"
-
-    base_task_project_file_path="$(awk "{ gsub(\"$git_dir/\", \"\", \$0); print }" "$(ptmp "$task_project_file")")"
-    git add $task_project_file
-
-    # Check that only the project file has been added (and that our file is actually
-    # modified)
-    if git status --porcelain=v2 | awk -v path="$base_task_project_file_path" 'BEGIN { hit = 0 } { if ($2 ~ /A./ || $2 ~ /M./) { if ($NF ~ path) { hit = 1 } else { hit = 0; exit 1 } } } END { if (hit == 1) { exit 0 } else { exit 1 } }'; then
-        git commit --verbose --message="chore($(dirname "$base_task_project_file_path")): Update"
-    fi
-}
diff --git a/pkgs/by-name/ne/neorg/functions/context.sh b/pkgs/by-name/ne/neorg/functions/context.sh
deleted file mode 100644
index 7095847d..00000000
--- a/pkgs/by-name/ne/neorg/functions/context.sh
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/usr/bin/env dash
-
-context0open_current_task_context() {
-    current_context="$(utils0get_current_context)"
-
-    if [ "$current_context" ]; then
-        context_path="$(utils0get_current_context_path "$current_context")"
-
-        extended_neorg_project_dir="$(utils0get_neorg_project_dir)"
-        cd "$extended_neorg_project_dir" || die "(BUG?): Can not access the project dir: $extended_neorg_project_dir"
-
-        nvim "$extended_neorg_project_dir/$context_path"
-
-        git add .
-        git commit --message="chore($(dirname "$context_path")): Update" --no-gpg-sign
-    else
-        warn "No context active"
-    fi
-}
-
-context0open_current_task_context_at_task_id() {
-    task_id="$1"
-    current_context="$(utils0get_current_context)"
-
-    if [ "$current_context" ]; then
-        context_path="$(utils0get_current_context_path "$current_context")"
-        extended_neorg_project_dir="$(utils0get_neorg_project_dir)"
-        task_uuid="$(task "$task_id" uuids)"
-
-        cd "$extended_neorg_project_dir" || die "(BUG?): Can not access the project dir: $extended_neorg_project_dir"
-
-        if ! grep -q "% $task_uuid" "$extended_neorg_project_dir/$context_path"; then
-            echo "* TITLE (% $task_uuid)" >>"$extended_neorg_project_dir/$context_path"
-        fi
-
-        nvim "$extended_neorg_project_dir/$context_path" -c "/% $task_uuid"
-
-        git add .
-        git commit --message="chore($(dirname "$context_path")): Update" --no-gpg-sign
-    else
-        warn "No context active"
-    fi
-}
diff --git a/pkgs/by-name/ne/neorg/functions/dmenu.sh b/pkgs/by-name/ne/neorg/functions/dmenu.sh
deleted file mode 100644
index 5a138982..00000000
--- a/pkgs/by-name/ne/neorg/functions/dmenu.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/usr/bin/env dash
-
-dmenu0open_context_in_browser() {
-    project="$(echo "%ALL_PROJECTS_PIPE" | rofi -sep "|" -dmenu)"
-
-    if [ "$project" ]; then
-        [ -d "%NEORG_REVIEW_PATH" ] || mkdir --parents "%NEORG_REVIEW_PATH"
-        [ -f "%NEORG_REVIEW_PATH/$project.lock" ] || touch "%NEORG_REVIEW_PATH/$project.lock"
-        project0open_project_in_browser "$project"
-    else
-        notify-send "(neorg/dmenu) No project selected"
-        exit 1
-    fi
-}
diff --git a/pkgs/by-name/ne/neorg/functions/f_start.sh b/pkgs/by-name/ne/neorg/functions/f_start.sh
deleted file mode 100644
index 2423dd44..00000000
--- a/pkgs/by-name/ne/neorg/functions/f_start.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/usr/bin/env dash
-
-fstart0start_new_task() {
-    task_id="$1"
-    fstop0stop_current_task
-    task start "$task_id"
-}
diff --git a/pkgs/by-name/ne/neorg/functions/f_stop.sh b/pkgs/by-name/ne/neorg/functions/f_stop.sh
deleted file mode 100644
index e4ff0b94..00000000
--- a/pkgs/by-name/ne/neorg/functions/f_stop.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/usr/bin/env dash
-
-fstop0stop_current_task() {
-    # we ensured that only one task may be active
-    active="$(task +ACTIVE _ids)"
-    [ "$active" ] && task stop "$active"
-}
diff --git a/pkgs/by-name/ne/neorg/functions/inputs.sh b/pkgs/by-name/ne/neorg/functions/inputs.sh
deleted file mode 100644
index d47b129a..00000000
--- a/pkgs/by-name/ne/neorg/functions/inputs.sh
+++ /dev/null
@@ -1,62 +0,0 @@
-#!/usr/bin/env dash
-
-_git_commit() {
-    message="$1"
-
-    cd "$(dirname "%NEORG_INPUTS_STORAGE_FILE")" || die "BUG. This should exist."
-    [ -d .git ] || git init
-    git add .
-    git commit --message "$message" --no-gpg-sign
-}
-
-inputs0add() {
-    url_file="$1"
-
-    mkdir --parents "$(dirname "%NEORG_INPUTS_STORAGE_FILE")"
-
-    {
-        # Add another newline
-        echo ""
-        # echo "# $url_file "
-
-        clean "$url_file"
-    } >>"%NEORG_INPUTS_STORAGE_FILE" &&
-        msg2 "Successfully added file '$url_file' with $(clean "$url_file" | wc -l) entries to the url list"
-
-    _git_commit "Add entries from '$url_file' ($(clean "$url_file" | wc -l))"
-}
-
-inputs0review() {
-    base_profile="$1"
-
-    [ -f "%NEORG_INPUTS_STORAGE_FILE" ] || die "'%NEORG_INPUTS_STORAGE_FILE' is not a file. Have you added something with 'inputs_add' yet?"
-
-    done_urls="$(mktmp)"
-
-    # We assume that the project is not yet open.
-    firefox -P "$base_profile" &
-    # Give it some time to start up.
-    sleep 2
-
-    if [ "$(wc -l <"%NEORG_INPUTS_STORAGE_FILE")" -gt 100 ]; then
-        echo "Your would want to review more than 100 inputs. Limiting it to the first 100 entries."
-    fi
-
-    head --lines=100 "%NEORG_INPUTS_STORAGE_FILE" | while read -r url; do
-        echo "-> '$url'"
-        firefox -P "$base_profile" "$url"
-
-        echo "$url" >>"$done_urls"
-    done
-
-    # Wait for the Firefox process from above to finish.
-    wait
-
-    tmp="$(mktmp)"
-    # source: https://stackoverflow.com/a/24324455
-    awk 'NR==FNR {a[$0]=1; next} !a[$0]' "$done_urls" "%NEORG_INPUTS_STORAGE_FILE" >"$tmp"
-
-    mv "$tmp" "%NEORG_INPUTS_STORAGE_FILE"
-
-    _git_commit "Dump entries into firefox profile '$base_profile'"
-}
diff --git a/pkgs/by-name/ne/neorg/functions/list.sh b/pkgs/by-name/ne/neorg/functions/list.sh
deleted file mode 100644
index 10659457..00000000
--- a/pkgs/by-name/ne/neorg/functions/list.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/usr/bin/env dash
-
-list0list_all_contexts_newline() {
-    print "%ALL_PROJECTS_NEWLINE"
-}
-list0list_all_contexts_comma() {
-    print "%ALL_PROJECTS_COMMA"
-}
diff --git a/pkgs/by-name/ne/neorg/functions/project.sh b/pkgs/by-name/ne/neorg/functions/project.sh
deleted file mode 100644
index 64591850..00000000
--- a/pkgs/by-name/ne/neorg/functions/project.sh
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/usr/bin/env dash
-
-project0open_current_context_in_browser() {
-    current_context="$(utils0get_current_context)"
-    [ "$current_context" ] || die "No current context to use"
-    project0open_context_in_browser "$(utils0context2project "$current_context")"
-}
-
-project0open_project_in_browser() {
-    project="$1"
-    [ "$project" ] || die "BUG: No context supplied to project0open_context_in_browser"
-
-    old_context="$(utils0get_current_context)"
-    # We have ensured that only one task may be active
-    old_started_task="$(task +ACTIVE _ids)"
-
-    tracking="$(mktmp)"
-    task "project:$project" _ids | xargs --no-run-if-empty task _zshids >"$tracking"
-    task context "$(utils0project2context "$project")"
-
-    while read -r description; do
-        desc="$(echo "$description" | awk -F: '{print $2}')"
-        if [ "$desc" = "tracking" ]; then
-            task_id="$(echo "$description" | awk -F: '{print $1}')"
-            notify-send "(Neorg)" "Starting task $project -> $desc"
-            task start "$task_id"
-            break
-        fi
-    done <"$tracking"
-
-    firefox -P "$project"
-
-    task stop "$task_id"
-    [ "$old_started_task" ] && task start "$old_started_task"
-
-    if [ "$old_context" ]; then
-        task context "$old_context"
-    else
-        task context none
-    fi
-}
diff --git a/pkgs/by-name/ne/neorg/functions/review.sh b/pkgs/by-name/ne/neorg/functions/review.sh
deleted file mode 100644
index a0a9ab8d..00000000
--- a/pkgs/by-name/ne/neorg/functions/review.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/env dash
-
-review0start() {
-    for project in $(list0list_all_contexts_newline); do
-        if [ -f "%NEORG_REVIEW_PATH/$project.lock" ]; then
-            msg "Reviewing '$project'"
-            notify-send "Neorg" "Reviewing '$project'"
-            firefox -P "$project"
-            rm "%NEORG_REVIEW_PATH/$project.lock"
-        fi
-    done
-}
diff --git a/pkgs/by-name/ne/neorg/functions/utils.sh b/pkgs/by-name/ne/neorg/functions/utils.sh
deleted file mode 100644
index c3843e8e..00000000
--- a/pkgs/by-name/ne/neorg/functions/utils.sh
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/usr/bin/env dash
-
-# Runs it's first argument and then the second, regardless if the first failed or
-# succeeded
-utils0chain() {
-    eval "$1"
-    eval "$2"
-}
-
-utils0get_current_context() {
-    current_context="$(task _get rc.context)"
-    printf "%s\n" "$current_context"
-}
-
-utils0get_current_context_path() {
-    current_context="$1"
-    context_path="$(task _get rc.context."$current_context".rc.neorg_path 2>/dev/null)"
-    if ! [ "$context_path" ]; then
-        context_path="$(grep "context.$current_context.rc.neorg_path" "%HOME_TASKRC" | awk 'BEGIN {FS="="} {print $2}')"
-        [ "$context_path" ] || die "All contexts should have a 'neorg_path' set!"
-    fi
-    printf "%s\n" "$context_path"
-}
-
-utils0get_neorg_project_dir() {
-    # Perform shell expansion of Tilde
-    neorg_project_dir="$(sed "s|^~|$HOME|" "$(ptmp "%DEFAULT_NEORG_PROJECT_DIR")")"
-    printf "%s\n" "$neorg_project_dir"
-}
-
-utils0project2context() {
-    project="$1"
-    context="$(sed 's|\.|_|g' "$(ptmp "$project")")"
-    printf "%s\n" "$context"
-}
-utils0context2project() {
-    context="$1"
-    project="$(sed 's|_|\.|g' "$(ptmp "$context")")"
-    printf "%s\n" "$project"
-}
diff --git a/pkgs/by-name/ne/neorg/functions/workspace.sh b/pkgs/by-name/ne/neorg/functions/workspace.sh
deleted file mode 100644
index d5eb2fca..00000000
--- a/pkgs/by-name/ne/neorg/functions/workspace.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/usr/bin/env dash
-
-workspace0open_neorg_workspace() {
-    workspace="$1"
-    nvim -c "NeorgStart" -s "$(ptmp ":Neorg workspace $workspace\n")"
-}
-workspace0open_neorg_workspace_prompt() {
-    nvim -c "NeorgStart" -s "$(ptmp ":Neorg workspace ")"
-}
diff --git a/pkgs/by-name/ne/neorg/main.sh b/pkgs/by-name/ne/neorg/main.sh
deleted file mode 100755
index b4f0f0e6..00000000
--- a/pkgs/by-name/ne/neorg/main.sh
+++ /dev/null
@@ -1,189 +0,0 @@
-#!/usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
-# load dependencies
-. ./functions/add.sh
-. ./functions/context.sh
-. ./functions/dmenu.sh
-. ./functions/f_start.sh
-. ./functions/f_stop.sh
-. ./functions/inputs.sh
-. ./functions/list.sh
-. ./functions/project.sh
-. ./functions/review.sh
-. ./functions/utils.sh
-. ./functions/workspace.sh
-
-# these are used in version()
-# shellcheck disable=2034
-AUTHORS="Soispha"
-# shellcheck disable=2034
-YEARS="2023"
-
-NAME="neorg"
-
-help() {
-    cat <<EOF
-This is the core interface to the system-integrated task management
-
-USAGE:
-    $NAME [OPTIONS] [COMMAND]
-
-OPTIONS:
-    --help      | -h
-                            Display this help and exit.
-
-    --version   | -v
-                            Display version and copyright information and exit.
-COMMANDS:
-    task [ID]
-                            Open the neorg context associated with the current context and
-                            the uuid of the task with id ID. Without ID, it'll open the
-                            current context's norg file.
-                            If no context is set, drops you to the selection prompt
-
-    dmenu
-                            Select a project in dmenu mode. This will give you all projects
-                            and exectute the selected one as in 'neorg projects <selected>'
-
-    workspace [WS]
-                            The neorg workspace (WS) to open at startup, an empty value drops
-                            you at a prompt to enter the workspace yourself.
-
-    project [P]
-                            Opens the webbrowser with either the context (P) or
-                            the current active context as argument if no context is supplied
-
-    list
-                            Lists all available contexts
-
-    add
-                            Allows you to quickly add projects
-
-    fstart ID
-                            Starts the task (ID) but only after it stooped
-                            the previous active task, if it existed.
-
-    fstop
-                            Stops the current active task
-
-    review
-                            Review all firefox tabs
-
-    inputs_add F
-                            Add all urls from the file F as inputs to be catogorized
-
-    inputs_review P
-                            Like 'review', but for the inputs that have previously been added.
-                            It takes a project in which to open the urls.
-ARGUMENTS:
-    ID | *([0-9]) := [[%ID_GENERATION_FUNCTION]]
-                            The function displays all possible IDs of the eligable tasks.
-
-    WS := %ALL_WORKSPACES
-                            All possible workspaces.
-
-    P := %ALL_PROJECTS_PIPE
-                            The possible project.
-
-    F := [[fd . --max-depth 3]]
-                            A URL-Input file to use as source.
-
-EOF
-}
-
-for arg in "$@"; do
-    case "$arg" in
-    "--help" | "-h")
-        help
-        exit 0
-        ;;
-    "--version" | "-v")
-        version
-        exit 0
-        ;;
-    esac
-done
-
-while [ "$#" -ne 0 ]; do
-    case "$1" in
-    "t"*) # task
-        shift 1
-        task_id="$1"
-        [ "$task_id" ] || utils0chain context0open_current_task_context "exit 0"
-        context0open_current_task_context_at_task_id "$task_id"
-        exit 0
-        ;;
-    "w"*) # workspace
-        shift 1
-        workspace_to_open="$1"
-        # TODO: Exit with 1 on error, instead of the 0 <2023-10-20>
-        [ "$workspace_to_open" ] || utils0chain workspace0open_neorg_workspace_prompt "exit 0"
-        workspace0open_neorg_workspace "$workspace_to_open"
-        exit 0
-        ;;
-    "p"*) # project
-        shift 1
-        project_to_open="$1"
-        # TODO: Exit with 1 on error, instead of the 0 <2023-10-20>
-        [ "$project_to_open" ] || utils0chain project0open_current_context_in_browser "exit 0"
-        if ! grep -q "$project_to_open" "$(ptmp "%ALL_PROJECTS_NEWLINE")"; then
-            die "Your project ('$project_to_open') is not in the list of available projects:
-%ALL_PROJECTS_COMMA"
-        fi
-        project0open_project_in_browser "$project_to_open"
-        exit 0
-        ;;
-    "l"*) # list
-        list0list_all_contexts_newline
-        exit 0
-        ;;
-    "a"*) # add-project
-        add0open_taskwarrior_project_file
-        exit 0
-        ;;
-    "d"*) # dmenu
-        dmenu0open_context_in_browser
-        exit 0
-        ;;
-    "fsta"*) # fstart
-        shift 1
-        task_id="$1"
-        [ "$task_id" ] || die "No task id provided to fstart"
-        fstart0start_new_task "$task_id"
-        exit 0
-        ;;
-    "fsto"*) # fstop
-        fstop0stop_current_task
-        exit 0
-        ;;
-    "r"*) # review
-        shift 1
-        review0start
-        exit 0
-        ;;
-    "inputs_a"*) # inputs_add
-        shift 1
-        url_file="$1"
-        [ -f "$url_file" ] || die "Url file ('$url_file') is not a valid file."
-        inputs0add "$url_file"
-        exit 0
-        ;;
-    "inputs_r"*) # inputs_review
-        shift 1
-        base_project="$1"
-        [ -z "$base_project" ] && die "'inputs_review' requires a project."
-        inputs0review "$base_project"
-        exit 0
-        ;;
-    *)
-        die "Command '$1' does not exist! Please look at:\n $NAME --help"
-        exit 0
-        ;;
-    esac
-done
-
-context0open_current_task_context
-# vim: ft=sh
diff --git a/pkgs/by-name/ne/neorg/neorg_id_function.sh b/pkgs/by-name/ne/neorg/neorg_id_function.sh
deleted file mode 100755
index 865ecacf..00000000
--- a/pkgs/by-name/ne/neorg/neorg_id_function.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#! /usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
-context="$(task _get rc.context)"
-if [ "$context" ]; then
-    filter="project:$context"
-else
-    filter="0-10000"
-fi
-tasks="$(task "$filter" _ids)"
-
-if [ "$tasks" ]; then
-    echo "$tasks" | xargs task _zshids | awk -F: -v q="'" '{gsub(/'\''/, q "\\" q q ); print $1 ":" q $2 q}'
-fi
diff --git a/pkgs/by-name/ne/neorg/package.nix b/pkgs/by-name/ne/neorg/package.nix
deleted file mode 100644
index 3d26d1fb..00000000
--- a/pkgs/by-name/ne/neorg/package.nix
+++ /dev/null
@@ -1,72 +0,0 @@
-{
-  lib,
-  sysLib,
-  # dependencies
-  cocogitto,
-  rofi,
-  libnotify,
-  taskwarrior,
-  gawk,
-  findutils,
-  # config
-  defaultNeorgProjectDir ? "/no-default-dir", # homeConfig.programs.nixvim.plugins.neorg.settings.load."core.dirman".config.workspaces.projects
-  allProjectsNewline ? "", # homeConfig.soispha.taskwarrior.projects.projects_newline
-  allProjectsComma ? "", # homeConfig.soispha.taskwarrior.projects.projects_comma
-  allProjectsPipe ? "", # homeConfig.soispha.taskwarrior.projects.projects_pipe
-  allWorkspaces ? {}, # homeConfig.programs.nixvim.plugins.neorg.settings.load."core.dirman".config.workspaces
-  xdgConfigHome ? builtins.getEnv "XDG_CONFIG_HOME",
-  xdgDataHome ? builtins.getEnv "XDG_DATA_HOME",
-}:
-sysLib.writeShellScriptMultiPart {
-  name = "neorg";
-  src = ./.;
-  generateCompletions = true;
-  keepPath = true;
-
-  baseName = "main.sh";
-  cmdPrefix = "functions";
-  cmdNames = [
-    "add.sh"
-    "context.sh"
-    "dmenu.sh"
-    "f_start.sh"
-    "f_stop.sh"
-    "inputs.sh"
-    "list.sh"
-    "project.sh"
-    "review.sh"
-    "utils.sh"
-    "workspace.sh"
-  ];
-
-  dependencies = [
-    cocogitto
-    rofi
-    libnotify
-  ];
-  replacementStrings = {
-    DEFAULT_NEORG_PROJECT_DIR = defaultNeorgProjectDir;
-    HOME_TASKRC = "${xdgConfigHome}/task/home-manager-taskrc";
-    NEORG_REVIEW_PATH = "${xdgDataHome}/neorg/review";
-
-    NEORG_INPUTS_STORAGE_FILE = "${xdgDataHome}/neorg/inputs/url_list.txt";
-
-    ALL_PROJECTS_NEWLINE = allProjectsNewline;
-    ALL_PROJECTS_COMMA = allProjectsComma;
-    ALL_PROJECTS_PIPE = allProjectsPipe;
-    ALL_WORKSPACES = "${lib.strings.concatStringsSep "|" (builtins.attrNames allWorkspaces)}";
-
-    ID_GENERATION_FUNCTION = "${sysLib.writeShellScript {
-      name = "neorg_id_function";
-      src = ./neorg_id_function.sh;
-      dependencies = [
-        taskwarrior
-        gawk
-        findutils # source of xargs
-      ];
-    }}/bin/neorg_id_function";
-
-    # TODO: Replace the hard-coded path here with some reference <2023-10-20>
-    TASK_PROJECT_FILE = "/home/soispha/repos/nix/nixos-config/hm/soispha/conf/taskwarrior/projects/default.nix";
-  };
-}
diff --git a/pkgs/by-name/up/update-vim-plugins/.envrc b/pkgs/by-name/ri/river-mk-keymap/.envrc
index 2f9f1a81..fdd3e9d8 100644
--- a/pkgs/by-name/up/update-vim-plugins/.envrc
+++ b/pkgs/by-name/ri/river-mk-keymap/.envrc
@@ -1,2 +1,3 @@
 #!/usr/bin/env sh
+
 use flake
diff --git a/pkgs/by-name/ri/river-mk-keymap/.gitignore b/pkgs/by-name/ri/river-mk-keymap/.gitignore
new file mode 100644
index 00000000..2d5df85d
--- /dev/null
+++ b/pkgs/by-name/ri/river-mk-keymap/.gitignore
@@ -0,0 +1,2 @@
+/target
+.direnv
diff --git a/pkgs/by-name/ri/river-mk-keymap/Cargo.lock b/pkgs/by-name/ri/river-mk-keymap/Cargo.lock
new file mode 100644
index 00000000..7fb009ef
--- /dev/null
+++ b/pkgs/by-name/ri/river-mk-keymap/Cargo.lock
@@ -0,0 +1,334 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "anstream"
+version = "0.6.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b"
+dependencies = [
+ "anstyle",
+ "anstyle-parse",
+ "anstyle-query",
+ "anstyle-wincon",
+ "colorchoice",
+ "is_terminal_polyfill",
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle"
+version = "1.0.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
+
+[[package]]
+name = "anstyle-parse"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
+dependencies = [
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle-query"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
+dependencies = [
+ "windows-sys",
+]
+
+[[package]]
+name = "anstyle-wincon"
+version = "3.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e"
+dependencies = [
+ "anstyle",
+ "once_cell",
+ "windows-sys",
+]
+
+[[package]]
+name = "anyhow"
+version = "1.0.97"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
+
+[[package]]
+name = "clap"
+version = "4.5.34"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e958897981290da2a852763fe9cdb89cd36977a5d729023127095fa94d95e2ff"
+dependencies = [
+ "clap_builder",
+ "clap_derive",
+]
+
+[[package]]
+name = "clap_builder"
+version = "4.5.34"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "83b0f35019843db2160b5bb19ae09b4e6411ac33fc6a712003c33e03090e2489"
+dependencies = [
+ "anstream",
+ "anstyle",
+ "clap_lex",
+ "strsim",
+]
+
+[[package]]
+name = "clap_derive"
+version = "4.5.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7"
+dependencies = [
+ "heck",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "clap_lex"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
+
+[[package]]
+name = "colorchoice"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
+
+[[package]]
+name = "heck"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
+
+[[package]]
+name = "is_terminal_polyfill"
+version = "1.70.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
+
+[[package]]
+name = "itoa"
+version = "1.0.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
+
+[[package]]
+name = "keymaps"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6cec33e805ecc09c4e4f91ca26e536978ad1ae28f2e1dc02fadafeec6d2f8504"
+dependencies = [
+ "serde",
+ "thiserror",
+]
+
+[[package]]
+name = "memchr"
+version = "2.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
+
+[[package]]
+name = "once_cell"
+version = "1.21.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.94"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.40"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "river-mk-keymap"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "clap",
+ "keymaps",
+ "serde",
+ "serde_json",
+]
+
+[[package]]
+name = "ryu"
+version = "1.0.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
+
+[[package]]
+name = "serde"
+version = "1.0.219"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.219"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.140"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
+dependencies = [
+ "itoa",
+ "memchr",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "strsim"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
+
+[[package]]
+name = "syn"
+version = "2.0.100"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "thiserror"
+version = "2.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "2.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
+
+[[package]]
+name = "utf8parse"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
+
+[[package]]
+name = "windows-sys"
+version = "0.59.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_gnullvm",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
+
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
diff --git a/pkgs/by-name/ri/river-mk-keymap/Cargo.toml b/pkgs/by-name/ri/river-mk-keymap/Cargo.toml
new file mode 100644
index 00000000..f14411f2
--- /dev/null
+++ b/pkgs/by-name/ri/river-mk-keymap/Cargo.toml
@@ -0,0 +1,71 @@
+[package]
+name = "river-mk-keymap"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+anyhow = "1.0.97"
+clap = { version = "4.5.34", features = ["derive"] }
+keymaps = { version = "1.0.0", features = ["serde", "mouse-keys"] }
+serde = { version = "1.0.219", features = ["derive"] }
+serde_json = "1.0.140"
+
+[profile.release]
+lto = true
+codegen-units = 1
+panic = "abort"
+split-debuginfo = "off"
+
+[lints.rust]
+# rustc lint groups https://doc.rust-lang.org/rustc/lints/groups.html
+warnings = "warn"
+future_incompatible = { level = "warn", priority = -1 }
+let_underscore = { level = "warn", priority = -1 }
+nonstandard_style = { level = "warn", priority = -1 }
+rust_2018_compatibility = { level = "warn", priority = -1 }
+rust_2018_idioms = { level = "warn", priority = -1 }
+rust_2021_compatibility = { level = "warn", priority = -1 }
+unused = { level = "warn", priority = -1 }
+# rustc allowed-by-default lints https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html
+# missing_docs = "warn"
+macro_use_extern_crate = "warn"
+meta_variable_misuse = "warn"
+missing_abi = "warn"
+missing_copy_implementations = "warn"
+missing_debug_implementations = "warn"
+non_ascii_idents = "warn"
+noop_method_call = "warn"
+single_use_lifetimes = "warn"
+trivial_casts = "warn"
+trivial_numeric_casts = "warn"
+unreachable_pub = "warn"
+unsafe_op_in_unsafe_fn = "warn"
+unused_crate_dependencies = "warn"
+unused_import_braces = "warn"
+unused_lifetimes = "warn"
+unused_qualifications = "warn"
+variant_size_differences = "warn"
+
+[lints.rustdoc]
+# rustdoc lints https://doc.rust-lang.org/rustdoc/lints.html
+broken_intra_doc_links = "warn"
+private_intra_doc_links = "warn"
+missing_crate_level_docs = "warn"
+private_doc_tests = "warn"
+invalid_codeblock_attributes = "warn"
+invalid_rust_codeblocks = "warn"
+bare_urls = "warn"
+
+[lints.clippy]
+# clippy allowed by default
+dbg_macro = "warn"
+# clippy categories https://doc.rust-lang.org/clippy/
+all = { level = "warn", priority = -1 }
+correctness = { level = "warn", priority = -1 }
+suspicious = { level = "warn", priority = -1 }
+style = { level = "warn", priority = -1 }
+complexity = { level = "warn", priority = -1 }
+perf = { level = "warn", priority = -1 }
+pedantic = { level = "warn", priority = -1 }
diff --git a/pkgs/by-name/ri/river-mk-keymap/TODO b/pkgs/by-name/ri/river-mk-keymap/TODO
new file mode 100644
index 00000000..be77953e
--- /dev/null
+++ b/pkgs/by-name/ri/river-mk-keymap/TODO
@@ -0,0 +1 @@
+Look at https://github.com/stefur/flow for river wayland inclusion
diff --git a/pkgs/by-name/ri/river-mk-keymap/contrib/example.json b/pkgs/by-name/ri/river-mk-keymap/contrib/example.json
new file mode 100644
index 00000000..c8673f9a
--- /dev/null
+++ b/pkgs/by-name/ri/river-mk-keymap/contrib/example.json
@@ -0,0 +1,5 @@
+{
+    "<M-a>": {
+        "command": ["focus-view", "next"]
+    }
+}
diff --git a/pkgs/by-name/ri/river-mk-keymap/flake.lock b/pkgs/by-name/ri/river-mk-keymap/flake.lock
new file mode 100644
index 00000000..82448387
--- /dev/null
+++ b/pkgs/by-name/ri/river-mk-keymap/flake.lock
@@ -0,0 +1,27 @@
+{
+  "nodes": {
+    "nixpkgs": {
+      "locked": {
+        "lastModified": 1743076231,
+        "narHash": "sha256-yQugdVfi316qUfqzN8JMaA2vixl+45GxNm4oUfXlbgw=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "6c5963357f3c1c840201eda129a99d455074db04",
+        "type": "github"
+      },
+      "original": {
+        "owner": "NixOS",
+        "ref": "nixpkgs-unstable",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
+    "root": {
+      "inputs": {
+        "nixpkgs": "nixpkgs"
+      }
+    }
+  },
+  "root": "root",
+  "version": 7
+}
diff --git a/pkgs/by-name/ri/river-mk-keymap/flake.nix b/pkgs/by-name/ri/river-mk-keymap/flake.nix
new file mode 100644
index 00000000..95a14456
--- /dev/null
+++ b/pkgs/by-name/ri/river-mk-keymap/flake.nix
@@ -0,0 +1,25 @@
+{
+  description = "A smart way to configure river keybindings";
+
+  inputs = {
+    nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
+  };
+
+  outputs = {nixpkgs, ...}: let
+    system = "x86_64-linux";
+    pkgs = nixpkgs.legacyPackages."${system}";
+  in {
+    devShells."${system}".default = pkgs.mkShell {
+      packages = with pkgs; [
+        cargo
+        clippy
+        rustc
+        rustfmt
+
+        cargo-edit
+      ];
+    };
+  };
+}
+# vim: ts=2
+
diff --git a/pkgs/by-name/ri/river-mk-keymap/package.nix b/pkgs/by-name/ri/river-mk-keymap/package.nix
new file mode 100644
index 00000000..d9519d48
--- /dev/null
+++ b/pkgs/by-name/ri/river-mk-keymap/package.nix
@@ -0,0 +1,14 @@
+{rustPlatform}:
+rustPlatform.buildRustPackage {
+  pname = "river-mk-keymap";
+  version = "0.1.0";
+
+  src = ./.;
+  cargoLock = {
+    lockFile = ./Cargo.lock;
+  };
+
+  meta = {
+    mainProgram = "river-mk-keymap";
+  };
+}
diff --git a/pkgs/by-name/ri/river-mk-keymap/src/cli.rs b/pkgs/by-name/ri/river-mk-keymap/src/cli.rs
new file mode 100644
index 00000000..55b87e1a
--- /dev/null
+++ b/pkgs/by-name/ri/river-mk-keymap/src/cli.rs
@@ -0,0 +1,11 @@
+use std::path::PathBuf;
+
+use clap::Parser;
+
+#[derive(Parser, Debug)]
+#[command(author, version, about, long_about = None)]
+/// A tool to manage your key mappings for the river window manager
+pub(super) struct Args {
+    /// Path to mappings JSON file
+    pub path: PathBuf,
+}
diff --git a/pkgs/by-name/ri/river-mk-keymap/src/key_map/commands.rs b/pkgs/by-name/ri/river-mk-keymap/src/key_map/commands.rs
new file mode 100644
index 00000000..a4ac0ebd
--- /dev/null
+++ b/pkgs/by-name/ri/river-mk-keymap/src/key_map/commands.rs
@@ -0,0 +1,109 @@
+use std::process::Command;
+
+use keymaps::key_repr::{KeyValue, MediaKeyCode, MouseKeyValue};
+
+use super::{KeyMap, MapMode};
+
+impl KeyMap {
+    #[must_use]
+    pub fn to_commands(self) -> Vec<Command> {
+        self.0
+            .iter()
+            .flat_map(|(key, value)| {
+                let key = key.last().expect("Will exist");
+                let mods = {
+                    let modifiers = key.modifiers();
+                    let mut output = vec![];
+
+                    if modifiers.alt() {
+                        output.push("Alt");
+                    }
+                    if modifiers.ctrl() {
+                        output.push("Control");
+                    }
+                    if modifiers.meta() {
+                        output.push("Super");
+                    }
+                    if modifiers.shift() {
+                        output.push("Shift");
+                    }
+                    if output.is_empty() {
+                        "None".to_owned()
+                    } else {
+                        output.join("+")
+                    }
+                };
+                let key_value = match key.value() {
+                    KeyValue::Backspace => "BackSpace".to_owned(),
+                    KeyValue::Enter => "Enter".to_owned(),
+                    KeyValue::Left => "Left".to_owned(),
+                    KeyValue::Right => "Right".to_owned(),
+                    KeyValue::Up => "Up".to_owned(),
+                    KeyValue::Down => "Down".to_owned(),
+                    KeyValue::Home => "Home".to_owned(),
+                    KeyValue::End => "End".to_owned(),
+                    KeyValue::PageUp => "Page_Up".to_owned(),
+                    KeyValue::PageDown => "Page_Down".to_owned(),
+                    KeyValue::Tab => "Tab".to_owned(),
+                    KeyValue::BackTab => "BackTab".to_owned(),
+                    KeyValue::Delete => "Delete".to_owned(),
+                    KeyValue::Insert => "Insert".to_owned(),
+                    KeyValue::F(num) => format!("F{num}"),
+                    KeyValue::Char(a) => a.to_string(),
+                    KeyValue::Null => "Null".to_owned(),
+                    KeyValue::Esc => "Esc".to_owned(),
+                    KeyValue::CapsLock => "CapsLock".to_owned(),
+                    KeyValue::ScrollLock => "ScrollLock".to_owned(),
+                    KeyValue::NumLock => "NumLock".to_owned(),
+                    KeyValue::PrintScreen => "Print".to_owned(),
+                    KeyValue::Pause => "Pause".to_owned(),
+                    KeyValue::Menu => "Menu".to_owned(),
+                    KeyValue::KeypadBegin => "KeypadBegin".to_owned(),
+                    KeyValue::Media(media_key_code) => match media_key_code {
+                        MediaKeyCode::Play => "XF86AudioPlay".to_owned(),
+                        MediaKeyCode::Pause => "XF86AudioPause".to_owned(),
+                        MediaKeyCode::PlayPause => "XF86AudioPlayPause".to_owned(),
+                        MediaKeyCode::Reverse => "XF86AudioReverse".to_owned(),
+                        MediaKeyCode::Stop => "XF86AudioStop".to_owned(),
+                        MediaKeyCode::FastForward => "XF86AudioFastForward".to_owned(),
+                        MediaKeyCode::Rewind => "XF86AudioRewind".to_owned(),
+                        MediaKeyCode::TrackNext => "XF86AudioTrackNext".to_owned(),
+                        MediaKeyCode::TrackPrevious => "XF86AudioTrackPrevious".to_owned(),
+                        MediaKeyCode::Record => "XF86AudioRecord".to_owned(),
+                        MediaKeyCode::LowerVolume => "XF86AudioLowerVolume".to_owned(),
+                        MediaKeyCode::RaiseVolume => "XF86AudioRaiseVolume".to_owned(),
+                        MediaKeyCode::MuteVolume => "XF86AudioMuteVolume".to_owned(),
+                    },
+                    KeyValue::MouseKey(mouse_key_value) => match mouse_key_value {
+                        MouseKeyValue::Left => "BTN_LEFT".to_owned(),
+                        MouseKeyValue::Right => "BTN_RIGHT".to_owned(),
+                        MouseKeyValue::Middle => "BTN_MIDDLE".to_owned(),
+                    },
+                    _ => todo!(),
+                };
+
+                value
+                    .modes
+                    .iter()
+                    .map(|mode| {
+                        let mut riverctl = Command::new("riverctl");
+                        riverctl.args([value.map_mode.as_command(), mode, &mods, &key_value]);
+
+                        riverctl.args(value.command.iter().map(String::as_str));
+                        riverctl
+                    })
+                    .collect::<Vec<_>>()
+            })
+            .collect()
+    }
+}
+
+impl MapMode {
+    pub(crate) fn as_command(self) -> &'static str {
+        match self {
+            MapMode::Map => "map",
+            MapMode::MapMouse => "map-pointer",
+            MapMode::Unmap => "unmap",
+        }
+    }
+}
diff --git a/pkgs/by-name/ri/river-mk-keymap/src/key_map/mod.rs b/pkgs/by-name/ri/river-mk-keymap/src/key_map/mod.rs
new file mode 100644
index 00000000..84a16c9d
--- /dev/null
+++ b/pkgs/by-name/ri/river-mk-keymap/src/key_map/mod.rs
@@ -0,0 +1,79 @@
+use std::{collections::HashMap, fmt::Display, ops::Deref, str::FromStr};
+
+use anyhow::Context;
+use keymaps::{key_repr::Key, map_tree::MapTrie};
+use serde::{Deserialize, Serialize};
+
+pub mod commands;
+
+#[derive(Deserialize, Serialize, Debug)]
+#[allow(clippy::module_name_repetitions)]
+pub struct RawKeyMap(HashMap<Key, KeyConfig>);
+
+#[derive(Clone, Deserialize, Serialize, Debug, PartialEq, PartialOrd)]
+/// What values to use for: `riverctl <map_mode> <mode> <mods> <key> <command..>`
+pub struct KeyConfig {
+    command: Vec<String>,
+
+    #[serde(default = "default_mode")]
+    modes: Vec<String>,
+
+    #[serde(default = "MapMode::default")]
+    map_mode: MapMode,
+}
+
+impl FromStr for KeyMap {
+    type Err = anyhow::Error;
+
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        let raw: RawKeyMap =
+            serde_json::from_str(s).context("Failed to parse the keymap config file as json.")?;
+        let mut out = MapTrie::<KeyConfig>::new();
+        for (key, value) in raw.0 {
+            out.insert(&[key], value.clone())
+                .with_context(|| format!("Failed to insert mapping {key} -> {value}"))?;
+        }
+
+        Ok(Self(out))
+    }
+}
+impl Display for KeyConfig {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        f.write_str(self.command.join(" ").as_str())
+    }
+}
+
+fn default_mode() -> Vec<String> {
+    vec!["normal".to_owned()]
+}
+
+#[derive(Copy, Deserialize, Serialize, Debug, Clone, Default, PartialEq, PartialOrd)]
+enum MapMode {
+    #[default]
+    Map,
+    MapMouse,
+    Unmap,
+}
+
+impl Display for MapMode {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        <Self as std::fmt::Debug>::fmt(self, f)
+    }
+}
+
+#[derive(Debug)]
+pub struct KeyMap(MapTrie<KeyConfig>);
+
+impl Display for KeyMap {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        self.0.fmt(f)
+    }
+}
+
+impl Deref for KeyMap {
+    type Target = MapTrie<KeyConfig>;
+
+    fn deref(&self) -> &Self::Target {
+        &self.0
+    }
+}
diff --git a/pkgs/by-name/ri/river-mk-keymap/src/main.rs b/pkgs/by-name/ri/river-mk-keymap/src/main.rs
new file mode 100644
index 00000000..5cb99f74
--- /dev/null
+++ b/pkgs/by-name/ri/river-mk-keymap/src/main.rs
@@ -0,0 +1,34 @@
+use std::fs;
+
+use anyhow::Context;
+use clap::Parser;
+
+mod cli;
+pub mod key_map;
+
+use crate::{cli::Args, key_map::KeyMap};
+
+fn main() -> Result<(), anyhow::Error> {
+    let args = Args::parse();
+    let keymap_file = fs::read_to_string(&args.path)
+        .with_context(|| format!("Failed to open keymap file at: '{}'.", args.path.display()))?;
+
+    let keymap: KeyMap = keymap_file
+        .parse()
+        .with_context(|| format!("Failed to parse keymap file at: {}", args.path.display()))?;
+
+    // println!("{keymap}");
+    // println!("Commands:");
+    for mut command in keymap.to_commands() {
+        // println!("Executing {command:?}");
+        let status = command
+            .status()
+            .with_context(|| format!("Failed to run command: '{command:?}'"))?;
+
+        if !status.success() {
+            eprintln!("Command ('{command:?}') returned with non zero exit code: {status}");
+        }
+    }
+
+    Ok(())
+}
diff --git a/pkgs/by-name/ri/river-mk-keymap/update.sh b/pkgs/by-name/ri/river-mk-keymap/update.sh
new file mode 100755
index 00000000..9268caf2
--- /dev/null
+++ b/pkgs/by-name/ri/river-mk-keymap/update.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+cargo update && cargo upgrade
diff --git a/pkgs/by-name/ri/river-start/package.nix b/pkgs/by-name/ri/river-start/package.nix
new file mode 100644
index 00000000..ab986708
--- /dev/null
+++ b/pkgs/by-name/ri/river-start/package.nix
@@ -0,0 +1,14 @@
+{
+  writeShellApplication,
+  river,
+}:
+writeShellApplication {
+  name = "river-start";
+  text = builtins.readFile ./river-start.sh;
+  runtimeInputs = [
+    river
+  ];
+  meta = {
+    mainProgram = "river-start";
+  };
+}
diff --git a/pkgs/by-name/ri/river-start/river-start.sh b/pkgs/by-name/ri/river-start/river-start.sh
new file mode 100755
index 00000000..4587ff96
--- /dev/null
+++ b/pkgs/by-name/ri/river-start/river-start.sh
@@ -0,0 +1,10 @@
+#! /usr/bin/env sh
+
+# NOTE: Keep this in sync with the file from `base_init.sh` <2025-02-03>
+RIVER_LOG_FILE="$HOME/.local/share/river/log"
+
+[ -d "$(dirname "$RIVER_LOG_FILE")" ] || mkdir --parents "$(dirname "$RIVER_LOG_FILE")"
+
+exec river -log-level info >"$RIVER_LOG_FILE" 2>&1
+
+# vim: ft=sh
diff --git a/pkgs/by-name/sc/screenshot_persistent/package.nix b/pkgs/by-name/sc/screenshot_persistent/package.nix
index f79315a1..12bb3968 100644
--- a/pkgs/by-name/sc/screenshot_persistent/package.nix
+++ b/pkgs/by-name/sc/screenshot_persistent/package.nix
@@ -1,5 +1,5 @@
 {
-  sysLib,
+  writeShellApplication,
   grim,
   slurp,
   alacritty,
@@ -7,12 +7,10 @@
   libnotify,
   lf, # TODO: add llp
 }:
-sysLib.writeShellScript {
+writeShellApplication {
   name = "screenshot_persistent";
-  src = ./screenshot_persistent.sh;
-  generateCompletions = false;
-  keepPath = true;
-  dependencies = [
+  text = builtins.readFile ./screenshot_persistent.sh;
+  runtimeInputs = [
     grim
     slurp
     alacritty
@@ -20,4 +18,7 @@ sysLib.writeShellScript {
     libnotify
     lf # TODO: add llp
   ];
+  meta = {
+    mainProgram = "screenshot_persistent";
+  };
 }
diff --git a/pkgs/by-name/sc/screenshot_persistent/screenshot_persistent.sh b/pkgs/by-name/sc/screenshot_persistent/screenshot_persistent.sh
index 4308b8d2..2bea69e3 100755
--- a/pkgs/by-name/sc/screenshot_persistent/screenshot_persistent.sh
+++ b/pkgs/by-name/sc/screenshot_persistent/screenshot_persistent.sh
@@ -1,10 +1,6 @@
-#! /usr/bin/env dash
+# shellcheck shell=bash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
-# only generate a path (this could lead to a time-of-check/time-of-use bug)
-tmp="$(mktmp --dry-run)"
+tmp="$(mktemp)"
 
 if grim -g "$(slurp)" "$tmp"; then
     name="$(rofi -dmenu -p "Name of screenshot: " -l 0)"
@@ -16,7 +12,7 @@ if grim -g "$(slurp)" "$tmp"; then
     done
 
     mv "$tmp" "$screen_shot_path"
-    alacritty -e lf -command ":{{ set sortby atime; set reverse!; }}"
+    alacritty --title "floating please" --command lf -command ":{{ set sortby atime; set reverse!; set info time; }}" "$screen_shot_path"
 fi
 
 # vim: ft=sh
diff --git a/pkgs/by-name/so/sort_song/package.nix b/pkgs/by-name/so/sort_song/package.nix
deleted file mode 100644
index f74ba57f..00000000
--- a/pkgs/by-name/so/sort_song/package.nix
+++ /dev/null
@@ -1,17 +0,0 @@
-{
-  sysLib,
-  mediainfo,
-  jq,
-  gawk,
-}:
-sysLib.writeShellScript {
-  name = "sort_song";
-  src = ./sort_song.sh;
-  generateCompletions = false;
-  keepPath = false;
-  dependencies = [
-    mediainfo
-    jq
-    gawk
-  ];
-}
diff --git a/pkgs/by-name/so/sort_song/sort_song.sh b/pkgs/by-name/so/sort_song/sort_song.sh
deleted file mode 100755
index e2978507..00000000
--- a/pkgs/by-name/so/sort_song/sort_song.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
-case "$("$1" | tr '[:upper:]' '[:lower:]')" in
-"lyrics")
-    filter="LYRICS"
-    directory="lyrics"
-    ;;
-"instrumental")
-    filter="INSTRUMENTAL"
-    directory="instrumental"
-    ;;
-*)
-    die "Expected 'instrumental|lyrics' but got '$1'"
-    ;;
-esac
-
-process() {
-    mediainfo --Output=JSON "$1" | jq '.media.track | map(.Lyrics) | join("")'
-}
-
-mkdir "../$directory"
-
-fd . --extension=opus | while read -r file; do
-    if [ "$(process "$file")" = '""' ] || [ "$(process "$file")" = '"Instrumental"' ] || [ "$(process "$file")" = '"instrumental"' ]; then
-        echo "INSTRUMENTAL::$file"
-    else
-        echo "LYRICS::$file"
-    fi
-done | grep "$filter" | awk 'BEGIN {FS="::"}{print $2}' | while read -r file; do ln -s "../all/$file" "../$directory/$file"; done
-
-# vim: ft=sh
diff --git a/pkgs/by-name/sp/spodi/package.nix b/pkgs/by-name/sp/spodi/package.nix
deleted file mode 100644
index 83540a21..00000000
--- a/pkgs/by-name/sp/spodi/package.nix
+++ /dev/null
@@ -1,39 +0,0 @@
-{
-  sysLib,
-  # dependencies
-  gawk,
-  expect,
-  spotdl,
-  fd,
-  coreutils,
-  # config
-  xdgCacheHome ? builtins.getEnv "XDG_CACHE_HOME",
-  xdgUserDirsMusic ? builtins.getEnv "XDG_MUSIC_HOME",
-}:
-sysLib.writeShellScriptMultiPart {
-  name = "spodi";
-  src = ./.;
-
-  generateCompletions = true;
-  keepPath = false;
-
-  baseName = "spodi.sh";
-  cmdPrefix = "sh";
-  cmdNames = [
-    "download.sh"
-    "update.sh"
-  ];
-
-  dependencies = [
-    gawk
-    expect
-    spotdl
-    fd
-    coreutils
-  ];
-
-  replacementStrings = {
-    XDG_CACHE_HOME = xdgCacheHome;
-    XDG_MUSIC_DIR = xdgUserDirsMusic;
-  };
-}
diff --git a/pkgs/by-name/sp/spodi/sh/download.sh b/pkgs/by-name/sp/spodi/sh/download.sh
deleted file mode 100755
index fe9746c8..00000000
--- a/pkgs/by-name/sp/spodi/sh/download.sh
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/usr/bin/env dash
-
-download_to_down() {
-    DOWNLOAD_DIRECTORY="%XDG_MUSIC_DIR/down/spotify"
-
-    already_downloaded_files="$(mktmp)"
-    fd . "$DOWNLOAD_DIRECTORY" --exclude spotdl.log --exclude spotdl-errors.log >"$already_downloaded_files"
-    if [ -z "$NO_CHECK" ] && [ "$(wc -l <"$already_downloaded_files")" -ne 0 ]; then
-        die "something is already downloaded"
-    fi
-    # [ -e "$DOWNLOAD_DIRECTORY/spotdl.log" ] && rm "$DOWNLOAD_DIRECTORY/spotdl.log"
-
-    download "$1" "$DOWNLOAD_DIRECTORY"
-}
-
-download() {
-    download_url="$1"
-    output_path="$2"
-
-    config="$(mktmp)"
-    cat <<EOF | clean >"$config"
-# Main options
---audio slider-kz bandcamp youtube-music piped youtube soundcloud
---lyrics genius musixmatch azlyrics synced
-
-# FFmpeg options
---ffmpeg ffmpeg
---threads 16
---bitrate 256k
-
-# Spotify options
---cache-path %XDG_CACHE_HOME/spotdl/.spotipy
-
-# Output options
---preload
---format opus
---output {artists}_-_{title}
---print-errors
---save-errors $output_path/spotdl-errors.log
-# TODO: Reactive whence spotdl support for these has improved <2023-12-19>
-# --generate-lrc
---overwrite skip
-
-# Misc options
---log-level INFO
-EOF
-
-    cd "$output_path" || die "BUG: no $output_path"
-    touch "$output_path/spotdl-errors.log"
-
-    # The sub shell needs to be unquoted, as the arguments may not be treated as one.
-    # shellcheck disable=2046
-    unbuffer spotdl $(cat "$config") download "$download_url" | tee "$output_path/spotdl.log"
-
-    [ -d ~/.spotdl ] && rm -r ~/.spotdl
-}
-
-# vim: ft=sh
diff --git a/pkgs/by-name/sp/spodi/sh/update.sh b/pkgs/by-name/sp/spodi/sh/update.sh
deleted file mode 100755
index a289cf58..00000000
--- a/pkgs/by-name/sp/spodi/sh/update.sh
+++ /dev/null
@@ -1,52 +0,0 @@
-#!/usr/bin/env dash
-
-update() {
-    UPDATE_DIRECTORY="%XDG_MUSIC_DIR/artists"
-    UPDATE_CONFIG_FILE="%XDG_MUSIC_DIR/artists/update.conf"
-
-    if ! [ -f "$UPDATE_CONFIG_FILE" ]; then
-        error="$(
-            cat <<EOF
-Please provide an update config file at: '$UPDATE_CONFIG_FILE'.
-
-The 'update.conf' file should follow this pattern:
-<path_to_artist>/<artist_name>|<spotify_url>
-
-All comments and empty lines are ignored
-EOF
-        )"
-        die "$error"
-    fi
-
-    config_file="$(mktmp)"
-    clean "$UPDATE_CONFIG_FILE" >"$config_file"
-
-    while IFS="|" read -r artist url; do
-        full_artist="$UPDATE_DIRECTORY/$artist"
-        [ -d "$full_artist" ] || mkdir --parents "$full_artist"
-        [ -d "$full_artist/update" ] || mkdir --parents "$full_artist/update"
-        [ -d "$full_artist/all" ] || mkdir --parents "$full_artist/all"
-        [ -d "$full_artist/filtered" ] || mkdir --parents "$full_artist/filtered"
-
-        while read -r file; do
-            ln --symbolic --relative "$file" "$full_artist/update/$(basename "$file")"
-        done <"$(tmp fd --type file --extension opus . "$full_artist/all")"
-
-        msg2 "Updating $artist with url: '$url'"
-        download "$url" "$full_artist/update"
-
-        while read -r file; do
-            mv "$file" "$full_artist/all"
-            ln --symbolic --relative "$full_artist/all/$(basename "$file")" "$full_artist/filtered/$(basename "$file")"
-        done <"$(tmp fd --type file --extension opus . "$full_artist/update")"
-
-        while read -r file; do
-            rm "$file"
-        done <"$(tmp fd --type symlink --extension opus . "$full_artist/update")"
-
-        cp "$full_artist/update/spotdl.log" "$full_artist/all/spotdl.$(date +%Y_%m_%d).log"
-        cp "$full_artist/update/spotdl-errors.log" "$full_artist/all/spotdl-errors.$(date +%Y_%m_%d).log"
-    done <"$config_file"
-}
-
-# vim: ft=sh
diff --git a/pkgs/by-name/sp/spodi/spodi.sh b/pkgs/by-name/sp/spodi/spodi.sh
deleted file mode 100755
index 475fd48a..00000000
--- a/pkgs/by-name/sp/spodi/spodi.sh
+++ /dev/null
@@ -1,71 +0,0 @@
-#!/usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
-# these are used in version()
-# shellcheck disable=2034
-AUTHORS="Soispha"
-# shellcheck disable=2034
-YEARS="2023"
-
-# load dependencies
-. ./sh/update.sh
-. ./sh/download.sh
-
-help() {
-    cat <<EOF
-This is a small wrapper around downloading things from spotify
-
-USAGE:
-    $NAME [OPTIONS] COMMAND
-
-OPTIONS:
-    --help      | -h
-                            Display this help and exit.
-
-    --version   | -v
-                            Display version and copyright information and exit.
-COMMANDS:
-    update
-                            Read the artist.conf file and download all newly released things
-
-    download URL
-                            Download a specific url to the DOWNLOAD_DIRECTORY
-EOF
-}
-
-for arg in "$@"; do
-    case "$arg" in
-    "--help" | "-h")
-        help
-        exit 0
-        ;;
-    "--version" | "-v")
-        version
-        exit 0
-        ;;
-    esac
-done
-
-case "$1" in
-"update")
-    shift 1
-    update
-    exit 0
-    ;;
-"download")
-    shift 1
-    download_url="$1"
-    [ -z "$download_url" ] && die "You need to provide a download url"
-    download_to_down "$download_url"
-    exit 0
-    ;;
-*)
-    die "Command '$1' is not know"
-    help
-    exit 1
-    ;;
-esac
-
-# vim: ft=sh
diff --git a/pkgs/by-name/st/stamp/stamp.sh b/pkgs/by-name/st/stamp/stamp.sh
index 0fced956..0aa6c281 100755
--- a/pkgs/by-name/st/stamp/stamp.sh
+++ b/pkgs/by-name/st/stamp/stamp.sh
@@ -93,7 +93,7 @@ done
 
 for file in "$@"; do
     if [ -d "$file" ]; then
-        fd . "$file" --type file --hidden | while read -r path_file; do
+        fd . "$file" --type file --hidden --exclude '/.git/*' | while read -r path_file; do
             reuse_run "$path_file"
         done
     else
diff --git a/pkgs/by-name/ts/tskm/.envrc b/pkgs/by-name/ts/tskm/.envrc
new file mode 100644
index 00000000..d21a17fc
--- /dev/null
+++ b/pkgs/by-name/ts/tskm/.envrc
@@ -0,0 +1,8 @@
+#!/usr/bin/env sh
+
+SHELL_COMPLETION_DIR="$(pwd)/target/shell"
+export SHELL_COMPLETION_DIR
+
+export TSKM_PROJECT_FILE=/home/soispha/repos/nix/config/modules/common/projects.json
+
+use flake
diff --git a/pkgs/by-name/ts/tskm/.gitignore b/pkgs/by-name/ts/tskm/.gitignore
new file mode 100644
index 00000000..2d5df85d
--- /dev/null
+++ b/pkgs/by-name/ts/tskm/.gitignore
@@ -0,0 +1,2 @@
+/target
+.direnv
diff --git a/pkgs/by-name/ts/tskm/Cargo.lock b/pkgs/by-name/ts/tskm/Cargo.lock
new file mode 100644
index 00000000..68823d3c
--- /dev/null
+++ b/pkgs/by-name/ts/tskm/Cargo.lock
@@ -0,0 +1,1252 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "adler2"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
+
+[[package]]
+name = "ahash"
+version = "0.8.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
+dependencies = [
+ "cfg-if",
+ "once_cell",
+ "version_check",
+ "zerocopy",
+]
+
+[[package]]
+name = "android-tzdata"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
+
+[[package]]
+name = "android_system_properties"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "anstream"
+version = "0.6.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b"
+dependencies = [
+ "anstyle",
+ "anstyle-parse",
+ "anstyle-query",
+ "anstyle-wincon",
+ "colorchoice",
+ "is_terminal_polyfill",
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle"
+version = "1.0.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
+
+[[package]]
+name = "anstyle-parse"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
+dependencies = [
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle-query"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
+dependencies = [
+ "windows-sys",
+]
+
+[[package]]
+name = "anstyle-wincon"
+version = "3.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e"
+dependencies = [
+ "anstyle",
+ "once_cell",
+ "windows-sys",
+]
+
+[[package]]
+name = "anyhow"
+version = "1.0.97"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
+
+[[package]]
+name = "autocfg"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
+
+[[package]]
+name = "bitflags"
+version = "2.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
+
+[[package]]
+name = "bumpalo"
+version = "3.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
+
+[[package]]
+name = "byteorder"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
+
+[[package]]
+name = "cc"
+version = "1.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a"
+dependencies = [
+ "shlex",
+]
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "chrono"
+version = "0.4.40"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c"
+dependencies = [
+ "android-tzdata",
+ "iana-time-zone",
+ "js-sys",
+ "num-traits",
+ "serde",
+ "wasm-bindgen",
+ "windows-link",
+]
+
+[[package]]
+name = "clap"
+version = "4.5.34"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e958897981290da2a852763fe9cdb89cd36977a5d729023127095fa94d95e2ff"
+dependencies = [
+ "clap_builder",
+ "clap_derive",
+]
+
+[[package]]
+name = "clap_builder"
+version = "4.5.34"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "83b0f35019843db2160b5bb19ae09b4e6411ac33fc6a712003c33e03090e2489"
+dependencies = [
+ "anstream",
+ "anstyle",
+ "clap_lex",
+ "strsim",
+]
+
+[[package]]
+name = "clap_complete"
+version = "4.5.47"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c06f5378ea264ad4f82bbc826628b5aad714a75abf6ece087e923010eb937fb6"
+dependencies = [
+ "clap",
+]
+
+[[package]]
+name = "clap_derive"
+version = "4.5.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7"
+dependencies = [
+ "heck",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "clap_lex"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
+
+[[package]]
+name = "colorchoice"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
+
+[[package]]
+name = "core-foundation-sys"
+version = "0.8.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
+
+[[package]]
+name = "crc32fast"
+version = "1.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "dirs"
+version = "6.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e"
+dependencies = [
+ "dirs-sys",
+]
+
+[[package]]
+name = "dirs-sys"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab"
+dependencies = [
+ "libc",
+ "option-ext",
+ "redox_users",
+ "windows-sys",
+]
+
+[[package]]
+name = "displaydoc"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "fallible-iterator"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649"
+
+[[package]]
+name = "fallible-streaming-iterator"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
+
+[[package]]
+name = "flate2"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece"
+dependencies = [
+ "crc32fast",
+ "miniz_oxide",
+]
+
+[[package]]
+name = "form_urlencoded"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
+dependencies = [
+ "percent-encoding",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi 0.11.0+wasi-snapshot-preview1",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "r-efi",
+ "wasi 0.14.2+wasi-0.2.4",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.14.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
+dependencies = [
+ "ahash",
+]
+
+[[package]]
+name = "hashlink"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af"
+dependencies = [
+ "hashbrown",
+]
+
+[[package]]
+name = "heck"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
+
+[[package]]
+name = "hermit-abi"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fbd780fe5cc30f81464441920d82ac8740e2e46b29a6fad543ddd075229ce37e"
+
+[[package]]
+name = "iana-time-zone"
+version = "0.1.62"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2fd658b06e56721792c5df4475705b6cda790e9298d19d2f8af083457bcd127"
+dependencies = [
+ "android_system_properties",
+ "core-foundation-sys",
+ "iana-time-zone-haiku",
+ "js-sys",
+ "log",
+ "wasm-bindgen",
+ "windows-core",
+]
+
+[[package]]
+name = "iana-time-zone-haiku"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "icu_collections"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526"
+dependencies = [
+ "displaydoc",
+ "yoke",
+ "zerofrom",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_locid"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637"
+dependencies = [
+ "displaydoc",
+ "litemap",
+ "tinystr",
+ "writeable",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_locid_transform"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e"
+dependencies = [
+ "displaydoc",
+ "icu_locid",
+ "icu_locid_transform_data",
+ "icu_provider",
+ "tinystr",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_locid_transform_data"
+version = "1.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d"
+
+[[package]]
+name = "icu_normalizer"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f"
+dependencies = [
+ "displaydoc",
+ "icu_collections",
+ "icu_normalizer_data",
+ "icu_properties",
+ "icu_provider",
+ "smallvec",
+ "utf16_iter",
+ "utf8_iter",
+ "write16",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_normalizer_data"
+version = "1.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7"
+
+[[package]]
+name = "icu_properties"
+version = "1.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5"
+dependencies = [
+ "displaydoc",
+ "icu_collections",
+ "icu_locid_transform",
+ "icu_properties_data",
+ "icu_provider",
+ "tinystr",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_properties_data"
+version = "1.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2"
+
+[[package]]
+name = "icu_provider"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9"
+dependencies = [
+ "displaydoc",
+ "icu_locid",
+ "icu_provider_macros",
+ "stable_deref_trait",
+ "tinystr",
+ "writeable",
+ "yoke",
+ "zerofrom",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_provider_macros"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "idna"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e"
+dependencies = [
+ "idna_adapter",
+ "smallvec",
+ "utf8_iter",
+]
+
+[[package]]
+name = "idna_adapter"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71"
+dependencies = [
+ "icu_normalizer",
+ "icu_properties",
+]
+
+[[package]]
+name = "is-terminal"
+version = "0.4.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9"
+dependencies = [
+ "hermit-abi",
+ "libc",
+ "windows-sys",
+]
+
+[[package]]
+name = "is_terminal_polyfill"
+version = "1.70.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
+
+[[package]]
+name = "itoa"
+version = "1.0.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
+
+[[package]]
+name = "js-sys"
+version = "0.3.77"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
+dependencies = [
+ "once_cell",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "libc"
+version = "0.2.171"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
+
+[[package]]
+name = "libredox"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
+dependencies = [
+ "bitflags",
+ "libc",
+]
+
+[[package]]
+name = "libsqlite3-sys"
+version = "0.30.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149"
+dependencies = [
+ "pkg-config",
+ "vcpkg",
+]
+
+[[package]]
+name = "litemap"
+version = "0.7.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856"
+
+[[package]]
+name = "log"
+version = "0.4.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
+
+[[package]]
+name = "lz4_flex"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75761162ae2b0e580d7e7c390558127e5f01b4194debd6221fd8c207fc80e3f5"
+dependencies = [
+ "twox-hash",
+]
+
+[[package]]
+name = "memchr"
+version = "2.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
+
+[[package]]
+name = "miniz_oxide"
+version = "0.8.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ff70ce3e48ae43fa075863cef62e8b43b71a4f2382229920e0df362592919430"
+dependencies = [
+ "adler2",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.2.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.21.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
+
+[[package]]
+name = "option-ext"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
+
+[[package]]
+name = "percent-encoding"
+version = "2.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
+
+[[package]]
+name = "pkg-config"
+version = "0.3.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.94"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.40"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "r-efi"
+version = "5.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
+
+[[package]]
+name = "redox_users"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b"
+dependencies = [
+ "getrandom 0.2.15",
+ "libredox",
+ "thiserror",
+]
+
+[[package]]
+name = "rusqlite"
+version = "0.32.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7753b721174eb8ff87a9a0e799e2d7bc3749323e773db92e0984debb00019d6e"
+dependencies = [
+ "bitflags",
+ "fallible-iterator",
+ "fallible-streaming-iterator",
+ "hashlink",
+ "libsqlite3-sys",
+ "smallvec",
+]
+
+[[package]]
+name = "rustversion"
+version = "1.0.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2"
+
+[[package]]
+name = "ryu"
+version = "1.0.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
+
+[[package]]
+name = "same-file"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "serde"
+version = "1.0.219"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.219"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.140"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
+dependencies = [
+ "itoa",
+ "memchr",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "shlex"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
+
+[[package]]
+name = "smallvec"
+version = "1.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd"
+
+[[package]]
+name = "stable_deref_trait"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
+
+[[package]]
+name = "static_assertions"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
+
+[[package]]
+name = "stderrlog"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "61c910772f992ab17d32d6760e167d2353f4130ed50e796752689556af07dc6b"
+dependencies = [
+ "chrono",
+ "is-terminal",
+ "log",
+ "termcolor",
+ "thread_local",
+]
+
+[[package]]
+name = "strsim"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
+
+[[package]]
+name = "strum"
+version = "0.27.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f64def088c51c9510a8579e3c5d67c65349dcf755e5479ad3d010aa6454e2c32"
+
+[[package]]
+name = "strum_macros"
+version = "0.27.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c77a8c5abcaf0f9ce05d62342b7d298c346515365c36b673df4ebe3ced01fde8"
+dependencies = [
+ "heck",
+ "proc-macro2",
+ "quote",
+ "rustversion",
+ "syn",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.100"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "synstructure"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "taskchampion"
+version = "2.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b010f5ebe51e88ae490691ed2a43b699e3468c8e3838e244accd8526aca7751b"
+dependencies = [
+ "anyhow",
+ "byteorder",
+ "chrono",
+ "flate2",
+ "log",
+ "rusqlite",
+ "serde",
+ "serde_json",
+ "strum",
+ "strum_macros",
+ "thiserror",
+ "uuid",
+]
+
+[[package]]
+name = "termcolor"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "thiserror"
+version = "2.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "2.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "thread_local"
+version = "1.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
+dependencies = [
+ "cfg-if",
+ "once_cell",
+]
+
+[[package]]
+name = "tinystr"
+version = "0.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f"
+dependencies = [
+ "displaydoc",
+ "zerovec",
+]
+
+[[package]]
+name = "tskm"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "clap",
+ "clap_complete",
+ "dirs",
+ "log",
+ "lz4_flex",
+ "serde",
+ "serde_json",
+ "stderrlog",
+ "taskchampion",
+ "url",
+ "walkdir",
+]
+
+[[package]]
+name = "twox-hash"
+version = "1.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675"
+dependencies = [
+ "cfg-if",
+ "static_assertions",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
+
+[[package]]
+name = "url"
+version = "2.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60"
+dependencies = [
+ "form_urlencoded",
+ "idna",
+ "percent-encoding",
+ "serde",
+]
+
+[[package]]
+name = "utf16_iter"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246"
+
+[[package]]
+name = "utf8_iter"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
+
+[[package]]
+name = "utf8parse"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
+
+[[package]]
+name = "uuid"
+version = "1.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9"
+dependencies = [
+ "getrandom 0.3.2",
+ "serde",
+]
+
+[[package]]
+name = "vcpkg"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
+
+[[package]]
+name = "version_check"
+version = "0.9.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
+
+[[package]]
+name = "walkdir"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
+dependencies = [
+ "same-file",
+ "winapi-util",
+]
+
+[[package]]
+name = "wasi"
+version = "0.11.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+
+[[package]]
+name = "wasi"
+version = "0.14.2+wasi-0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
+dependencies = [
+ "wit-bindgen-rt",
+]
+
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.100"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
+dependencies = [
+ "cfg-if",
+ "once_cell",
+ "rustversion",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.100"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
+dependencies = [
+ "bumpalo",
+ "log",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.100"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.100"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.100"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "winapi-util"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
+dependencies = [
+ "windows-sys",
+]
+
+[[package]]
+name = "windows-core"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-link"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
+
+[[package]]
+name = "windows-sys"
+version = "0.59.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_gnullvm",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
+
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
+
+[[package]]
+name = "wit-bindgen-rt"
+version = "0.39.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
+name = "write16"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936"
+
+[[package]]
+name = "writeable"
+version = "0.5.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
+
+[[package]]
+name = "yoke"
+version = "0.7.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40"
+dependencies = [
+ "serde",
+ "stable_deref_trait",
+ "yoke-derive",
+ "zerofrom",
+]
+
+[[package]]
+name = "yoke-derive"
+version = "0.7.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "synstructure",
+]
+
+[[package]]
+name = "zerocopy"
+version = "0.7.35"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
+dependencies = [
+ "zerocopy-derive",
+]
+
+[[package]]
+name = "zerocopy-derive"
+version = "0.7.35"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "zerofrom"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5"
+dependencies = [
+ "zerofrom-derive",
+]
+
+[[package]]
+name = "zerofrom-derive"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "synstructure",
+]
+
+[[package]]
+name = "zerovec"
+version = "0.10.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079"
+dependencies = [
+ "yoke",
+ "zerofrom",
+ "zerovec-derive",
+]
+
+[[package]]
+name = "zerovec-derive"
+version = "0.10.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
diff --git a/pkgs/by-name/ts/tskm/Cargo.toml b/pkgs/by-name/ts/tskm/Cargo.toml
new file mode 100644
index 00000000..41fc5888
--- /dev/null
+++ b/pkgs/by-name/ts/tskm/Cargo.toml
@@ -0,0 +1,91 @@
+[package]
+name = "tskm"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+anyhow = "1.0.97"
+clap = { version = "4.5.34", features = ["derive"] }
+dirs = "6.0.0"
+log = "0.4.27"
+lz4_flex = "0.11.3"
+serde = { version = "1.0.219", features = ["derive"] }
+serde_json = "1.0.140"
+stderrlog = "0.6.0"
+taskchampion = { version = "2.0.3", default-features = false }
+url = { version = "2.5.4", features = ["serde"] }
+walkdir = "2.5.0"
+
+[profile.release]
+lto = true
+codegen-units = 1
+panic = "abort"
+split-debuginfo = "off"
+
+[lints.rust]
+# rustc lint groups https://doc.rust-lang.org/rustc/lints/groups.html
+warnings = "warn"
+future_incompatible = { level = "warn", priority = -1 }
+let_underscore = { level = "warn", priority = -1 }
+nonstandard_style = { level = "warn", priority = -1 }
+rust_2018_compatibility = { level = "warn", priority = -1 }
+rust_2018_idioms = { level = "warn", priority = -1 }
+rust_2021_compatibility = { level = "warn", priority = -1 }
+unused = { level = "warn", priority = -1 }
+# rustc allowed-by-default lints https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html
+# missing_docs = "warn"
+macro_use_extern_crate = "warn"
+meta_variable_misuse = "warn"
+missing_abi = "warn"
+missing_copy_implementations = "warn"
+missing_debug_implementations = "warn"
+non_ascii_idents = "warn"
+noop_method_call = "warn"
+single_use_lifetimes = "warn"
+trivial_casts = "warn"
+trivial_numeric_casts = "warn"
+unreachable_pub = "warn"
+unsafe_op_in_unsafe_fn = "warn"
+unused_crate_dependencies = "warn"
+unused_import_braces = "warn"
+unused_lifetimes = "warn"
+unused_qualifications = "warn"
+variant_size_differences = "warn"
+
+[lints.rustdoc]
+# rustdoc lints https://doc.rust-lang.org/rustdoc/lints.html
+broken_intra_doc_links = "warn"
+private_intra_doc_links = "warn"
+missing_crate_level_docs = "warn"
+private_doc_tests = "warn"
+invalid_codeblock_attributes = "warn"
+invalid_rust_codeblocks = "warn"
+bare_urls = "warn"
+
+[lints.clippy]
+# clippy allowed by default
+dbg_macro = "warn"
+# clippy categories https://doc.rust-lang.org/clippy/
+all = { level = "warn", priority = -1 }
+correctness = { level = "warn", priority = -1 }
+suspicious = { level = "warn", priority = -1 }
+style = { level = "warn", priority = -1 }
+complexity = { level = "warn", priority = -1 }
+perf = { level = "warn", priority = -1 }
+pedantic = { level = "warn", priority = -1 }
+missing_panics_doc = "allow"
+missing_errors_doc = "allow"
+
+[build-dependencies]
+anyhow = "1.0.97"
+clap = { version = "4.5.34", features = ["derive"] }
+clap_complete = "4.5.47"
+dirs = "6.0.0"
+log = "0.4.27"
+serde = { version = "1.0.219", features = ["derive"] }
+serde_json = "1.0.140"
+taskchampion = { version = "2.0.3", default-features = false }
+url = "2.5.4"
+walkdir = "2.5.0"
diff --git a/pkgs/by-name/ts/tskm/build.rs b/pkgs/by-name/ts/tskm/build.rs
new file mode 100644
index 00000000..e3b60bb9
--- /dev/null
+++ b/pkgs/by-name/ts/tskm/build.rs
@@ -0,0 +1,52 @@
+use anyhow::{Context, Result};
+use clap::{CommandFactory, ValueEnum};
+use clap_complete::generate_to;
+use clap_complete::Shell;
+
+use std::env;
+use std::fs;
+use std::path::PathBuf;
+
+use crate::cli::CliArgs;
+
+pub mod task {
+    include!("src/task/mod.rs");
+}
+pub mod state {
+    include!("src/state.rs");
+}
+
+pub mod interface {
+    pub mod input {
+        include!("src/interface/input/mod.rs");
+    }
+    pub mod project {
+        include!("src/interface/project/mod.rs");
+    }
+}
+
+pub mod cli {
+    include!("src/cli.rs");
+}
+
+fn main() -> Result<()> {
+    let outdir = match env::var_os("SHELL_COMPLETION_DIR") {
+        None => return Ok(()),
+        Some(outdir) => outdir,
+    };
+
+    if !PathBuf::from(&outdir).exists() {
+        fs::create_dir_all(&outdir)?;
+    }
+
+    let mut cmd = CliArgs::command();
+
+    for &shell in Shell::value_variants() {
+        let path = generate_to(shell, &mut cmd, "tskm", &outdir).with_context(|| {
+            format!("Failed to output shell completion for {shell} to {outdir:?}")
+        })?;
+        println!("cargo:warning=completion file for {shell} is generated at: {path:?}");
+    }
+
+    Ok(())
+}
diff --git a/pkgs/by-name/ts/tskm/flake.lock b/pkgs/by-name/ts/tskm/flake.lock
new file mode 100644
index 00000000..82448387
--- /dev/null
+++ b/pkgs/by-name/ts/tskm/flake.lock
@@ -0,0 +1,27 @@
+{
+  "nodes": {
+    "nixpkgs": {
+      "locked": {
+        "lastModified": 1743076231,
+        "narHash": "sha256-yQugdVfi316qUfqzN8JMaA2vixl+45GxNm4oUfXlbgw=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "6c5963357f3c1c840201eda129a99d455074db04",
+        "type": "github"
+      },
+      "original": {
+        "owner": "NixOS",
+        "ref": "nixpkgs-unstable",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
+    "root": {
+      "inputs": {
+        "nixpkgs": "nixpkgs"
+      }
+    }
+  },
+  "root": "root",
+  "version": 7
+}
diff --git a/pkgs/by-name/ts/tskm/flake.nix b/pkgs/by-name/ts/tskm/flake.nix
new file mode 100644
index 00000000..5a5f628b
--- /dev/null
+++ b/pkgs/by-name/ts/tskm/flake.nix
@@ -0,0 +1,29 @@
+{
+  description = "This is the core interface to the system-integrated task management";
+
+  inputs = {
+    nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
+  };
+
+  outputs = {nixpkgs, ...}: let
+    system = "x86_64-linux";
+    pkgs = nixpkgs.legacyPackages."${system}";
+  in {
+    devShells."${system}".default = pkgs.mkShell {
+      buildInputs = [
+        pkgs.sqlite
+      ];
+
+      packages = with pkgs; [
+        cargo
+        clippy
+        rustc
+        rustfmt
+
+        cargo-edit
+      ];
+    };
+  };
+}
+# vim: ts=2
+
diff --git a/pkgs/by-name/ts/tskm/package.nix b/pkgs/by-name/ts/tskm/package.nix
new file mode 100644
index 00000000..3d320772
--- /dev/null
+++ b/pkgs/by-name/ts/tskm/package.nix
@@ -0,0 +1,53 @@
+{
+  rustPlatform,
+  installShellFiles,
+  makeWrapper,
+  lib,
+  # Dependencies
+  taskwarrior3,
+  git,
+  rofi,
+  firefox,
+  sqlite,
+}:
+rustPlatform.buildRustPackage (finalAttrs: {
+  pname = "tskm";
+  version = "0.1.0";
+
+  src = ./.;
+  cargoLock = {
+    lockFile = ./Cargo.lock;
+  };
+
+  env = {
+    SHELL_COMPLETION_DIR = "./shell";
+  };
+
+  buildInputs = [
+    taskwarrior3
+    git
+    rofi
+    firefox
+    sqlite
+  ];
+
+  nativeBuildInputs = [
+    installShellFiles
+    makeWrapper
+  ];
+
+  postInstall = ''
+    installShellCompletion --cmd tskm \
+      --bash ./shell/tskm.bash \
+      --fish ./shell/tskm.fish \
+      --zsh ./shell/_tskm
+
+    # NOTE: We cannot clear the path, because we need access to the $EDITOR. <2025-04-04>
+    wrapProgram $out/bin/tskm \
+      --prefix PATH : ${lib.makeBinPath finalAttrs.buildInputs}
+  '';
+
+  meta = {
+    mainProgram = "tskm";
+  };
+})
diff --git a/pkgs/by-name/ts/tskm/src/cli.rs b/pkgs/by-name/ts/tskm/src/cli.rs
new file mode 100644
index 00000000..1c72b3c2
--- /dev/null
+++ b/pkgs/by-name/ts/tskm/src/cli.rs
@@ -0,0 +1,153 @@
+use std::path::PathBuf;
+
+use anyhow::{bail, Result};
+use clap::{ArgAction, Parser, Subcommand};
+use url::Url;
+
+use crate::{
+    interface::{input::Input, project::ProjectName},
+    state::State,
+    task,
+};
+
+#[derive(Parser, Debug)]
+#[command(author, version, about, long_about, verbatim_doc_comment)]
+/// This is the core interface to the system-integrated task management
+///
+/// `tskm` effectively combines multiple applications together:
+/// - `taskwarrior` projects are raised connected to `firefox` profiles, making it possible to “open”
+///   a project.
+/// - Every `taskwarrior` project has a determined `neorg` path, so that extra information for a
+///   `project` can be stored in this `norg` file.
+/// - `tskm` can track inputs for you. These are URLs with optional tags which you can that
+///   “review” to open tasks based on them.
+pub struct CliArgs {
+    #[command(subcommand)]
+    pub command: Command,
+
+    /// Increase message verbosity
+    #[arg(long="verbose", short = 'v', action = ArgAction::Count, default_value_t = 2)]
+    pub verbosity: u8,
+
+    /// Silence all output
+    #[arg(long, short = 'q')]
+    pub quiet: bool,
+}
+
+#[derive(Subcommand, Debug)]
+pub enum Command {
+    /// Interact with projects.
+    Projects {
+        #[command(subcommand)]
+        command: ProjectCommand,
+    },
+
+    /// Manage the input queue.
+    Inputs {
+        #[command(subcommand)]
+        command: InputCommand,
+    },
+
+    /// Access the associated `neorg` workspace for the project/task.
+    Neorg {
+        #[command(subcommand)]
+        command: NeorgCommand,
+    },
+
+    /// Interface with the Firefox profile of each project.
+    Open {
+        #[command(subcommand)]
+        command: OpenCommand,
+    },
+}
+
+#[derive(Subcommand, Debug)]
+pub enum ProjectCommand {
+    /// Lists all available projects.
+    List,
+
+    /// Allows you to quickly add projects.
+    Add {
+        /// The name of the new project.
+        #[arg(value_parser = ProjectName::try_from_project)]
+        new_project_name: ProjectName,
+    },
+}
+
+#[derive(Subcommand, Debug, Clone, Copy)]
+pub enum NeorgCommand {
+    /// Open the `neorg` project associated with id of the task.
+    Task {
+        /// The working set id of the task
+        #[arg(value_parser = task_from_working_set_id)]
+        id: task::Task,
+    },
+}
+
+fn task_from_working_set_id(id: &str) -> Result<task::Task> {
+    let id: usize = id.parse()?;
+    let mut state = State::new_ro()?;
+
+    let Some(task) = task::Task::from_working_set(id, &mut state)? else {
+        bail!("Working set id '{id}' is not valid!")
+    };
+    Ok(task)
+}
+
+#[derive(Subcommand, Debug)]
+pub enum OpenCommand {
+    /// Open each project's Firefox profile consecutively, that was opened since the last review.
+    ///
+    /// This allows you to remove stale opened tabs and to commit open tabs to the `inputs`.
+    Review,
+
+    /// Opens Firefox with either the supplied project or the currently active project profile.
+    Project {
+        /// The project to open.
+        #[arg(value_parser = task::Project::from_project_string)]
+        project: task::Project,
+
+        /// The URL to open.
+        url: Option<Url>,
+    },
+
+    /// Open a selected project in it's Firefox profile.
+    ///
+    /// This will use rofi's dmenu mode to select one project from the list of all registered
+    /// projects.
+    Select {
+        /// The URL to open.
+        url: Option<Url>,
+    },
+
+    /// List all open tabs in the project.
+    ListTabs {
+        /// The project to open.
+        #[arg(value_parser = task::Project::from_project_string)]
+        project: Option<task::Project>,
+    },
+}
+
+#[derive(Subcommand, Debug)]
+pub enum InputCommand {
+    /// Add URLs as inputs to be categorized.
+    Add { inputs: Vec<Input> },
+    /// Remove URLs
+    Remove { inputs: Vec<Input> },
+
+    /// Add all URLs in the file as inputs to be categorized.
+    ///
+    /// This expects each line to contain one URL.
+    File { file: PathBuf },
+
+    /// Like 'review', but for the inputs that have previously been added.
+    /// It takes a project in which to open the URLs.
+    Review {
+        /// Opens all the URLs in this project.
+        #[arg(value_parser = task::Project::from_project_string)]
+        project: task::Project,
+    },
+
+    /// List all the previously added inputs.
+    List,
+}
diff --git a/pkgs/by-name/ts/tskm/src/interface/input/handle.rs b/pkgs/by-name/ts/tskm/src/interface/input/handle.rs
new file mode 100644
index 00000000..0ff0e56e
--- /dev/null
+++ b/pkgs/by-name/ts/tskm/src/interface/input/handle.rs
@@ -0,0 +1,112 @@
+use std::{
+    fs, process,
+    str::FromStr,
+    thread::{self, sleep},
+    time::Duration,
+};
+
+use anyhow::{Context, Result};
+use log::{error, info};
+
+use crate::cli::InputCommand;
+
+use super::Input;
+
+/// # Errors
+/// When command handling fails.
+///
+/// # Panics
+/// When internal assertions fail.
+pub fn handle(command: InputCommand) -> Result<()> {
+    match command {
+        InputCommand::Add { inputs } => {
+            for input in inputs {
+                input.commit().with_context(|| {
+                    format!("Failed to add input ('{input}') to the input storage.")
+                })?;
+            }
+        }
+        InputCommand::Remove { inputs } => {
+            for input in inputs {
+                input.remove().with_context(|| {
+                    format!("Failed to remove input ('{input}') from the input storage.")
+                })?;
+            }
+        }
+        InputCommand::File { file } => {
+            let file = fs::read_to_string(file)?;
+            for line in file.lines() {
+                let input = Input::from_str(line)?;
+                input.commit().with_context(|| {
+                    format!("Failed to add input ('{input}') to the input storage.")
+                })?;
+            }
+        }
+        InputCommand::Review { project } => {
+            let project = project.to_project_display();
+
+            let local_project = project.clone();
+            let handle = thread::spawn(move || {
+                // We assume that the project is not yet open.
+                let mut firefox = process::Command::new("firefox")
+                    .args(["-P", local_project.as_str(), "about:newtab"])
+                    .spawn()?;
+
+                Ok::<_, anyhow::Error>(firefox.wait()?)
+            });
+            // Give Firefox some time to start.
+            info!("Waiting on firefox to start");
+            sleep(Duration::from_secs(4));
+
+            let project_str = project.as_str();
+            'outer: for all in Input::all()?.chunks(100) {
+                info!("Starting review for the first hundred URLs.");
+
+                for input in all {
+                    info!("-> '{input}'");
+                    let status = process::Command::new("firefox")
+                        .args(["-P", project_str, input.url().to_string().as_str()])
+                        .status()?;
+
+                    if status.success() {
+                        input.remove()?;
+                    } else {
+                        error!("Adding `{input}` to Firefox failed!");
+                    }
+                }
+
+                {
+                    use std::io::{stdin, stdout, Write};
+
+                    let mut s = String::new();
+                    eprint!("Continue? (y/N) ");
+                    stdout().flush()?;
+
+                    stdin()
+                        .read_line(&mut s)
+                        .expect("Did not enter a correct string");
+
+                    if let Some('\n') = s.chars().next_back() {
+                        s.pop();
+                    }
+                    if let Some('\r') = s.chars().next_back() {
+                        s.pop();
+                    }
+
+                    if s != "y" {
+                        break 'outer;
+                    }
+                }
+            }
+
+            info!("Waiting for firefox to stop");
+            handle.join().expect("Should be joinable")?;
+        }
+        InputCommand::List => {
+            for url in Input::all()? {
+                println!("{url}");
+            }
+        }
+    }
+    Ok(())
+}
diff --git a/pkgs/by-name/ts/tskm/src/interface/input/mod.rs b/pkgs/by-name/ts/tskm/src/interface/input/mod.rs
new file mode 100644
index 00000000..9ece7a3a
--- /dev/null
+++ b/pkgs/by-name/ts/tskm/src/interface/input/mod.rs
@@ -0,0 +1,257 @@
+use std::{
+    collections::HashSet,
+    fmt::Display,
+    fs::{self, read_to_string, File},
+    io::Write,
+    path::PathBuf,
+    process::Command,
+    str::FromStr,
+};
+
+use anyhow::{bail, Context, Result};
+use url::Url;
+use walkdir::WalkDir;
+
+pub mod handle;
+pub use handle::handle;
+
+#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
+pub struct NoWhitespaceString(String);
+
+impl NoWhitespaceString {
+    /// # Panics
+    /// If the input contains whitespace.
+    #[must_use]
+    pub fn new(input: String) -> Self {
+        if input.contains(' ') {
+            panic!("Your input '{input}' contains whitespace. I did not expect that.")
+        } else {
+            Self(input)
+        }
+    }
+}
+
+impl Display for NoWhitespaceString {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        self.0.fmt(f)
+    }
+}
+
+impl NoWhitespaceString {
+    #[must_use]
+    pub fn as_str(&self) -> &str {
+        &self.0
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct Input {
+    url: Url,
+    tags: HashSet<NoWhitespaceString>,
+}
+
+impl FromStr for Input {
+    type Err = anyhow::Error;
+
+    fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
+        if s.contains(' ') {
+            let (url, tags) = s.split_once(' ').expect("Should work");
+            Ok(Self {
+                url: Url::from_str(url)?,
+                tags: {
+                    tags.trim()
+                        .split(' ')
+                        .map(|tag| {
+                            if let Some(tag) = tag.strip_prefix('+') {
+                                Ok(NoWhitespaceString::new(tag.to_owned()))
+                            } else {
+                                bail!("Your tag '{tag}' does not start with the required '+'");
+                            }
+                        })
+                        .collect::<Result<_, _>>()?
+                },
+            })
+        } else {
+            Ok(Self {
+                url: Url::from_str(s)?,
+                tags: HashSet::new(),
+            })
+        }
+    }
+}
+
+impl Display for Input {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        if self.tags.is_empty() {
+            self.url.fmt(f)
+        } else {
+            write!(
+                f,
+                "{} {}",
+                self.url,
+                self.tags
+                    .iter()
+                    .fold(String::new(), |mut acc, tag| {
+                        acc.push('+');
+                        acc.push_str(tag.as_str());
+                        acc.push(' ');
+                        acc
+                    })
+                    .trim()
+            )
+        }
+    }
+}
+
+impl Input {
+    fn base_path() -> PathBuf {
+        dirs::data_local_dir()
+            .expect("This should be set")
+            .join("tskm/inputs")
+    }
+
+    fn url_path(url: &Url) -> Result<PathBuf> {
+        let base_path = Self::base_path();
+
+        let url_path = base_path.join(url.to_string());
+        fs::create_dir_all(&url_path)
+            .with_context(|| format!("Failed to open file: '{}'", url_path.display()))?;
+
+        Ok(url_path.join("url_value"))
+    }
+
+    #[must_use]
+    pub fn url(&self) -> &Url {
+        &self.url
+    }
+
+    /// Commit this constructed [`Input`] to storage.
+    ///
+    /// # Errors
+    /// If IO operations fail.
+    pub fn commit(&self) -> Result<()> {
+        let url_path = Self::url_path(&self.url)?;
+
+        let url_content = {
+            if url_path.exists() {
+                read_to_string(&url_path)?
+            } else {
+                String::new()
+            }
+        };
+
+        let mut file = File::create(&url_path)
+            .with_context(|| format!("Failed to open file: '{}'", url_path.display()))?;
+        writeln!(file, "{url_content}{self}")?;
+
+        Self::git_commit(&format!("Add new url: '{self}'"))?;
+
+        Ok(())
+    }
+
+    /// Remove this constructed [`Input`] to storage.
+    ///
+    /// Beware that this does not take tags into account.
+    ///
+    /// # Errors
+    /// If IO operations fail.
+    pub fn remove(&self) -> Result<()> {
+        let url_path = Self::url_path(&self.url)?;
+
+        fs::remove_file(&url_path)
+            .with_context(|| format!("Failed to remove file: '{}'", url_path.display()))?;
+
+        let mut url_path = url_path.as_path();
+        while let Some(parent) = url_path.parent() {
+            if fs::read_dir(parent)?.count() == 0 {
+                fs::remove_dir(parent)?;
+            }
+            url_path = parent;
+        }
+
+        Self::git_commit(&format!("Remove url: '{self}'"))?;
+        Ok(())
+    }
+
+    /// Commit your changes
+    fn git_commit(message: &str) -> Result<()> {
+        let status = Command::new("git")
+            .args(["add", "."])
+            .current_dir(Self::base_path())
+            .status()?;
+        if !status.success() {
+            bail!("Git add . failed!");
+        }
+
+        let status = Command::new("git")
+            .args(["commit", "--message", message, "--no-gpg-sign"])
+            .current_dir(Self::base_path())
+            .status()?;
+        if !status.success() {
+            bail!("Git commit failed!");
+        }
+
+        Ok(())
+    }
+
+    /// Get all previously [`Self::commit`]ed inputs.
+    ///
+    /// # Errors
+    /// When IO handling fails.
+    ///
+    /// # Panics
+    /// If internal assertions fail.
+    pub fn all() -> Result<Vec<Self>> {
+        let mut output = vec![];
+        for entry in WalkDir::new(Self::base_path())
+            .min_depth(1)
+            .into_iter()
+            .filter_entry(|e| {
+                let s = e.file_name().to_str();
+                s != Some(".git")
+            })
+        {
+            let entry = entry?;
+
+            if !entry.file_type().is_file() {
+                continue;
+            }
+
+            let url_value_file = entry
+                .path()
+                .to_str()
+                .expect("All of these should be URLs and thus valid strings");
+            assert!(url_value_file.ends_with("/url_value"));
+
+            let url = {
+                let base = url_value_file
+                    .strip_prefix(&format!("{}/", Self::base_path().display()))
+                    .expect("This will exist");
+
+                let (proto, path) = base.split_once(':').expect("This will countain a :");
+
+                let path = path.strip_suffix("/url_value").expect("Will exist");
+
+                Url::from_str(&format!("{proto}:/{path}"))
+                    .expect("This was a URL, it should still be one")
+            };
+            let tags = {
+                let url_values = read_to_string(PathBuf::from(url_value_file))?;
+                url_values
+                    .lines()
+                    .map(|line| {
+                        let input = Self::from_str(line)?;
+                        Ok::<_, anyhow::Error>(input.tags)
+                    })
+                    .collect::<Result<Vec<HashSet<NoWhitespaceString>>, _>>()?
+                    .into_iter()
+                    .flatten()
+                    .collect()
+            };
+
+            output.push(Self { url, tags });
+        }
+
+        Ok(output)
+    }
+}
diff --git a/pkgs/by-name/ts/tskm/src/interface/mod.rs b/pkgs/by-name/ts/tskm/src/interface/mod.rs
new file mode 100644
index 00000000..1a0d934c
--- /dev/null
+++ b/pkgs/by-name/ts/tskm/src/interface/mod.rs
@@ -0,0 +1,4 @@
+pub mod input;
+pub mod neorg;
+pub mod open;
+pub mod project;
diff --git a/pkgs/by-name/ts/tskm/src/interface/neorg/handle.rs b/pkgs/by-name/ts/tskm/src/interface/neorg/handle.rs
new file mode 100644
index 00000000..d904b12e
--- /dev/null
+++ b/pkgs/by-name/ts/tskm/src/interface/neorg/handle.rs
@@ -0,0 +1,88 @@
+use std::{
+    env,
+    fs::{self, read_to_string, File, OpenOptions},
+    io::Write,
+    process::Command,
+};
+
+use anyhow::{bail, Context, Result};
+
+use crate::{cli::NeorgCommand, state::State};
+
+pub fn handle(command: NeorgCommand, state: &mut State) -> Result<()> {
+    match command {
+        NeorgCommand::Task { id } => {
+            let project = id.project(state)?;
+            let base = dirs::data_local_dir()
+                .expect("This should exists")
+                .join("tskm/notes");
+            let path = base.join(project.get_neorg_path()?);
+
+            fs::create_dir_all(path.parent().expect("This should exist"))?;
+
+            {
+                let contents = if path.exists() {
+                    read_to_string(&path)
+                        .with_context(|| format!("Failed to read file: '{}'", path.display()))?
+                } else {
+                    File::create(&path)
+                        .with_context(|| format!("Failed to create file: '{}'", path.display()))?;
+                    String::new()
+                };
+
+                if !contents.contains(format!("% {}", id.uuid()).as_str()) {
+                    let mut options = OpenOptions::new();
+                    options.append(true).create(false);
+
+                    let mut file = options.open(&path)?;
+                    file.write_all(format!("* TITLE (% {})", id.uuid()).as_bytes())
+                        .with_context(|| {
+                            format!("Failed to write task uuid to file: '{}'", path.display())
+                        })?;
+                    file.flush()
+                        .with_context(|| format!("Failed to flush file: '{}'", path.display()))?;
+                }
+            }
+
+            let editor = env::var("EDITOR").unwrap_or("nvim".to_owned());
+            let status = Command::new(editor)
+                .args([
+                    path.to_str().expect("Should be a utf-8 str"),
+                    "-c",
+                    format!("/% {}", id.uuid()).as_str(),
+                ])
+                .status()?;
+            if !status.success() {
+                bail!("$EDITOR fail with error code: {status}");
+            }
+
+            {
+                let status = Command::new("git")
+                    .args(["add", "."])
+                    .current_dir(path.parent().expect("Will exist"))
+                    .status()?;
+                if !status.success() {
+                    bail!("Git add . failed!");
+                }
+
+                let status = Command::new("git")
+                    .args([
+                        "commit",
+                        "--message",
+                        format!("chore({}): Update", project.get_neorg_path()?.display()).as_str(),
+                        "--no-gpg-sign",
+                    ])
+                    .current_dir(path.parent().expect("Will exist"))
+                    .status()?;
+                if !status.success() {
+                    bail!("Git commit failed!");
+                }
+            }
+
+            {
+                id.mark_neorg_data(state)?;
+            }
+        }
+    }
+    Ok(())
+}
diff --git a/pkgs/by-name/ts/tskm/src/interface/neorg/mod.rs b/pkgs/by-name/ts/tskm/src/interface/neorg/mod.rs
new file mode 100644
index 00000000..51d58ab3
--- /dev/null
+++ b/pkgs/by-name/ts/tskm/src/interface/neorg/mod.rs
@@ -0,0 +1,25 @@
+use std::path::PathBuf;
+
+use anyhow::Result;
+
+use crate::task::{run_task, Project};
+
+pub mod handle;
+pub use handle::handle;
+
+impl Project {
+    /// Return the stored neorg path of this project.
+    /// The returned path will never start with a slash (/).
+    pub(super) fn get_neorg_path(&self) -> Result<PathBuf> {
+        let project_path = run_task(&[
+            "_get",
+            format!("rc.context.{}.rc.neorg_path", self.to_context_display()).as_str(),
+        ])?;
+
+        let final_path = project_path
+            .strip_prefix('/')
+            .unwrap_or(project_path.as_str());
+
+        Ok(PathBuf::from(final_path))
+    }
+}
diff --git a/pkgs/by-name/ts/tskm/src/interface/open/handle.rs b/pkgs/by-name/ts/tskm/src/interface/open/handle.rs
new file mode 100644
index 00000000..4d7341b2
--- /dev/null
+++ b/pkgs/by-name/ts/tskm/src/interface/open/handle.rs
@@ -0,0 +1,232 @@
+use std::{
+    fs,
+    net::{IpAddr, Ipv4Addr},
+    path::PathBuf,
+    process,
+};
+
+use anyhow::{bail, Context, Result};
+use log::{error, info, warn};
+use url::Url;
+
+use crate::{cli::OpenCommand, rofi, state::State, task};
+
+pub fn handle(command: OpenCommand, state: &mut State) -> Result<()> {
+    match command {
+        OpenCommand::Review => {
+            for project in task::Project::all().context("Failed to get all project files")? {
+                if project.is_touched() {
+                    info!("Reviewing project: '{}'", project.to_project_display());
+                    open_in_browser(project, state, None).with_context(|| {
+                        format!(
+                            "Failed to open project ('{}') in Firefox",
+                            project.to_project_display()
+                        )
+                    })?;
+                    project.untouch().with_context(|| {
+                        format!(
+                            "Failed to untouch project ('{}')",
+                            project.to_project_display()
+                        )
+                    })?;
+                }
+            }
+        }
+        OpenCommand::Project { project, url } => {
+            project.touch().context("Failed to touch project")?;
+            open_in_browser(&project, state, url).with_context(|| {
+                format!("Failed to open project: {}", project.to_project_display())
+            })?;
+        }
+        OpenCommand::Select { url } => {
+            let selected_project: task::Project = task::Project::from_project_string(
+                &rofi::select(
+                    task::Project::all()
+                        .context("Failed to get all registered projects")?
+                        .iter()
+                        .map(task::Project::to_project_display)
+                        .collect::<Vec<_>>()
+                        .as_slice(),
+                )
+                .context("Failed to get selected project")?,
+            )
+            .expect("This should work, as we send only projects in");
+
+            selected_project
+                .touch()
+                .context("Failed to touch project")?;
+
+            open_in_browser(&selected_project, state, url).context("Failed to open project")?;
+        }
+        OpenCommand::ListTabs { project } => {
+            let project = if let Some(p) = project {
+                p
+            } else if let Some(p) =
+                task::Project::get_current().context("Failed to get currently focused project")?
+            {
+                p
+            } else {
+                bail!("You need to either supply a project or have a project active!");
+            };
+
+            let session_store = project.get_sessionstore().with_context(|| {
+                format!(
+                    "Failed to get session store for project: '{}'",
+                    project.to_project_display()
+                )
+            })?;
+
+            let selected = session_store
+                .windows
+                .iter()
+                .map(|w| w.selected)
+                .collect::<Vec<_>>();
+
+            let tabs = session_store
+                .windows
+                .iter()
+                .flat_map(|window| window.tabs.iter())
+                .map(|tab| tab.entries.get(tab.index - 1).expect("This should be Some"))
+                .collect::<Vec<_>>();
+
+            for (index, entry) in tabs.iter().enumerate() {
+                let index = index + 1;
+                let is_selected = {
+                    if selected.contains(&index) {
+                        "🔻 "
+                    } else {
+                        "   "
+                    }
+                };
+                println!("{}{}", is_selected, entry.url);
+            }
+        }
+    }
+    Ok(())
+}
+
+fn open_in_browser(
+    selected_project: &task::Project,
+    state: &mut State,
+    url: Option<Url>,
+) -> Result<()> {
+    let old_project: Option<task::Project> =
+        task::Project::get_current().context("Failed to get currently active project")?;
+    let old_task: Option<task::Task> =
+        task::Task::get_current(state).context("Failed to get currently active task")?;
+
+    selected_project.activate().with_context(|| {
+        format!(
+            "Failed to active project: '{}'",
+            selected_project.to_project_display()
+        )
+    })?;
+
+    let tracking_task = {
+        let all_tasks = selected_project.get_tasks(state).with_context(|| {
+            format!(
+                "Failed to get assoctiated tasks for project: '{}'",
+                selected_project.to_project_display()
+            )
+        })?;
+
+        let tracking_task = all_tasks.into_iter().find(|t| {
+            let maybe_desc = t.description(state);
+            if let Ok(desc) = maybe_desc {
+                desc == "tracking"
+            } else {
+                error!(
+                    "Getting task description returned error: {}",
+                    maybe_desc.expect_err("We already check for Ok")
+                );
+                false
+            }
+        });
+
+        if let Some(task) = tracking_task {
+            info!(
+                "Starting task {} -> tracking",
+                selected_project.to_project_display()
+            );
+            task.start(state)
+                .with_context(|| format!("Failed to start task {task}"))?;
+        }
+        tracking_task
+    };
+
+    let status = {
+        let mut args = vec!["-P".to_owned(), selected_project.to_project_display()];
+        if let Some(url) = url {
+            args.push(url.to_string());
+        } else {
+            let lock_file = dirs::home_dir()
+                .expect("Exists")
+                .join(".mozilla/firefox")
+                .join(selected_project.to_project_display())
+                .join("lock");
+
+            if lock_file.exists() {
+                let (ip, pid): (IpAddr, u32) = {
+                    let link = fs::read_link(&lock_file).with_context(|| {
+                        format!("Failed to readlink lock at '{}'", lock_file.display())
+                    })?;
+
+                    let (ip, pid) = link
+                        .to_str()
+                        .expect("Should work")
+                        .split_once(':')
+                        .expect("The split works");
+
+                    (
+                        ip.parse().expect("Should be a valid ip address"),
+                        pid.parse().expect("Should be a valid pid"),
+                    )
+                };
+
+                if ip != Ipv4Addr::new(127, 0, 0, 2) {
+                    warn!("Your ip is weird..");
+                }
+
+                if PathBuf::from("/proc").join(pid.to_string()).exists() {
+                    // Another Firefox instance has already been started for this project
+                    // Add a buffer URL to force Firefox to open it in the already open instance
+                    args.push("about:newtab".to_owned());
+                } else {
+                    // This project does not yet have another Firefox instance
+                    // We do not need to add anything to the arguments, Firefox will open a new
+                    // instance.
+                }
+            } else {
+                // There is no lock file and thus no instance already open.
+            }
+        };
+
+        process::Command::new("firefox")
+            .args(args)
+            .status()
+            .context("Failed to start firefox")?
+    };
+
+    if !status.success() {
+        error!("Firefox run exited with error.");
+    }
+
+    if let Some(task) = tracking_task {
+        task.stop(state)
+            .with_context(|| format!("Failed to stop task {task}"))?;
+    }
+    if let Some(task) = old_task {
+        task.start(state)
+            .with_context(|| format!("Failed to start task {task}"))?;
+    }
+
+    if let Some(project) = old_project {
+        project.activate().with_context(|| {
+            format!("Failed to active project {}", project.to_project_display())
+        })?;
+    } else {
+        task::Project::clear().context("Failed to clear currently focused project")?;
+    }
+
+    Ok(())
+}
diff --git a/pkgs/by-name/ts/tskm/src/interface/open/mod.rs b/pkgs/by-name/ts/tskm/src/interface/open/mod.rs
new file mode 100644
index 00000000..2dc75957
--- /dev/null
+++ b/pkgs/by-name/ts/tskm/src/interface/open/mod.rs
@@ -0,0 +1,106 @@
+use std::{collections::HashMap, fs::File, io};
+
+use anyhow::{Context, Result};
+use lz4_flex::decompress_size_prepended;
+use serde::Deserialize;
+use serde_json::Value;
+use url::Url;
+
+use crate::task::Project;
+
+pub mod handle;
+pub use handle::handle;
+
+impl Project {
+    pub(super) fn get_sessionstore(&self) -> Result<SessionStore> {
+        let path = dirs::home_dir()
+            .expect("Will exist")
+            .join(".mozilla/firefox")
+            .join(self.to_project_display())
+            .join("sessionstore-backups/recovery.jsonlz4");
+        let file = decompress_mozlz4(
+            File::open(&path)
+                .with_context(|| format!("Failed to open path '{}'", path.display()))?,
+        )
+        .with_context(|| format!("Failed to decompress file as mozlzh '{}'", path.display()))?;
+
+        let contents: SessionStore = serde_json::from_str(&file).with_context(|| {
+            format!(
+                "Failed to deserialize file ('{}') as session store.",
+                path.display()
+            )
+        })?;
+        Ok(contents)
+    }
+}
+
+fn decompress_mozlz4<P: io::Read>(mut file: P) -> Result<String> {
+    const MOZLZ4_MAGIC_NUMBER: &[u8] = b"mozLz40\0";
+
+    let mut buf = [0u8; 8];
+    file.read_exact(&mut buf)
+        .context("Failed to read the mozlz40 header.")?;
+
+    assert_eq!(buf, MOZLZ4_MAGIC_NUMBER);
+
+    let mut buf = vec![];
+    file.read_to_end(&mut buf).context("Failed to read file")?;
+
+    let uncompressed = decompress_size_prepended(&buf).context("Failed to decompress file")?;
+
+    Ok(String::from_utf8(uncompressed).expect("This should be valid json and thus utf8"))
+}
+
+#[derive(Deserialize, Debug)]
+pub struct SessionStore {
+    pub windows: Vec<Window>,
+}
+
+#[derive(Deserialize, Debug)]
+pub struct Window {
+    pub tabs: Vec<Tab>,
+    pub selected: usize,
+}
+
+#[derive(Deserialize, Debug)]
+pub struct Tab {
+    pub entries: Vec<TabEntry>,
+    #[serde(rename = "lastAccessed")]
+    pub last_accessed: u64,
+    pub hidden: bool,
+    #[serde(rename = "searchMode")]
+    pub search_mode: Option<Value>,
+    #[serde(rename = "userContextId")]
+    pub user_context_id: u32,
+    pub attributes: TabAttributes,
+    #[serde(rename = "extData")]
+    pub ext_data: Option<HashMap<String, Value>>,
+    pub index: usize,
+    #[serde(rename = "requestedIndex")]
+    pub requested_index: Option<u32>,
+    pub image: Option<Url>,
+}
+
+#[derive(Deserialize, Debug)]
+pub struct TabEntry {
+    pub url: Url,
+    pub title: String,
+    #[serde(rename = "cacheKey")]
+    pub cache_key: u32,
+    #[serde(rename = "ID")]
+    pub id: u32,
+    #[serde(rename = "docshellUUID")]
+    pub docshell_uuid: Value,
+    #[serde(rename = "resultPrincipalURI")]
+    pub result_principal_uri: Option<Url>,
+    #[serde(rename = "hasUserInteraction")]
+    pub has_user_interaction: bool,
+    #[serde(rename = "triggeringPrincipal_base64")]
+    pub triggering_principal_base64: Value,
+    #[serde(rename = "docIdentifier")]
+    pub doc_identifier: u32,
+    pub persist: bool,
+}
+
+#[derive(Deserialize, Debug, Clone, Copy)]
+pub struct TabAttributes {}
diff --git a/pkgs/by-name/ts/tskm/src/interface/project/handle.rs b/pkgs/by-name/ts/tskm/src/interface/project/handle.rs
new file mode 100644
index 00000000..2b01f5d1
--- /dev/null
+++ b/pkgs/by-name/ts/tskm/src/interface/project/handle.rs
@@ -0,0 +1,87 @@
+use std::{env, fs::File, io::Write};
+
+use anyhow::{anyhow, Context, Result};
+use log::trace;
+
+use crate::{cli::ProjectCommand, task};
+
+use super::{ProjectDefinition, ProjectList, SortAlphabetically};
+
+/// # Panics
+/// If internal expectations fail.
+///
+/// # Errors
+/// If IO operations fail.
+pub fn handle(command: ProjectCommand) -> Result<()> {
+    match command {
+        ProjectCommand::List => {
+            for project in task::Project::all()? {
+                println!("{}", project.to_project_display());
+            }
+        }
+        ProjectCommand::Add {
+            mut new_project_name,
+        } => {
+            let project_file = env::var("TSKM_PROJECT_FILE")
+                .map_err(|err| anyhow!("The `TSKM_PROJECT_FILE` env var is unset: {err}"))?;
+
+            let mut projects_content: ProjectList =
+                serde_json::from_reader(File::open(&project_file).with_context(|| {
+                    format!("Failed to open project file ('{project_file:?}') for reading")
+                })?)?;
+
+            let first = new_project_name.project_segments.remove(0);
+            if let Some(mut definition) = projects_content.0.get_mut(&first) {
+                for segment in new_project_name.project_segments {
+                    if definition.subprojects.contains_key(&segment) {
+                        definition = definition
+                            .subprojects
+                            .get_mut(&segment)
+                            .expect("We checked");
+                    } else {
+                        let new_definition = ProjectDefinition::default();
+                        let output = definition
+                            .subprojects
+                            .insert(segment.clone(), new_definition);
+
+                        assert_eq!(output, None);
+
+                        definition = definition
+                            .subprojects
+                            .get_mut(&segment)
+                            .expect("Was just inserted");
+                    }
+                }
+            } else {
+                let mut orig_definition = ProjectDefinition::default();
+                let mut definition = &mut orig_definition;
+                for segment in new_project_name.project_segments {
+                    trace!("Adding segment: {segment}");
+
+                    let new_definition = ProjectDefinition::default();
+
+                    assert!(definition
+                        .subprojects
+                        .insert(segment.clone(), new_definition)
+                        .is_none());
+
+                    definition = definition
+                        .subprojects
+                        .get_mut(&segment)
+                        .expect("Was just inserted");
+                }
+                assert!(projects_content.0.insert(first, orig_definition).is_none());
+            };
+
+            let mut file = File::create(&project_file).with_context(|| {
+                format!("Failed to open project file ('{project_file:?}') for writing")
+            })?;
+            serde_json::to_writer_pretty(
+                &file,
+                &SortAlphabetically::<ProjectList>(projects_content),
+            )?;
+            writeln!(file)?;
+        }
+    }
+    Ok(())
+}
diff --git a/pkgs/by-name/ts/tskm/src/interface/project/mod.rs b/pkgs/by-name/ts/tskm/src/interface/project/mod.rs
new file mode 100644
index 00000000..62069746
--- /dev/null
+++ b/pkgs/by-name/ts/tskm/src/interface/project/mod.rs
@@ -0,0 +1,73 @@
+use std::collections::HashMap;
+
+use anyhow::Result;
+use serde::{Deserialize, Serialize};
+
+pub mod handle;
+pub use handle::handle;
+
+#[derive(Deserialize, Serialize)]
+struct ProjectList(HashMap<String, ProjectDefinition>);
+
+#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, Default)]
+struct ProjectDefinition {
+    #[serde(default)]
+    #[serde(skip_serializing_if = "is_default")]
+    name: String,
+
+    #[serde(default)]
+    #[serde(skip_serializing_if = "is_default")]
+    prefix: String,
+
+    #[serde(default)]
+    #[serde(skip_serializing_if = "is_default")]
+    subprojects: HashMap<String, ProjectDefinition>,
+}
+
+fn is_default<T: Default + PartialEq>(input: &T) -> bool {
+    input == &T::default()
+}
+
+#[derive(Debug, Clone)]
+pub struct ProjectName {
+    project_segments: Vec<String>,
+}
+
+impl ProjectName {
+    #[must_use]
+    pub fn segments(&self) -> &[String] {
+        &self.project_segments
+    }
+
+    /// # Errors
+    /// Never.
+    pub fn try_from_project(s: &str) -> Result<Self> {
+        Ok(Self::from_project(s))
+    }
+    pub fn from_project(s: &str) -> Self {
+        let me = Self {
+            project_segments: s.split('.').map(ToOwned::to_owned).collect(),
+        };
+        me
+    }
+    pub fn from_context(s: &str) -> Self {
+        let me = Self {
+            project_segments: s.split('_').map(ToOwned::to_owned).collect(),
+        };
+        me
+    }
+}
+
+// Source: https://stackoverflow.com/a/67792465
+fn sort_alphabetically<T: Serialize, S: serde::Serializer>(
+    value: &T,
+    serializer: S,
+) -> Result<S::Ok, S::Error> {
+    let value = serde_json::to_value(value).map_err(serde::ser::Error::custom)?;
+    value.serialize(serializer)
+}
+
+#[derive(Serialize)]
+pub(super) struct SortAlphabetically<T: Serialize>(
+    #[serde(serialize_with = "sort_alphabetically")] T,
+);
diff --git a/pkgs/by-name/ts/tskm/src/main.rs b/pkgs/by-name/ts/tskm/src/main.rs
new file mode 100644
index 00000000..f4416c6d
--- /dev/null
+++ b/pkgs/by-name/ts/tskm/src/main.rs
@@ -0,0 +1,67 @@
+use anyhow::Result;
+use clap::Parser;
+use state::State;
+
+use crate::interface::{input, neorg, open, project};
+
+pub mod cli;
+pub mod interface;
+pub mod rofi;
+pub mod state;
+pub mod task;
+
+use crate::cli::{CliArgs, Command};
+
+fn main() -> Result<(), anyhow::Error> {
+    // TODO: Support these completions for the respective types <2025-04-04>
+    //
+    // ID_GENERATION_FUNCTION
+    // ```sh
+    //  context="$(task _get rc.context)"
+    //  if [ "$context" ]; then
+    //      filter="project:$context"
+    //  else
+    //      filter="0-10000"
+    //  fi
+    //  tasks="$(task "$filter" _ids)"
+    //
+    //  if [ "$tasks" ]; then
+    //      echo "$tasks" | xargs task _zshids | awk -F: -v q="'" '{gsub(/'\''/, q "\\" q q ); print $1 ":" q $2 q}'
+    //  fi
+    // ```
+    //
+    // ARGUMENTS:
+    //     ID | *([0-9]) := [[%ID_GENERATION_FUNCTION]]
+    //                             The function displays all possible IDs of the eligible tasks.
+    //
+    //     WS := %ALL_WORKSPACES
+    //                             All possible workspaces.
+    //
+    //     P := %ALL_PROJECTS_PIPE
+    //                             The possible project.
+    //
+    //     F := [[fd . --max-depth 3]]
+    //                             A URL-Input file to use as source.
+    let args = CliArgs::parse();
+
+    stderrlog::new()
+        .module(module_path!())
+        .quiet(args.quiet)
+        .show_module_names(true)
+        .color(stderrlog::ColorChoice::Auto)
+        .verbosity(usize::from(args.verbosity))
+        .timestamp(stderrlog::Timestamp::Off)
+        .init()
+        .expect("Let's just hope that this does not panic");
+
+    let mut state = State::new_rw()?;
+
+    match args.command {
+        Command::Inputs { command } => input::handle(command)?,
+        Command::Neorg { command } => neorg::handle(command, &mut state)?,
+        Command::Open { command } => open::handle(command, &mut state)?,
+        Command::Projects { command } => project::handle(command)?,
+    }
+
+    Ok(())
+}
diff --git a/pkgs/by-name/ts/tskm/src/rofi/mod.rs b/pkgs/by-name/ts/tskm/src/rofi/mod.rs
new file mode 100644
index 00000000..a0591b7f
--- /dev/null
+++ b/pkgs/by-name/ts/tskm/src/rofi/mod.rs
@@ -0,0 +1,37 @@
+use std::{
+    io::Write,
+    process::{Command, Stdio},
+};
+
+use anyhow::{Context, Result};
+
+pub fn select(options: &[String]) -> Result<String> {
+    let mut child = Command::new("rofi")
+        .args(["-sep", "\n", "-dmenu"])
+        .stdin(Stdio::piped())
+        .stdout(Stdio::piped())
+        .spawn()
+        .context("Failed to spawn rofi")?;
+
+    let mut stdin = child
+        .stdin
+        .take()
+        .expect("We piped this, so should be available");
+
+    stdin
+        .write_all(options.join("\n").as_bytes())
+        .context("Failed to write to rofi's stdin")?;
+
+    let output = child
+        .wait_with_output()
+        .context("Failed to wait for rofi's output")?;
+
+    let selected = String::from_utf8(output.stdout.clone()).with_context(|| {
+        format!(
+            "Failed to decode '{}' as utf8",
+            String::from_utf8_lossy(&output.stdout)
+        )
+    })?;
+
+    Ok(selected.trim_end().to_owned())
+}
diff --git a/pkgs/by-name/ts/tskm/src/state.rs b/pkgs/by-name/ts/tskm/src/state.rs
new file mode 100644
index 00000000..175a7f03
--- /dev/null
+++ b/pkgs/by-name/ts/tskm/src/state.rs
@@ -0,0 +1,45 @@
+use std::path::PathBuf;
+
+use anyhow::Result;
+use taskchampion::{storage::AccessMode, Replica, StorageConfig};
+
+pub struct State {
+    replica: Replica,
+}
+
+impl std::fmt::Debug for State {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        write!(f, "State")
+    }
+}
+
+impl State {
+    fn taskdb_dir() -> PathBuf {
+        dirs::data_local_dir().expect("Should exist").join("task")
+    }
+
+    fn new(taskdb_dir: PathBuf, access_mode: AccessMode) -> Result<Self> {
+        let storage = StorageConfig::OnDisk {
+            taskdb_dir,
+            create_if_missing: false,
+            access_mode,
+        }
+        .into_storage()?;
+
+        let replica = Replica::new(storage);
+
+        Ok(Self { replica })
+    }
+
+    pub fn new_ro() -> Result<Self> {
+        Self::new(Self::taskdb_dir(), AccessMode::ReadOnly)
+    }
+    pub fn new_rw() -> Result<Self> {
+        Self::new(Self::taskdb_dir(), AccessMode::ReadWrite)
+    }
+
+    #[must_use]
+    pub fn replica(&mut self) -> &mut Replica {
+        &mut self.replica
+    }
+}
diff --git a/pkgs/by-name/ts/tskm/src/task/mod.rs b/pkgs/by-name/ts/tskm/src/task/mod.rs
new file mode 100644
index 00000000..03a12faa
--- /dev/null
+++ b/pkgs/by-name/ts/tskm/src/task/mod.rs
@@ -0,0 +1,342 @@
+use std::{
+    fmt::Display,
+    fs::{self, read_to_string, File},
+    path::PathBuf,
+    process::Command,
+    str::FromStr,
+    sync::OnceLock,
+};
+
+use anyhow::{bail, Context, Result};
+use log::{debug, info, trace};
+use taskchampion::Tag;
+
+use crate::{interface::project::ProjectName, state::State};
+
+/// The `taskwarrior` id of a task.
+#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Ord, Eq)]
+pub struct Task {
+    uuid: taskchampion::Uuid,
+}
+
+impl From<&taskchampion::Task> for Task {
+    fn from(value: &taskchampion::Task) -> Self {
+        Self {
+            uuid: value.get_uuid(),
+        }
+    }
+}
+impl From<&taskchampion::TaskData> for Task {
+    fn from(value: &taskchampion::TaskData) -> Self {
+        Self {
+            uuid: value.get_uuid(),
+        }
+    }
+}
+
+impl Task {
+    pub fn from_working_set(id: usize, state: &mut State) -> Result<Option<Self>> {
+        Ok(state
+            .replica()
+            .working_set()?
+            .by_index(id)
+            .map(|uuid| Self { uuid }))
+    }
+
+    pub fn get_current(state: &mut State) -> Result<Option<Self>> {
+        let tasks = state
+            .replica()
+            .pending_tasks()?
+            .into_iter()
+            .filter(taskchampion::Task::is_active)
+            .collect::<Vec<_>>();
+
+        assert!(
+            tasks.len() <= 1,
+            "We have ensured that only one task may be active, via a hook"
+        );
+        if let Some(active) = tasks.first() {
+            Ok(Some(Self::from(active)))
+        } else {
+            Ok(None)
+        }
+    }
+
+    #[must_use]
+    pub fn uuid(&self) -> &taskchampion::Uuid {
+        &self.uuid
+    }
+
+    fn as_task(&self, state: &mut State) -> Result<taskchampion::Task> {
+        Ok(state
+            .replica()
+            .get_task(self.uuid)?
+            .expect("We have the task from this replica, it should still be in it"))
+    }
+
+    /// Adds a tag to the task, to show the user that it has additional neorg data.
+    pub fn mark_neorg_data(&self, state: &mut State) -> Result<()> {
+        let mut ops = vec![];
+        self.as_task(state)?
+            .add_tag(&Tag::from_str("neorg_data").expect("Is valid"), &mut ops)?;
+        state.replica().commit_operations(ops)?;
+        Ok(())
+    }
+
+    /// Try to start this task.
+    /// It will stop previously active tasks.
+    pub fn start(&self, state: &mut State) -> Result<()> {
+        info!("Activating {self}");
+
+        if let Some(active) = Self::get_current(state)? {
+            active.stop(state)?;
+        }
+
+        let mut ops = vec![];
+        self.as_task(state)?.start(&mut ops)?;
+        state.replica().commit_operations(ops)?;
+        Ok(())
+    }
+
+    /// Stops this task.
+    pub fn stop(&self, state: &mut State) -> Result<()> {
+        info!("Stopping {self}");
+
+        let mut ops = vec![];
+        self.as_task(state)?.stop(&mut ops)?;
+        state.replica().commit_operations(ops)?;
+        Ok(())
+    }
+
+    pub fn description(&self, state: &mut State) -> Result<String> {
+        Ok(self.as_task(state)?.get_description().to_owned())
+    }
+
+    pub fn project(&self, state: &mut State) -> Result<Project> {
+        let output = {
+            let task = self.as_task(state)?;
+            let task_data = task.into_task_data();
+            task_data
+                .get("project")
+                .expect("Every task should have a project")
+                .to_owned()
+        };
+        let project = Project::from_project_string(output.as_str())
+            .expect("This comes from tw, it should be valid");
+        Ok(project)
+    }
+}
+
+impl Display for Task {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        self.uuid.fmt(f)
+    }
+}
+
+impl FromStr for Task {
+    type Err = anyhow::Error;
+
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        let uuid = taskchampion::Uuid::from_str(s)?;
+        Ok(Self { uuid })
+    }
+}
+
+/// A registered task Project
+#[derive(Debug, Clone, PartialEq)]
+pub struct Project {
+    /// The project name.
+    /// For example:
+    /// ```no_run
+    /// &["trinitrix", "testing", "infra"]
+    /// ```
+    name: Vec<String>,
+}
+
+static ALL_CACHE: OnceLock<Vec<Project>> = OnceLock::new();
+impl Project {
+    #[must_use]
+    pub fn to_project_display(&self) -> String {
+        self.name.join(".")
+    }
+    #[must_use]
+    pub fn to_context_display(&self) -> String {
+        self.name.join("_")
+    }
+
+    /// # Errors
+    /// - When the string does not encode a previously registered project.
+    /// - When the string does not adhere to the project syntax.
+    pub fn from_project_string(s: &str) -> Result<Self> {
+        Self::from_input(s, ProjectName::from_project)
+    }
+
+    /// # Errors
+    /// - When the string does not encode a previously registered project.
+    /// - When the string does not adhere to the context syntax.
+    pub fn from_context_string(s: &str) -> Result<Self> {
+        Self::from_input(s, ProjectName::from_context)
+    }
+
+    fn from_input<F>(s: &str, f: F) -> Result<Self>
+    where
+        F: Fn(&str) -> ProjectName,
+    {
+        if s.is_empty() {
+            bail!("Your project is empty")
+        }
+
+        let all = Self::all()?;
+        let me = Self::from_project_name_unchecked(&f(s));
+        if all.contains(&me) {
+            Ok(me)
+        } else {
+            bail!(
+                "Your project '{}' is not registered!",
+                me.to_project_display()
+            );
+        }
+    }
+    fn from_project_name_unchecked(pn: &ProjectName) -> Self {
+        Self {
+            name: pn.segments().to_owned(),
+        }
+    }
+
+    /// Return all known valid projects.
+    ///
+    /// # Errors
+    /// When file operations fail.
+    ///
+    /// # Panics
+    /// Only when internal assertions fail.
+    pub fn all<'a>() -> Result<&'a [Project]> {
+        // Inlined from `OnceLock::get_or_try_init`
+        {
+            let this = &ALL_CACHE;
+            let f = || {
+                let file = dirs::config_local_dir()
+                    .expect("Should be some")
+                    .join("tskm/projects.list");
+                let contents = read_to_string(&file)
+                    .with_context(|| format!("Failed to read file: '{}'", file.display()))?;
+
+                Ok::<_, anyhow::Error>(
+                    contents
+                        .lines()
+                        .map(|s| Self::from_project_name_unchecked(&ProjectName::from_project(s)))
+                        .collect::<Vec<_>>(),
+                )
+            };
+
+            // Fast path check
+            // NOTE: We need to perform an acquire on the state in this method
+            // in order to correctly synchronize `LazyLock::force`. This is
+            // currently done by calling `self.get()`, which in turn calls
+            // `self.is_initialized()`, which in turn performs the acquire.
+            if let Some(value) = this.get() {
+                return Ok(value);
+            }
+
+            this.set(f()?).expect(
+                "This should always be able to take our value, as we initialize only once.",
+            );
+
+            Ok(this.get().expect("This was initialized"))
+        }
+    }
+
+    fn touch_dir(&self) -> PathBuf {
+        let lock_dir = dirs::data_dir()
+            .expect("Should be found")
+            .join("tskm/review");
+        lock_dir.join(format!("{}.opened", self.to_project_display()))
+    }
+
+    /// Mark this project as having been interacted with.
+    ///
+    /// # Errors
+    /// When IO operations fail.
+    pub fn touch(&self) -> Result<()> {
+        let lock_file = self.touch_dir();
+
+        File::create(&lock_file)
+            .with_context(|| format!("Failed to create lock_file at: {}", lock_file.display()))?;
+
+        Ok(())
+    }
+    /// Returns [`true`] if it was previously [`Self::touch`]ed.
+    #[must_use]
+    pub fn is_touched(&self) -> bool {
+        let lock_file = self.touch_dir();
+        lock_file.exists()
+    }
+    /// Mark this project as having not been interacted with.
+    ///
+    /// # Errors
+    /// When IO operations fail.
+    pub fn untouch(&self) -> Result<()> {
+        let lock_file = self.touch_dir();
+
+        fs::remove_file(&lock_file)
+            .with_context(|| format!("Failed to create lock_file at: {}", lock_file.display()))?;
+
+        Ok(())
+    }
+
+    /// # Errors
+    /// When `task` execution fails.
+    pub fn get_tasks(&self, state: &mut State) -> Result<Vec<Task>> {
+        Ok(state
+            .replica()
+            .pending_task_data()?
+            .into_iter()
+            .filter(|t| t.get("project").expect("Is set") == self.to_project_display())
+            .map(|t| Task::from(&t))
+            .collect())
+    }
+
+    /// # Errors
+    /// When `task` execution fails.
+    pub fn activate(&self) -> Result<()> {
+        debug!("Setting project {}", self.to_context_display());
+
+        run_task(&["context", self.to_context_display().as_str()]).map(|_| ())
+    }
+    /// # Errors
+    /// When `task` execution fails.
+    pub fn clear() -> Result<()> {
+        debug!("Clearing active project");
+
+        run_task(&["context", "none"]).map(|_| ())
+    }
+
+    /// # Errors
+    /// When `task` execution fails.
+    pub fn get_current() -> Result<Option<Self>> {
+        let self_str = run_task(&["_get", "rc.context"])?;
+
+        if self_str.is_empty() {
+            Ok(None)
+        } else {
+            Self::from_context_string(&self_str).map(Some)
+        }
+    }
+}
+
+pub(crate) fn run_task(args: &[&str]) -> Result<String> {
+    debug!("Running task command: `task {}`", args.join(" "));
+
+    let output = Command::new("task")
+        .args(args)
+        .output()
+        .with_context(|| format!("Failed to run `task {}`", args.join(" ")))?;
+
+    let stdout = String::from_utf8(output.stdout).context("Failed to read task output as utf8")?;
+    let stderr = String::from_utf8(output.stderr).context("Failed to read task output as utf8")?;
+
+    trace!("Output (stdout): '{}'", stdout.trim());
+    trace!("Output (stderr): '{}'", stderr.trim());
+
+    Ok(stdout.trim().to_owned())
+}
diff --git a/pkgs/by-name/ts/tskm/update.sh b/pkgs/by-name/ts/tskm/update.sh
new file mode 100755
index 00000000..9268caf2
--- /dev/null
+++ b/pkgs/by-name/ts/tskm/update.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+cargo update && cargo upgrade
diff --git a/pkgs/by-name/up/update-vim-plugins/check-duplicates.sh b/pkgs/by-name/up/update-vim-plugins/check-duplicates.sh
deleted file mode 100755
index 781b8aeb..00000000
--- a/pkgs/by-name/up/update-vim-plugins/check-duplicates.sh
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/usr/bin/env bash
-
-plugins="$(grep -E "^  [a-zA-Z-]+ =" ./pkgs/vim-plugins.nix | sed -E 's/^  ([a-zA-Z-]+) =.*$/\1/' | sort)"
-count=$(echo "$plugins" | uniq -d | wc -l)
-
-echo "duplicates count: $count"
-
-if [ "$count" -gt 0 ]; then
-    filtered_plugins=$(echo "$plugins" | uniq -d)
-
-    if [ "$1" == "check-only" ]; then
-        echo "$filtered_plugins"
-        exit 1
-    else
-        known_issues=$(gh issue list --state "open" --label "bot" --json "body" | jq -r ".[].body")
-
-        echo "known_issues: $known_issues"
-
-        # iterate over plugins we found missing and
-        # compare them to all open issues.
-        # We no matching issue was found, we create a new one
-        for f in $filtered_plugins; do # do not add " " here. It would break the plugin
-            found=false
-
-            for k in $known_issues; do
-                if [[ $f == "$k" ]]; then
-                    found=true
-                    break
-                fi
-            done
-
-            # test if matching issue was found
-            if ! $found; then
-                echo "Did not find an issue for $f. Creating a new one ..."
-                gh issue create --title "Detected broken plugin: $f" --label "bot" --body "$f"
-            else
-                echo "Issue for $f already exists"
-            fi
-        done
-    fi
-else
-    echo "No duplicates found"
-fi
diff --git a/pkgs/by-name/up/update-vim-plugins/flake.lock b/pkgs/by-name/up/update-vim-plugins/flake.lock
deleted file mode 100644
index 132287b7..00000000
--- a/pkgs/by-name/up/update-vim-plugins/flake.lock
+++ /dev/null
@@ -1,61 +0,0 @@
-{
-  "nodes": {
-    "flake-utils": {
-      "inputs": {
-        "systems": "systems"
-      },
-      "locked": {
-        "lastModified": 1731533236,
-        "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
-        "owner": "numtide",
-        "repo": "flake-utils",
-        "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
-        "type": "github"
-      },
-      "original": {
-        "owner": "numtide",
-        "repo": "flake-utils",
-        "type": "github"
-      }
-    },
-    "nixpkgs": {
-      "locked": {
-        "lastModified": 1735471104,
-        "narHash": "sha256-0q9NGQySwDQc7RhAV2ukfnu7Gxa5/ybJ2ANT8DQrQrs=",
-        "owner": "NixOS",
-        "repo": "nixpkgs",
-        "rev": "88195a94f390381c6afcdaa933c2f6ff93959cb4",
-        "type": "github"
-      },
-      "original": {
-        "owner": "NixOS",
-        "ref": "nixos-unstable",
-        "repo": "nixpkgs",
-        "type": "github"
-      }
-    },
-    "root": {
-      "inputs": {
-        "flake-utils": "flake-utils",
-        "nixpkgs": "nixpkgs"
-      }
-    },
-    "systems": {
-      "locked": {
-        "lastModified": 1681028828,
-        "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
-        "owner": "nix-systems",
-        "repo": "default",
-        "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
-        "type": "github"
-      },
-      "original": {
-        "owner": "nix-systems",
-        "repo": "default",
-        "type": "github"
-      }
-    }
-  },
-  "root": "root",
-  "version": 7
-}
diff --git a/pkgs/by-name/up/update-vim-plugins/flake.nix b/pkgs/by-name/up/update-vim-plugins/flake.nix
deleted file mode 100644
index ef440af0..00000000
--- a/pkgs/by-name/up/update-vim-plugins/flake.nix
+++ /dev/null
@@ -1,24 +0,0 @@
-{
-  description = "update_vim_plugins";
-
-  inputs = {
-    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
-
-    flake-utils.url = "github:numtide/flake-utils";
-  };
-
-  outputs = {
-    self,
-    nixpkgs,
-    flake-utils,
-  }: (flake-utils.lib.eachDefaultSystem (system: let
-    pkgs = nixpkgs.legacyPackages.${system};
-  in {
-    devShells.default = pkgs.mkShell {
-      packages = [
-        pkgs.python3
-        pkgs.poetry
-      ];
-    };
-  }));
-}
diff --git a/pkgs/by-name/up/update-vim-plugins/package.nix b/pkgs/by-name/up/update-vim-plugins/package.nix
deleted file mode 100644
index e74a29b1..00000000
--- a/pkgs/by-name/up/update-vim-plugins/package.nix
+++ /dev/null
@@ -1,47 +0,0 @@
-{
-  python3,
-  # dependencies
-  nix,
-  alejandra,
-  nix-prefetch-git,
-}:
-python3.pkgs.buildPythonApplication {
-  pname = "update-vim-plugins";
-  version = "0.1.0";
-  format = "pyproject";
-
-  src = ./.;
-
-  # NOTE: The test are not really meant to work <2023-12-09>
-  doCheck = false;
-
-  nativeBuildInputs = [
-    python3.pkgs.poetry-core
-  ];
-  buildInputs = [
-    alejandra
-    nix-prefetch-git
-    nix
-  ];
-  propagatedBuildInputs = with python3.pkgs; [
-    requests
-    cleo
-    jsonpickle
-    dateparser
-  ];
-  nativeCheckInputs = with python3.pkgs; [
-    pytestCheckHook
-
-    pytest-cov
-    pytest-mock
-  ];
-  pytestFlagsArray = [
-    "--cov"
-    "update_vim_plugins"
-    "--cov-report"
-    "term-missing:skip-covered"
-    "--cov-fail-under"
-    "50"
-    "update_vim_plugins/tests"
-  ];
-}
diff --git a/pkgs/by-name/up/update-vim-plugins/poetry.lock b/pkgs/by-name/up/update-vim-plugins/poetry.lock
deleted file mode 100644
index 83e11762..00000000
--- a/pkgs/by-name/up/update-vim-plugins/poetry.lock
+++ /dev/null
@@ -1,740 +0,0 @@
-# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand.
-
-[[package]]
-name = "certifi"
-version = "2024.12.14"
-description = "Python package for providing Mozilla's CA Bundle."
-optional = false
-python-versions = ">=3.6"
-files = [
-    {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"},
-    {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"},
-]
-
-[[package]]
-name = "charset-normalizer"
-version = "3.4.1"
-description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"},
-    {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"},
-    {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"},
-    {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"},
-    {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"},
-    {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"},
-    {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"},
-    {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"},
-    {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"},
-    {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"},
-    {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"},
-    {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"},
-    {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"},
-    {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"},
-    {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"},
-    {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"},
-    {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"},
-    {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"},
-    {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"},
-    {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"},
-    {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"},
-    {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"},
-    {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"},
-    {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"},
-    {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"},
-    {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"},
-    {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"},
-    {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"},
-    {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"},
-    {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"},
-    {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"},
-    {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"},
-    {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"},
-    {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"},
-    {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"},
-    {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"},
-    {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"},
-    {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"},
-    {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"},
-    {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"},
-    {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"},
-    {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"},
-    {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"},
-    {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"},
-    {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"},
-    {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"},
-    {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"},
-    {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"},
-    {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"},
-    {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"},
-    {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"},
-    {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"},
-    {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"},
-    {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"},
-    {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"},
-    {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"},
-    {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"},
-    {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"},
-    {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"},
-    {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"},
-    {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"},
-    {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"},
-    {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"},
-    {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"},
-    {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"},
-    {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"},
-    {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"},
-    {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"},
-    {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"},
-    {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"},
-    {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"},
-    {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"},
-    {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"},
-    {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"},
-    {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"},
-    {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"},
-    {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"},
-    {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"},
-    {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"},
-    {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"},
-    {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"},
-    {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"},
-    {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"},
-    {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"},
-    {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"},
-    {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"},
-    {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"},
-    {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"},
-    {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"},
-    {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"},
-    {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"},
-    {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"},
-]
-
-[[package]]
-name = "cleo"
-version = "2.1.0"
-description = "Cleo allows you to create beautiful and testable command-line interfaces."
-optional = false
-python-versions = ">=3.7,<4.0"
-files = [
-    {file = "cleo-2.1.0-py3-none-any.whl", hash = "sha256:4a31bd4dd45695a64ee3c4758f583f134267c2bc518d8ae9a29cf237d009b07e"},
-    {file = "cleo-2.1.0.tar.gz", hash = "sha256:0b2c880b5d13660a7ea651001fb4acb527696c01f15c9ee650f377aa543fd523"},
-]
-
-[package.dependencies]
-crashtest = ">=0.4.1,<0.5.0"
-rapidfuzz = ">=3.0.0,<4.0.0"
-
-[[package]]
-name = "colorama"
-version = "0.4.6"
-description = "Cross-platform colored terminal text."
-optional = false
-python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
-files = [
-    {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
-    {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
-]
-
-[[package]]
-name = "coverage"
-version = "7.6.10"
-description = "Code coverage measurement for Python"
-optional = false
-python-versions = ">=3.9"
-files = [
-    {file = "coverage-7.6.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5c912978f7fbf47ef99cec50c4401340436d200d41d714c7a4766f377c5b7b78"},
-    {file = "coverage-7.6.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a01ec4af7dfeb96ff0078ad9a48810bb0cc8abcb0115180c6013a6b26237626c"},
-    {file = "coverage-7.6.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3b204c11e2b2d883946fe1d97f89403aa1811df28ce0447439178cc7463448a"},
-    {file = "coverage-7.6.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32ee6d8491fcfc82652a37109f69dee9a830e9379166cb73c16d8dc5c2915165"},
-    {file = "coverage-7.6.10-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675cefc4c06e3b4c876b85bfb7c59c5e2218167bbd4da5075cbe3b5790a28988"},
-    {file = "coverage-7.6.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f4f620668dbc6f5e909a0946a877310fb3d57aea8198bde792aae369ee1c23b5"},
-    {file = "coverage-7.6.10-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:4eea95ef275de7abaef630c9b2c002ffbc01918b726a39f5a4353916ec72d2f3"},
-    {file = "coverage-7.6.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e2f0280519e42b0a17550072861e0bc8a80a0870de260f9796157d3fca2733c5"},
-    {file = "coverage-7.6.10-cp310-cp310-win32.whl", hash = "sha256:bc67deb76bc3717f22e765ab3e07ee9c7a5e26b9019ca19a3b063d9f4b874244"},
-    {file = "coverage-7.6.10-cp310-cp310-win_amd64.whl", hash = "sha256:0f460286cb94036455e703c66988851d970fdfd8acc2a1122ab7f4f904e4029e"},
-    {file = "coverage-7.6.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ea3c8f04b3e4af80e17bab607c386a830ffc2fb88a5484e1df756478cf70d1d3"},
-    {file = "coverage-7.6.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:507a20fc863cae1d5720797761b42d2d87a04b3e5aeb682ef3b7332e90598f43"},
-    {file = "coverage-7.6.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d37a84878285b903c0fe21ac8794c6dab58150e9359f1aaebbeddd6412d53132"},
-    {file = "coverage-7.6.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a534738b47b0de1995f85f582d983d94031dffb48ab86c95bdf88dc62212142f"},
-    {file = "coverage-7.6.10-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d7a2bf79378d8fb8afaa994f91bfd8215134f8631d27eba3e0e2c13546ce994"},
-    {file = "coverage-7.6.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6713ba4b4ebc330f3def51df1d5d38fad60b66720948112f114968feb52d3f99"},
-    {file = "coverage-7.6.10-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ab32947f481f7e8c763fa2c92fd9f44eeb143e7610c4ca9ecd6a36adab4081bd"},
-    {file = "coverage-7.6.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7bbd8c8f1b115b892e34ba66a097b915d3871db7ce0e6b9901f462ff3a975377"},
-    {file = "coverage-7.6.10-cp311-cp311-win32.whl", hash = "sha256:299e91b274c5c9cdb64cbdf1b3e4a8fe538a7a86acdd08fae52301b28ba297f8"},
-    {file = "coverage-7.6.10-cp311-cp311-win_amd64.whl", hash = "sha256:489a01f94aa581dbd961f306e37d75d4ba16104bbfa2b0edb21d29b73be83609"},
-    {file = "coverage-7.6.10-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:27c6e64726b307782fa5cbe531e7647aee385a29b2107cd87ba7c0105a5d3853"},
-    {file = "coverage-7.6.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c56e097019e72c373bae32d946ecf9858fda841e48d82df7e81c63ac25554078"},
-    {file = "coverage-7.6.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7827a5bc7bdb197b9e066cdf650b2887597ad124dd99777332776f7b7c7d0d0"},
-    {file = "coverage-7.6.10-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:204a8238afe787323a8b47d8be4df89772d5c1e4651b9ffa808552bdf20e1d50"},
-    {file = "coverage-7.6.10-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e67926f51821b8e9deb6426ff3164870976fe414d033ad90ea75e7ed0c2e5022"},
-    {file = "coverage-7.6.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e78b270eadb5702938c3dbe9367f878249b5ef9a2fcc5360ac7bff694310d17b"},
-    {file = "coverage-7.6.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:714f942b9c15c3a7a5fe6876ce30af831c2ad4ce902410b7466b662358c852c0"},
-    {file = "coverage-7.6.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:abb02e2f5a3187b2ac4cd46b8ced85a0858230b577ccb2c62c81482ca7d18852"},
-    {file = "coverage-7.6.10-cp312-cp312-win32.whl", hash = "sha256:55b201b97286cf61f5e76063f9e2a1d8d2972fc2fcfd2c1272530172fd28c359"},
-    {file = "coverage-7.6.10-cp312-cp312-win_amd64.whl", hash = "sha256:e4ae5ac5e0d1e4edfc9b4b57b4cbecd5bc266a6915c500f358817a8496739247"},
-    {file = "coverage-7.6.10-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:05fca8ba6a87aabdd2d30d0b6c838b50510b56cdcfc604d40760dae7153b73d9"},
-    {file = "coverage-7.6.10-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9e80eba8801c386f72e0712a0453431259c45c3249f0009aff537a517b52942b"},
-    {file = "coverage-7.6.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a372c89c939d57abe09e08c0578c1d212e7a678135d53aa16eec4430adc5e690"},
-    {file = "coverage-7.6.10-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec22b5e7fe7a0fa8509181c4aac1db48f3dd4d3a566131b313d1efc102892c18"},
-    {file = "coverage-7.6.10-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26bcf5c4df41cad1b19c84af71c22cbc9ea9a547fc973f1f2cc9a290002c8b3c"},
-    {file = "coverage-7.6.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e4630c26b6084c9b3cb53b15bd488f30ceb50b73c35c5ad7871b869cb7365fd"},
-    {file = "coverage-7.6.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2396e8116db77789f819d2bc8a7e200232b7a282c66e0ae2d2cd84581a89757e"},
-    {file = "coverage-7.6.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:79109c70cc0882e4d2d002fe69a24aa504dec0cc17169b3c7f41a1d341a73694"},
-    {file = "coverage-7.6.10-cp313-cp313-win32.whl", hash = "sha256:9e1747bab246d6ff2c4f28b4d186b205adced9f7bd9dc362051cc37c4a0c7bd6"},
-    {file = "coverage-7.6.10-cp313-cp313-win_amd64.whl", hash = "sha256:254f1a3b1eef5f7ed23ef265eaa89c65c8c5b6b257327c149db1ca9d4a35f25e"},
-    {file = "coverage-7.6.10-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2ccf240eb719789cedbb9fd1338055de2761088202a9a0b73032857e53f612fe"},
-    {file = "coverage-7.6.10-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0c807ca74d5a5e64427c8805de15b9ca140bba13572d6d74e262f46f50b13273"},
-    {file = "coverage-7.6.10-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bcfa46d7709b5a7ffe089075799b902020b62e7ee56ebaed2f4bdac04c508d8"},
-    {file = "coverage-7.6.10-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4e0de1e902669dccbf80b0415fb6b43d27edca2fbd48c74da378923b05316098"},
-    {file = "coverage-7.6.10-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f7b444c42bbc533aaae6b5a2166fd1a797cdb5eb58ee51a92bee1eb94a1e1cb"},
-    {file = "coverage-7.6.10-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b330368cb99ef72fcd2dc3ed260adf67b31499584dc8a20225e85bfe6f6cfed0"},
-    {file = "coverage-7.6.10-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:9a7cfb50515f87f7ed30bc882f68812fd98bc2852957df69f3003d22a2aa0abf"},
-    {file = "coverage-7.6.10-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f93531882a5f68c28090f901b1d135de61b56331bba82028489bc51bdd818d2"},
-    {file = "coverage-7.6.10-cp313-cp313t-win32.whl", hash = "sha256:89d76815a26197c858f53c7f6a656686ec392b25991f9e409bcef020cd532312"},
-    {file = "coverage-7.6.10-cp313-cp313t-win_amd64.whl", hash = "sha256:54a5f0f43950a36312155dae55c505a76cd7f2b12d26abeebbe7a0b36dbc868d"},
-    {file = "coverage-7.6.10-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:656c82b8a0ead8bba147de9a89bda95064874c91a3ed43a00e687f23cc19d53a"},
-    {file = "coverage-7.6.10-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ccc2b70a7ed475c68ceb548bf69cec1e27305c1c2606a5eb7c3afff56a1b3b27"},
-    {file = "coverage-7.6.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5e37dc41d57ceba70956fa2fc5b63c26dba863c946ace9705f8eca99daecdc4"},
-    {file = "coverage-7.6.10-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0aa9692b4fdd83a4647eeb7db46410ea1322b5ed94cd1715ef09d1d5922ba87f"},
-    {file = "coverage-7.6.10-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa744da1820678b475e4ba3dfd994c321c5b13381d1041fe9c608620e6676e25"},
-    {file = "coverage-7.6.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:c0b1818063dc9e9d838c09e3a473c1422f517889436dd980f5d721899e66f315"},
-    {file = "coverage-7.6.10-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:59af35558ba08b758aec4d56182b222976330ef8d2feacbb93964f576a7e7a90"},
-    {file = "coverage-7.6.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7ed2f37cfce1ce101e6dffdfd1c99e729dd2ffc291d02d3e2d0af8b53d13840d"},
-    {file = "coverage-7.6.10-cp39-cp39-win32.whl", hash = "sha256:4bcc276261505d82f0ad426870c3b12cb177752834a633e737ec5ee79bbdff18"},
-    {file = "coverage-7.6.10-cp39-cp39-win_amd64.whl", hash = "sha256:457574f4599d2b00f7f637a0700a6422243b3565509457b2dbd3f50703e11f59"},
-    {file = "coverage-7.6.10-pp39.pp310-none-any.whl", hash = "sha256:fd34e7b3405f0cc7ab03d54a334c17a9e802897580d964bd8c2001f4b9fd488f"},
-    {file = "coverage-7.6.10.tar.gz", hash = "sha256:7fb105327c8f8f0682e29843e2ff96af9dcbe5bab8eeb4b398c6a33a16d80a23"},
-]
-
-[package.dependencies]
-tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""}
-
-[package.extras]
-toml = ["tomli"]
-
-[[package]]
-name = "crashtest"
-version = "0.4.1"
-description = "Manage Python errors with ease"
-optional = false
-python-versions = ">=3.7,<4.0"
-files = [
-    {file = "crashtest-0.4.1-py3-none-any.whl", hash = "sha256:8d23eac5fa660409f57472e3851dab7ac18aba459a8d19cbbba86d3d5aecd2a5"},
-    {file = "crashtest-0.4.1.tar.gz", hash = "sha256:80d7b1f316ebfbd429f648076d6275c877ba30ba48979de4191714a75266f0ce"},
-]
-
-[[package]]
-name = "dateparser"
-version = "1.2.0"
-description = "Date parsing library designed to parse dates from HTML pages"
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "dateparser-1.2.0-py2.py3-none-any.whl", hash = "sha256:0b21ad96534e562920a0083e97fd45fa959882d4162acc358705144520a35830"},
-    {file = "dateparser-1.2.0.tar.gz", hash = "sha256:7975b43a4222283e0ae15be7b4999d08c9a70e2d378ac87385b1ccf2cffbbb30"},
-]
-
-[package.dependencies]
-python-dateutil = "*"
-pytz = "*"
-regex = "<2019.02.19 || >2019.02.19,<2021.8.27 || >2021.8.27"
-tzlocal = "*"
-
-[package.extras]
-calendars = ["convertdate", "hijri-converter"]
-fasttext = ["fasttext"]
-langdetect = ["langdetect"]
-
-[[package]]
-name = "exceptiongroup"
-version = "1.2.2"
-description = "Backport of PEP 654 (exception groups)"
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"},
-    {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"},
-]
-
-[package.extras]
-test = ["pytest (>=6)"]
-
-[[package]]
-name = "idna"
-version = "3.10"
-description = "Internationalized Domain Names in Applications (IDNA)"
-optional = false
-python-versions = ">=3.6"
-files = [
-    {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"},
-    {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"},
-]
-
-[package.extras]
-all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"]
-
-[[package]]
-name = "iniconfig"
-version = "2.0.0"
-description = "brain-dead simple config-ini parsing"
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"},
-    {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"},
-]
-
-[[package]]
-name = "jsonpickle"
-version = "4.0.1"
-description = "jsonpickle encodes/decodes any Python object to/from JSON"
-optional = false
-python-versions = ">=3.8"
-files = [
-    {file = "jsonpickle-4.0.1-py3-none-any.whl", hash = "sha256:2973c0b0d988c6792ed6c446fa582c48352e79c2880fa2c013f1abde15905555"},
-    {file = "jsonpickle-4.0.1.tar.gz", hash = "sha256:b5336144d902958b92cb08bc1e76bfa47199b8afd454303693894defd2fa50c5"},
-]
-
-[package.extras]
-cov = ["pytest-cov"]
-dev = ["black", "pyupgrade"]
-docs = ["furo", "rst.linker (>=1.9)", "sphinx (>=3.5)"]
-packaging = ["build", "setuptools (>=61.2)", "setuptools-scm[toml] (>=6.0)", "twine"]
-testing = ["PyYAML", "atheris (>=2.3.0,<2.4.0)", "bson", "ecdsa", "feedparser", "gmpy2", "numpy", "pandas", "pymongo", "pytest (>=6.0,!=8.1.*)", "pytest-benchmark", "pytest-benchmark[histogram]", "pytest-checkdocs (>=1.2.3)", "pytest-enabler (>=1.0.1)", "pytest-ruff (>=0.2.1)", "scikit-learn", "scipy", "scipy (>=1.9.3)", "simplejson", "sqlalchemy", "ujson"]
-
-[[package]]
-name = "packaging"
-version = "24.2"
-description = "Core utilities for Python packages"
-optional = false
-python-versions = ">=3.8"
-files = [
-    {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"},
-    {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"},
-]
-
-[[package]]
-name = "pluggy"
-version = "1.5.0"
-description = "plugin and hook calling mechanisms for python"
-optional = false
-python-versions = ">=3.8"
-files = [
-    {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"},
-    {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"},
-]
-
-[package.extras]
-dev = ["pre-commit", "tox"]
-testing = ["pytest", "pytest-benchmark"]
-
-[[package]]
-name = "pytest"
-version = "7.4.4"
-description = "pytest: simple powerful testing with Python"
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"},
-    {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"},
-]
-
-[package.dependencies]
-colorama = {version = "*", markers = "sys_platform == \"win32\""}
-exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""}
-iniconfig = "*"
-packaging = "*"
-pluggy = ">=0.12,<2.0"
-tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""}
-
-[package.extras]
-testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
-
-[[package]]
-name = "pytest-cov"
-version = "4.1.0"
-description = "Pytest plugin for measuring coverage."
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "pytest-cov-4.1.0.tar.gz", hash = "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6"},
-    {file = "pytest_cov-4.1.0-py3-none-any.whl", hash = "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a"},
-]
-
-[package.dependencies]
-coverage = {version = ">=5.2.1", extras = ["toml"]}
-pytest = ">=4.6"
-
-[package.extras]
-testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"]
-
-[[package]]
-name = "pytest-mock"
-version = "3.14.0"
-description = "Thin-wrapper around the mock package for easier use with pytest"
-optional = false
-python-versions = ">=3.8"
-files = [
-    {file = "pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0"},
-    {file = "pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f"},
-]
-
-[package.dependencies]
-pytest = ">=6.2.5"
-
-[package.extras]
-dev = ["pre-commit", "pytest-asyncio", "tox"]
-
-[[package]]
-name = "python-dateutil"
-version = "2.9.0.post0"
-description = "Extensions to the standard Python datetime module"
-optional = false
-python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
-files = [
-    {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"},
-    {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"},
-]
-
-[package.dependencies]
-six = ">=1.5"
-
-[[package]]
-name = "pytz"
-version = "2024.2"
-description = "World timezone definitions, modern and historical"
-optional = false
-python-versions = "*"
-files = [
-    {file = "pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725"},
-    {file = "pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a"},
-]
-
-[[package]]
-name = "rapidfuzz"
-version = "3.11.0"
-description = "rapid fuzzy string matching"
-optional = false
-python-versions = ">=3.9"
-files = [
-    {file = "rapidfuzz-3.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eb8a54543d16ab1b69e2c5ed96cabbff16db044a50eddfc028000138ca9ddf33"},
-    {file = "rapidfuzz-3.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:231c8b2efbd7f8d2ecd1ae900363ba168b8870644bb8f2b5aa96e4a7573bde19"},
-    {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54e7f442fb9cca81e9df32333fb075ef729052bcabe05b0afc0441f462299114"},
-    {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:906f1f2a1b91c06599b3dd1be207449c5d4fc7bd1e1fa2f6aef161ea6223f165"},
-    {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ed59044aea9eb6c663112170f2399b040d5d7b162828b141f2673e822093fa8"},
-    {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1cb1965a28b0fa64abdee130c788a0bc0bb3cf9ef7e3a70bf055c086c14a3d7e"},
-    {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b488b244931d0291412917e6e46ee9f6a14376625e150056fe7c4426ef28225"},
-    {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f0ba13557fec9d5ffc0a22826754a7457cc77f1b25145be10b7bb1d143ce84c6"},
-    {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3871fa7dfcef00bad3c7e8ae8d8fd58089bad6fb21f608d2bf42832267ca9663"},
-    {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:b2669eafee38c5884a6e7cc9769d25c19428549dcdf57de8541cf9e82822e7db"},
-    {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:ffa1bb0e26297b0f22881b219ffc82a33a3c84ce6174a9d69406239b14575bd5"},
-    {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:45b15b8a118856ac9caac6877f70f38b8a0d310475d50bc814698659eabc1cdb"},
-    {file = "rapidfuzz-3.11.0-cp310-cp310-win32.whl", hash = "sha256:22033677982b9c4c49676f215b794b0404073f8974f98739cb7234e4a9ade9ad"},
-    {file = "rapidfuzz-3.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:be15496e7244361ff0efcd86e52559bacda9cd975eccf19426a0025f9547c792"},
-    {file = "rapidfuzz-3.11.0-cp310-cp310-win_arm64.whl", hash = "sha256:714a7ba31ba46b64d30fccfe95f8013ea41a2e6237ba11a805a27cdd3bce2573"},
-    {file = "rapidfuzz-3.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8724a978f8af7059c5323d523870bf272a097478e1471295511cf58b2642ff83"},
-    {file = "rapidfuzz-3.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8b63cb1f2eb371ef20fb155e95efd96e060147bdd4ab9fc400c97325dfee9fe1"},
-    {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82497f244aac10b20710448645f347d862364cc4f7d8b9ba14bd66b5ce4dec18"},
-    {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:339607394941801e6e3f6c1ecd413a36e18454e7136ed1161388de674f47f9d9"},
-    {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84819390a36d6166cec706b9d8f0941f115f700b7faecab5a7e22fc367408bc3"},
-    {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eea8d9e20632d68f653455265b18c35f90965e26f30d4d92f831899d6682149b"},
-    {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b659e1e2ea2784a9a397075a7fc395bfa4fe66424042161c4bcaf6e4f637b38"},
-    {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1315cd2a351144572e31fe3df68340d4b83ddec0af8b2e207cd32930c6acd037"},
-    {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a7743cca45b4684c54407e8638f6d07b910d8d811347b9d42ff21262c7c23245"},
-    {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:5bb636b0150daa6d3331b738f7c0f8b25eadc47f04a40e5c23c4bfb4c4e20ae3"},
-    {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:42f4dd264ada7a9aa0805ea0da776dc063533917773cf2df5217f14eb4429eae"},
-    {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:51f24cb39e64256221e6952f22545b8ce21cacd59c0d3e367225da8fc4b868d8"},
-    {file = "rapidfuzz-3.11.0-cp311-cp311-win32.whl", hash = "sha256:aaf391fb6715866bc14681c76dc0308f46877f7c06f61d62cc993b79fc3c4a2a"},
-    {file = "rapidfuzz-3.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:ebadd5b8624d8ad503e505a99b8eb26fe3ea9f8e9c2234e805a27b269e585842"},
-    {file = "rapidfuzz-3.11.0-cp311-cp311-win_arm64.whl", hash = "sha256:d895998fec712544c13cfe833890e0226585cf0391dd3948412441d5d68a2b8c"},
-    {file = "rapidfuzz-3.11.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f382fec4a7891d66fb7163c90754454030bb9200a13f82ee7860b6359f3f2fa8"},
-    {file = "rapidfuzz-3.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:dfaefe08af2a928e72344c800dcbaf6508e86a4ed481e28355e8d4b6a6a5230e"},
-    {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92ebb7c12f682b5906ed98429f48a3dd80dd0f9721de30c97a01473d1a346576"},
-    {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a1b3ebc62d4bcdfdeba110944a25ab40916d5383c5e57e7c4a8dc0b6c17211a"},
-    {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9c6d7fea39cb33e71de86397d38bf7ff1a6273e40367f31d05761662ffda49e4"},
-    {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99aebef8268f2bc0b445b5640fd3312e080bd17efd3fbae4486b20ac00466308"},
-    {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4469307f464ae3089acf3210b8fc279110d26d10f79e576f385a98f4429f7d97"},
-    {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:eb97c53112b593f89a90b4f6218635a9d1eea1d7f9521a3b7d24864228bbc0aa"},
-    {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:ef8937dae823b889c0273dfa0f0f6c46a3658ac0d851349c464d1b00e7ff4252"},
-    {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d95f9e9f3777b96241d8a00d6377cc9c716981d828b5091082d0fe3a2924b43e"},
-    {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:b1d67d67f89e4e013a5295e7523bc34a7a96f2dba5dd812c7c8cb65d113cbf28"},
-    {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d994cf27e2f874069884d9bddf0864f9b90ad201fcc9cb2f5b82bacc17c8d5f2"},
-    {file = "rapidfuzz-3.11.0-cp312-cp312-win32.whl", hash = "sha256:ba26d87fe7fcb56c4a53b549a9e0e9143f6b0df56d35fe6ad800c902447acd5b"},
-    {file = "rapidfuzz-3.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:b1f7efdd7b7adb32102c2fa481ad6f11923e2deb191f651274be559d56fc913b"},
-    {file = "rapidfuzz-3.11.0-cp312-cp312-win_arm64.whl", hash = "sha256:ed78c8e94f57b44292c1a0350f580e18d3a3c5c0800e253f1583580c1b417ad2"},
-    {file = "rapidfuzz-3.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e60814edd0c9b511b5f377d48b9782b88cfe8be07a98f99973669299c8bb318a"},
-    {file = "rapidfuzz-3.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3f28952da055dbfe75828891cd3c9abf0984edc8640573c18b48c14c68ca5e06"},
-    {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e8f93bc736020351a6f8e71666e1f486bb8bd5ce8112c443a30c77bfde0eb68"},
-    {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:76a4a11ba8f678c9e5876a7d465ab86def047a4fcc043617578368755d63a1bc"},
-    {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc0e0d41ad8a056a9886bac91ff9d9978e54a244deb61c2972cc76b66752de9c"},
-    {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e8ea35f2419c7d56b3e75fbde2698766daedb374f20eea28ac9b1f668ef4f74"},
-    {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd340bbd025302276b5aa221dccfe43040c7babfc32f107c36ad783f2ffd8775"},
-    {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:494eef2c68305ab75139034ea25328a04a548d297712d9cf887bf27c158c388b"},
-    {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5a167344c1d6db06915fb0225592afdc24d8bafaaf02de07d4788ddd37f4bc2f"},
-    {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:8c7af25bda96ac799378ac8aba54a8ece732835c7b74cfc201b688a87ed11152"},
-    {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d2a0f7e17f33e7890257367a1662b05fecaf56625f7dbb6446227aaa2b86448b"},
-    {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4d0d26c7172bdb64f86ee0765c5b26ea1dc45c52389175888ec073b9b28f4305"},
-    {file = "rapidfuzz-3.11.0-cp313-cp313-win32.whl", hash = "sha256:6ad02bab756751c90fa27f3069d7b12146613061341459abf55f8190d899649f"},
-    {file = "rapidfuzz-3.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:b1472986fd9c5d318399a01a0881f4a0bf4950264131bb8e2deba9df6d8c362b"},
-    {file = "rapidfuzz-3.11.0-cp313-cp313-win_arm64.whl", hash = "sha256:c408f09649cbff8da76f8d3ad878b64ba7f7abdad1471efb293d2c075e80c822"},
-    {file = "rapidfuzz-3.11.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1bac4873f6186f5233b0084b266bfb459e997f4c21fc9f029918f44a9eccd304"},
-    {file = "rapidfuzz-3.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4f9f12c2d0aa52b86206d2059916153876a9b1cf9dfb3cf2f344913167f1c3d4"},
-    {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8dd501de6f7a8f83557d20613b58734d1cb5f0be78d794cde64fe43cfc63f5f2"},
-    {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4416ca69af933d4a8ad30910149d3db6d084781d5c5fdedb713205389f535385"},
-    {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f0821b9bdf18c5b7d51722b906b233a39b17f602501a966cfbd9b285f8ab83cd"},
-    {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0edecc3f90c2653298d380f6ea73b536944b767520c2179ec5d40b9145e47aa"},
-    {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4513dd01cee11e354c31b75f652d4d466c9440b6859f84e600bdebfccb17735a"},
-    {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d9727b85511b912571a76ce53c7640ba2c44c364e71cef6d7359b5412739c570"},
-    {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ab9eab33ee3213f7751dc07a1a61b8d9a3d748ca4458fffddd9defa6f0493c16"},
-    {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:6b01c1ddbb054283797967ddc5433d5c108d680e8fa2684cf368be05407b07e4"},
-    {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:3857e335f97058c4b46fa39ca831290b70de554a5c5af0323d2f163b19c5f2a6"},
-    {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d98a46cf07c0c875d27e8a7ed50f304d83063e49b9ab63f21c19c154b4c0d08d"},
-    {file = "rapidfuzz-3.11.0-cp39-cp39-win32.whl", hash = "sha256:c36539ed2c0173b053dafb221458812e178cfa3224ade0960599bec194637048"},
-    {file = "rapidfuzz-3.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:ec8d7d8567e14af34a7911c98f5ac74a3d4a743cd848643341fc92b12b3784ff"},
-    {file = "rapidfuzz-3.11.0-cp39-cp39-win_arm64.whl", hash = "sha256:62171b270ecc4071be1c1f99960317db261d4c8c83c169e7f8ad119211fe7397"},
-    {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:f06e3c4c0a8badfc4910b9fd15beb1ad8f3b8fafa8ea82c023e5e607b66a78e4"},
-    {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:fe7aaf5a54821d340d21412f7f6e6272a9b17a0cbafc1d68f77f2fc11009dcd5"},
-    {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25398d9ac7294e99876a3027ffc52c6bebeb2d702b1895af6ae9c541ee676702"},
-    {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a52eea839e4bdc72c5e60a444d26004da00bb5bc6301e99b3dde18212e41465"},
-    {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c87319b0ab9d269ab84f6453601fd49b35d9e4a601bbaef43743f26fabf496c"},
-    {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:3048c6ed29d693fba7d2a7caf165f5e0bb2b9743a0989012a98a47b975355cca"},
-    {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b04f29735bad9f06bb731c214f27253bd8bedb248ef9b8a1b4c5bde65b838454"},
-    {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:7864e80a0d4e23eb6194254a81ee1216abdc53f9dc85b7f4d56668eced022eb8"},
-    {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3794df87313dfb56fafd679b962e0613c88a293fd9bd5dd5c2793d66bf06a101"},
-    {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d71da0012face6f45432a11bc59af19e62fac5a41f8ce489e80c0add8153c3d1"},
-    {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff38378346b7018f42cbc1f6d1d3778e36e16d8595f79a312b31e7c25c50bd08"},
-    {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:6668321f90aa02a5a789d4e16058f2e4f2692c5230252425c3532a8a62bc3424"},
-    {file = "rapidfuzz-3.11.0.tar.gz", hash = "sha256:a53ca4d3f52f00b393fab9b5913c5bafb9afc27d030c8a1db1283da6917a860f"},
-]
-
-[package.extras]
-all = ["numpy"]
-
-[[package]]
-name = "regex"
-version = "2024.11.6"
-description = "Alternative regular expression module, to replace re."
-optional = false
-python-versions = ">=3.8"
-files = [
-    {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"},
-    {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"},
-    {file = "regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e"},
-    {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde"},
-    {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e"},
-    {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2"},
-    {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf"},
-    {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c"},
-    {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86"},
-    {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67"},
-    {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d"},
-    {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2"},
-    {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008"},
-    {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62"},
-    {file = "regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e"},
-    {file = "regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519"},
-    {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638"},
-    {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7"},
-    {file = "regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20"},
-    {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114"},
-    {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3"},
-    {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f"},
-    {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0"},
-    {file = "regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55"},
-    {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89"},
-    {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d"},
-    {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34"},
-    {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d"},
-    {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45"},
-    {file = "regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9"},
-    {file = "regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60"},
-    {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a"},
-    {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9"},
-    {file = "regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2"},
-    {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4"},
-    {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577"},
-    {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3"},
-    {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e"},
-    {file = "regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe"},
-    {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e"},
-    {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29"},
-    {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39"},
-    {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51"},
-    {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad"},
-    {file = "regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54"},
-    {file = "regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b"},
-    {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84"},
-    {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4"},
-    {file = "regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0"},
-    {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0"},
-    {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7"},
-    {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7"},
-    {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c"},
-    {file = "regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3"},
-    {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07"},
-    {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e"},
-    {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6"},
-    {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4"},
-    {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d"},
-    {file = "regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff"},
-    {file = "regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a"},
-    {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3a51ccc315653ba012774efca4f23d1d2a8a8f278a6072e29c7147eee7da446b"},
-    {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ad182d02e40de7459b73155deb8996bbd8e96852267879396fb274e8700190e3"},
-    {file = "regex-2024.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba9b72e5643641b7d41fa1f6d5abda2c9a263ae835b917348fc3c928182ad467"},
-    {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40291b1b89ca6ad8d3f2b82782cc33807f1406cf68c8d440861da6304d8ffbbd"},
-    {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdf58d0e516ee426a48f7b2c03a332a4114420716d55769ff7108c37a09951bf"},
-    {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a36fdf2af13c2b14738f6e973aba563623cb77d753bbbd8d414d18bfaa3105dd"},
-    {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1cee317bfc014c2419a76bcc87f071405e3966da434e03e13beb45f8aced1a6"},
-    {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50153825ee016b91549962f970d6a4442fa106832e14c918acd1c8e479916c4f"},
-    {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea1bfda2f7162605f6e8178223576856b3d791109f15ea99a9f95c16a7636fb5"},
-    {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:df951c5f4a1b1910f1a99ff42c473ff60f8225baa1cdd3539fe2819d9543e9df"},
-    {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:072623554418a9911446278f16ecb398fb3b540147a7828c06e2011fa531e773"},
-    {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f654882311409afb1d780b940234208a252322c24a93b442ca714d119e68086c"},
-    {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:89d75e7293d2b3e674db7d4d9b1bee7f8f3d1609428e293771d1a962617150cc"},
-    {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f65557897fc977a44ab205ea871b690adaef6b9da6afda4790a2484b04293a5f"},
-    {file = "regex-2024.11.6-cp38-cp38-win32.whl", hash = "sha256:6f44ec28b1f858c98d3036ad5d7d0bfc568bdd7a74f9c24e25f41ef1ebfd81a4"},
-    {file = "regex-2024.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:bb8f74f2f10dbf13a0be8de623ba4f9491faf58c24064f32b65679b021ed0001"},
-    {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5704e174f8ccab2026bd2f1ab6c510345ae8eac818b613d7d73e785f1310f839"},
-    {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:220902c3c5cc6af55d4fe19ead504de80eb91f786dc102fbd74894b1551f095e"},
-    {file = "regex-2024.11.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7e351589da0850c125f1600a4c4ba3c722efefe16b297de54300f08d734fbf"},
-    {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5056b185ca113c88e18223183aa1a50e66507769c9640a6ff75859619d73957b"},
-    {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e34b51b650b23ed3354b5a07aab37034d9f923db2a40519139af34f485f77d0"},
-    {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5670bce7b200273eee1840ef307bfa07cda90b38ae56e9a6ebcc9f50da9c469b"},
-    {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08986dce1339bc932923e7d1232ce9881499a0e02925f7402fb7c982515419ef"},
-    {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93c0b12d3d3bc25af4ebbf38f9ee780a487e8bf6954c115b9f015822d3bb8e48"},
-    {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:764e71f22ab3b305e7f4c21f1a97e1526a25ebdd22513e251cf376760213da13"},
-    {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f056bf21105c2515c32372bbc057f43eb02aae2fda61052e2f7622c801f0b4e2"},
-    {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69ab78f848845569401469da20df3e081e6b5a11cb086de3eed1d48f5ed57c95"},
-    {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:86fddba590aad9208e2fa8b43b4c098bb0ec74f15718bb6a704e3c63e2cef3e9"},
-    {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:684d7a212682996d21ca12ef3c17353c021fe9de6049e19ac8481ec35574a70f"},
-    {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a03e02f48cd1abbd9f3b7e3586d97c8f7a9721c436f51a5245b3b9483044480b"},
-    {file = "regex-2024.11.6-cp39-cp39-win32.whl", hash = "sha256:41758407fc32d5c3c5de163888068cfee69cb4c2be844e7ac517a52770f9af57"},
-    {file = "regex-2024.11.6-cp39-cp39-win_amd64.whl", hash = "sha256:b2837718570f95dd41675328e111345f9b7095d821bac435aac173ac80b19983"},
-    {file = "regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519"},
-]
-
-[[package]]
-name = "requests"
-version = "2.32.3"
-description = "Python HTTP for Humans."
-optional = false
-python-versions = ">=3.8"
-files = [
-    {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"},
-    {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"},
-]
-
-[package.dependencies]
-certifi = ">=2017.4.17"
-charset-normalizer = ">=2,<4"
-idna = ">=2.5,<4"
-urllib3 = ">=1.21.1,<3"
-
-[package.extras]
-socks = ["PySocks (>=1.5.6,!=1.5.7)"]
-use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
-
-[[package]]
-name = "six"
-version = "1.17.0"
-description = "Python 2 and 3 compatibility utilities"
-optional = false
-python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
-files = [
-    {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"},
-    {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"},
-]
-
-[[package]]
-name = "tomli"
-version = "2.2.1"
-description = "A lil' TOML parser"
-optional = false
-python-versions = ">=3.8"
-files = [
-    {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"},
-    {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"},
-    {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"},
-    {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"},
-    {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"},
-    {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"},
-    {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"},
-    {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"},
-    {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"},
-    {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"},
-    {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"},
-    {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"},
-    {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"},
-    {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"},
-    {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"},
-    {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"},
-    {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"},
-    {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"},
-    {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"},
-    {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"},
-    {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"},
-    {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"},
-    {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"},
-    {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"},
-    {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"},
-    {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"},
-    {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"},
-    {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"},
-    {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"},
-    {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"},
-    {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"},
-    {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"},
-]
-
-[[package]]
-name = "tzdata"
-version = "2024.2"
-description = "Provider of IANA time zone data"
-optional = false
-python-versions = ">=2"
-files = [
-    {file = "tzdata-2024.2-py2.py3-none-any.whl", hash = "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd"},
-    {file = "tzdata-2024.2.tar.gz", hash = "sha256:7d85cc416e9382e69095b7bdf4afd9e3880418a2413feec7069d533d6b4e31cc"},
-]
-
-[[package]]
-name = "tzlocal"
-version = "5.2"
-description = "tzinfo object for the local timezone"
-optional = false
-python-versions = ">=3.8"
-files = [
-    {file = "tzlocal-5.2-py3-none-any.whl", hash = "sha256:49816ef2fe65ea8ac19d19aa7a1ae0551c834303d5014c6d5a62e4cbda8047b8"},
-    {file = "tzlocal-5.2.tar.gz", hash = "sha256:8d399205578f1a9342816409cc1e46a93ebd5755e39ea2d85334bea911bf0e6e"},
-]
-
-[package.dependencies]
-tzdata = {version = "*", markers = "platform_system == \"Windows\""}
-
-[package.extras]
-devenv = ["check-manifest", "pytest (>=4.3)", "pytest-cov", "pytest-mock (>=3.3)", "zest.releaser"]
-
-[[package]]
-name = "urllib3"
-version = "2.3.0"
-description = "HTTP library with thread-safe connection pooling, file post, and more."
-optional = false
-python-versions = ">=3.9"
-files = [
-    {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"},
-    {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"},
-]
-
-[package.extras]
-brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"]
-h2 = ["h2 (>=4,<5)"]
-socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
-zstd = ["zstandard (>=0.18.0)"]
-
-[metadata]
-lock-version = "2.0"
-python-versions = "^3.10"
-content-hash = "f65cd66387236673e2a5afb3b2a75362c97815cdde592a86712737fb9ca71695"
diff --git a/pkgs/by-name/up/update-vim-plugins/pyproject.toml b/pkgs/by-name/up/update-vim-plugins/pyproject.toml
deleted file mode 100644
index 38caf76d..00000000
--- a/pkgs/by-name/up/update-vim-plugins/pyproject.toml
+++ /dev/null
@@ -1,45 +0,0 @@
-[tool.poetry]
-name = "update_vim_plugins"
-version = "0.1.0"
-description = ""
-authors = ["Your Name <you@example.com>"]
-packages = [{ include = "update_vim_plugins" }]
-
-[tool.poetry.scripts]
-update-vim-plugins = "update_vim_plugins.__main__:main"
-
-[tool.poetry.dependencies]
-python = "^3.10"
-requests = "^2.28.2"
-cleo = "^2.0.1"
-jsonpickle = "*"
-dateparser = "^1.1.8"
-
-[tool.poetry.group.test.dependencies]
-pytest-cov = "^4.0.0"
-pytest = "^7.3.1"
-pytest-mock = "^3.10.0"
-
-[tool.poetry.group.dev]
-optional = true
-
-[tool.poetry.group.dev.dependencies]
-# black = "^23.3.0"
-# ruff-lsp = "^0.0.24"
-# mypy = "^1.2.0"
-# types-requests = "^2.28.11.17"
-# isort = "^5.12.0"
-# ruff = "^0.0.262"
-
-[tool.isort]
-profile = "black"
-
-[tool.black]
-line-length = 120
-
-[tool.ruff]
-line-length = 120
-
-[build-system]
-requires = ["poetry-core"]
-build-backend = "poetry.core.masonry.api"
diff --git a/pkgs/by-name/up/update-vim-plugins/update.sh b/pkgs/by-name/up/update-vim-plugins/update.sh
deleted file mode 100755
index 1bad12a9..00000000
--- a/pkgs/by-name/up/update-vim-plugins/update.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/usr/bin/env sh
-
-poetry update --lock
-
-# vim: ft=sh
diff --git a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/__init__.py b/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/__init__.py
+++ /dev/null
diff --git a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/__main__.py b/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/__main__.py
deleted file mode 100644
index a8d9e06f..00000000
--- a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/__main__.py
+++ /dev/null
@@ -1,15 +0,0 @@
-from cleo.application import Application
-
-from .update import UpdateCommand
-from .cleanup import CleanUpCommand
-
-
-def main():
-    application = Application()
-    application.add(UpdateCommand())
-    application.add(CleanUpCommand())
-    application.run()
-
-
-if __name__ == "__main__":
-    main()
diff --git a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/cleanup.py b/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/cleanup.py
deleted file mode 100644
index fd313ed0..00000000
--- a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/cleanup.py
+++ /dev/null
@@ -1,100 +0,0 @@
-from cleo.commands.command import Command
-from cleo.helpers import argument
-
-from .helpers import read_manifest_to_spec, read_blacklist_to_spec, write_manifest_from_spec
-
-
-class CleanUpCommand(Command):
-    name = "cleanup"
-    description = "Clean up manifest"
-    arguments = [argument("plug_dir", description="Path to the plugin directory", optional=False)]
-
-    def handle(self):
-        """Main command function"""
-
-        plug_dir = self.argument("plug_dir")
-        self.line("<comment>Checking manifest file</comment>")
-        # all cleaning up will be done during reading and writing automatically
-        manifest = read_manifest_to_spec(plug_dir)
-        blacklist = read_blacklist_to_spec(plug_dir)
-
-        new_manifest = [spec for spec in manifest if spec not in blacklist]
-
-        new_manifest_filterd = self.filter_renamed(new_manifest)
-
-        write_manifest_from_spec(new_manifest_filterd, plug_dir)
-
-        self.line("<comment>Done</comment>")
-
-    def filter_renamed(self, specs):
-        """Filter specs that define the same plugin (same owner and same repo) but with different properties.
-        This could be a different name, source, or branch
-        """
-
-        error = False
-        for i, p in enumerate(specs):
-            for p2 in specs:
-                same_owner = p.owner.lower() == p2.owner.lower()
-                same_repo = p.repo.lower() == p2.repo.lower()
-                different_specs = p != p2
-                marked_duplicate = p.marked_duplicate or p2.marked_duplicate
-
-                if same_owner and same_repo and different_specs and not marked_duplicate:
-                    self.line("<info>The following lines appear to define the same plugin</info>")
-
-                    p_props_defined = p.branch is not None or p.custom_name is not None
-                    p2_props_defined = p2.branch is not None or p2.custom_name is not None
-                    p_is_lower_case = p.owner == p.owner.lower() and p.name == p.name.lower()
-                    p2_is_lower_case = p2.owner == p2.owner.lower() and p2.name == p2.name.lower()
-
-                    # list of conditions for selecting p
-                    select_p = p_props_defined and not p2_props_defined or p2_is_lower_case and not p_is_lower_case
-                    # list of conditions for selecting p2
-                    select_p2 = p2_props_defined and not p_props_defined or p_is_lower_case and not p2_is_lower_case
-
-                    # one is more defined and is all lower, but the other is not all lower
-                    # (we assume the not all lower case is the correct naming)
-                    error_props_lower = (
-                        p_props_defined and p_is_lower_case and not p2_props_defined and not p2_is_lower_case
-                    )
-                    error_props_lower2 = (
-                        p2_props_defined and p2_is_lower_case and not p_props_defined and not p_is_lower_case
-                    )
-
-                    # both props are defined
-                    error_props = p_props_defined and p2_props_defined
-
-                    # the sources are different
-                    error_source = p.repository_host != p2.repository_host
-
-                    if error_props_lower or error_props_lower2 or error_props or error_source:
-                        self.line(" • <error>Cannot determine which is the correct plugin</error>")
-                        self.line(f" - {p.line}")
-                        self.line(f" - {p2.line}")
-                        error = True
-                        # remove second spec to not encounter the error twice
-                        # this will not be written to the manifest.txt because we set
-                        # the error flag and will exit after the loop
-                        specs.remove(p2)
-                    elif select_p:
-                        self.line(f" - <comment>{p.line}</comment>")
-                        self.line(f" - {p2.line}")
-                        specs.remove(p2)
-                    elif select_p2:
-                        self.line(f" - {p.line}")
-                        self.line(f" - <comment>{p2.line}</comment>")
-                        specs.remove(p)
-                    else:
-                        self.line(" • <error>Logic error in correct spec determination</error>")
-                        self.line(f" - {p.line}")
-                        self.line(f" - {p2.line}")
-                        error = True
-                        # remove second spec to not encounter the error twice
-                        # this will not be written to the manifest.txt because we set
-                        # the error flag and will exit after the loop
-                        specs.remove(p)
-        if error:
-            # exit after all errors have been found
-            exit(1)
-
-        return specs
diff --git a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/helpers.py b/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/helpers.py
deleted file mode 100644
index 8a28b0e8..00000000
--- a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/helpers.py
+++ /dev/null
@@ -1,61 +0,0 @@
-from .spec import PluginSpec
-
-MANIFEST_FILE = "manifest.txt"
-BLACKLIST_FILE = "blacklist.txt"
-PKGS_FILE = "default.nix"
-JSON_FILE = ".plugins.json"
-PLUGINS_LIST_FILE = "plugins.md"
-
-
-def get_const(const: str, plug_dir: str) -> str:
-    out = plug_dir + "/" + const
-    return out
-
-
-def read_manifest(plug_dir: str) -> list[str]:
-    with open(get_const(MANIFEST_FILE, plug_dir), "r") as file:
-        specs = set([spec.strip() for spec in file.readlines()])
-
-    return sorted(specs)
-
-
-def read_manifest_to_spec(plug_dir: str) -> list[PluginSpec]:
-    manifest = read_manifest(plug_dir)
-    specs = [PluginSpec.from_spec(spec.strip()) for spec in manifest]
-
-    return sorted(specs)
-
-
-def read_blacklist(plug_dir: str) -> list[str]:
-    with open(get_const(BLACKLIST_FILE, plug_dir), "r") as file:
-        if len(file.readlines()) == 0:
-            return [""]
-        else:
-            blacklisted_specs = set([spec.strip() for spec in file.readlines()])
-
-    return sorted(blacklisted_specs)
-
-
-def read_blacklist_to_spec(plug_dir: str) -> list[PluginSpec]:
-    blacklist = read_blacklist(plug_dir)
-    specs = [PluginSpec.from_spec(spec.strip()) for spec in blacklist]
-
-    return sorted(specs)
-
-
-def write_manifest(specs: list[str] | set[str], plug_dir: str):
-    """write specs to manifest file. Does some cleaning up"""
-
-    with open(get_const(MANIFEST_FILE, plug_dir), "w") as file:
-        specs = sorted(set(specs), key=lambda x: x.lower())
-        specs = [p for p in specs]
-
-        for s in specs:
-            file.write(f"{s}\n")
-
-
-def write_manifest_from_spec(specs: list[PluginSpec], plug_dir: str):
-    """write specs to manifest file. Does some cleaning up"""
-
-    strings = [f"{spec}" for spec in specs]
-    write_manifest(strings, plug_dir)
diff --git a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/nix.py b/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/nix.py
deleted file mode 100644
index 66a8df4c..00000000
--- a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/nix.py
+++ /dev/null
@@ -1,121 +0,0 @@
-import abc
-import enum
-import json
-import subprocess
-
-
-def nix_prefetch_url(url):
-    """Return the sha256 hash of the given url."""
-    subprocess_output = subprocess.check_output(
-        ["nix-prefetch-url", "--type", "sha256", url],
-        stderr=subprocess.DEVNULL,
-    )
-    sha256 = subprocess_output.decode("utf-8").strip()
-    return sha256
-
-
-def nix_prefetch_git(url):
-    """Return the sha256 hash of the given git url."""
-    subprocess_output = subprocess.check_output(["nix-prefetch-git", url], stderr=subprocess.DEVNULL)
-    sha256 = json.loads(subprocess_output)["sha256"]
-    return sha256
-
-
-class Source(abc.ABC):
-    """Abstract base class for sources."""
-
-    url: str
-    sha256: str
-
-    @abc.abstractmethod
-    def __init__(self, url: str) -> None:
-        """Initialize a Source."""
-
-    @abc.abstractmethod
-    def get_nix_expression(self):
-        """Return the nix expression for this source."""
-
-    def __repr__(self):
-        """Return the representation of this source."""
-        return self.get_nix_expression()
-
-
-class UrlSource(Source):
-    """A source that is a url."""
-
-    def __init__(self, url: str) -> None:
-        """Initialize a UrlSource."""
-        self.url = url
-        self.sha256 = nix_prefetch_url(url)
-
-    def get_nix_expression(self):
-        """Return the nix expression for this source."""
-        return f'fetchurl {{ url = "{self.url}"; sha256 = "{self.sha256}"; }}'
-
-
-class GitSource(Source):
-    """A source that is a git repository."""
-
-    def __init__(self, url: str, rev: str) -> None:
-        """Initialize a GitSource."""
-        self.url = url
-        self.rev = rev
-        self.sha256 = nix_prefetch_git(url)
-
-    def get_nix_expression(self):
-        """Return the nix expression for this source."""
-        return f'fetchgit {{ url = "{self.url}"; rev = "{self.rev}"; sha256 = "{self.sha256}"; }}'
-
-
-class License(enum.Enum):
-    """An enumeration of licenses."""
-
-    AGPL_3_0 = "agpl3Only"
-    APACHE_2_0 = "asf20"
-    BSD_2_CLAUSE = "bsd2"
-    BSD_3_CLAUSE = "bsd3"
-    BSL_1_0 = "bsl1_0"
-    CC0_1_0 = "cc0"
-    EPL_2_0 = "epl20"
-    GPL_2_0 = "gpl2Only"
-    GPL_3_0 = "gpl3Only"
-    ISCLGPL_2_1 = "lgpl21Only"
-    MIT = "mit"
-    MPL_2_0 = "mpl20"
-    UNLUNLICENSE = "unlicense"
-    WTFPL = "wtfpl"
-    UNFREE = "unfree"
-    UNKNOWN = ""
-
-    @classmethod
-    def from_spdx_id(cls, spdx_id: str | None) -> "License":
-        """Return the License from the given spdx_id."""
-        mapping = {
-            "AGPL-3.0": cls.AGPL_3_0,
-            "AGPL-3.0-only": cls.AGPL_3_0,
-            "Apache-2.0": cls.APACHE_2_0,
-            "BSD-2-Clause": cls.BSD_2_CLAUSE,
-            "BSD-3-Clause": cls.BSD_3_CLAUSE,
-            "BSL-1.0": cls.BSL_1_0,
-            "CC0-1.0": cls.CC0_1_0,
-            "EPL-2.0": cls.EPL_2_0,
-            "GPL-2.0": cls.GPL_2_0,
-            "GPL-2.0-only": cls.GPL_2_0,
-            "GPL-3.0": cls.GPL_3_0,
-            "GPL-3.0-only": cls.GPL_3_0,
-            "LGPL-2.1-only": cls.ISCLGPL_2_1,
-            "MIT": cls.MIT,
-            "MPL-2.0": cls.MPL_2_0,
-            "Unlicense": cls.UNLUNLICENSE,
-            "WTFPL": cls.WTFPL,
-        }
-
-        if spdx_id is None:
-            return cls.UNKNOWN
-
-        spdx_id = spdx_id.upper()
-        return mapping.get(spdx_id, cls.UNKNOWN)
-
-    def __str__(self):
-        """Return the string representation of this license."""
-        return self.value
diff --git a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/plugin.py b/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/plugin.py
deleted file mode 100644
index 8334ad53..00000000
--- a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/plugin.py
+++ /dev/null
@@ -1,182 +0,0 @@
-import logging
-import os
-import urllib
-
-import requests
-import jsonpickle
-from datetime import datetime, date
-from dateparser import parse
-
-from .nix import GitSource, License, Source, UrlSource
-from .spec import PluginSpec, RepositoryHost
-
-
-logger = logging.getLogger(__name__)
-
-
-class VimPlugin:
-    """Abstract base class for vim plugins."""
-
-    name: str
-    owner: str
-    repo: str
-    version: date
-    source: Source
-    description: str = "No description"
-    homepage: str
-    license: License
-    source_line: str
-    checked: date = datetime.now().date()
-
-    def to_nix(self):
-        """Return the nix expression for this plugin."""
-        meta = f'with lib; {{ description = "{self.description}"; homepage = "{self.homepage}"; license = with licenses; [ {self.license.value} ]; }}'
-        return f'/* Generated from: {self.source_line} */ {self.name} = buildVimPlugin {{ pname = "{self.name}";  version = "{self.version}"; src = {self.source.get_nix_expression()}; meta = {meta}; }};'
-
-    def to_json(self):
-        """Serizalize the plugin to json"""
-        return jsonpickle.encode(self)
-
-    def to_markdown(self):
-        link = f"[{self.source_line}]({self.homepage})"
-        version = f"{self.version}"
-        package_name = f"{self.name}"
-        checked = f"{self.checked}"
-
-        return f"| {link} | {version} | `{package_name}` | {checked} |"
-
-    def __lt__(self, o: object) -> bool:
-        if not isinstance(o, VimPlugin):
-            return False
-
-        return self.name.lower() < o.name.lower()
-
-    def __repr__(self):
-        """Return the representation of this plugin."""
-        return f"VimPlugin({self.name!r}, {self.version.strftime('%Y-%m-%d')})"
-
-
-def _get_github_token():
-    token = os.environ.get("GITHUB_TOKEN")
-    if token is None:
-        # NOTE: This should never use more than the free api requests <2023-12-09>
-        pass
-        # logger.warning("GITHUB_TOKEN environment variable not set")
-    return token
-
-
-class GitHubPlugin(VimPlugin):
-    def __init__(self, plugin_spec: PluginSpec) -> None:
-        """Initialize a GitHubPlugin."""
-
-        full_name = f"{plugin_spec.owner}/{plugin_spec.repo}"
-        repo_info = self._api_call(f"repos/{full_name}")
-        default_branch = plugin_spec.branch or repo_info["default_branch"]
-        api_callback = self._api_call(f"repos/{full_name}/commits/{default_branch}")
-        latest_commit = api_callback["commit"]
-        sha = api_callback["sha"]
-
-        self.name = plugin_spec.name
-        self.owner = plugin_spec.owner
-        self.version = parse(latest_commit["committer"]["date"]).date()
-        self.source = UrlSource(f"https://github.com/{full_name}/archive/{sha}.tar.gz")
-        self.description = (repo_info.get("description") or "").replace('"', '\\"')
-        self.homepage = repo_info["html_url"]
-        self.license = plugin_spec.license or License.from_spdx_id((repo_info.get("license") or {}).get("spdx_id"))
-        self.source_line = plugin_spec.line
-
-    def _api_call(self, path: str, token: str | None = _get_github_token()):
-        """Call the GitHub API."""
-        url = f"https://api.github.com/{path}"
-        headers = {"Content-Type": "application/json"}
-        if token is not None:
-            headers["Authorization"] = f"token {token}"
-        response = requests.get(url, headers=headers)
-        if response.status_code != 200:
-            raise RuntimeError(f"GitHub API call failed: {response.text}")
-        return response.json()
-
-
-class GitlabPlugin(VimPlugin):
-    def __init__(self, plugin_spec: PluginSpec) -> None:
-        """Initialize a GitlabPlugin."""
-
-        full_name = urllib.parse.quote(f"{plugin_spec.owner}/{plugin_spec.repo}", safe="")
-        repo_info = self._api_call(f"projects/{full_name}")
-        default_branch = plugin_spec.branch or repo_info["default_branch"]
-        api_callback = self._api_call(f"projects/{full_name}/repository/branches/{default_branch}")
-        latest_commit = api_callback["commit"]
-        sha = latest_commit["id"]
-
-        self.name = plugin_spec.name
-        self.owner = plugin_spec.owner
-        self.version = parse(latest_commit["created_at"]).date()
-        self.source = UrlSource(f"https://gitlab.com/api/v4/projects/{full_name}/repository/archive.tar.gz?sha={sha}")
-        self.description = (repo_info.get("description") or "").replace('"', '\\"')
-        self.homepage = repo_info["web_url"]
-        self.license = plugin_spec.license or License.from_spdx_id(repo_info.get("license", {}).get("key"))
-        self.source_line = plugin_spec.line
-
-    def _api_call(self, path: str) -> dict:
-        """Call the Gitlab API."""
-        url = f"https://gitlab.com/api/v4/{path}"
-        response = requests.get(url)
-        if response.status_code != 200:
-            raise RuntimeError(f"Gitlab API call failed: {response.text}")
-        return response.json()
-
-
-def _get_sourcehut_token():
-    token = os.environ.get("SOURCEHUT_TOKEN")
-    if token is None:
-        # NOTE: This should never use more than the free requests <2023-12-09>
-        pass
-        # logger.warning("SOURCEHUT_TOKEN environment variable not set")
-    return token
-
-
-class SourceHutPlugin(VimPlugin):
-    def __init__(self, plugin_spec: PluginSpec) -> None:
-        """Initialize a SourceHutPlugin."""
-
-        repo_info = self._api_call(f"~{plugin_spec.owner}/repos/{plugin_spec.repo}")
-        if plugin_spec.branch is None:
-            commits = self._api_call(f"~{plugin_spec.owner}/repos/{plugin_spec.repo}/log")
-        else:
-            commits = self._api_call(f"~{plugin_spec.owner}/repos/{plugin_spec.repo}/log/{plugin_spec.branch}")
-        latest_commit = commits["results"][0]
-        sha = latest_commit["id"]
-
-        self.name = plugin_spec.name
-        self.owner = plugin_spec.owner
-        self.version = parse(latest_commit["timestamp"]).date()
-        self.description = (repo_info.get("description") or "").replace('"', '\\"')
-        self.homepage = f"https://git.sr.ht/~{plugin_spec.owner}/{plugin_spec.repo}"
-        self.source = GitSource(self.homepage, sha)
-        self.license = plugin_spec.license or License.UNKNOWN  # cannot be determined via API
-        self.source_line = plugin_spec.line
-
-    def _api_call(self, path: str, token: str | None = _get_sourcehut_token()):
-        """Call the SourceHut API."""
-
-        url = f"https://git.sr.ht/api/{path}"
-        headers = {"Content-Type": "application/json"}
-        if token is not None:
-            headers["Authorization"] = f"token {token}"
-        response = requests.get(url, headers=headers)
-        if response.status_code != 200:
-            raise RuntimeError(f"SourceHut API call failed: {response.json()}")
-        return response.json()
-
-
-def plugin_from_spec(plugin_spec: PluginSpec) -> VimPlugin:
-    """Initialize a VimPlugin."""
-
-    if plugin_spec.repository_host == RepositoryHost.GITHUB:
-        return GitHubPlugin(plugin_spec)
-    elif plugin_spec.repository_host == RepositoryHost.GITLAB:
-        return GitlabPlugin(plugin_spec)
-    elif plugin_spec.repository_host == RepositoryHost.SOURCEHUT:
-        return SourceHutPlugin(plugin_spec)
-    else:
-        raise NotImplementedError(f"Unsupported source: {plugin_spec.repository_host}")
diff --git a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/spec.py b/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/spec.py
deleted file mode 100644
index 0f2fb29c..00000000
--- a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/spec.py
+++ /dev/null
@@ -1,143 +0,0 @@
-import enum
-import re
-
-from .nix import License
-
-
-class RepositoryHost(enum.Enum):
-    """A repository host."""
-
-    GITHUB = "github"
-    GITLAB = "gitlab"
-    SOURCEHUT = "sourcehut"
-
-
-class PluginSpec:
-    """A Vim plugin Spec."""
-
-    @classmethod
-    def from_spec(cls, spec):
-        """The spec line must be in the format:
-            [<repository_host>:]<owner>/<repo>[:<branch>][:name].
-
-        repository_host is one of github (default), gitlab, or sourcehut.
-        owner is the repository owner.
-        repo is the repository name.
-        branch is the git branch.
-        name is the name to use for the plugin (default is value of repo).
-        """
-        repository_host = RepositoryHost.GITHUB
-        # gitref = "master"
-
-        repository_host_regex = r"((?P<repository_host>[^:]+):)"
-        owner_regex = r"(?P<owner>[^/:]+)"
-        repo_regex = r"(?P<repo>[^:]+)"
-        branch_regex = r"(:(?P<branch>[^:]+)?)"
-        name_regex = r"(:(?P<name>[^:]+)?)"
-        license_regex = r"(:(?P<license>[^:]+)?)"
-        marked_duplicate_regex = r"(:(?P<duplicate>duplicate))"
-
-        spec_regex = re.compile(
-            f"^{repository_host_regex}?{owner_regex}/{repo_regex}{branch_regex}?{name_regex}?{license_regex}?{marked_duplicate_regex}?$",
-        )
-
-        match = spec_regex.match(spec)
-        if match is None:
-            raise ValueError(f"Invalid spec: {spec}")
-
-        group_dict = match.groupdict()
-
-        repository_host = RepositoryHost(group_dict.get("repository_host") or "github")
-
-        owner = group_dict.get("owner")
-        if owner is None:
-            raise RuntimeError("Could not get owner")
-
-        repo = group_dict.get("repo")
-        if repo is None:
-            raise RuntimeError("Could not get repo")
-
-        branch = group_dict.get("branch")
-        name = group_dict.get("name")
-        license = group_dict.get("license")
-        marked_duplicate = bool(group_dict.get("duplicate"))  # True if 'duplicate', False if None
-
-        line = spec
-
-        return cls(repository_host, owner, repo, line, branch, name, license, marked_duplicate)
-
-    def __init__(
-        self,
-        repository_host: RepositoryHost,
-        owner: str,
-        repo: str,
-        line: str,
-        branch: str | None = None,
-        name: str | None = None,
-        license: str | None = None,
-        marked_duplicate: bool = False,
-    ) -> None:
-        """Initialize a VimPluginSpec."""
-        self.repository_host = repository_host
-        self.owner = owner
-        self.repo = repo
-        self.branch = branch
-        self.custom_name = name
-        self.name = name or repo.replace(".", "-").replace("_", "-")
-        self.license = License(license) if license else None
-        self.line = line
-        self.marked_duplicate = marked_duplicate
-
-    def __str__(self) -> str:
-        """Return a string representation of a VimPluginSpec."""
-        spec = ""
-
-        if self.repository_host != RepositoryHost.GITHUB:
-            spec += f"{self.repository_host.value}:"
-
-        spec += f"{self.owner}/{self.repo}"
-
-        spec += ":"
-        if self.branch is not None:
-            spec += self.branch
-
-        spec += ":"
-        if self.custom_name is not None:
-            spec += self.custom_name
-
-        spec += ":"
-        if self.license is not None:
-            spec += str(self.license)
-
-        spec += ":"
-        if self.marked_duplicate:
-            spec += "duplicate"
-
-        return spec.rstrip(":")
-
-    def __repr__(self):
-        """Return the representation of the specs"""
-        return f"PluginSpec({self.owner}/{self.repo}, {self.name})"
-
-    def to_spec(self):
-        """Return a spec line for a VimPluginSpec."""
-        return str(self)
-
-    def __lt__(self, o: object) -> bool:
-        if not isinstance(o, PluginSpec):
-            return False
-
-        return self.name.lower() < o.name.lower()
-
-    def __eq__(self, o: object) -> bool:
-        """Return True if the two specs are equal."""
-        if not isinstance(o, PluginSpec):
-            return False
-
-        return (
-            self.repository_host == o.repository_host
-            and self.owner == o.owner
-            and self.repo == o.repo
-            and self.branch == o.branch
-            and self.name == o.name
-        )
diff --git a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/__init__.py b/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/__init__.py
+++ /dev/null
diff --git a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/fixtures.py b/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/fixtures.py
deleted file mode 100644
index 75dd251a..00000000
--- a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/fixtures.py
+++ /dev/null
@@ -1,44 +0,0 @@
-import json
-
-import pytest
-from pytest_mock import MockerFixture
-
-from update_vim_plugins.nix import GitSource, UrlSource
-
-
-@pytest.fixture()
-def url():
-    return "https://example.com"
-
-
-@pytest.fixture()
-def rev():
-    return "1234567890abcdef"
-
-
-@pytest.fixture()
-def sha256():
-    return "sha256-1234567890abcdef"
-
-
-@pytest.fixture()
-def url_source(mocker: MockerFixture, url: str, sha256: str):
-    mocker.patch("subprocess.check_output", return_value=bytes(sha256, "utf-8"))
-    return UrlSource(url)
-
-
-@pytest.fixture()
-def git_source(mocker: MockerFixture, url: str, rev: str, sha256: str):
-    return_value = {
-        "url": url,
-        "rev": rev,
-        "date": "1970-01-01T00:00:00+00:00",
-        "path": "",
-        "sha256": sha256,
-        "fetchLFS": False,
-        "fetchSubmodules": False,
-        "deepClone": False,
-        "leaveDotGit": False,
-    }
-    mocker.patch("subprocess.check_output", return_value=json.dumps(return_value).encode("utf-8"))
-    return GitSource(url, rev)
diff --git a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/test_nix.py b/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/test_nix.py
deleted file mode 100644
index 46e59f76..00000000
--- a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/test_nix.py
+++ /dev/null
@@ -1,32 +0,0 @@
-from update_vim_plugins.nix import GitSource, License, UrlSource
-
-
-def test_url_source(url_source: UrlSource, url: str, sha256: str):
-    assert url_source.url == url
-    assert url_source.sha256 == sha256
-
-
-def test_url_source_nix_expression(url_source: UrlSource, url: str, sha256: str):
-    assert url_source.get_nix_expression() == f'fetchurl {{ url = "{url}"; sha256 = "{sha256}"; }}'
-
-
-def test_git_source(git_source: GitSource, url: str, rev: str, sha256: str):
-    assert git_source.url == url
-    assert git_source.sha256 == sha256
-    assert git_source.rev == rev
-
-
-def test_git_source_nix_expression(git_source: GitSource, url: str, rev: str, sha256: str):
-    assert git_source.get_nix_expression() == f'fetchgit {{ url = "{url}"; rev = "{rev}"; sha256 = "{sha256}"; }}'
-
-
-def test_license_github():
-    github_license = "MIT"
-    license = License.from_spdx_id(github_license)
-    assert license == License.MIT
-
-
-def test_license_gitlab():
-    gitlab_license = "mit"
-    license = License.from_spdx_id(gitlab_license)
-    assert license == License.MIT
diff --git a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/test_plugin.py b/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/test_plugin.py
deleted file mode 100644
index 32377e24..00000000
--- a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/test_plugin.py
+++ /dev/null
@@ -1,144 +0,0 @@
-import json
-from typing import Callable
-
-import pytest
-from pytest_mock import MockFixture
-
-from update_vim_plugins.nix import License, UrlSource
-from update_vim_plugins.plugin import GitHubPlugin, VimPlugin
-from update_vim_plugins.spec import PluginSpec
-
-
-@pytest.fixture()
-def mock_source(sha256: str):
-    class MockSource:
-        def __init__(self, *args, **kwargs):
-            pass
-
-        def get_nix_expression(self):
-            return "src"
-
-    return MockSource()
-
-
-@pytest.fixture()
-def mock_plugin(mock_source):
-    class MockVimPlugin(VimPlugin):
-        def __init__(self):
-            self.name = "test"
-            self.version = "1.0.0"
-            self.source = mock_source
-            self.description = "No description"
-            self.homepage = "https://example.com"
-            self.license = License.UNKNOWN
-
-    return MockVimPlugin()
-
-
-def test_vim_plugin_nix_expression(mock_plugin):
-    assert (
-        mock_plugin.get_nix_expression()
-        == 'test = buildVimPluginFrom2Nix { pname = "test"; version = "1.0.0"; src = src; meta = with lib; { description = "No description"; homepage = "https://example.com"; license = with licenses; [  ]; }; };'
-    )
-
-
-class MockResponse:
-    def __init__(self, status_code: int, content: bytes):
-        self.status_code = status_code
-        self.content = content
-
-    def json(self):
-        return json.loads(self.content)
-
-
-def mock_request_get(repsonses: dict[str, MockResponse]):
-    respones_not_found = MockResponse(404, b'{"message": "Not Found"}')
-
-    def mock_get(url: str, *args, **kwargs):
-        return repsonses.get(url, respones_not_found)
-
-    return mock_get
-
-
-@pytest.fixture()
-def github_commits_response():
-    return MockResponse(
-        200,
-        json.dumps(
-            {
-                "sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e",
-                "commit": {
-                    "committer": {
-                        "date": "2011-04-14T16:00:49Z",
-                    },
-                },
-            }
-        ),
-    )
-
-
-@pytest.fixture()
-def github_get(github_commits_response: MockResponse):
-    repos_response = MockResponse(
-        200,
-        json.dumps(
-            {
-                "html_url": "https://github.com/octocat/Hello-World",
-                "description": "This your first repo!",
-                "fork": False,
-                "default_branch": "master",
-                "license": {
-                    "spdx_id": "MIT",
-                },
-            }
-        ),
-    )
-    responses = {
-        "https://api.github.com/repos/octocat/Hello-World": repos_response,
-        "https://api.github.com/repos/octocat/Hello-World/commits/master": github_commits_response,
-    }
-    return mock_request_get(responses)
-
-
-@pytest.fixture()
-def github_get_no_license(github_commits_response: MockResponse):
-    repos_response = MockResponse(
-        200,
-        json.dumps(
-            {
-                "html_url": "https://github.com/octocat/Hello-World",
-                "description": "This your first repo!",
-                "fork": False,
-                "default_branch": "master",
-            }
-        ),
-    )
-    responses = {
-        "https://api.github.com/repos/octocat/Hello-World": repos_response,
-        "https://api.github.com/repos/octocat/Hello-World/commits/master": github_commits_response,
-    }
-    return mock_request_get(responses)
-
-
-def test_github_plugin(mocker: MockFixture, github_get: Callable, url_source: UrlSource):
-    mocker.patch("requests.get", github_get)
-    url_source = mocker.patch("update_vim_plugins.nix.UrlSource", url_source)
-
-    spec = PluginSpec.from_spec("octocat/Hello-World")
-    plugin = GitHubPlugin(spec)
-
-    assert plugin.name == "Hello-World"
-    assert plugin.version == "2011-04-14"
-    assert plugin.description == "This your first repo!"
-    assert plugin.homepage == "https://github.com/octocat/Hello-World"
-    assert plugin.license == License.MIT
-
-
-def test_github_plugin_no_license(mocker: MockFixture, github_get_no_license: Callable, url_source: UrlSource):
-    mocker.patch("requests.get", github_get_no_license)
-    url_source = mocker.patch("update_vim_plugins.nix.UrlSource", url_source)
-
-    spec = PluginSpec.from_spec("octocat/Hello-World")
-    plugin = GitHubPlugin(spec)
-
-    assert plugin.license == License.UNKNOWN
diff --git a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/test_spec.py b/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/test_spec.py
deleted file mode 100644
index 2b9a1d24..00000000
--- a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/tests/test_spec.py
+++ /dev/null
@@ -1,136 +0,0 @@
-import pytest
-
-from update_vim_plugins.spec import PluginSpec, RepositoryHost
-
-
-@pytest.fixture()
-def owner():
-    return "owner"
-
-
-@pytest.fixture()
-def repo():
-    return "repo.nvim"
-
-
-@pytest.fixture()
-def branch():
-    return "main"
-
-
-@pytest.fixture()
-def name():
-    return "repo-nvim"
-
-
-@pytest.fixture()
-def license():
-    return "mit"
-
-
-def test_from_spec_simple(owner: str, repo: str):
-    vim_plugin = PluginSpec.from_spec(f"{owner}/{repo}")
-
-    assert vim_plugin.owner == owner
-    assert vim_plugin.repo == repo
-
-
-def test_from_spec_with_gitref(owner: str, repo: str, branch: str):
-    vim_plugin = PluginSpec.from_spec(f"{owner}/{repo}:{branch}")
-
-    assert vim_plugin.branch == branch
-
-
-def test_from_spec_with_name(owner: str, repo: str, name: str):
-    vim_plugin = PluginSpec.from_spec(f"{owner}/{repo}::{name}")
-
-    assert vim_plugin.name == name
-
-
-@pytest.mark.parametrize("host", RepositoryHost)
-def test_from_spec_with_repository_host(owner: str, repo: str, host: RepositoryHost):
-    vim_plugin = PluginSpec.from_spec(f"{host.value}:{owner}/{repo}")
-
-    assert vim_plugin.repository_host == host
-
-
-def test_from_spec_without_repository_host(owner: str, repo: str):
-    vim_plugin = PluginSpec.from_spec(f"{owner}/{repo}")
-
-    assert vim_plugin.repository_host == RepositoryHost.GITHUB
-
-
-def test_from_spec_complex(owner: str, repo: str, branch: str, name: str):
-    vim_plugin = PluginSpec.from_spec(f"gitlab:{owner}/{repo}:{branch}:{name}")
-
-    assert vim_plugin.repository_host == RepositoryHost.GITLAB
-    assert vim_plugin.owner == owner
-    assert vim_plugin.repo == repo
-    assert vim_plugin.branch == branch
-    assert vim_plugin.name == name
-
-
-def test_from_spec_invalid_spec():
-    with pytest.raises(ValueError):
-        PluginSpec.from_spec("invalid_spec")
-
-
-def test_to_spec_simple(owner: str, repo: str):
-    vim_plugin = PluginSpec(RepositoryHost.GITHUB, owner, repo)
-
-    assert vim_plugin.to_spec() == f"{owner}/{repo}"
-
-
-def test_to_spec_with_branch(owner: str, repo: str, branch: str):
-    vim_plugin = PluginSpec(RepositoryHost.GITHUB, owner, repo, branch=branch)
-    assert vim_plugin.to_spec() == f"{owner}/{repo}:{branch}"
-
-
-def test_to_spec_with_name(owner: str, repo: str, name: str):
-    vim_plugin = PluginSpec(RepositoryHost.GITHUB, owner, repo, name=name)
-
-    assert vim_plugin.to_spec() == f"{owner}/{repo}::{name}"
-
-
-@pytest.mark.parametrize("host", [RepositoryHost.GITLAB, RepositoryHost.SOURCEHUT])
-def test_to_spec_with_repository_host(host: RepositoryHost, owner: str, repo: str):
-    vim_plugin = PluginSpec(host, owner, repo)
-
-    assert vim_plugin.to_spec() == f"{host.value}:{owner}/{repo}"
-
-
-def test_to_spec_complex(owner: str, repo: str, branch: str, name: str, license: str):
-    vim_plugin = PluginSpec(RepositoryHost.GITLAB, owner, repo, branch=branch, name=name, license=license)
-
-    assert vim_plugin.to_spec() == f"gitlab:{owner}/{repo}:{branch}:{name}:{license}"
-
-
-def test_spec_equal(owner: str, repo: str):
-    vim_plugin = PluginSpec(RepositoryHost.GITHUB, owner, repo)
-    vim_plugin2 = PluginSpec(RepositoryHost.GITHUB, owner, repo)
-
-    assert vim_plugin == vim_plugin2
-
-
-def test_spec_not_equal_different_branch(owner: str, repo: str):
-    vim_plugin = PluginSpec(RepositoryHost.GITHUB, owner, repo)
-    vim_plugin2 = PluginSpec(RepositoryHost.GITHUB, owner, repo, branch="main")
-
-    assert vim_plugin != vim_plugin2
-
-
-def test_spec_not_equal_different_name(owner: str, repo: str):
-    vim_plugin = PluginSpec(RepositoryHost.GITHUB, owner, repo)
-    vim_plugin2 = PluginSpec(RepositoryHost.GITHUB, owner, repo, name="renamed")
-
-    assert vim_plugin != vim_plugin2
-
-
-def test_spec_equal_same_normalized_name(owner: str):
-    repo = "repo.nvim"
-    name = "repo-nvim"
-
-    vim_plugin = PluginSpec(RepositoryHost.GITHUB, owner, repo)
-    vim_plugin2 = PluginSpec(RepositoryHost.GITHUB, owner, repo, name=name)
-
-    assert vim_plugin == vim_plugin2
diff --git a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/update.py b/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/update.py
deleted file mode 100644
index 7eb3eeb4..00000000
--- a/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/update.py
+++ /dev/null
@@ -1,212 +0,0 @@
-import subprocess
-from random import shuffle
-from cleo.helpers import argument, option
-from cleo.commands.command import Command
-from concurrent.futures import ThreadPoolExecutor, as_completed
-
-from pprint import pprint
-
-from .plugin import plugin_from_spec
-
-from .helpers import read_manifest_to_spec, get_const
-from .helpers import JSON_FILE, PLUGINS_LIST_FILE, PKGS_FILE
-
-import json
-import jsonpickle
-
-jsonpickle.set_encoder_options("json", sort_keys=True)
-
-
-class UpdateCommand(Command):
-    name = "update"
-    description = "Generate nix module from input file"
-    arguments = [argument("plug_dir", description="Path to the plugin directory", optional=False)]
-    options = [
-        option("all", "a", description="Update all plugins. Else only update new plugins", flag=True),
-        option("dry-run", "d", description="Show which plugins would be updated", flag=True),
-    ]
-
-    def handle(self):
-        """Main command function"""
-
-        plug_dir = self.argument("plug_dir")
-        self.specs = read_manifest_to_spec(plug_dir)
-
-        if self.option("all"):
-            # update all plugins
-            spec_list = self.specs
-            known_plugins = []
-        else:
-            # filter plugins we already know
-            spec_list = self.specs
-
-            with open(get_const(JSON_FILE, plug_dir), "r") as json_file:
-                data = json.load(json_file)
-
-                known_specs = list(filter(lambda x: x.line in data, spec_list))
-                known_plugins = [jsonpickle.decode(data[x.line]) for x in known_specs]
-
-                spec_list = list(filter(lambda x: x.line not in data, spec_list))
-
-        if self.option("dry-run"):
-            self.line("<comment>These plugins would be updated</comment>")
-            pprint(spec_list)
-            self.line(f"<info>Total:</info> {len(spec_list)}")
-            exit(0)
-
-        processed_plugins, failed_plugins, failed_but_known = self.process_manifest(spec_list, plug_dir)
-
-        processed_plugins += known_plugins  # add plugins from .plugins.json
-        processed_plugins: list = sorted(set(processed_plugins))  # remove duplicates based only on source line
-
-        self.check_duplicates(processed_plugins)
-
-        if failed_plugins != []:
-            self.line("<error>Not processed:</error> The following plugins could not be updated")
-            for s, e in failed_plugins:
-                self.line(f" - {s!r} - {e}")
-
-        if failed_but_known != []:
-            self.line(
-                "<error>Not updated:</error> The following plugins could not be updated but an older version is known"
-            )
-            for s, e in failed_but_known:
-                self.line(f" - {s!r} - {e}")
-
-        # update plugin "database"
-        self.write_plugins_json(processed_plugins, plug_dir)
-
-        # generate output
-        self.write_plugins_nix(processed_plugins, plug_dir)
-
-        self.write_plugins_markdown(processed_plugins, plug_dir)
-
-        self.line("<comment>Done</comment>")
-
-    def write_plugins_markdown(self, plugins, plug_dir):
-        """Write the list of all plugins to PLUGINS_LIST_FILE in markdown"""
-
-        plugins.sort()
-
-        self.line("<info>Updating plugins.md</info>")
-
-        header = f" - Plugin count: {len(plugins)}\n\n| Repo | Last Update | Nix package name | Last checked |\n|:---|:---|:---|:---|\n"
-
-        with open(get_const(PLUGINS_LIST_FILE, plug_dir), "w") as file:
-            file.write(header)
-            for plugin in plugins:
-                file.write(f"{plugin.to_markdown()}\n")
-
-    def write_plugins_nix(self, plugins, plug_dir):
-        self.line("<info>Generating nix output</info>")
-
-        plugins.sort()
-
-        header = "{ lib, buildVimPlugin, fetchurl, fetchgit }: {"
-        footer = "}"
-
-        with open(get_const(PKGS_FILE, plug_dir), "w") as file:
-            file.write(header)
-            for plugin in plugins:
-                file.write(f"{plugin.to_nix()}\n")
-            file.write(footer)
-
-        self.line("<info>Formatting nix output</info>")
-
-        subprocess.run(
-            ["alejandra", get_const(PKGS_FILE, plug_dir)],
-            stdout=subprocess.DEVNULL,
-            stderr=subprocess.DEVNULL,
-        )
-
-    def write_plugins_json(self, plugins, plug_dir):
-        self.line("<info>Storing results in .plugins.json</info>")
-
-        plugins.sort()
-
-        with open(get_const(JSON_FILE, plug_dir), "r+") as json_file:
-            data = json.load(json_file)
-
-            for plugin in plugins:
-                data.update({f"{plugin.source_line}": plugin.to_json()})
-
-            json_file.seek(0)
-            json_file.write(json.dumps(data, indent=2, sort_keys=True))
-            json_file.truncate()
-
-    def check_duplicates(self, plugins):
-        """check for duplicates in proccesed_plugins"""
-        error = False
-        for i, plugin in enumerate(plugins):
-            for p in plugins[i + 1 :]:
-                if plugin.name == p.name:
-                    self.line(
-                        f"<error>Error:</error> The following two lines produce the same plugin name:\n - {plugin.source_line}\n - {p.source_line}\n -> {p.name}"
-                    )
-                    error = True
-
-        # We want to exit if the resulting nix file would be broken
-        # But we want to go through all plugins before we do so
-        if error:
-            exit(1)
-
-    def generate_plugin(self, spec, i, size, plug_dir):
-        debug_string = ""
-
-        processed_plugin = None
-        failed_but_known = None
-        failed_plugin = None
-        try:
-            debug_string += f" - <info>({i+1}/{size}) Processing</info> {spec!r}\n"
-            vim_plugin = plugin_from_spec(spec)
-            debug_string += f"   • <comment>Success</comment> {vim_plugin!r}\n"
-            processed_plugin = vim_plugin
-        except Exception as e:
-            debug_string += f"   • <error>Error:</error> Could not update <info>{spec.name}</info>. Keeping old values. Reason: {e}\n"
-            with open(get_const(JSON_FILE, plug_dir), "r") as json_file:
-                data = json.load(json_file)
-
-            plugin_json = data.get(spec.line)
-            if plugin_json:
-                vim_plugin = jsonpickle.decode(plugin_json)
-                processed_plugin = vim_plugin
-                failed_but_known = (vim_plugin, e)
-            else:
-                debug_string += f"   • <error>Error:</error> No entries for <info>{spec.name}</info> in '.plugins.json'. Skipping...\n"
-                failed_plugin = (spec, e)
-
-        self.line(debug_string.strip())
-
-        return processed_plugin, failed_plugin, failed_but_known
-
-    def process_manifest(self, spec_list, plug_dir):
-        """Read specs in 'spec_list' and generate plugins"""
-
-        size = len(spec_list)
-
-        # We have to assume that we will reach an api limit. Therefore
-        # we randomize the spec list to give every entry the same change to be updated and
-        # not favor those at the start of the list
-        shuffle(spec_list)
-
-        with ThreadPoolExecutor() as executor:
-            futures = [
-                executor.submit(self.generate_plugin, spec, i, size, plug_dir) for i, spec in enumerate(spec_list)
-            ]
-            results = [future.result() for future in as_completed(futures)]
-
-        processed_plugins = [r[0] for r in results]
-        failed_plugins = [r[1] for r in results]
-        failed_but_known = [r[2] for r in results]
-
-        processed_plugins = list(filter(lambda x: x is not None, processed_plugins))
-        failed_plugins = list(filter(lambda x: x is not None, failed_plugins))
-        failed_but_known = list(filter(lambda x: x is not None, failed_but_known))
-
-        processed_plugins.sort()
-        failed_plugins.sort()
-        failed_but_known.sort()
-
-        assert len(processed_plugins) == len(spec_list) - len(failed_plugins)
-
-        return processed_plugins, failed_plugins, failed_but_known
diff --git a/pkgs/by-name/vi/vimExtraPlugins/README.md b/pkgs/by-name/vi/vimExtraPlugins/README.md
deleted file mode 100644
index e8169951..00000000
--- a/pkgs/by-name/vi/vimExtraPlugins/README.md
+++ /dev/null
@@ -1,92 +0,0 @@
-# Fork
-
-All files in this repository where forked form [here](https://github.com/NixNeovim/NixNeovimPlugins) on commit `5010b91eb03696574c3c293f072a090618227e87`.
-Below the original README. They were licensed under the MIT license.
-
-# All vim plugins, ready to go
-
-This repo auto generates nix packages for vim/neovim plugins.
-Packages are automatically updated twice per week using a GitHub Actions.
-Plugins are fetched from the `manifest.txt` and [awesome-neovim][0] repo.
-
-This is a fork of [this repo](https://github.com/m15a/nixpkgs-vim-extra-plugins); however, we fetch all additions from the original repo, so we will never have less plugins.
-Further, the original deletes plugins that are available in the nixpkgs. We, instead, try to assemble a list of all available plugins.
-Therefore, to access plugins you will never have to search in two places.
-
-This repo can be used as a stand-alone, by adding it to your inputs.
-However, we recommend to use [NixNeovim](https://github.com/NixNeovim/NixNeovim) modules instead, and use this only when you need a plugins, which does not have a module, yet.
-
-## Available plugins
-
-The [plugins.md](plugins.md) contains an auto-generated list of all available plugins.
-
-## Usage
-
-- We recommend using [NixNeovim](https://github.com/NixNeovim/NixNeovim), and only access the plugins directly when they do not have a module in NixNeovim.
-
-However, you can also use this repo without NixNeovim:
-To access the plugins, you need to add the overlay.
-The overlay adds extra Vim plugins to `pkgs.vimExtraPlugins`.
-First, add this repo to your inputs:
-
-```
-inputs.nixneovimplugins.url = github:jooooscha/nixpkgs-vim-extra-plugins
-```
-
-Next, apply the provided overlay:
-
-```
-nixpkgs.overlays = [
-  inputs.nixneovimplugins.overlays.default
-];
-```
-
-Finally, you can add the packages to your vim/neovim config. For example you can use [NixNeovim](https://github.com/NixNeovim/Nixneovim) or you can add the plugins directly:
-
-```
- programs.neovim = {
-   plugins = [
-     pkgs.vimExtraPlugins.nvim-colorizer-lua
-   ];
- }
-```
-
-More info on using neovim with nix can be found here: [NixOS Neovim](https://nixos.wiki/wiki/Neovim)
-
-## Contribution
-
-### How to add a new plugin
-
-#### 1. Add the plugin to manifest.txt:
-
-```
-# Examples
-
-haringsrob/nvim_context_vt
-sourcehut:henriquehbr/ataraxis.lua
-gitlab:yorickpeterse/nvim-pqf
-williamboman/mason.nvim:45b9a4da776d9fb017960b3ac7241161fb7bc578
-foo/bar::baz                   --> renamed to baz
-foo/bar:dev                    --> using dev branch
-```
-
-Supported are Github (default), SourceHut, and GitLab.
-
-#### 2. Create a Pull Request
-
-- Create a pull request with the changed manifest.txt (and blacklist.txt if neccessary).
-- A GitHub action will check your contribution and generate all neccessary nix code for your new plugin. It will also take care of sorting and cleaning the manifest.txt
-- After all checks have passed, I will merge your change.
-
-I am happy for any contribution. :)
-
-### How to remove a new plugin
-
-Copy the entry from manifest.txt to blacklist.txt and create a PR.
-The GitHub Actions will do the rest, including removing the entry from manifest.txt
-
-## Credits
-
-This is originally based on work by [m15a](https://github.com/m15a/nixpkgs-vim-extra-plugins)
-
-[0]: https://github.com/rockerBOO/awesome-neovim
diff --git a/pkgs/by-name/vi/vimExtraPlugins/check.nix b/pkgs/by-name/vi/vimExtraPlugins/check.nix
deleted file mode 100644
index ad23e2c7..00000000
--- a/pkgs/by-name/vi/vimExtraPlugins/check.nix
+++ /dev/null
@@ -1,37 +0,0 @@
-{
-  pkgs,
-  lib,
-  ...
-}: let
-  # checks if a plugin has a license
-  hasLicense = _: pkg: let
-    warn = x: lib.warn x x;
-
-    msg =
-      if builtins.hasAttr "license" pkg.meta
-      then "${pkg.name} has license"
-      else warn "${pkg.name} has no license";
-
-    msg' = lib.replaceStrings [" "] ["-"] msg;
-  in
-    pkgs.runCommandNoCC msg' {} "echo : > $out ";
-
-  # function to check License for all packages
-  check-missing-licenses = let
-    buildInputs =
-      lib.mapAttrsToList
-      hasLicense
-      pkgs.vimExtraPlugins;
-  in
-    pkgs.runCommandNoCC
-    "check-missing-licenses"
-    {inherit buildInputs;}
-    "echo : > $out";
-in {
-  checks =
-    pkgs.vimExtraPlugins
-    // {
-      inherit check-missing-licenses;
-      inherit (pkgs) update-vim-plugins;
-    };
-}
diff --git a/pkgs/by-name/vi/vimExtraPlugins/overrides.nix b/pkgs/by-name/vi/vimExtraPlugins/overrides.nix
deleted file mode 100644
index e03a78b1..00000000
--- a/pkgs/by-name/vi/vimExtraPlugins/overrides.nix
+++ /dev/null
@@ -1,34 +0,0 @@
-final: prev: let
-  inherit (final) lib;
-
-  /*
-  * Mark broken packages here.
-  */
-  markBrokenPackages = self: super:
-    lib.mapAttrs (attrName: broken:
-      super.${attrName}.overrideAttrs (old: {
-        meta = old.meta // {inherit broken;};
-      }))
-    {
-      # <name> = true;
-    };
-
-  /*
-  * Add licenses if missing or incorrect in generated ./pkgs/vim-plugins.nix.
-  */
-  fixLicenses = self: super:
-    lib.mapAttrs (attrName: license:
-      super.${attrName}.overrideAttrs (old: {
-        meta = old.meta // {inherit license;};
-      })) (with lib.licenses; {
-      /*
-      * Example:
-      * plugin-name = [<licenses>]
-      */
-    });
-in {
-  vimExtraPlugins = prev.vimExtraPlugins.extend (lib.composeManyExtensions [
-    markBrokenPackages
-    fixLicenses
-  ]);
-}
diff --git a/pkgs/by-name/vi/vimExtraPlugins/package.nix b/pkgs/by-name/vi/vimExtraPlugins/package.nix
deleted file mode 100644
index e2e4a117..00000000
--- a/pkgs/by-name/vi/vimExtraPlugins/package.nix
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  lib,
-  fetchurl,
-  fetchgit,
-  vimUtils,
-}: let
-  origin = import ./plugins {
-    inherit
-      (vimUtils)
-      buildVimPlugin
-      ;
-    inherit
-      lib
-      fetchurl
-      fetchgit
-      ;
-  };
-in
-  origin
diff --git a/pkgs/by-name/vi/vimExtraPlugins/plugins/.plugins.json b/pkgs/by-name/vi/vimExtraPlugins/plugins/.plugins.json
deleted file mode 100644
index b080b069..00000000
--- a/pkgs/by-name/vi/vimExtraPlugins/plugins/.plugins.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "ThePrimeagen/harpoon:master": "{\"description\": \"\", \"homepage\": \"https://github.com/ThePrimeagen/harpoon\", \"license\": {\"py/reduce\": [{\"py/type\": \"update_vim_plugins.nix.License\"}, {\"py/tuple\": [\"mit\"]}]}, \"name\": \"harpoon\", \"owner\": \"ThePrimeagen\", \"py/object\": \"update_vim_plugins.plugin.GitHubPlugin\", \"source\": {\"py/object\": \"update_vim_plugins.nix.UrlSource\", \"sha256\": \"1pzj8wgzskv2pq9576clisjazcgi0f8w1bmsfy6c3lr69qdcpkwi\", \"url\": \"https://github.com/ThePrimeagen/harpoon/archive/1bc17e3e42ea3c46b33c0bbad6a880792692a1b3.tar.gz\"}, \"source_line\": \"ThePrimeagen/harpoon:master\", \"version\": {\"__reduce__\": [{\"py/type\": \"datetime.date\"}, [\"B+gIHQ==\"]], \"py/object\": \"datetime.date\"}}",
-  "akinsho/toggleterm.nvim": "{\"description\": \"A neovim lua plugin to help easily manage multiple terminal windows\", \"homepage\": \"https://github.com/akinsho/toggleterm.nvim\", \"license\": {\"py/reduce\": [{\"py/type\": \"update_vim_plugins.nix.License\"}, {\"py/tuple\": [\"gpl3Only\"]}]}, \"name\": \"toggleterm-nvim\", \"owner\": \"akinsho\", \"py/object\": \"update_vim_plugins.plugin.GitHubPlugin\", \"source\": {\"py/object\": \"update_vim_plugins.nix.UrlSource\", \"sha256\": \"0nx69q9597vy7lzvvh58fnjyin23ns6apmyp532sgf547bw7mld6\", \"url\": \"https://github.com/akinsho/toggleterm.nvim/archive/cbd041d91b90cd3c02df03fe6133208888f8e008.tar.gz\"}, \"source_line\": \"akinsho/toggleterm.nvim\", \"version\": {\"__reduce__\": [{\"py/type\": \"datetime.date\"}, [\"B+cMBg==\"]], \"py/object\": \"datetime.date\"}}",
-  "andrewferrier/debugprint.nvim": "{\"description\": \"Debugging in NeoVim the print() way!\", \"homepage\": \"https://github.com/andrewferrier/debugprint.nvim\", \"license\": {\"py/reduce\": [{\"py/type\": \"update_vim_plugins.nix.License\"}, {\"py/tuple\": [\"mit\"]}]}, \"name\": \"debugprint-nvim\", \"owner\": \"andrewferrier\", \"py/object\": \"update_vim_plugins.plugin.GitHubPlugin\", \"source\": {\"py/object\": \"update_vim_plugins.nix.UrlSource\", \"sha256\": \"06r1jhx7jd15q8wvnw0xqwk3bkx39pm4pbv70hf9ggd6zsnmsrmn\", \"url\": \"https://github.com/andrewferrier/debugprint.nvim/archive/54297dd0a4f318b279a1cb954e7714f3942df123.tar.gz\"}, \"source_line\": \"andrewferrier/debugprint.nvim\", \"version\": {\"__reduce__\": [{\"py/type\": \"datetime.date\"}, [\"B+gDHQ==\"]], \"py/object\": \"datetime.date\"}}",
-  "lmburns/lf.nvim": "{\"description\": \"Lf file manager for Neovim (in Lua)\", \"homepage\": \"https://github.com/lmburns/lf.nvim\", \"license\": {\"py/reduce\": [{\"py/type\": \"update_vim_plugins.nix.License\"}, {\"py/tuple\": [\"mit\"]}]}, \"name\": \"lf-nvim\", \"owner\": \"lmburns\", \"py/object\": \"update_vim_plugins.plugin.GitHubPlugin\", \"source\": {\"py/object\": \"update_vim_plugins.nix.UrlSource\", \"sha256\": \"1nwf90bnzqhlgs007gg6xpx0vf4r1d19586nld78ipi1ch7nz4px\", \"url\": \"https://github.com/lmburns/lf.nvim/archive/69ab1efcffee6928bf68ac9bd0c016464d9b2c8b.tar.gz\"}, \"source_line\": \"lmburns/lf.nvim\", \"version\": {\"__reduce__\": [{\"py/type\": \"datetime.date\"}, [\"B+cKAw==\"]], \"py/object\": \"datetime.date\"}}",
-  "nvim-telescope/telescope-bibtex.nvim": "{\"description\": \"A telescope.nvim extension to search and paste bibtex entries into your TeX files.\", \"homepage\": \"https://github.com/nvim-telescope/telescope-bibtex.nvim\", \"license\": {\"py/reduce\": [{\"py/type\": \"update_vim_plugins.nix.License\"}, {\"py/tuple\": [\"mit\"]}]}, \"name\": \"telescope-bibtex-nvim\", \"owner\": \"nvim-telescope\", \"py/object\": \"update_vim_plugins.plugin.GitHubPlugin\", \"source\": {\"py/object\": \"update_vim_plugins.nix.UrlSource\", \"sha256\": \"1sd6p8cvv3dckgrhc7grlyfcibjxhxbfyh0w7p5m4mdcazhy1kqs\", \"url\": \"https://github.com/nvim-telescope/telescope-bibtex.nvim/archive/289a6f86ebec06e8ae1590533b732b9981d84900.tar.gz\"}, \"source_line\": \"nvim-telescope/telescope-bibtex.nvim\", \"version\": {\"__reduce__\": [{\"py/type\": \"datetime.date\"}, [\"B+gDHA==\"]], \"py/object\": \"datetime.date\"}}"
-}
\ No newline at end of file
diff --git a/pkgs/by-name/vi/vimExtraPlugins/plugins/blacklist.txt b/pkgs/by-name/vi/vimExtraPlugins/plugins/blacklist.txt
deleted file mode 100644
index 8b137891..00000000
--- a/pkgs/by-name/vi/vimExtraPlugins/plugins/blacklist.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/pkgs/by-name/vi/vimExtraPlugins/plugins/default.nix b/pkgs/by-name/vi/vimExtraPlugins/plugins/default.nix
deleted file mode 100644
index 59c08c5e..00000000
--- a/pkgs/by-name/vi/vimExtraPlugins/plugins/default.nix
+++ /dev/null
@@ -1,39 +0,0 @@
-{
-  lib,
-  buildVimPlugin,
-  fetchurl,
-  fetchgit,
-}: {
-  /*
-  Generated from: lmburns/lf.nvim
-  */
-  lf-nvim = buildVimPlugin {
-    pname = "lf-nvim";
-    version = "2023-10-03";
-    src = fetchurl {
-      url = "https://github.com/lmburns/lf.nvim/archive/69ab1efcffee6928bf68ac9bd0c016464d9b2c8b.tar.gz";
-      sha256 = "1nwf90bnzqhlgs007gg6xpx0vf4r1d19586nld78ipi1ch7nz4px";
-    };
-    meta = with lib; {
-      description = "Lf file manager for Neovim (in Lua)";
-      homepage = "https://github.com/lmburns/lf.nvim";
-      license = with licenses; [mit];
-    };
-  };
-  /*
-  Generated from: nvim-telescope/telescope-bibtex.nvim
-  */
-  telescope-bibtex-nvim = buildVimPlugin {
-    pname = "telescope-bibtex-nvim";
-    version = "2024-03-28";
-    src = fetchurl {
-      url = "https://github.com/nvim-telescope/telescope-bibtex.nvim/archive/289a6f86ebec06e8ae1590533b732b9981d84900.tar.gz";
-      sha256 = "1sd6p8cvv3dckgrhc7grlyfcibjxhxbfyh0w7p5m4mdcazhy1kqs";
-    };
-    meta = with lib; {
-      description = "A telescope.nvim extension to search and paste bibtex entries into your TeX files.";
-      homepage = "https://github.com/nvim-telescope/telescope-bibtex.nvim";
-      license = with licenses; [mit];
-    };
-  };
-}
diff --git a/pkgs/by-name/vi/vimExtraPlugins/plugins/manifest.txt b/pkgs/by-name/vi/vimExtraPlugins/plugins/manifest.txt
deleted file mode 100644
index 02333b9a..00000000
--- a/pkgs/by-name/vi/vimExtraPlugins/plugins/manifest.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-lmburns/lf.nvim
-nvim-telescope/telescope-bibtex.nvim
diff --git a/pkgs/by-name/vi/vimExtraPlugins/plugins/plugins.md b/pkgs/by-name/vi/vimExtraPlugins/plugins/plugins.md
deleted file mode 100644
index dd09bd6b..00000000
--- a/pkgs/by-name/vi/vimExtraPlugins/plugins/plugins.md
+++ /dev/null
@@ -1,6 +0,0 @@
-- Plugin count: 2
-
-| Repo | Last Update | Nix package name | Last checked |
-|:---|:---|:---|:---|
-| [lmburns/lf.nvim](https://github.com/lmburns/lf.nvim) | 2023-10-03 | `lf-nvim` | 2024-12-30 |
-| [nvim-telescope/telescope-bibtex.nvim](https://github.com/nvim-telescope/telescope-bibtex.nvim) | 2024-03-28 | `telescope-bibtex-nvim` | 2024-12-30 |
diff --git a/pkgs/by-name/vi/vimExtraPlugins/plugins/whitelist.txt b/pkgs/by-name/vi/vimExtraPlugins/plugins/whitelist.txt
deleted file mode 100644
index e69de29b..00000000
--- a/pkgs/by-name/vi/vimExtraPlugins/plugins/whitelist.txt
+++ /dev/null
diff --git a/pkgs/by-name/vi/vimExtraPlugins/update.sh b/pkgs/by-name/vi/vimExtraPlugins/update.sh
deleted file mode 100755
index 6a0d3452..00000000
--- a/pkgs/by-name/vi/vimExtraPlugins/update.sh
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env sh
-
-BASE_DIR="$(readlink -f "$(dirname "$0")/plugins")"
-
-# Fetch plugins
-cd "$BASE_DIR" || (echo "BUG: No '$BASE_DIR'" && exit 1)
-
-# Cleanup manifest
-sort -o "$BASE_DIR/manifest.txt" "$BASE_DIR/manifest.txt"
-sort -o "$BASE_DIR/blacklist.txt" "$BASE_DIR/blacklist.txt"
-## Remove all plugins, which are on the blacklist
-# The same file is read and written to
-# shellcheck disable=SC2005
-echo "$(comm -23 "$BASE_DIR/manifest.txt" "$BASE_DIR/blacklist.txt")" >"$BASE_DIR/manifest.txt"
-
-# Backup vim-plugins.nix
-mv "$BASE_DIR/default.nix" "$BASE_DIR/default.nix.bak"
-echo "{...} : {}" >"$BASE_DIR/default.nix"
-
-# Generate derivations for new plugins (this binary is provided by the dev-environment)
-update-vim-plugins cleanup "$BASE_DIR"
-
-# Restore vim-plugins.nix
-mv "$BASE_DIR/default.nix.bak" "$BASE_DIR/default.nix"
-
-# Update new plugins
-update-vim-plugins update "$BASE_DIR" --all
diff --git a/pkgs/by-name/vi/virsh-del/package.nix b/pkgs/by-name/vi/virsh-del/package.nix
deleted file mode 100644
index 3f27e2be..00000000
--- a/pkgs/by-name/vi/virsh-del/package.nix
+++ /dev/null
@@ -1,13 +0,0 @@
-{
-  sysLib,
-  libvirt,
-}:
-sysLib.writeShellScript {
-  name = "virsh-del";
-  src = ./virsh-del.sh;
-  generateCompletions = false;
-  keepPath = false;
-  dependencies = [
-    libvirt
-  ];
-}
diff --git a/pkgs/by-name/vi/virsh-del/virsh-del.sh b/pkgs/by-name/vi/virsh-del/virsh-del.sh
deleted file mode 100755
index c3de5484..00000000
--- a/pkgs/by-name/vi/virsh-del/virsh-del.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#! /usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
-virsh destroy "$1"
-virsh undefine "$1" --nvram
-virsh vol-delete --pool default "$1".qcow2
-
-# vim: ft=sh
diff --git a/pkgs/by-name/yt/yt/package.nix b/pkgs/by-name/yt/yt/package.nix
index 90a70473..3c780374 100644
--- a/pkgs/by-name/yt/yt/package.nix
+++ b/pkgs/by-name/yt/yt/package.nix
@@ -10,18 +10,18 @@
   python3,
   rustPlatform,
   sqlite,
-  blake3,
+  fd,
 }: let
-  version = "1.4.1";
+  version = "1.5.0";
 
   src = fetchgit {
     url = "https://git.foss-syndicate.org/bpeetz/clients/yt";
     rev = "v${version}";
-    hash = "sha256-Zuc3hrhvYdz2ktQhfMcLX7E5W/ZneMMLJ6+CoJ/JZMs=";
+    hash = "sha256-P/mpF2KPjoC7XZ6juJubeGEHhL2ajdOeiuIEb5sYrS0=";
   };
 
   buildInputs = [
-    (python3.withPackages (ps: [ps.yt-dlp blake3]))
+    (python3.withPackages (ps: [ps.yt-dlp]))
     mpv-unwrapped.dev
     ffmpeg
   ];
@@ -33,6 +33,7 @@ in
     nativeBuildInputs = [
       makeWrapper
       sqlite
+      fd
     ];
 
     passthru.updateScript = gitUpdater {rev-prefix = "v";};
@@ -46,7 +47,7 @@ in
       PYO3_PYTHON = lib.getExe (python3.withPackages (ps: [ps.yt-dlp]));
 
       C_INCLUDE_PATH = "${glibc.dev}/include";
-      DATABASE_URL = "sqlite://target/database.sqlite";
+      DATABASE_URL = "sqlite://target/database.sqlx";
       LIBCLANG_INCLUDE_PATH = "${llvmPackages_latest.clang-unwrapped.lib}/lib/clang/${clang_version}/include";
       LIBCLANG_PATH = "${llvmPackages_latest.clang-unwrapped.lib}/lib/libclang.so";
     };
@@ -55,19 +56,14 @@ in
     doCheck = false;
 
     prePatch = ''
-      echo "$PATH"
       bash ./scripts/mkdb.sh
     '';
 
-    cargoHash = "sha256-QIAZb8twLxLm3TJOtb++pTWz98v49pt13auAEAeYFSk=";
-
-    postBuild = ''
-      install -m755 ./python_update/raw_update.py -D "$out/bin/raw_update.py"
-      patchShebangs "$out/bin/raw_update.py"
-    '';
+    useFetchCargoVendor = true;
+    cargoHash = "sha256-0XTbC+mFsczUFXqAtiQ+BIsCfKilerhlzE41pzVjLVs=";
 
     postInstall = ''
       wrapProgram $out/bin/yt \
-        --prefix PATH : ${lib.makeBinPath buildInputs}:$out/bin
+        --prefix PATH : ${lib.makeBinPath buildInputs}
     '';
   }
diff --git a/pkgs/by-name/yt/yti/package.nix b/pkgs/by-name/yt/yti/package.nix
deleted file mode 100644
index 5a39512a..00000000
--- a/pkgs/by-name/yt/yti/package.nix
+++ /dev/null
@@ -1,17 +0,0 @@
-{
-  sysLib,
-  gawk,
-  expect,
-  yt-dlp,
-}:
-sysLib.writeShellScript {
-  name = "yti";
-  src = ./yti.sh;
-  generateCompletions = false;
-  keepPath = false;
-  dependencies = [
-    gawk
-    expect
-    yt-dlp
-  ];
-}
diff --git a/pkgs/by-name/yt/yti/yti.sh b/pkgs/by-name/yt/yti/yti.sh
deleted file mode 100755
index a69ffa74..00000000
--- a/pkgs/by-name/yt/yti/yti.sh
+++ /dev/null
@@ -1,33 +0,0 @@
-#! /usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
-DOWN_DIR=/home/soispha/media/music/down/youtube
-
-tmp=$(mktmp)
-config=$(mktmp)
-
-for e in "$DOWN_DIR"/*.opus; do echo "$e" >>"$tmp"; done
-[ "$(wc -l "$tmp" | awk '{print $1}')" -gt 2 ] && die "something is already downloaded"
-
-cat <<EO >"$config"
---paths home:"$DOWN_DIR"
-#--output %(fulltitle)
---restrict-filenames
---no-overwrites
---no-write-info-json
---clean-info-json
---prefer-free-formats
-#--format mp3
---extract-audio
---audio-quality 0
---audio-format best
-EO
-
-rm "$DOWN_DIR/yt-dlp.log"
-cd "$DOWN_DIR" || die "BUG: no $DOWN_DIR"
-
-unbuffer yt-dlp --config-location "$config" "$1" | tee "$DOWN_DIR/yt-dlp.log"
-
-# vim: ft=sh
diff --git a/tests/by-name/nv/nvim-neorg/test.desc b/tests/by-name/nv/nvim-neorg/test.desc
index bd7b7312..bd1e8f49 100644
--- a/tests/by-name/nv/nvim-neorg/test.desc
+++ b/tests/by-name/nv/nvim-neorg/test.desc
@@ -61,7 +61,7 @@ Sleep 0.5
 
 
 Type 10t
-Sleep 0.5
+Sleep 1.0
 
 Expect ^11\s*◉ Some other content$
 
diff --git a/tests/default.nix b/tests/default.nix
index c36a5906..af004feb 100644
--- a/tests/default.nix
+++ b/tests/default.nix
@@ -6,6 +6,8 @@
   nixpkgs_as_input,
   sysLib,
   extraModules,
+  nixpkgs_open_prs,
+  system,
 }: let
   mkTest = import ./infrastructure {
     inherit
@@ -15,6 +17,8 @@
       myPkgs
       extraModules
       sysLib
+      nixpkgs_open_prs
+      system
       ;
   };
 
diff --git a/tests/infrastructure/default.nix b/tests/infrastructure/default.nix
index e0ad6889..9e6ab08c 100644
--- a/tests/infrastructure/default.nix
+++ b/tests/infrastructure/default.nix
@@ -5,7 +5,8 @@
   nixos-lib,
   extraModules,
   sysLib,
-  ...
+  nixpkgs_open_prs,
+  system,
 }: {
   name,
   configuration,
@@ -22,7 +23,12 @@ nixos-lib.runTest {
 
   node = {
     specialArgs = {
-      inherit myPkgs sysLib;
+      inherit
+        myPkgs
+        sysLib
+        nixpkgs_open_prs
+        system
+        ;
     };
     # Use the nixpkgs as constructed by the `nixpkgs.*` options
     pkgs = null;
diff --git a/update.sh b/update.sh
index 77cb9482..b4408bea 100755
--- a/update.sh
+++ b/update.sh
@@ -10,7 +10,7 @@ __update_sh_run() {
     unset __update_sh_command
 }
 
-__update_sh_run ./modules/home.legacy/conf/firefox/scripts/update_extensions.sh "$@"
+__update_sh_run ./modules/by-name/fi/firefox/update_extensions.sh "$@"
 __update_sh_run ./pkgs/update_pkgs.sh "$@"
 
 echo "Also update out-of tree dependencies, like yt!" 2>&1