about summary refs log tree commit diff stats
path: root/pkgs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--pkgs/by-name/at/atuin-dvorak/package.nix9
-rw-r--r--pkgs/by-name/at/atuin-dvorak/set-dvorak-keybindings.patch.license9
-rwxr-xr-xpkgs/by-name/au/aumo/aumo.sh57
-rw-r--r--pkgs/by-name/au/aumo/package.nix27
-rwxr-xr-xpkgs/by-name/ba/battery/battery.sh11
-rw-r--r--pkgs/by-name/ba/battery/package.nix25
-rw-r--r--pkgs/by-name/be/beetsExtraPlugins/package.nix9
-rw-r--r--pkgs/by-name/be/beetsExtraPlugins/xtractor.nix9
-rwxr-xr-xpkgs/by-name/br/brightness/brightness.sh38
-rw-r--r--pkgs/by-name/br/brightness/package.nix29
-rwxr-xr-xpkgs/by-name/co/con2pdf/con2pdf.sh29
-rw-r--r--pkgs/by-name/co/con2pdf/package.nix26
-rw-r--r--pkgs/by-name/ct/ctpv-64-types/allow-up-to-64-types.patch.license9
-rw-r--r--pkgs/by-name/ct/ctpv-64-types/package.nix9
-rwxr-xr-xpkgs/by-name/fd/fd_list/fd_list.sh40
-rw-r--r--pkgs/by-name/fd/fd_list/package.nix28
-rwxr-xr-xpkgs/by-name/fu/fupdate-flake/fupdate-flake.sh194
-rw-r--r--pkgs/by-name/fu/fupdate-flake/package.nix37
-rwxr-xr-xpkgs/by-name/fu/fupdate-sys/fupdate-sys.sh168
-rw-r--r--pkgs/by-name/fu/fupdate-sys/package.nix38
-rw-r--r--pkgs/by-name/fu/fupdate/.envrc13
-rw-r--r--pkgs/by-name/fu/fupdate/.gitignore12
-rw-r--r--pkgs/by-name/fu/fupdate/Cargo.lock310
-rw-r--r--pkgs/by-name/fu/fupdate/Cargo.toml81
-rw-r--r--pkgs/by-name/fu/fupdate/flake.lock27
-rw-r--r--pkgs/by-name/fu/fupdate/flake.lock.license9
-rw-r--r--pkgs/by-name/fu/fupdate/flake.nix34
-rw-r--r--pkgs/by-name/fu/fupdate/fupdate.1.md70
-rwxr-xr-xpkgs/by-name/fu/fupdate/fupdate.sh197
-rw-r--r--pkgs/by-name/fu/fupdate/package.nix64
-rw-r--r--pkgs/by-name/fu/fupdate/src/cli.rs56
-rw-r--r--pkgs/by-name/fu/fupdate/src/main.rs52
-rwxr-xr-xpkgs/by-name/fu/fupdate/update.sh14
-rw-r--r--pkgs/by-name/ge/generate_moz_extension/.envrc11
-rw-r--r--pkgs/by-name/ge/generate_moz_extension/.gitignore10
-rw-r--r--pkgs/by-name/ge/generate_moz_extension/Cargo.lock337
-rw-r--r--pkgs/by-name/ge/generate_moz_extension/Cargo.toml16
-rwxr-xr-xpkgs/by-name/ge/generate_moz_extension/examples/generate_extensions.sh10
-rw-r--r--pkgs/by-name/ge/generate_moz_extension/flake.lock18
-rw-r--r--pkgs/by-name/ge/generate_moz_extension/flake.lock.license9
-rw-r--r--pkgs/by-name/ge/generate_moz_extension/flake.nix9
-rw-r--r--pkgs/by-name/ge/generate_moz_extension/package.nix9
-rw-r--r--pkgs/by-name/ge/generate_moz_extension/res/generate_extensions.py11
-rw-r--r--pkgs/by-name/ge/generate_moz_extension/res/reference.json.license9
-rw-r--r--pkgs/by-name/ge/generate_moz_extension/res/test.json.license9
-rw-r--r--pkgs/by-name/ge/generate_moz_extension/src/main.rs10
-rw-r--r--pkgs/by-name/ge/generate_moz_extension/src/types.rs10
-rwxr-xr-xpkgs/by-name/ge/generate_moz_extension/update.sh10
-rwxr-xr-xpkgs/by-name/gi/git-cm/git-cm.sh13
-rw-r--r--pkgs/by-name/gi/git-cm/package.nix23
-rwxr-xr-xpkgs/by-name/gi/git-edit-index/git-edit-index.sh61
-rw-r--r--pkgs/by-name/gi/git-edit-index/package.nix24
-rwxr-xr-xpkgs/by-name/hi/hibernate/hibernate.sh13
-rw-r--r--pkgs/by-name/hi/hibernate/package.nix20
-rw-r--r--pkgs/by-name/i3/i3bar-river-patched/0001-revert-use-std-io-pipe.patch67
-rw-r--r--pkgs/by-name/i3/i3bar-river-patched/0002-feat-crate-bar-Put-the-leftmost-block-in-the-middle-.patch111
-rw-r--r--pkgs/by-name/i3/i3bar-river-patched/package.nix66
-rw-r--r--pkgs/by-name/i3/i3status-rust-patched/package.nix34
-rw-r--r--pkgs/by-name/lf/lf-make-map/.envrc11
-rw-r--r--pkgs/by-name/lf/lf-make-map/.gitignore10
-rw-r--r--pkgs/by-name/lf/lf-make-map/Cargo.lock145
-rw-r--r--pkgs/by-name/lf/lf-make-map/Cargo.toml17
-rw-r--r--pkgs/by-name/lf/lf-make-map/README.md12
-rw-r--r--pkgs/by-name/lf/lf-make-map/flake.lock120
-rw-r--r--pkgs/by-name/lf/lf-make-map/flake.lock.license9
-rw-r--r--pkgs/by-name/lf/lf-make-map/flake.nix137
-rw-r--r--pkgs/by-name/lf/lf-make-map/package.nix9
-rw-r--r--pkgs/by-name/lf/lf-make-map/src/cli.rs10
-rw-r--r--pkgs/by-name/lf/lf-make-map/src/main.rs70
-rw-r--r--pkgs/by-name/lf/lf-make-map/src/mapping/lf_mapping.rs35
-rw-r--r--pkgs/by-name/lf/lf-make-map/src/mapping/map_key.rs274
-rw-r--r--pkgs/by-name/lf/lf-make-map/src/mapping/map_tree/display.rs91
-rw-r--r--pkgs/by-name/lf/lf-make-map/src/mapping/map_tree/iterator.rs53
-rw-r--r--pkgs/by-name/lf/lf-make-map/src/mapping/map_tree/lf_mapping.rs24
-rw-r--r--pkgs/by-name/lf/lf-make-map/src/mapping/map_tree/mod.rs402
-rw-r--r--pkgs/by-name/lf/lf-make-map/src/mapping/mod.rs337
-rwxr-xr-xpkgs/by-name/lf/lf-make-map/tests/base.sh25
-rwxr-xr-xpkgs/by-name/lf/lf-make-map/tests/cases/child_insert/test.sh27
-rw-r--r--pkgs/by-name/lf/lf-make-map/tests/cases/simple/output.old46
-rw-r--r--pkgs/by-name/lf/lf-make-map/tests/cases/simple/output.old.license9
-rwxr-xr-xpkgs/by-name/lf/lf-make-map/tests/cases/simple/test.sh49
-rwxr-xr-xpkgs/by-name/lf/lf-make-map/update.sh10
-rwxr-xr-xpkgs/by-name/ll/ll/ll.sh19
-rw-r--r--pkgs/by-name/ll/ll/package.nix9
-rwxr-xr-xpkgs/by-name/lm/lm/lm.sh12
-rw-r--r--pkgs/by-name/lm/lm/package.nix9
-rwxr-xr-xpkgs/by-name/lo/lock/lock.sh10
-rw-r--r--pkgs/by-name/lo/lock/package.nix9
-rwxr-xr-xpkgs/by-name/mp/mpp-beetrm/mpp-beetrm.sh11
-rw-r--r--pkgs/by-name/mp/mpp-beetrm/package.nix21
-rwxr-xr-xpkgs/by-name/mp/mpp-lyrics/mpp-lyrics.sh22
-rw-r--r--pkgs/by-name/mp/mpp-lyrics/package.nix26
-rwxr-xr-xpkgs/by-name/mp/mpp-searchadd/mpp-searchadd.sh18
-rw-r--r--pkgs/by-name/mp/mpp-searchadd/package.nix21
-rwxr-xr-xpkgs/by-name/mp/mpp/mpp.sh13
-rw-r--r--pkgs/by-name/mp/mpp/package.nix41
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/.envrc10
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/.gitignore10
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/Cargo.lock45
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/Cargo.toml16
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/TODO.license9
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/contrib/example.json.license9
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/flake.lock6
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/flake.lock.license9
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/flake.nix9
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/package.nix9
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/src/cli.rs10
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/src/key_map/commands.rs10
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/src/key_map/mod.rs10
-rw-r--r--pkgs/by-name/ri/river-mk-keymap/src/main.rs10
-rwxr-xr-xpkgs/by-name/ri/river-mk-keymap/update.sh13
-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.nix9
-rwxr-xr-xpkgs/by-name/sc/screenshot_persistent/screenshot_persistent.sh10
-rw-r--r--pkgs/by-name/sc/screenshot_temporary/package.nix21
-rwxr-xr-xpkgs/by-name/sc/screenshot_temporary/screenshot_temporary.sh11
-rw-r--r--pkgs/by-name/sn/snap-sync-forked/package.nix36
-rwxr-xr-xpkgs/by-name/sn/snap-sync-forked/snap-sync-forked.sh534
-rw-r--r--pkgs/by-name/st/stamp/package.nix29
-rwxr-xr-xpkgs/by-name/st/stamp/stamp.sh16
-rw-r--r--pkgs/by-name/tr/tree-sitter-yts/package.nix9
-rw-r--r--pkgs/by-name/ts/tskm/.envrc11
-rw-r--r--pkgs/by-name/ts/tskm/.gitignore10
-rw-r--r--pkgs/by-name/ts/tskm/Cargo.lock357
-rw-r--r--pkgs/by-name/ts/tskm/Cargo.toml43
-rw-r--r--pkgs/by-name/ts/tskm/build.rs52
-rw-r--r--pkgs/by-name/ts/tskm/flake.lock6
-rw-r--r--pkgs/by-name/ts/tskm/flake.lock.license9
-rw-r--r--pkgs/by-name/ts/tskm/flake.nix9
-rw-r--r--pkgs/by-name/ts/tskm/package.nix19
-rw-r--r--pkgs/by-name/ts/tskm/src/cli.rs179
-rw-r--r--pkgs/by-name/ts/tskm/src/interface/input/handle.rs32
-rw-r--r--pkgs/by-name/ts/tskm/src/interface/input/mod.rs179
-rw-r--r--pkgs/by-name/ts/tskm/src/interface/mod.rs10
-rw-r--r--pkgs/by-name/ts/tskm/src/interface/neorg/handle.rs26
-rw-r--r--pkgs/by-name/ts/tskm/src/interface/neorg/mod.rs21
-rw-r--r--pkgs/by-name/ts/tskm/src/interface/open/handle.rs78
-rw-r--r--pkgs/by-name/ts/tskm/src/interface/open/mod.rs10
-rw-r--r--pkgs/by-name/ts/tskm/src/interface/project/handle.rs22
-rw-r--r--pkgs/by-name/ts/tskm/src/interface/project/mod.rs10
-rw-r--r--pkgs/by-name/ts/tskm/src/main.rs53
-rw-r--r--pkgs/by-name/ts/tskm/src/rofi/mod.rs10
-rw-r--r--pkgs/by-name/ts/tskm/src/state.rs12
-rw-r--r--pkgs/by-name/ts/tskm/src/task/mod.rs24
-rwxr-xr-xpkgs/by-name/ts/tskm/update.sh13
-rw-r--r--pkgs/by-name/up/update-sys/package.nix29
-rwxr-xr-xpkgs/by-name/up/update-sys/update-sys.sh85
-rw-r--r--pkgs/by-name/ya/yambar-modules/.envrc2
-rw-r--r--pkgs/by-name/ya/yambar-modules/.gitignore1
-rw-r--r--pkgs/by-name/ya/yambar-modules/Cargo.lock131
-rw-r--r--pkgs/by-name/ya/yambar-modules/Cargo.toml9
-rw-r--r--pkgs/by-name/ya/yambar-modules/flake.lock61
-rw-r--r--pkgs/by-name/ya/yambar-modules/flake.nix32
-rw-r--r--pkgs/by-name/ya/yambar-modules/package.nix14
-rw-r--r--pkgs/by-name/ya/yambar-modules/src/cpu.rs21
-rw-r--r--pkgs/by-name/ya/yambar-modules/src/main.rs26
-rw-r--r--pkgs/by-name/ya/yambar-modules/src/memory.rs29
-rw-r--r--pkgs/by-name/yt/yt/package.nix9
-rw-r--r--pkgs/default.nix26
-rwxr-xr-xpkgs/update_pkgs.sh10
161 files changed, 4182 insertions, 3215 deletions
diff --git a/pkgs/by-name/at/atuin-dvorak/package.nix b/pkgs/by-name/at/atuin-dvorak/package.nix
index c651eb75..d3f92961 100644
--- a/pkgs/by-name/at/atuin-dvorak/package.nix
+++ b/pkgs/by-name/at/atuin-dvorak/package.nix
@@ -1,3 +1,12 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 {atuin}:
 atuin.overrideAttrs (finalAttrs: previousAttrs: {
   pname = previousAttrs.pname + "-dvorak";
diff --git a/pkgs/by-name/at/atuin-dvorak/set-dvorak-keybindings.patch.license b/pkgs/by-name/at/atuin-dvorak/set-dvorak-keybindings.patch.license
new file mode 100644
index 00000000..eae6a84c
--- /dev/null
+++ b/pkgs/by-name/at/atuin-dvorak/set-dvorak-keybindings.patch.license
@@ -0,0 +1,9 @@
+nixos-config - My current NixOS configuration
+
+Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+SPDX-License-Identifier: GPL-3.0-or-later
+
+This file is part of my nixos-config.
+
+You should have received a copy of the License along with this program.
+If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
diff --git a/pkgs/by-name/au/aumo/aumo.sh b/pkgs/by-name/au/aumo/aumo.sh
index 84d39deb..dba5ef63 100755
--- a/pkgs/by-name/au/aumo/aumo.sh
+++ b/pkgs/by-name/au/aumo/aumo.sh
@@ -1,28 +1,73 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+NAME="aumo"
+
+error() {
+    printf "\033[1;91m==> ERROR:\033[0m \033[1;93m%s\033[0m\n" "$*" >&2
+}
+
+die() {
+    error "$1"
+    exit "${2-1}"
+}
+
+usage() {
+    echo "Usage: $NAME mount|unmount"
+}
+
+get_mounted_labels() {
+    findmnt --output label --json | jq '.filesystems | map(.label) | sort | unique | map(select(. != null))'
+}
+get_unmounted_labels() {
+    first=true
+
+    find /dev/disk/by-label -printf "%P\n" | while read -r label; do
+        if ! get_mounted_labels | jq 'join("\n")' --raw-output | grep "$label" --quiet; then
+            if [ "$first" = "true" ]; then
+                first=false
+            else
+                printf "|"
+            fi
+            printf "%s" "$label"
+        fi
+    done
+}
 
 unmounting() {
-    disk_name="$(find /dev/disk/by-label -type l -printf "%P|" | rofi -sep "|" -dmenu -p "Select disk to mount")"
+    disk_name="$(get_mounted_labels | jq 'join("|")' --join-output | rofi -sep "|" -dmenu -p "Select disk to unmount")"
 
     udisksctl unmount --block-device "/dev/disk/by-label/$disk_name"
 }
 
 mounting() {
-    disk_name="$(find /dev/disk/by-label -type l -printf "%P|" | rofi -sep "|" -dmenu -p "Select disk to mount")"
+    disk_name="$(get_unmounted_labels | rofi -sep "|" -dmenu -p "Select disk to mount")"
 
     udisksctl mount --block-device "/dev/disk/by-label/$disk_name"
 }
 
-case "$1" in
+case "${1-unset}" in
 "mount")
     mounting
     ;;
 "unmount" | "umount")
     unmounting
     ;;
+"unset")
+    usage
+    die "You need to provide one argument."
+    ;;
 *)
-    die "Usage: $NAME mount|unmount"
+    usage
+    die "Unknown command: '$1'"
     ;;
 esac
diff --git a/pkgs/by-name/au/aumo/package.nix b/pkgs/by-name/au/aumo/package.nix
index 20054bb5..8132a15a 100644
--- a/pkgs/by-name/au/aumo/package.nix
+++ b/pkgs/by-name/au/aumo/package.nix
@@ -1,17 +1,32 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 {
-  sysLib,
+  writeShellApplication,
+  # Dependencies
   udisks,
   findutils,
   rofi,
+  jq,
+  gnugrep,
+  util-linux,
 }:
-sysLib.writeShellScript {
+writeShellApplication {
   name = "aumo";
-  src = ./aumo.sh;
-  generateCompletions = false;
-  keepPath = false;
-  dependencies = [
+  text = builtins.readFile ./aumo.sh;
+  inheritPath = false;
+  runtimeInputs = [
     udisks
     findutils
     rofi
+    jq
+    gnugrep
+    util-linux # for findmnt
   ];
 }
diff --git a/pkgs/by-name/ba/battery/battery.sh b/pkgs/by-name/ba/battery/battery.sh
index e650ba5d..5ccb303d 100755
--- a/pkgs/by-name/ba/battery/battery.sh
+++ b/pkgs/by-name/ba/battery/battery.sh
@@ -1,7 +1,14 @@
 #!/usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 
 capacity="$(cat /sys/class/power_supply/BAT0/capacity)"
 status="$(cat /sys/class/power_supply/BAT0/status)"
diff --git a/pkgs/by-name/ba/battery/package.nix b/pkgs/by-name/ba/battery/package.nix
index 9c0e194b..560ec59b 100644
--- a/pkgs/by-name/ba/battery/package.nix
+++ b/pkgs/by-name/ba/battery/package.nix
@@ -1,9 +1,20 @@
-{sysLib}:
-sysLib.writeShellScript {
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+{
+  writeShellApplication,
+  # Dependencies
+  coreutils,
+}:
+writeShellApplication {
   name = "battery";
-  src = ./battery.sh;
-  generateCompletions = false;
-  keepPath = false;
-  dependencies = [
-  ];
+  text = builtins.readFile ./battery.sh;
+  inheritPath = false;
+  runtimeInputs = [coreutils];
 }
diff --git a/pkgs/by-name/be/beetsExtraPlugins/package.nix b/pkgs/by-name/be/beetsExtraPlugins/package.nix
index f019922e..b310715b 100644
--- a/pkgs/by-name/be/beetsExtraPlugins/package.nix
+++ b/pkgs/by-name/be/beetsExtraPlugins/package.nix
@@ -1,3 +1,12 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 {...}: {
   # 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 17981cdb..c6b942fd 100644
--- a/pkgs/by-name/be/beetsExtraPlugins/xtractor.nix
+++ b/pkgs/by-name/be/beetsExtraPlugins/xtractor.nix
@@ -1,3 +1,12 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 {
   lib,
   fetchFromGitHub,
diff --git a/pkgs/by-name/br/brightness/brightness.sh b/pkgs/by-name/br/brightness/brightness.sh
index 887dbb1e..f38bb5a5 100755
--- a/pkgs/by-name/br/brightness/brightness.sh
+++ b/pkgs/by-name/br/brightness/brightness.sh
@@ -1,24 +1,33 @@
-#!/usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+#!/usr/bin/env sh
+
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+die() {
+    echo "ERROR: $1"
+    exit 1
+}
 
 help() {
     cat <<EOF
 This is a system brightness manager
 
 USAGE:
-    $NAME up [VALUE] | down [VALUE]
+    $NAME set VALUE
 
 OPTIONS:
     --help   | -h
                                 Output this help and exit.
 
-    --version   | -v
-                                Output the version and exit.
-
 COMMANDS:
-    set [VALUE]
+    set VALUE
                                 Set the brightness to the specified percentage.
 
 ARGUMENTS:
@@ -27,17 +36,14 @@ ARGUMENTS:
 EOF
 }
 
-BACKLIGHT="/sys/class/backlight/%BACKLIGHT_NAME"
+BACKLIGHT="/sys/class/backlight/$BACKLIGHT_NAME"
 
 brightness() {
     perc="$1"
 
-    max="$(cat $BACKLIGHT/max_brightness)"
-
+    max="$(cat "$BACKLIGHT/max_brightness")"
     new="$(echo | awk --assign=perc="$perc" '{printf (perc / 100)}')"
-
     output="$(echo | awk --assign=new="$new" --assign=max="$max" '{printf max * new}')"
-
     echo "$output" >"$BACKLIGHT/brightness"
 }
 
@@ -47,10 +53,6 @@ for arg in "$@"; do
         help
         exit 0
         ;;
-    "--version" | "-v")
-        version
-        exit 0
-        ;;
     esac
 done
 
diff --git a/pkgs/by-name/br/brightness/package.nix b/pkgs/by-name/br/brightness/package.nix
index c2e31a0c..f3797d43 100644
--- a/pkgs/by-name/br/brightness/package.nix
+++ b/pkgs/by-name/br/brightness/package.nix
@@ -1,14 +1,29 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 {
-  sysLib,
+  writeShellApplication,
+  # Arguments
   backlightName ? "intel_backlight", # nixosConfig.soispha.laptop.backlight
+  # Dependencies
+  gawk,
+  coreutils,
 }:
-sysLib.writeShellScript {
+writeShellApplication {
   name = "brightness";
-  src = ./brightness.sh;
-  generateCompletions = true;
-  keepPath = false;
+  text = builtins.readFile ./brightness.sh;
+  inheritPath = false;
 
-  replacementStrings = {BACKLIGHT_NAME = backlightName;};
+  runtimeEnv = {BACKLIGHT_NAME = backlightName;};
 
-  dependencies = [];
+  runtimeInputs = [
+    gawk
+    coreutils
+  ];
 }
diff --git a/pkgs/by-name/co/con2pdf/con2pdf.sh b/pkgs/by-name/co/con2pdf/con2pdf.sh
index 27c9d092..ebe35ad3 100755
--- a/pkgs/by-name/co/con2pdf/con2pdf.sh
+++ b/pkgs/by-name/co/con2pdf/con2pdf.sh
@@ -1,19 +1,18 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
-# needed for help() and version
-# shellcheck disable=2034
-AUTHORS="Soispha"
-# shellcheck disable=2034
-YEARS="2023"
-# shellcheck disable=2034
-VERSION="1.0.0"
-
-# NAME is from the wrapper
-# shellcheck disable=SC2269
-NAME="$NAME"
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+# TODO(@bpeetz): This should probably be rewritten in rust. <2025-04-14>
+
+NAME="con2pdf"
 help() {
     cat <<EOF
 Scan images and turn them into a pdf.
@@ -52,7 +51,7 @@ ARGUMENTS:
     NUM | *([0-9]) := 0 | 1 | 2 | 3 | 4
                             Possible numbers of pages, can be more than 4
 
-    DEVICE := [[$(cat %DEVICE_FUNCTION)]]
+    DEVICE := [[$(cat "$DEVICE_FUNCTION")]]
                             Possible scanner names
 
     METHOD := ADF | Flatbed
diff --git a/pkgs/by-name/co/con2pdf/package.nix b/pkgs/by-name/co/con2pdf/package.nix
index 8eb994fd..11d45ab5 100644
--- a/pkgs/by-name/co/con2pdf/package.nix
+++ b/pkgs/by-name/co/con2pdf/package.nix
@@ -1,24 +1,34 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 {
-  sysLib,
+  writeShellApplication,
   writeText,
-  # dependencies
+  # Dependencies
   sane-backends,
   imagemagick,
   coreutils,
   fd,
 }:
-sysLib.writeShellScript {
+writeShellApplication {
   name = "con2pdf";
-  src = ./con2pdf.sh;
-  generateCompletions = true;
-  keepPath = false;
-  dependencies = [
+  text = builtins.readFile ./con2pdf.sh;
+  inheritPath = false;
+
+  runtimeInputs = [
     sane-backends
     imagemagick
     coreutils
     fd
   ];
-  replacementStrings = {
+
+  runtimeEnv = {
     DEVICE_FUNCTION =
       # This is here, because escaping the whole function, to use it in the shell script
       # directly just isn't possible
diff --git a/pkgs/by-name/ct/ctpv-64-types/allow-up-to-64-types.patch.license b/pkgs/by-name/ct/ctpv-64-types/allow-up-to-64-types.patch.license
new file mode 100644
index 00000000..eae6a84c
--- /dev/null
+++ b/pkgs/by-name/ct/ctpv-64-types/allow-up-to-64-types.patch.license
@@ -0,0 +1,9 @@
+nixos-config - My current NixOS configuration
+
+Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+SPDX-License-Identifier: GPL-3.0-or-later
+
+This file is part of my nixos-config.
+
+You should have received a copy of the License along with this program.
+If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
diff --git a/pkgs/by-name/ct/ctpv-64-types/package.nix b/pkgs/by-name/ct/ctpv-64-types/package.nix
index 763b0325..087e1d28 100644
--- a/pkgs/by-name/ct/ctpv-64-types/package.nix
+++ b/pkgs/by-name/ct/ctpv-64-types/package.nix
@@ -1,3 +1,12 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 {ctpv}:
 ctpv.overrideAttrs (finalAttrs: previousAttrs: {
   pname = previousAttrs.pname + "-64-types";
diff --git a/pkgs/by-name/fd/fd_list/fd_list.sh b/pkgs/by-name/fd/fd_list/fd_list.sh
new file mode 100755
index 00000000..568d73c8
--- /dev/null
+++ b/pkgs/by-name/fd/fd_list/fd_list.sh
@@ -0,0 +1,40 @@
+#!/usr/bin/env bash
+
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+# Lists all fds in use with their respective associated programs.
+# This can be useful, if you need to debug, why your system is out of fds.
+
+# This script is not POSIX shell compatible, as the `ulimit` flags `-H` and `-n` are not defined by POSIX (thus we use `bash` instead).
+
+find /proc/ -maxdepth 1 | while read -r path; do
+    pid="${path#/proc/}"
+    fd_dir="$path/fd/"
+
+    [ -d "$fd_dir" ] && echo "PID = $pid with $(find "$fd_dir" | wc -l) file descriptors"
+done | sort -rn -k5 | head | while read -r _ _ pid _ fdcount _; do
+    command_execution="$(ps -o cmd -p "$pid" -h)"
+
+    command_arguments="$(echo "$command_execution" | awk '{$1=""; print $0}')"
+    command_name="$(basename "$(echo "$command_execution" | awk '{print $1}')")"
+
+    command="$command_name$command_arguments"
+
+    printf "PID %8d with %4d file descriptors: %s\n" "$pid" "$fdcount" "$command"
+done || true
+# ^ Ignore SIGPIPE
+
+printf "\nThe Kernel has %7d file handles allocated.\n" "$(awk '{print $1}' /proc/sys/fs/file-nr)"
+printf "    -> The per-process fd maxium is: %d\n" "$(ulimit -Hn)"
+printf "    -> The per-process fd soft-maximum is: %d\n" "$(ulimit -n)"
+printf "    -> The global fd maximum is: %d\n" "$(cat /proc/sys/fs/file-max)"
+
+# vim: ft=sh
diff --git a/pkgs/by-name/fd/fd_list/package.nix b/pkgs/by-name/fd/fd_list/package.nix
new file mode 100644
index 00000000..34129b10
--- /dev/null
+++ b/pkgs/by-name/fd/fd_list/package.nix
@@ -0,0 +1,28 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+{
+  writeShellApplication,
+  findutils,
+  gawk,
+  coreutils,
+  procps,
+}:
+writeShellApplication {
+  name = "fd_list";
+  text = builtins.readFile ./fd_list.sh;
+
+  inheritPath = false;
+  runtimeInputs = [
+    findutils
+    gawk
+    coreutils
+    procps
+  ];
+}
diff --git a/pkgs/by-name/fu/fupdate-flake/fupdate-flake.sh b/pkgs/by-name/fu/fupdate-flake/fupdate-flake.sh
new file mode 100755
index 00000000..5b8d9469
--- /dev/null
+++ b/pkgs/by-name/fu/fupdate-flake/fupdate-flake.sh
@@ -0,0 +1,194 @@
+#! /usr/bin/env sh
+
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+UPDATE_SCRIPT_NAME="update.sh"
+
+info() {
+    echo "Info: $1"
+}
+dbg() {
+    if [ "${DEBUG_ENABLE-unset}" != "unset" ]; then
+        echo "Debug: $1" >&2
+    fi
+}
+die() {
+    echo "Error: $1"
+    exit 1
+}
+
+# Search for a file “upwards”.
+# This will return the relative path from "$1" to the found file.
+#
+# # Type
+# upfind :: Path -> String -> Path
+#
+# # Arguments
+# $1
+# : The directory to use as start of your search.
+#
+# $2
+# : The file to search for.
+#
+# # Example
+# upfind "/home/user1" "/usr"
+# => /usr
+upfind() {
+    starting_directory="$(readlink --canonicalize "$1")"
+    search_string="$2"
+
+    current_directory="$starting_directory"
+
+    while
+        search_result=$(fd "$search_string" "$current_directory/" --max-depth 1)
+        dbg "upfind - search in $current_directory gives: $search_result"
+        [ -z "$search_result" ] && [ "$current_directory" != "/" ]
+    do current_directory=$(dirname "$current_directory"); done
+
+    realpath --relative-to="$1" "$search_result"
+}
+
+# Construct the storage path for the update script allowed hashes.
+#
+# # Type
+# get_storage_path :: Path -> Path
+#
+# # Arguments
+# $1
+# : The path to the update script
+#
+# # Returns
+# The constructed storage path.
+get_storage_path() {
+    update_script="$(realpath "$1")"
+
+    storage_path="$XDG_DATA_HOME/fupdate-flake/$update_script"
+    echo "$storage_path"
+}
+
+# Checks if a given path to the update script is allowed.
+#
+# # Type
+# is_allowed :: Path -> bool
+#
+# # Arguments
+# $1
+# : The path to the update script to check.
+#
+# # Return exit code
+# 0
+# : If the update script is allowed
+#
+# 1
+# : If it is not.
+is_allowed() {
+    update_script="$(realpath "$1")"
+
+    storage_path="$(get_storage_path "$update_script")"
+
+    # Use this invocation, to also include the path to the `$update_script`
+    update_script_hash="$(sha256sum "$update_script")"
+
+    if [ -f "$storage_path" ]; then
+        if [ "$(cat "$storage_path")" = "$update_script_hash" ]; then
+            return 0
+        else
+            return 1
+        fi
+    else
+        return 1
+    fi
+}
+
+# Asks the user if they want to allow a given script.
+#
+# # Type
+# ask_to_allow_update_script :: Path
+#
+# # Arguments
+# $1
+# : The path to the update script to ask for.
+ask_to_allow_update_script() {
+    update_script="$(realpath "$1")"
+
+    printf "\033[2J" # clear the screen
+    cat "$update_script"
+
+    printf "Do you want to allow this script?[N/y]: "
+    read -r allow
+
+    case "$allow" in
+    [yY])
+        info "Update script allowed."
+
+        storage_path="$(get_storage_path "$update_script")"
+        update_script_hash="$(sha256sum "$update_script")"
+
+        mkdir --parents "$(dirname "$storage_path")"
+        printf "%s" "$update_script_hash" >"$storage_path"
+        ;;
+    *)
+        info "Update script not allowed."
+        ;;
+    esac
+}
+
+# Performs a full update.
+# This consists of running an update script.
+# Additionally, it also checks for duplicated inputs in a `flake.lock` file, if it exists.
+#
+# # Type
+# update :: Path -> Path -> [String]
+#
+# # Arguments
+# $1
+# : The path to the update script to execute.
+#
+# $2
+# : The base directory from which to start the update.
+#
+# $3
+# : Arguments to pass to the update script.
+update() {
+    update_script="$1"
+    base_directory="$2"
+    shift 2
+
+    cd "$base_directory" || die "The provided base directory '$base_directory' cannot be accessed"
+    dbg "Changed directory to: $base_directory"
+
+    dbg "Executing update script ('$update_script') following args: '$*'"
+    "$update_script" "$@"
+
+    if [ -f "flake.lock" ] && grep '[^0-9]_[0-9]' flake.lock --quiet; then
+        batgrep '[^0-9]_[0-9]' flake.lock
+        die "Your flake.nix contains duplicate inputs!"
+    fi
+}
+
+main() {
+    base_directory="$(git rev-parse --show-toplevel)"
+    update_script="$(upfind "$PWD" "$UPDATE_SCRIPT_NAME")"
+    dbg "update_script is: $update_script"
+
+    if [ "$update_script" = "" ]; then
+        die "Failed to find update script."
+    elif is_allowed "$update_script"; then
+        update "$update_script" "$base_directory" "$@"
+    else
+        ask_to_allow_update_script "$update_script"
+        is_allowed "$update_script" && main "$@"
+    fi
+}
+
+main "$@"
+
+# vim: ft=sh
diff --git a/pkgs/by-name/fu/fupdate-flake/package.nix b/pkgs/by-name/fu/fupdate-flake/package.nix
new file mode 100644
index 00000000..c8646f26
--- /dev/null
+++ b/pkgs/by-name/fu/fupdate-flake/package.nix
@@ -0,0 +1,37 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+{
+  writeShellApplication,
+  # Dependencies
+  coreutils,
+  fd,
+  gnugrep,
+  bat-extras, # For `batgrep`
+  bat, # used by batgrep
+  gnused, # required by batgrep
+  git,
+}:
+writeShellApplication {
+  name = "fupdate-flake";
+  text = builtins.readFile ./fupdate-flake.sh;
+
+  # The `update.sh` script might actually want to keep the path.
+  inheritPath = true;
+
+  runtimeInputs = [
+    coreutils
+    fd
+    gnugrep
+    bat-extras.batgrep
+    bat # Used by `batgrep`
+    gnused # Required by `batgrep`
+    git
+  ];
+}
diff --git a/pkgs/by-name/fu/fupdate-sys/fupdate-sys.sh b/pkgs/by-name/fu/fupdate-sys/fupdate-sys.sh
new file mode 100755
index 00000000..4ec3e9e8
--- /dev/null
+++ b/pkgs/by-name/fu/fupdate-sys/fupdate-sys.sh
@@ -0,0 +1,168 @@
+#!/usr/bin/env dash
+
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+# FIXME(@bpeetz): Ideally I could replace this script with a deployment tool. Thus we
+# would have the same tool on the server as I use in my config. <2025-04-14>
+
+# Shell library {{{
+die() {
+    error "$1"
+    if [ -n "$2" ]; then
+        exit "$2"
+    else
+        exit 1
+    fi
+}
+print() {
+    # shellcheck disable=SC2059
+    printf "$*"
+}
+println() {
+    # shellcheck disable=SC2059
+    printf "$*\n"
+}
+eprint() {
+    >&2 print "$@"
+}
+eprintln() {
+    >&2 println "$@"
+}
+if [ "${NO_COLOR-unset}" != "unset" ]; then
+    error() {
+        eprintln "==> ERROR:" "$*"
+    }
+    warning() {
+        eprintln "==> WARNING:" "$*"
+    }
+    debug() {
+        [ -n "$SHELL_LIBRARY_DEBUG" ] && eprintln "==> [Debug:]" "$*"
+    }
+    debug2() {
+        [ -n "$SHELL_LIBRARY_DEBUG" ] && eprintln " -> [Debug:]" "$*"
+    }
+    msg() {
+        eprintln "==>" "$*"
+    }
+    msg2() {
+        eprintln " ->" "$*"
+    }
+    prompt() {
+        eprint "..>" "$*"
+    }
+else
+    error() {
+        eprintln "\033[1;91m==> ERROR:\033[0m" "\033[1;93m$*\033[0m"
+    }
+    warning() {
+        eprintln "\033[1;91m==> WARNING:\033[0m" "\033[1;93m$*\033[0m"
+    }
+    debug() {
+        [ -n "$SHELL_LIBRARY_DEBUG" ] && eprintln "\033[1;94m==> [Debug:]\033[0m" "\033[1;93m$*\033[0m"
+    }
+    debug2() {
+        [ -n "$SHELL_LIBRARY_DEBUG" ] && eprintln "\033[1;94m -> [Debug:]\033[0m" "\033[1;93m$*\033[0m"
+    }
+    msg() {
+        eprintln "\033[1;96m==>\033[0m" "\033[1;93m$*\033[0m"
+    }
+    msg2() {
+        eprintln "\033[1;96m ->\033[0m" "\033[1;93m$*\033[0m"
+    }
+    prompt() {
+        eprint "\033[1;96m..>\033[0m" "\033[1;93m$*\033[0m"
+    }
+fi
+# }}}
+
+NAME="update-sys"
+help() {
+    cat <<EOF
+This is a NixOS System flake update manager.
+
+USAGE:
+    $NAME [--branch <branchname>] [--help]
+
+OPTIONS:
+    --branch | -b  BRANCHNAME
+                                select a branch to update from.
+
+    --mode   | -m  MODE
+                                select a mode to update with
+
+    --help   | -h
+                                output this help.
+ARGUMENTS:
+    BRANCHNAME := [[ git branch --list --format '%(refname:short)' ]]
+                                The name of the branch to deploy the config from
+
+    MODE := switch|boot|test|build|dry-build|dry-activate|edit|repl|build-vm|build-vm-with-bootloader
+                                See the 'nixos-rebuild' manpage for more information about these modes.
+EOF
+    exit "$1"
+}
+BRANCH=""
+
+while [ "$#" -gt 0 ]; do
+    case "$1" in
+    "--help" | "-h")
+        help 0
+        ;;
+    "--branch" | "-b")
+        if [ "${2-unset}" != "unset" ]; then
+            BRANCH="$2"
+        else
+            error "$1 requires an argument"
+            help 1
+        fi
+        shift 2
+        ;;
+    "--mode" | "-m")
+        if [ "${2-unset}" != "unset" ]; then
+            MODE="$2"
+        else
+            error "$1 requires an argument"
+            help 1
+        fi
+        shift 2
+        ;;
+    *)
+        error "the option $1 does not exist!"
+        help 1
+        ;;
+    esac
+done
+
+cd /etc/nixos || die "No /etc/nixos"
+msg "Starting system update..."
+git remote update origin --prune >/dev/null 2>&1
+if ! [ "$BRANCH" = "" ]; then
+    git switch "$BRANCH" >/dev/null 2>&1 && msg2 "Switched to branch '$BRANCH'"
+fi
+msg2 "Updating git repository..."
+git pull --rebase
+
+# We use a tempfile, to make this truly async.
+default_branch=$(mktemp)
+cleanup() {
+    rm "$default_branch"
+}
+trap cleanup EXIT
+
+git remote show origin | grep 'HEAD' | cut -d':' -f2 | sed -e 's/^ *//g' -e 's/ *$//g' >"$default_branch" &
+
+msg2 "Updating system..."
+nixos-rebuild "${MODE-switch}"
+
+git switch "$(cat "$default_branch")" >/dev/null 2>&1 && msg2 "Switched to branch '$(cat "$default_branch")'"
+msg "Finished Update!"
+
+# vim: ft=sh
diff --git a/pkgs/by-name/fu/fupdate-sys/package.nix b/pkgs/by-name/fu/fupdate-sys/package.nix
new file mode 100644
index 00000000..7fd4674b
--- /dev/null
+++ b/pkgs/by-name/fu/fupdate-sys/package.nix
@@ -0,0 +1,38 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+{
+  writeShellApplication,
+  # Dependencies
+  git,
+  nixos-rebuild,
+  sudo,
+  openssh,
+  coreutils,
+  mktemp,
+  gnugrep,
+  gnused,
+  systemd,
+}:
+writeShellApplication {
+  name = "fupdate-sys";
+  text = builtins.readFile ./fupdate-sys.sh;
+  inheritPath = false;
+  runtimeInputs = [
+    git
+    nixos-rebuild
+    sudo
+    openssh
+    coreutils
+    mktemp
+    gnugrep
+    gnused
+    systemd
+  ];
+}
diff --git a/pkgs/by-name/fu/fupdate/.envrc b/pkgs/by-name/fu/fupdate/.envrc
new file mode 100644
index 00000000..294de504
--- /dev/null
+++ b/pkgs/by-name/fu/fupdate/.envrc
@@ -0,0 +1,13 @@
+#!/usr/bin/env sh
+
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+use flake
diff --git a/pkgs/by-name/fu/fupdate/.gitignore b/pkgs/by-name/fu/fupdate/.gitignore
new file mode 100644
index 00000000..f255eebd
--- /dev/null
+++ b/pkgs/by-name/fu/fupdate/.gitignore
@@ -0,0 +1,12 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+/target
+.direnv
diff --git a/pkgs/by-name/fu/fupdate/Cargo.lock b/pkgs/by-name/fu/fupdate/Cargo.lock
new file mode 100644
index 00000000..934e004b
--- /dev/null
+++ b/pkgs/by-name/fu/fupdate/Cargo.lock
@@ -0,0 +1,310 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+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.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6680de5231bd6ee4c6191b8a1325daa282b415391ec9d3a37bd34f2060dc73fa"
+dependencies = [
+ "anstyle",
+ "once_cell_polyfill",
+ "windows-sys",
+]
+
+[[package]]
+name = "anyhow"
+version = "1.0.98"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
+
+[[package]]
+name = "clap"
+version = "4.5.39"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fd60e63e9be68e5fb56422e397cf9baddded06dae1d2e523401542383bc72a9f"
+dependencies = [
+ "clap_builder",
+ "clap_derive",
+]
+
+[[package]]
+name = "clap_builder"
+version = "4.5.39"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "89cc6392a1f72bbeb820d71f32108f61fdaf18bc526e1d23954168a67759ef51"
+dependencies = [
+ "anstream",
+ "anstyle",
+ "clap_lex",
+ "strsim",
+]
+
+[[package]]
+name = "clap_complete"
+version = "4.5.51"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8d2267df7f3c8e74e38268887ea5235d4dfadd39bfff2d56ab82d61776be355e"
+dependencies = [
+ "clap",
+ "clap_lex",
+ "is_executable",
+ "shlex",
+]
+
+[[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 = "fupdate"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "clap",
+ "clap_complete",
+]
+
+[[package]]
+name = "heck"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
+
+[[package]]
+name = "is_executable"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4a1b5bad6f9072935961dfbf1cced2f3d129963d091b6f69f007fe04e758ae2"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "is_terminal_polyfill"
+version = "1.70.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
+
+[[package]]
+name = "once_cell_polyfill"
+version = "1.70.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.95"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
+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 = "shlex"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
+
+[[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.101"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[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 = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[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/fu/fupdate/Cargo.toml b/pkgs/by-name/fu/fupdate/Cargo.toml
new file mode 100644
index 00000000..2412876a
--- /dev/null
+++ b/pkgs/by-name/fu/fupdate/Cargo.toml
@@ -0,0 +1,81 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+[package]
+name = "fupdate"
+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.98"
+clap = { version = "4.5.39", features = ["derive"] }
+clap_complete = { version = "4.5.51", features = ["unstable-dynamic"] }
+
+[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"
diff --git a/pkgs/by-name/fu/fupdate/flake.lock b/pkgs/by-name/fu/fupdate/flake.lock
new file mode 100644
index 00000000..280e8a51
--- /dev/null
+++ b/pkgs/by-name/fu/fupdate/flake.lock
@@ -0,0 +1,27 @@
+{
+  "nodes": {
+    "nixpkgs": {
+      "locked": {
+        "lastModified": 1748406211,
+        "narHash": "sha256-B3BsCRbc+x/d0WiG1f+qfSLUy+oiIfih54kalWBi+/M=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "3d1f29646e4b57ed468d60f9d286cde23a8d1707",
+        "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/fu/fupdate/flake.lock.license b/pkgs/by-name/fu/fupdate/flake.lock.license
new file mode 100644
index 00000000..eae6a84c
--- /dev/null
+++ b/pkgs/by-name/fu/fupdate/flake.lock.license
@@ -0,0 +1,9 @@
+nixos-config - My current NixOS configuration
+
+Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+SPDX-License-Identifier: GPL-3.0-or-later
+
+This file is part of my nixos-config.
+
+You should have received a copy of the License along with this program.
+If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
diff --git a/pkgs/by-name/fu/fupdate/flake.nix b/pkgs/by-name/fu/fupdate/flake.nix
new file mode 100644
index 00000000..0ebceece
--- /dev/null
+++ b/pkgs/by-name/fu/fupdate/flake.nix
@@ -0,0 +1,34 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+{
+  description = "This is a Nix flake update manager.";
+
+  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/fu/fupdate/fupdate.1.md b/pkgs/by-name/fu/fupdate/fupdate.1.md
deleted file mode 100644
index 710e8fb7..00000000
--- a/pkgs/by-name/fu/fupdate/fupdate.1.md
+++ /dev/null
@@ -1,70 +0,0 @@
-% FUPDATE(1) fupdate 1.0.0
-% Soispha
-% May 2023
-
-# NAME
-
-fupdate - updates your flake, while checking for common mistakes
-
-# SYNOPSIS
-
-**fupdate** list of \[*flake*|*\<some word>*|*--help*|*-h*\]
-
-# DESCRIPTION
-
-Argument can be stacked, this makes it possible to specify multiple targets to be updated in succession. See the Examples section for further details.
-
-No argument or *flake*
-: **fupdate**, when executed without arguments or with *flake*, will update your *flake.lock*, check for duplicate flake inputs, i.e., an input has an input declared, which you have also declared as input, and will run a script called *update.sh*, if you allow it.
-The allowance for the script is asked, when you run **fupdate** and the found script is not yet allowed. Furthermore, the allowance is based on the concrete sha256 hash of the script, so any changes will require another allowance.
-
-**\<some word>** as argument
-: If the executable **update-\<some word>** is reachable thought the PATH variable, than this is run. Otherwise, the program will exit.
-
-# OPTIONS
-
-**--help**, **-h**
-: Displays a help message and exit.
-
-**--version**, **-v**
-: Displays the software version and exit.
-
-# EXAMPLES
-
-**fupdate** or **fupdate flake**
-: Updates your *flake.lock*. See the Description section for further details.
-
-**fupdate sys**
-: Run the executable **update-sys**, if it exists. See the Description section for further details.
-
-**fupdate flake sys docs**
-: First updates your flake, then, if the command succeeded, runs **update-sys**, afterweich **update-docs** is run.
-
-# FILES
-
-*update.sh*
-: This is supposed to be a shell script located in your flake base directory, i.e., the directory which contains both a *flake.nix* and a *flake.lock* file.
-
-*~/.local/share/flake-update/*
-: **fupdate** will store the hashes to the allowed *update.sh* files here.
-
-# BUGS
-
-Report bugs to <https://codeberg.org/soispha/flake_update/issues>.
-
-# COPYRIGHT
-
-Copyright (C) 2023  Soispha
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program.  If not, see <https://www.gnu.org/licenses/>.
diff --git a/pkgs/by-name/fu/fupdate/fupdate.sh b/pkgs/by-name/fu/fupdate/fupdate.sh
deleted file mode 100755
index 4322610a..00000000
--- a/pkgs/by-name/fu/fupdate/fupdate.sh
+++ /dev/null
@@ -1,197 +0,0 @@
-#! /usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
-UPDATE_SCRIPT_NAME="update.sh"
-CONFIG_DIRECTORY_PATH="$HOME/.local/share/flake-update"
-
-# Both are used in version()
-# shellcheck disable=SC2034
-AUTHORS="Soispha"
-# shellcheck disable=SC2034
-YEARS="2023"
-
-UPDATE_SCRIPT_NOT_WANTED=false
-
-# Searches upward for a `UPDATE_SCRIPT_NAME` script
-# Returns a path to the script if it exists, otherwise nothing is returned
-check_for_update_script() {
-    dirname="$(search_upward_files "$UPDATE_SCRIPT_NAME")"
-    if [ "$dirname" ]; then
-        printf "%s/%s" "$dirname" "$UPDATE_SCRIPT_NAME"
-    fi
-}
-
-# Checks if a given path to the update script is allowed.
-# Takes the path as input
-# Return 0, if allowed, 1 if not.
-check_for_allowed_update_script() {
-    update_script="$1"
-    config_path="${CONFIG_DIRECTORY_PATH}${update_script}"
-    update_script_hash="$(sha256sum "$update_script")"
-    if [ -f "$config_path" ]; then
-        if [ "$(cat "$config_path")" = "$update_script_hash" ]; then
-            dbg "Recorded hash matches"
-            return 0
-        else
-            dbg "Recorded hash \'$(cat "$config_path")\' does not match real hash \'$update_script_hash\', assuming not allowed"
-            return 1
-        fi
-    else
-        dbg "Path \'$config_path\' does not exist, assuming not allowed"
-        return 1
-    fi
-}
-
-# Asks the user if they want to allow a given script.
-# Takes the path as input
-ask_to_allow_update_script() {
-    update_script="$1"
-    config_path="${CONFIG_DIRECTORY_PATH}${update_script}"
-    update_script_hash="$(sha256sum "$update_script")"
-    println "\033[2J" # clear the screen
-    cat "$update_script"
-    readp "Do you want to allow this script?[N/y]: " allow
-    # shellcheck disable=SC2154
-    dbg "allow is: $allow"
-    case "$allow" in
-    [yY])
-        dbg "allowed script"
-        dbg "storing contents in: $config_path"
-        mkdir --parents "$(dirname "$config_path")"
-        print "$update_script_hash" >"$config_path"
-        ;;
-    *)
-        UPDATE_SCRIPT_NOT_ALLOWED=true
-        ;;
-    esac
-}
-
-# Runs the provided script and continues to update the nix flake
-# Takes the path to the script and the directory to the flake as arguments
-# If the path to the update script is empty, it will be ignored
-update() {
-    update_script="$1"
-    flake_base_dir="$2"
-    shift 2
-    dbg "Provided following args to update script: '$*'"
-
-    cd "$flake_base_dir" || die "Provided dir \'$flake_base_dir\' can not be accessed"
-    dbg "changed directory to: $flake_base_dir"
-
-    nix flake update
-
-    if ! [ "$update_script" = "" ] && ! [ "$UPDATE_SCRIPT_NOT_WANTED" = "true" ]; then
-        "$update_script" "$@"
-    fi
-
-    if grep '[^0-9]_[0-9]' flake.lock >/dev/null; then
-        batgrep '[^0-9]_[0-9]' flake.lock
-        die "Your flake.nix contains duplicate inputs!"
-    fi
-}
-
-help() {
-    cat <<EOF
-This is a Nix flake update manager.
-
-USAGE:
-    $NAME [--help | --version] [flake [--no-script] | <some other command>]
-
-OPTIONS:
-    --help   | -h
-                            Display this help and exit.
-
-    --version   | -v
-                            Display version and copyright information and exit.
-
-    --no-script
-                            Avoid running the 'update.sh' script
-COMMANDS:
-    flake
-                            update the flake project
-
-    <some other command>
-                            runs a executable called "update-<some other command>", if it exists
-EOF
-}
-
-main() {
-    if ! [ "$UPDATE_SCRIPT_NOT_ALLOWED" = true ]; then
-        update_script="$(check_for_update_script)"
-        flake_base_dir="$(search_flake_base_dir)" # Assume, that the update script is in the base dir
-        dbg "update_script is: $update_script"
-        dbg "flake_base_dir is: $flake_base_dir"
-
-        if [ "$update_script" = "" ]; then
-            update "" "$flake_base_dir" "$@"
-        elif check_for_allowed_update_script "$update_script" && ! [ "$update_script" = "" ]; then
-            update "$update_script" "$flake_base_dir" "$@"
-        else
-            ask_to_allow_update_script "$update_script"
-            main "$@"
-        fi
-    fi
-}
-
-if [ "$#" -eq 0 ]; then
-    main
-    exit 0
-fi
-
-for input in "$@"; do
-    case "$input" in
-    "--help" | "-h")
-        help
-        exit 0
-        ;;
-    "--version" | "-v")
-        version
-        exit 0
-        ;;
-    "--no-script" | "-n")
-        UPDATE_SCRIPT_NOT_WANTED=true
-        ;;
-    "--")
-        end_of_cli_options=true
-
-        # Stop processing args after that marker.
-        break
-        ;;
-    esac
-    [ "$end_of_cli_options" = "true" ] && break
-done
-
-case "$1" in
-"flake")
-    shift 1
-
-    # Filter out fupdate specific flags
-    while [ "$1" != "--" ]; do
-        # FIXME: This check allows to add a flag multiple times, but this should probably
-        # not be allowed <2024-03-29>
-        case "$1" in
-        "--no-script" | "-n")
-            shift 1
-            ;;
-        *)
-            break
-            ;;
-        esac
-    done
-
-    [ "$1" = "--" ] && shift 1
-    main "$@"
-    ;;
-*)
-    command="$1"
-    shift 1
-    [ "$1" = "--" ] && shift 1
-    if which update-"$command" >/dev/null 2>&1; then
-        update-"$command" "$@"
-    else
-        die "command \"update-$command\" is not executable, or does not exist"
-    fi
-    ;;
-esac
diff --git a/pkgs/by-name/fu/fupdate/package.nix b/pkgs/by-name/fu/fupdate/package.nix
index 66372add..86eccaf7 100644
--- a/pkgs/by-name/fu/fupdate/package.nix
+++ b/pkgs/by-name/fu/fupdate/package.nix
@@ -1,29 +1,41 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 {
-  sysLib,
-  dash,
-  lix,
-  gnugrep,
-  fd,
-  coreutils,
-  bat, # used by batgrep
-  bat-extras,
-  gnused, # required by batgrep
-  git, # needed to fetch through git
+  rustPlatform,
+  installShellFiles,
+  makeWrapper,
 }:
-sysLib.writeShellScript {
-  name = "fupdate";
-  src = ./fupdate.sh;
-  generateCompletions = true;
-  keepPath = true;
-  dependencies = [
-    dash
-    lix
-    gnugrep
-    fd
-    coreutils
-    bat # used by batgrep
-    bat-extras.batgrep
-    gnused # required by batgrep
-    git # needed to fetch through git
+rustPlatform.buildRustPackage (finalAttrs: {
+  pname = "fupdate";
+  version = "0.1.0";
+
+  src = ./.;
+  cargoLock = {
+    lockFile = ./Cargo.lock;
+  };
+
+  buildInputs = [];
+
+  nativeBuildInputs = [
+    installShellFiles
+    makeWrapper
   ];
-}
+
+  postInstall = ''
+    installShellCompletion --cmd fupdate \
+      --bash <(COMPLETE=bash $out/bin/fupdate) \
+      --fish <(COMPLETE=fish $out/bin/fupdate) \
+      --zsh <(COMPLETE=zsh $out/bin/fupdate)
+  '';
+
+  meta = {
+    mainProgram = "fupdate";
+  };
+})
diff --git a/pkgs/by-name/fu/fupdate/src/cli.rs b/pkgs/by-name/fu/fupdate/src/cli.rs
new file mode 100644
index 00000000..6ebd1bc4
--- /dev/null
+++ b/pkgs/by-name/fu/fupdate/src/cli.rs
@@ -0,0 +1,56 @@
+// nixos-config - My current NixOS configuration
+//
+// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+// This file is part of my nixos-config.
+//
+// You should have received a copy of the License along with this program.
+// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+use std::{env, ffi::OsStr, fs::read_dir};
+
+use clap::Parser;
+use clap_complete::{engine::ArgValueCompleter, CompletionCandidate};
+
+/// This is a Nix flake update manager.
+#[derive(Parser, Debug)]
+#[command(author, version, about)]
+pub struct CliArgs {
+    /// The command to execute.
+    #[arg(add = ArgValueCompleter::new(get_fupdate_commands))]
+    pub command: Vec<String>,
+}
+
+fn get_fupdate_commands(current: &OsStr) -> Vec<CompletionCandidate> {
+    let mut output = vec![];
+    let path = env::var("PATH").unwrap_or_default();
+
+    let Some(current) = current.to_str() else {
+        return output;
+    };
+
+    for directory in path.split(':') {
+        if let Ok(mut read) = read_dir(directory) {
+            for value in read.by_ref().flatten() {
+                let file_name = value.file_name();
+                let name = file_name.to_string_lossy();
+                let Some(stripped) = name.strip_prefix("fupdate-") else {
+                    continue;
+                };
+
+                if stripped.starts_with(current) {
+                    output.push(CompletionCandidate::new(
+                        value
+                            .file_name()
+                            .to_string_lossy()
+                            .strip_prefix("fupdate-")
+                            .expect("Exists"),
+                    ));
+                }
+            }
+        }
+    }
+
+    output
+}
diff --git a/pkgs/by-name/fu/fupdate/src/main.rs b/pkgs/by-name/fu/fupdate/src/main.rs
new file mode 100644
index 00000000..c73f2777
--- /dev/null
+++ b/pkgs/by-name/fu/fupdate/src/main.rs
@@ -0,0 +1,52 @@
+// nixos-config - My current NixOS configuration
+//
+// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+// This file is part of my nixos-config.
+//
+// You should have received a copy of the License along with this program.
+// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+use std::process::Command;
+
+use anyhow::{bail, Context, Result};
+use clap::{CommandFactory, Parser};
+
+pub mod cli;
+
+use crate::cli::CliArgs;
+
+fn main() -> Result<(), anyhow::Error> {
+    clap_complete::CompleteEnv::with_factory(CliArgs::command).complete();
+
+    let args = CliArgs::parse();
+
+    let command = args.command.first().map_or("flake", String::as_str);
+
+    {
+        let args = if args.command.len() > 1 {
+            &args.command[1..]
+        } else {
+            &[]
+        };
+
+        // println!("Running: `fupdate-{command} {}`", args.join(" "));
+
+        let child = Command::new(format!("fupdate-{command}"))
+            .args(args)
+            .status()
+            .with_context(|| format!("Failed to spawn `fupdate-{command}`"))?;
+
+        if !child.success() {
+            bail!("Command `fupdate-{command} {}` failed!", args.join(" "));
+        }
+    }
+
+    Ok(())
+}
+
+#[test]
+fn verify_cli() {
+    CliArgs::command().debug_assert();
+}
diff --git a/pkgs/by-name/fu/fupdate/update.sh b/pkgs/by-name/fu/fupdate/update.sh
new file mode 100755
index 00000000..8e36e13e
--- /dev/null
+++ b/pkgs/by-name/fu/fupdate/update.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+[ "$1" = "upgrade" ] && cargo upgrade
+cargo update
diff --git a/pkgs/by-name/ge/generate_moz_extension/.envrc b/pkgs/by-name/ge/generate_moz_extension/.envrc
index 2f9f1a81..294de504 100644
--- a/pkgs/by-name/ge/generate_moz_extension/.envrc
+++ b/pkgs/by-name/ge/generate_moz_extension/.envrc
@@ -1,2 +1,13 @@
 #!/usr/bin/env sh
+
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 use flake
diff --git a/pkgs/by-name/ge/generate_moz_extension/.gitignore b/pkgs/by-name/ge/generate_moz_extension/.gitignore
index f717ddd7..cc03ebd7 100644
--- a/pkgs/by-name/ge/generate_moz_extension/.gitignore
+++ b/pkgs/by-name/ge/generate_moz_extension/.gitignore
@@ -1,3 +1,13 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 /target
 /result
 .direnv
diff --git a/pkgs/by-name/ge/generate_moz_extension/Cargo.lock b/pkgs/by-name/ge/generate_moz_extension/Cargo.lock
index 10970fa6..dde9f88e 100644
--- a/pkgs/by-name/ge/generate_moz_extension/Cargo.lock
+++ b/pkgs/by-name/ge/generate_moz_extension/Cargo.lock
@@ -1,5 +1,14 @@
 # This file is automatically @generated by Cargo.
 # It is not intended for manual editing.
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 version = 4
 
 [[package]]
@@ -19,9 +28,9 @@ checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
 
 [[package]]
 name = "anyhow"
-version = "1.0.97"
+version = "1.0.98"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
+checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
 
 [[package]]
 name = "atomic-waker"
@@ -37,9 +46,9 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
 
 [[package]]
 name = "backtrace"
-version = "0.3.74"
+version = "0.3.75"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a"
+checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002"
 dependencies = [
  "addr2line",
  "cfg-if",
@@ -58,9 +67,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
 
 [[package]]
 name = "bitflags"
-version = "2.9.0"
+version = "2.9.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
+checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
 
 [[package]]
 name = "bumpalo"
@@ -76,9 +85,9 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
 
 [[package]]
 name = "cc"
-version = "1.2.17"
+version = "1.2.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a"
+checksum = "16595d3be041c03b09d08d0858631facccee9221e579704070e6e9e4915d3bc7"
 dependencies = [
  "shlex",
 ]
@@ -133,9 +142,9 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
 
 [[package]]
 name = "errno"
-version = "0.3.10"
+version = "0.3.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
+checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18"
 dependencies = [
  "libc",
  "windows-sys 0.59.0",
@@ -280,9 +289,9 @@ dependencies = [
 
 [[package]]
 name = "getrandom"
-version = "0.2.15"
+version = "0.2.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
+checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
 dependencies = [
  "cfg-if",
  "libc",
@@ -291,9 +300,9 @@ dependencies = [
 
 [[package]]
 name = "getrandom"
-version = "0.3.2"
+version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0"
+checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
 dependencies = [
  "cfg-if",
  "libc",
@@ -309,9 +318,9 @@ checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
 
 [[package]]
 name = "h2"
-version = "0.4.8"
+version = "0.4.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5017294ff4bb30944501348f6f8e42e6ad28f42c8bbef7a74029aff064a4e3c2"
+checksum = "a9421a676d1b147b16b82c9225157dc629087ef8ec4d5e2960f9437a90dac0a5"
 dependencies = [
  "atomic-waker",
  "bytes",
@@ -328,9 +337,9 @@ dependencies = [
 
 [[package]]
 name = "hashbrown"
-version = "0.15.2"
+version = "0.15.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
+checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3"
 
 [[package]]
 name = "http"
@@ -394,11 +403,10 @@ dependencies = [
 
 [[package]]
 name = "hyper-rustls"
-version = "0.27.5"
+version = "0.27.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2"
+checksum = "03a01595e11bdcec50946522c32dde3fc6914743000a68b93000965f2f02406d"
 dependencies = [
- "futures-util",
  "http",
  "hyper",
  "hyper-util",
@@ -427,40 +435,48 @@ dependencies = [
 
 [[package]]
 name = "hyper-util"
-version = "0.1.10"
+version = "0.1.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4"
+checksum = "b1c293b6b3d21eca78250dc7dbebd6b9210ec5530e038cbfe0661b5c47ab06e8"
 dependencies = [
+ "base64",
  "bytes",
  "futures-channel",
+ "futures-core",
  "futures-util",
  "http",
  "http-body",
  "hyper",
+ "ipnet",
+ "libc",
+ "percent-encoding",
  "pin-project-lite",
  "socket2",
+ "system-configuration",
  "tokio",
  "tower-service",
  "tracing",
+ "windows-registry",
 ]
 
 [[package]]
 name = "icu_collections"
-version = "1.5.0"
+version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526"
+checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47"
 dependencies = [
  "displaydoc",
+ "potential_utf",
  "yoke",
  "zerofrom",
  "zerovec",
 ]
 
 [[package]]
-name = "icu_locid"
-version = "1.5.0"
+name = "icu_locale_core"
+version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637"
+checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a"
 dependencies = [
  "displaydoc",
  "litemap",
@@ -470,30 +486,10 @@ dependencies = [
 ]
 
 [[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"
+version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f"
+checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979"
 dependencies = [
  "displaydoc",
  "icu_collections",
@@ -501,68 +497,55 @@ dependencies = [
  "icu_properties",
  "icu_provider",
  "smallvec",
- "utf16_iter",
- "utf8_iter",
- "write16",
  "zerovec",
 ]
 
 [[package]]
 name = "icu_normalizer_data"
-version = "1.5.1"
+version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7"
+checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3"
 
 [[package]]
 name = "icu_properties"
-version = "1.5.1"
+version = "2.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5"
+checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b"
 dependencies = [
  "displaydoc",
  "icu_collections",
- "icu_locid_transform",
+ "icu_locale_core",
  "icu_properties_data",
  "icu_provider",
- "tinystr",
+ "potential_utf",
+ "zerotrie",
  "zerovec",
 ]
 
 [[package]]
 name = "icu_properties_data"
-version = "1.5.1"
+version = "2.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2"
+checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632"
 
 [[package]]
 name = "icu_provider"
-version = "1.5.0"
+version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9"
+checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af"
 dependencies = [
  "displaydoc",
- "icu_locid",
- "icu_provider_macros",
+ "icu_locale_core",
  "stable_deref_trait",
  "tinystr",
  "writeable",
  "yoke",
  "zerofrom",
+ "zerotrie",
  "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"
@@ -575,9 +558,9 @@ dependencies = [
 
 [[package]]
 name = "idna_adapter"
-version = "1.2.0"
+version = "1.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71"
+checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344"
 dependencies = [
  "icu_normalizer",
  "icu_properties",
@@ -585,9 +568,9 @@ dependencies = [
 
 [[package]]
 name = "indexmap"
-version = "2.8.0"
+version = "2.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058"
+checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e"
 dependencies = [
  "equivalent",
  "hashbrown",
@@ -600,6 +583,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
 
 [[package]]
+name = "iri-string"
+version = "0.7.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2"
+dependencies = [
+ "memchr",
+ "serde",
+]
+
+[[package]]
 name = "itoa"
 version = "1.0.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -617,21 +610,21 @@ dependencies = [
 
 [[package]]
 name = "libc"
-version = "0.2.171"
+version = "0.2.172"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
+checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
 
 [[package]]
 name = "linux-raw-sys"
-version = "0.9.3"
+version = "0.9.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413"
+checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12"
 
 [[package]]
 name = "litemap"
-version = "0.7.5"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856"
+checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956"
 
 [[package]]
 name = "log"
@@ -653,22 +646,22 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
 
 [[package]]
 name = "miniz_oxide"
-version = "0.8.5"
+version = "0.8.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5"
+checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a"
 dependencies = [
  "adler2",
 ]
 
 [[package]]
 name = "mio"
-version = "1.0.3"
+version = "1.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd"
+checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c"
 dependencies = [
  "libc",
  "wasi 0.11.0+wasi-snapshot-preview1",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
 ]
 
 [[package]]
@@ -705,9 +698,9 @@ checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
 
 [[package]]
 name = "openssl"
-version = "0.10.71"
+version = "0.10.73"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd"
+checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8"
 dependencies = [
  "bitflags",
  "cfg-if",
@@ -737,9 +730,9 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
 
 [[package]]
 name = "openssl-sys"
-version = "0.9.106"
+version = "0.9.109"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8bb61ea9811cc39e3c2069f40b8b8e2e70d8569b361f879786cc7ed48b777cdd"
+checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571"
 dependencies = [
  "cc",
  "libc",
@@ -772,10 +765,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
 
 [[package]]
+name = "potential_utf"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585"
+dependencies = [
+ "zerovec",
+]
+
+[[package]]
 name = "proc-macro2"
-version = "1.0.94"
+version = "1.0.95"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
+checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
 dependencies = [
  "unicode-ident",
 ]
@@ -797,15 +799,14 @@ checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
 
 [[package]]
 name = "reqwest"
-version = "0.12.15"
+version = "0.12.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb"
+checksum = "e98ff6b0dbbe4d5a37318f433d4fc82babd21631f194d370409ceb2e40b2f0b5"
 dependencies = [
  "base64",
  "bytes",
  "encoding_rs",
  "futures-core",
- "futures-util",
  "h2",
  "http",
  "http-body",
@@ -822,21 +823,20 @@ dependencies = [
  "once_cell",
  "percent-encoding",
  "pin-project-lite",
- "rustls-pemfile",
+ "rustls-pki-types",
  "serde",
  "serde_json",
  "serde_urlencoded",
  "sync_wrapper",
- "system-configuration",
  "tokio",
  "tokio-native-tls",
  "tower",
+ "tower-http",
  "tower-service",
  "url",
  "wasm-bindgen",
  "wasm-bindgen-futures",
  "web-sys",
- "windows-registry",
 ]
 
 [[package]]
@@ -847,7 +847,7 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
 dependencies = [
  "cc",
  "cfg-if",
- "getrandom 0.2.15",
+ "getrandom 0.2.16",
  "libc",
  "untrusted",
  "windows-sys 0.52.0",
@@ -861,9 +861,9 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
 
 [[package]]
 name = "rustix"
-version = "1.0.3"
+version = "1.0.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e56a18552996ac8d29ecc3b190b4fdbb2d91ca4ec396de7bbffaf43f3d637e96"
+checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266"
 dependencies = [
  "bitflags",
  "errno",
@@ -874,9 +874,9 @@ dependencies = [
 
 [[package]]
 name = "rustls"
-version = "0.23.25"
+version = "0.23.27"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "822ee9188ac4ec04a2f0531e55d035fb2de73f18b41a63c70c2712503b6fb13c"
+checksum = "730944ca083c1c233a75c09f199e973ca499344a2b7ba9e755c457e86fb4a321"
 dependencies = [
  "once_cell",
  "rustls-pki-types",
@@ -886,25 +886,19 @@ dependencies = [
 ]
 
 [[package]]
-name = "rustls-pemfile"
-version = "2.2.0"
+name = "rustls-pki-types"
+version = "1.12.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50"
+checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79"
 dependencies = [
- "rustls-pki-types",
+ "zeroize",
 ]
 
 [[package]]
-name = "rustls-pki-types"
-version = "1.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c"
-
-[[package]]
 name = "rustls-webpki"
-version = "0.103.1"
+version = "0.103.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fef8b8769aaccf73098557a87cd1816b4f9c7c16811c9c77142aa695c16f2c03"
+checksum = "e4a72fe2bcf7a6ac6fd7d0b9e5cb68aeb7d4c0a0271730218b3e92d43b4eb435"
 dependencies = [
  "ring",
  "rustls-pki-types",
@@ -913,9 +907,9 @@ dependencies = [
 
 [[package]]
 name = "rustversion"
-version = "1.0.20"
+version = "1.0.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2"
+checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d"
 
 [[package]]
 name = "ryu"
@@ -1016,15 +1010,15 @@ dependencies = [
 
 [[package]]
 name = "smallvec"
-version = "1.14.0"
+version = "1.15.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd"
+checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9"
 
 [[package]]
 name = "socket2"
-version = "0.5.8"
+version = "0.5.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8"
+checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678"
 dependencies = [
  "libc",
  "windows-sys 0.52.0",
@@ -1044,9 +1038,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
 
 [[package]]
 name = "syn"
-version = "2.0.100"
+version = "2.0.101"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
+checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1064,9 +1058,9 @@ dependencies = [
 
 [[package]]
 name = "synstructure"
-version = "0.13.1"
+version = "0.13.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
+checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1096,12 +1090,12 @@ dependencies = [
 
 [[package]]
 name = "tempfile"
-version = "3.19.1"
+version = "3.20.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf"
+checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1"
 dependencies = [
  "fastrand",
- "getrandom 0.3.2",
+ "getrandom 0.3.3",
  "once_cell",
  "rustix",
  "windows-sys 0.59.0",
@@ -1109,9 +1103,9 @@ dependencies = [
 
 [[package]]
 name = "tinystr"
-version = "0.7.6"
+version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f"
+checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b"
 dependencies = [
  "displaydoc",
  "zerovec",
@@ -1119,9 +1113,9 @@ dependencies = [
 
 [[package]]
 name = "tokio"
-version = "1.44.1"
+version = "1.45.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a"
+checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779"
 dependencies = [
  "backtrace",
  "bytes",
@@ -1166,9 +1160,9 @@ dependencies = [
 
 [[package]]
 name = "tokio-util"
-version = "0.7.14"
+version = "0.7.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6b9590b93e6fcc1739458317cccd391ad3955e2bde8913edf6f95f9e65a8f034"
+checksum = "66a539a9ad6d5d281510d5bd368c973d636c02dbf8a67300bfb6b950696ad7df"
 dependencies = [
  "bytes",
  "futures-core",
@@ -1193,6 +1187,24 @@ dependencies = [
 ]
 
 [[package]]
+name = "tower-http"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fdb0c213ca27a9f57ab69ddb290fd80d970922355b83ae380b395d3986b8a2e"
+dependencies = [
+ "bitflags",
+ "bytes",
+ "futures-util",
+ "http",
+ "http-body",
+ "iri-string",
+ "pin-project-lite",
+ "tower",
+ "tower-layer",
+ "tower-service",
+]
+
+[[package]]
 name = "tower-layer"
 version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1253,12 +1265,6 @@ dependencies = [
 ]
 
 [[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"
@@ -1394,9 +1400,9 @@ dependencies = [
 
 [[package]]
 name = "windows-result"
-version = "0.3.2"
+version = "0.3.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252"
+checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
 dependencies = [
  "windows-link",
 ]
@@ -1566,22 +1572,16 @@ dependencies = [
 ]
 
 [[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"
+version = "0.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
+checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb"
 
 [[package]]
 name = "yoke"
-version = "0.7.5"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40"
+checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc"
 dependencies = [
  "serde",
  "stable_deref_trait",
@@ -1591,9 +1591,9 @@ dependencies = [
 
 [[package]]
 name = "yoke-derive"
-version = "0.7.5"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154"
+checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1629,10 +1629,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
 
 [[package]]
+name = "zerotrie"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595"
+dependencies = [
+ "displaydoc",
+ "yoke",
+ "zerofrom",
+]
+
+[[package]]
 name = "zerovec"
-version = "0.10.4"
+version = "0.11.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079"
+checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428"
 dependencies = [
  "yoke",
  "zerofrom",
@@ -1641,9 +1652,9 @@ dependencies = [
 
 [[package]]
 name = "zerovec-derive"
-version = "0.10.3"
+version = "0.11.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6"
+checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f"
 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 1b3ff4f0..af970bd4 100644
--- a/pkgs/by-name/ge/generate_moz_extension/Cargo.toml
+++ b/pkgs/by-name/ge/generate_moz_extension/Cargo.toml
@@ -1,3 +1,13 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 [package]
 name = "generate_extensions"
 version = "0.1.0"
@@ -6,9 +16,9 @@ edition = "2021"
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
-anyhow = "1.0.97"
+anyhow = "1.0.98"
 futures = "0.3.31"
-reqwest = "0.12.15"
+reqwest = "0.12.18"
 serde = { version = "1.0.219", features = ["derive"] }
 serde_json = "1.0.140"
-tokio = { version = "1.44.1", features = ["macros", "rt-multi-thread"] }
+tokio = { version = "1.45.1", features = ["macros", "rt-multi-thread"] }
diff --git a/pkgs/by-name/ge/generate_moz_extension/examples/generate_extensions.sh b/pkgs/by-name/ge/generate_moz_extension/examples/generate_extensions.sh
index 96802992..3e990b6d 100755
--- a/pkgs/by-name/ge/generate_moz_extension/examples/generate_extensions.sh
+++ b/pkgs/by-name/ge/generate_moz_extension/examples/generate_extensions.sh
@@ -1,5 +1,15 @@
 #!/bin/sh
 
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 tmp=$(mktemp)
 cat <<EOF | awk '!/^\s*#/' >"$tmp"
     darkreader:navbar
diff --git a/pkgs/by-name/ge/generate_moz_extension/flake.lock b/pkgs/by-name/ge/generate_moz_extension/flake.lock
index 9d72fb5b..7fe05591 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": 1742394900,
-        "narHash": "sha256-vVOAp9ahvnU+fQoKd4SEXB2JG2wbENkpqcwlkIXgUC0=",
+        "lastModified": 1748047550,
+        "narHash": "sha256-t0qLLqb4C1rdtiY8IFRH5KIapTY/n3Lqt57AmxEv9mk=",
         "owner": "ipetkov",
         "repo": "crane",
-        "rev": "70947c1908108c0c551ddfd73d4f750ff2ea67cd",
+        "rev": "b718a78696060df6280196a6f992d04c87a16aef",
         "type": "github"
       },
       "original": {
@@ -35,11 +35,11 @@
     },
     "nixpkgs": {
       "locked": {
-        "lastModified": 1743076231,
-        "narHash": "sha256-yQugdVfi316qUfqzN8JMaA2vixl+45GxNm4oUfXlbgw=",
+        "lastModified": 1748406211,
+        "narHash": "sha256-B3BsCRbc+x/d0WiG1f+qfSLUy+oiIfih54kalWBi+/M=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "6c5963357f3c1c840201eda129a99d455074db04",
+        "rev": "3d1f29646e4b57ed468d60f9d286cde23a8d1707",
         "type": "github"
       },
       "original": {
@@ -64,11 +64,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1743215516,
-        "narHash": "sha256-52qbrkG65U1hyrQWltgHTgH4nm0SJL+9TWv2UDCEPNI=",
+        "lastModified": 1748486227,
+        "narHash": "sha256-veMuFa9cq/XgUXp1S57oC8K0TIw3XyZWL2jIyGWlW0c=",
         "owner": "oxalica",
         "repo": "rust-overlay",
-        "rev": "524463199fdee49338006b049bc376b965a2cfed",
+        "rev": "4bf1892eb81113e868efe67982b64f1da15c8c5a",
         "type": "github"
       },
       "original": {
diff --git a/pkgs/by-name/ge/generate_moz_extension/flake.lock.license b/pkgs/by-name/ge/generate_moz_extension/flake.lock.license
new file mode 100644
index 00000000..eae6a84c
--- /dev/null
+++ b/pkgs/by-name/ge/generate_moz_extension/flake.lock.license
@@ -0,0 +1,9 @@
+nixos-config - My current NixOS configuration
+
+Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+SPDX-License-Identifier: GPL-3.0-or-later
+
+This file is part of my nixos-config.
+
+You should have received a copy of the License along with this program.
+If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
diff --git a/pkgs/by-name/ge/generate_moz_extension/flake.nix b/pkgs/by-name/ge/generate_moz_extension/flake.nix
index 5575f90b..a7125642 100644
--- a/pkgs/by-name/ge/generate_moz_extension/flake.nix
+++ b/pkgs/by-name/ge/generate_moz_extension/flake.nix
@@ -1,3 +1,12 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 {
   description = "A simple way to query the mozialla api for extension data";
 
diff --git a/pkgs/by-name/ge/generate_moz_extension/package.nix b/pkgs/by-name/ge/generate_moz_extension/package.nix
index abd95c77..aae5ea6c 100644
--- a/pkgs/by-name/ge/generate_moz_extension/package.nix
+++ b/pkgs/by-name/ge/generate_moz_extension/package.nix
@@ -1,3 +1,12 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 {
   rustPlatform,
   openssl,
diff --git a/pkgs/by-name/ge/generate_moz_extension/res/generate_extensions.py b/pkgs/by-name/ge/generate_moz_extension/res/generate_extensions.py
index ee8cc966..a262ca77 100644
--- a/pkgs/by-name/ge/generate_moz_extension/res/generate_extensions.py
+++ b/pkgs/by-name/ge/generate_moz_extension/res/generate_extensions.py
@@ -1,4 +1,15 @@
 #!/usr/bin/env python
+
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 # source: https://github.com/etu/nixconfig/blob/ba47d577c8bfb4a1c06927c34ece34118f4a0460/modules/graphical/firefox/generate.py
 
 from concurrent.futures import ThreadPoolExecutor
diff --git a/pkgs/by-name/ge/generate_moz_extension/res/reference.json.license b/pkgs/by-name/ge/generate_moz_extension/res/reference.json.license
new file mode 100644
index 00000000..eae6a84c
--- /dev/null
+++ b/pkgs/by-name/ge/generate_moz_extension/res/reference.json.license
@@ -0,0 +1,9 @@
+nixos-config - My current NixOS configuration
+
+Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+SPDX-License-Identifier: GPL-3.0-or-later
+
+This file is part of my nixos-config.
+
+You should have received a copy of the License along with this program.
+If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
diff --git a/pkgs/by-name/ge/generate_moz_extension/res/test.json.license b/pkgs/by-name/ge/generate_moz_extension/res/test.json.license
new file mode 100644
index 00000000..eae6a84c
--- /dev/null
+++ b/pkgs/by-name/ge/generate_moz_extension/res/test.json.license
@@ -0,0 +1,9 @@
+nixos-config - My current NixOS configuration
+
+Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+SPDX-License-Identifier: GPL-3.0-or-later
+
+This file is part of my nixos-config.
+
+You should have received a copy of the License along with this program.
+If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
diff --git a/pkgs/by-name/ge/generate_moz_extension/src/main.rs b/pkgs/by-name/ge/generate_moz_extension/src/main.rs
index bde986a3..58a19160 100644
--- a/pkgs/by-name/ge/generate_moz_extension/src/main.rs
+++ b/pkgs/by-name/ge/generate_moz_extension/src/main.rs
@@ -1,3 +1,13 @@
+// nixos-config - My current NixOS configuration
+//
+// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+// This file is part of my nixos-config.
+//
+// You should have received a copy of the License along with this program.
+// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 use std::env::args;
 
 use anyhow::{bail, Context};
diff --git a/pkgs/by-name/ge/generate_moz_extension/src/types.rs b/pkgs/by-name/ge/generate_moz_extension/src/types.rs
index b830fe0d..231e747c 100644
--- a/pkgs/by-name/ge/generate_moz_extension/src/types.rs
+++ b/pkgs/by-name/ge/generate_moz_extension/src/types.rs
@@ -1,3 +1,13 @@
+// nixos-config - My current NixOS configuration
+//
+// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+// This file is part of my nixos-config.
+//
+// You should have received a copy of the License along with this program.
+// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 use std::fmt::Display;
 
 use anyhow::anyhow;
diff --git a/pkgs/by-name/ge/generate_moz_extension/update.sh b/pkgs/by-name/ge/generate_moz_extension/update.sh
index b9404867..c7c35d39 100755
--- a/pkgs/by-name/ge/generate_moz_extension/update.sh
+++ b/pkgs/by-name/ge/generate_moz_extension/update.sh
@@ -1,5 +1,15 @@
 #!/usr/bin/env sh
 
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 [ "$1" = "upgrade" ] && cargo upgrade
 cargo update
 
diff --git a/pkgs/by-name/gi/git-cm/git-cm.sh b/pkgs/by-name/gi/git-cm/git-cm.sh
index 2204e4d6..7ab957df 100755
--- a/pkgs/by-name/gi/git-cm/git-cm.sh
+++ b/pkgs/by-name/gi/git-cm/git-cm.sh
@@ -1,7 +1,14 @@
 #!/usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 
 ROOT="$(git rev-parse --show-toplevel)"
 
@@ -13,6 +20,6 @@ else
 fi
 sed '1d' "$(git config commit.template)" >>"$ROOT/.git/COMMIT_TEMPLATE"
 
-git commit --template "$ROOT/.git/COMMIT_TEMPLATE" --verbose "$@"
+git commit --template "$ROOT/.git/COMMIT_TEMPLATE" "$@"
 
 # vim: ft=sh
diff --git a/pkgs/by-name/gi/git-cm/package.nix b/pkgs/by-name/gi/git-cm/package.nix
index a9949783..f124ce90 100644
--- a/pkgs/by-name/gi/git-cm/package.nix
+++ b/pkgs/by-name/gi/git-cm/package.nix
@@ -1,13 +1,26 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 {
-  sysLib,
+  writeShellApplication,
+  # Dependencies
   git,
   gnused,
 }:
-sysLib.writeShellScript {
+writeShellApplication {
   name = "git-cm";
-  src = ./git-cm.sh;
-  keepPath = true;
-  dependencies = [
+  text = builtins.readFile ./git-cm.sh;
+
+  # We need access to the $EDITOR
+  inheritPath = true;
+
+  runtimeInputs = [
     git
     gnused
   ];
diff --git a/pkgs/by-name/gi/git-edit-index/git-edit-index.sh b/pkgs/by-name/gi/git-edit-index/git-edit-index.sh
index e73dc53c..46fbc9c5 100755
--- a/pkgs/by-name/gi/git-edit-index/git-edit-index.sh
+++ b/pkgs/by-name/gi/git-edit-index/git-edit-index.sh
@@ -1,19 +1,20 @@
 #!/usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
-# needed for help() and version
-# shellcheck disable=2034
-AUTHORS="Soispha"
-# shellcheck disable=2034
-YEARS="2024"
-# shellcheck disable=2034
-VERSION="1.0.0"
-
-# NAME is from the wrapper
-# shellcheck disable=SC2269
-NAME="$NAME"
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+NAME="git-edit-index"
+
+warn() {
+    echo "WARNING: $1"
+}
 
 help() {
     cat <<EOF
@@ -55,37 +56,35 @@ materialize_file() {
 }
 
 edit() {
-    files_to_add="$(mktmp)"
-    realpath --relative-to=. "$@" >"$files_to_add"
+    files_to_add="$(mktemp)"
+    cleanup() {
+        rm "$files_to_add"
+    }
+    trap cleanup EXIT
 
-    index_files="$(mktmp)"
-    git diff --name-only --cached --diff-filter=AM >"$index_files"
+    realpath --relative-to=. "$@" >"$files_to_add"
 
-    while read -r file; do
-        if grep -q "$file" "$files_to_add"; then
-            sed -i "s|$file||" "$files_to_add"
-            materialize_file "$file"
+    git diff --name-only --cached --diff-filter=AM | while read -r index_file; do
+        if grep -q "$index_file" "$files_to_add"; then
+            sed -i "s|$index_file||" "$files_to_add"
+            materialize_file "$index_file"
         fi
-    done <"$index_files"
+    done
 
-    files_to_check="$(mktmp)"
-    clean "$files_to_add" >"$files_to_check"
-    if [ "$(wc -l <"$files_to_check")" -gt 0 ]; then
-        warn "Could not edit every file:"
+    unedided_files="$(sed '/^\s*$/d' "$files_to_add" | wc -l)"
+    if [ "$unedided_files" -gt 0 ]; then
+        warn "Failed to edit $unedided_files file(s):"
         cat "$files_to_add"
     fi
 }
 
+end_of_cli_options=false
 for arg in "$@"; do
     case "$arg" in
     "--help" | "-h")
         help
         exit 0
         ;;
-    "--version" | "-v")
-        version
-        exit 0
-        ;;
     "--")
         end_of_cli_options=true
         ;;
diff --git a/pkgs/by-name/gi/git-edit-index/package.nix b/pkgs/by-name/gi/git-edit-index/package.nix
index 8ac085bf..5e855b49 100644
--- a/pkgs/by-name/gi/git-edit-index/package.nix
+++ b/pkgs/by-name/gi/git-edit-index/package.nix
@@ -1,19 +1,29 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 {
-  sysLib,
+  writeShellApplication,
+  # Dependencies
+  coreutils,
   git,
   gnused,
 }:
-sysLib.writeShellScript {
+writeShellApplication {
   name = "git-edit-index";
-  src = ./git-edit-index.sh;
-  generateCompletions = true;
+  text = builtins.readFile ./git-edit-index.sh;
 
   # `git-edit-index` starts neovim, wich might want to shell out from
-  keepPath = true;
+  inheritPath = true;
 
-  dependencies = [
+  runtimeInputs = [
+    coreutils
     git
     gnused
-    # $EDITOR
   ];
 }
diff --git a/pkgs/by-name/hi/hibernate/hibernate.sh b/pkgs/by-name/hi/hibernate/hibernate.sh
index 30868fd1..4a68e0d7 100755
--- a/pkgs/by-name/hi/hibernate/hibernate.sh
+++ b/pkgs/by-name/hi/hibernate/hibernate.sh
@@ -1,7 +1,16 @@
 #!/usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+# TODO(@bpeetz): This functionality could be moved to `tskm`. <2025-04-14>
 
 context="$(task _get rc.context)"
 [ "$context" ] && task context none
diff --git a/pkgs/by-name/hi/hibernate/package.nix b/pkgs/by-name/hi/hibernate/package.nix
index 54716606..c2e8c0b6 100644
--- a/pkgs/by-name/hi/hibernate/package.nix
+++ b/pkgs/by-name/hi/hibernate/package.nix
@@ -1,14 +1,22 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 {
-  sysLib,
+  writeShellApplication,
   systemd,
   taskwarrior3,
 }:
-sysLib.writeShellScript {
+writeShellApplication {
   name = "hibernate";
-  src = ./hibernate.sh;
-  generateCompletions = false;
-  keepPath = false;
-  dependencies = [
+  text = builtins.readFile ./hibernate.sh;
+  inheritPath = false;
+  runtimeInputs = [
     systemd
     taskwarrior3
   ];
diff --git a/pkgs/by-name/i3/i3bar-river-patched/0001-revert-use-std-io-pipe.patch b/pkgs/by-name/i3/i3bar-river-patched/0001-revert-use-std-io-pipe.patch
new file mode 100644
index 00000000..e1564753
--- /dev/null
+++ b/pkgs/by-name/i3/i3bar-river-patched/0001-revert-use-std-io-pipe.patch
@@ -0,0 +1,67 @@
+From 017ed59239e48ca689af36f1ddaec877a3c86175 Mon Sep 17 00:00:00 2001
+From: Benedikt Peetz <benedikt.peetz@b-peetz.de>
+Date: Tue, 20 May 2025 17:10:47 +0200
+Subject: [PATCH] Revert "use std::io::pipe"
+
+This reverts commit c9cee90d765198cf72c5a5155ee0d8ab566d98a9 as this
+commit requires rustc 1.87.0
+---
+ src/main.rs | 24 +++++++++++++++++++-----
+ 1 file changed, 19 insertions(+), 5 deletions(-)
+
+diff --git a/src/main.rs b/src/main.rs
+index 4a86593..2e7aeb2 100644
+--- a/src/main.rs
++++ b/src/main.rs
+@@ -18,8 +18,8 @@ mod text;
+ mod utils;
+ mod wm_info_provider;
+ 
+-use std::io::{self, ErrorKind, Read};
+-use std::os::fd::AsRawFd;
++use std::io::{self, ErrorKind};
++use std::os::fd::{AsRawFd, RawFd};
+ use std::path::PathBuf;
+ 
+ use clap::Parser;
+@@ -40,7 +40,7 @@ struct Cli {
+ fn main() -> anyhow::Result<()> {
+     let args = Cli::parse();
+ 
+-    let (mut sig_read, sig_write) = io::pipe()?;
++    let [sig_read, sig_write] = pipe(libc::O_NONBLOCK | libc::O_CLOEXEC)?;
+     signal_hook::low_level::pipe::register(SIGUSR1, sig_write)?;
+ 
+     let mut conn = Connection::connect()?;
+@@ -55,8 +55,12 @@ fn main() -> anyhow::Result<()> {
+         Ok(event_loop::Action::Keep)
+     });
+ 
+-    el.register_with_fd(sig_read.as_raw_fd(), move |ctx| {
+-        sig_read.read_exact(&mut [0u8]).unwrap();
++    el.register_with_fd(sig_read, move |ctx| {
++        let mut buf = [0u8];
++        assert_eq!(
++            unsafe { libc::read(sig_read, buf.as_mut_ptr().cast(), 1) },
++            1
++        );
+         ctx.state.toggle_visibility(ctx.conn);
+         Ok(event_loop::Action::Keep)
+     });
+@@ -104,3 +108,13 @@ fn main() -> anyhow::Result<()> {
+     el.run(&mut conn, &mut state)?;
+     unreachable!();
+ }
++
++// TODO: remove once Rust 1.87.0 is stable
++fn pipe(flags: libc::c_int) -> io::Result<[RawFd; 2]> {
++    let mut fds = [0; 2];
++    if unsafe { libc::pipe2(fds.as_mut_ptr(), flags) } == -1 {
++        Err(io::Error::last_os_error())
++    } else {
++        Ok(fds)
++    }
++}
+-- 
+2.49.0
+
diff --git a/pkgs/by-name/i3/i3bar-river-patched/0002-feat-crate-bar-Put-the-leftmost-block-in-the-middle-.patch b/pkgs/by-name/i3/i3bar-river-patched/0002-feat-crate-bar-Put-the-leftmost-block-in-the-middle-.patch
new file mode 100644
index 00000000..6f4bd528
--- /dev/null
+++ b/pkgs/by-name/i3/i3bar-river-patched/0002-feat-crate-bar-Put-the-leftmost-block-in-the-middle-.patch
@@ -0,0 +1,111 @@
+From b8568a2b626bd4d5f50ee24c304d19177bda5d4b Mon Sep 17 00:00:00 2001
+From: Benedikt Peetz <benedikt.peetz@b-peetz.de>
+Date: Tue, 20 May 2025 19:58:57 +0200
+Subject: [PATCH] feat(crate::bar): Put the leftmost block in the middle of the
+ bar
+
+This is a workaround for the limitation in the i3 blocks protocol, as
+this does not allow for centred blocks.
+---
+ src/bar.rs | 64 ++++++++++++++++++++++++++++++++++++++++++++----------
+ 1 file changed, 53 insertions(+), 11 deletions(-)
+
+diff --git a/src/bar.rs b/src/bar.rs
+index fb88150..e66c2cf 100644
+--- a/src/bar.rs
++++ b/src/bar.rs
+@@ -344,16 +344,56 @@ impl Bar {
+         }
+ 
+         // Display the blocks
+-        render_blocks(
+-            &cairo_ctx,
+-            ss,
+-            &self.output,
+-            ss.blocks_cache.get_computed(),
+-            &mut self.blocks_btns,
+-            offset_left,
+-            width_f,
+-            height_f,
+-        );
++        {
++            if !ss.blocks_cache.get_computed().is_empty() {
++                let first_block = &ss.blocks_cache.get_computed()[0];
++
++                let blocks = &ss.blocks_cache.get_computed()[1..];
++
++                let other_start = render_blocks(
++                    &cairo_ctx,
++                    ss,
++                    &self.output,
++                    blocks,
++                    &mut self.blocks_btns,
++                    offset_left,
++                    width_f,
++                    height_f,
++                );
++
++                // Draw the first block _after_ the other ones, so that we can nudge it more to the
++                // left, if the others are spanning over the middle.
++                let mut start = (width_f / 2.0) - (first_block.full.width / 2.0);
++                if start + first_block.full.width > other_start {
++                    start = other_start - first_block.full.width - first_block.block.separator_block_width as f64;
++                }
++
++                first_block.full.render(
++                    &cairo_ctx,
++                    RenderOptions {
++                        x_offset: start,
++                        bar_height: height_f,
++                        fg_color: first_block
++                            .block
++                            .color
++                            .unwrap_or(sfo!(ss, &self.output, color)),
++                        bg_color: first_block.block.background,
++                        r_left: ss.config.blocks_r,
++                        r_right: ss.config.blocks_r,
++                        overlap: ss.config.blocks_overlap,
++                    },
++                );
++
++                self.blocks_btns.push(
++                    start,
++                    first_block.full.width,
++                    (
++                        first_block.block.name.clone(),
++                        first_block.block.instance.clone(),
++                    ),
++                );
++            }
++        }
+ 
+         self.viewport
+             .set_destination(conn, self.width as i32, self.height as i32);
+@@ -428,7 +468,7 @@ fn render_blocks(
+     offset_left: f64,
+     full_width: f64,
+     full_height: f64,
+-) {
++) -> f64 {
+     context.rectangle(offset_left, 0.0, full_width - offset_left, full_height);
+     context.clip();
+ 
+@@ -513,6 +553,7 @@ fn render_blocks(
+     }
+ 
+     // Render blocks
++    let leftmost_start = full_width - blocks_width;
+     buttons.clear();
+     for series in blocks_computed {
+         let s_len = series.blocks.len();
+@@ -560,6 +601,7 @@ fn render_blocks(
+     }
+ 
+     context.reset_clip();
++    leftmost_start
+ }
+ 
+ fn layer_surface_cb(ctx: EventCtx<State, ZwlrLayerSurfaceV1>) {
+-- 
+2.49.0
+
diff --git a/pkgs/by-name/i3/i3bar-river-patched/package.nix b/pkgs/by-name/i3/i3bar-river-patched/package.nix
new file mode 100644
index 00000000..88af5d8a
--- /dev/null
+++ b/pkgs/by-name/i3/i3bar-river-patched/package.nix
@@ -0,0 +1,66 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+{
+  lib,
+  fetchFromGitHub,
+  rustPlatform,
+  pkg-config,
+  pango,
+  fetchpatch2,
+}:
+rustPlatform.buildRustPackage {
+  pname = "i3bar-river-patched";
+  version = "1.1.0-unstable-2025-05-20";
+
+  src = fetchFromGitHub {
+    owner = "MaxVerevkin";
+    repo = "i3bar-river";
+    rev = "73446cac559b10adf4beb5567a816d1be5273457";
+    hash = "sha256-NxlFKTnd2erHtSG56aWlZEkWVzBqe2hqQuVAWDdBq2c=";
+  };
+
+  useFetchCargoVendor = true;
+  cargoHash = "sha256-8sub8cXC/1iDY6v/9opO4FiLAo9CFrGJSDPNQydGvhQ=";
+
+  cargoPatches = [
+    # Add a separate theme for unfocused outputs.
+    (fetchpatch2 {
+      name = "Add support for special theme for unfocused outputs";
+      url = "https://patch-diff.githubusercontent.com/raw/MaxVerevkin/i3bar-river/pull/44.patch";
+      hash = "sha256-yH3K52kAXGW19maP77gOTHSauqQX7Px8qCZDua6wo4w=";
+    })
+
+    # TODO(@bpeetz): Remove this patch once the rustc update hits unstable. <2025-05-20>
+    ./0001-revert-use-std-io-pipe.patch
+
+    # TODO(@bpeetz): Open an issues, whether something like that could be upstreamed. <2025-05-20>
+    ./0002-feat-crate-bar-Put-the-leftmost-block-in-the-middle-.patch
+  ];
+
+  # Remove the WMs that I don't use.
+  buildNoDefaultFeatures = true;
+  buildFeatures = [
+    # "hyprland"
+    # "niri"
+    "river"
+  ];
+
+  nativeBuildInputs = [pkg-config];
+  buildInputs = [pango];
+
+  meta = with lib; {
+    description = "Port of i3bar for river";
+    homepage = "https://github.com/MaxVerevkin/i3bar-river";
+    license = licenses.gpl3Only;
+    maintainers = with maintainers; [nicegamer7];
+    mainProgram = "i3bar-river";
+    platforms = platforms.linux;
+  };
+}
diff --git a/pkgs/by-name/i3/i3status-rust-patched/package.nix b/pkgs/by-name/i3/i3status-rust-patched/package.nix
new file mode 100644
index 00000000..9f172d49
--- /dev/null
+++ b/pkgs/by-name/i3/i3status-rust-patched/package.nix
@@ -0,0 +1,34 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+{
+  i3status-rust,
+  fetchpatch2,
+}:
+i3status-rust.overrideAttrs (final: prev: {
+  pname = "${prev.pname}-patched";
+
+  patches =
+    (prev.patches or [])
+    ++ [
+      # Btrfs support for disk_space block.
+      (fetchpatch2 {
+        name = "disk_space: Support btrfs backend";
+        url = "https://patch-diff.githubusercontent.com/raw/greshake/i3status-rust/pull/2159.patch";
+        hash = "sha256-S2/biX6FTLJNfI9QVgwr+V8IGMRnSFIZnTrhc+1LvqQ=";
+      })
+
+      # Correctly calculate the used memory.
+      (fetchpatch2 {
+        name = "memory: Avoid estimating available memory, use kernel estimate instead";
+        url = "https://patch-diff.githubusercontent.com/raw/greshake/i3status-rust/pull/2160.patch";
+        hash = "sha256-1wB2KpXhC/UIxAgRioOYj/bnrzRSuaHAdbeoZ2O5E/Y=";
+      })
+    ];
+})
diff --git a/pkgs/by-name/lf/lf-make-map/.envrc b/pkgs/by-name/lf/lf-make-map/.envrc
index 2b742cf6..880b1809 100644
--- a/pkgs/by-name/lf/lf-make-map/.envrc
+++ b/pkgs/by-name/lf/lf-make-map/.envrc
@@ -1,4 +1,15 @@
 #!/usr/bin/env sh
+
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 use flake || use nix
 watch_file flake.nix
 
diff --git a/pkgs/by-name/lf/lf-make-map/.gitignore b/pkgs/by-name/lf/lf-make-map/.gitignore
index cb87f36f..8f29eabf 100644
--- a/pkgs/by-name/lf/lf-make-map/.gitignore
+++ b/pkgs/by-name/lf/lf-make-map/.gitignore
@@ -1,3 +1,13 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 # build
 /target
 /result
diff --git a/pkgs/by-name/lf/lf-make-map/Cargo.lock b/pkgs/by-name/lf/lf-make-map/Cargo.lock
index d68f7492..59154d51 100644
--- a/pkgs/by-name/lf/lf-make-map/Cargo.lock
+++ b/pkgs/by-name/lf/lf-make-map/Cargo.lock
@@ -1,5 +1,14 @@
 # This file is automatically @generated by Cargo.
 # It is not intended for manual editing.
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 version = 4
 
 [[package]]
@@ -58,20 +67,20 @@ dependencies = [
 
 [[package]]
 name = "anstyle-wincon"
-version = "3.0.7"
+version = "3.0.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e"
+checksum = "6680de5231bd6ee4c6191b8a1325daa282b415391ec9d3a37bd34f2060dc73fa"
 dependencies = [
  "anstyle",
- "once_cell",
+ "once_cell_polyfill",
  "windows-sys",
 ]
 
 [[package]]
 name = "anyhow"
-version = "1.0.97"
+version = "1.0.98"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
+checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
 
 [[package]]
 name = "autocfg"
@@ -87,9 +96,9 @@ checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
 
 [[package]]
 name = "cc"
-version = "1.2.17"
+version = "1.2.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a"
+checksum = "16595d3be041c03b09d08d0858631facccee9221e579704070e6e9e4915d3bc7"
 dependencies = [
  "shlex",
 ]
@@ -102,9 +111,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
 [[package]]
 name = "chrono"
-version = "0.4.40"
+version = "0.4.41"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c"
+checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d"
 dependencies = [
  "android-tzdata",
  "iana-time-zone",
@@ -116,9 +125,9 @@ dependencies = [
 
 [[package]]
 name = "clap"
-version = "4.5.34"
+version = "4.5.39"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e958897981290da2a852763fe9cdb89cd36977a5d729023127095fa94d95e2ff"
+checksum = "fd60e63e9be68e5fb56422e397cf9baddded06dae1d2e523401542383bc72a9f"
 dependencies = [
  "clap_builder",
  "clap_derive",
@@ -126,9 +135,9 @@ dependencies = [
 
 [[package]]
 name = "clap_builder"
-version = "4.5.34"
+version = "4.5.39"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "83b0f35019843db2160b5bb19ae09b4e6411ac33fc6a712003c33e03090e2489"
+checksum = "89cc6392a1f72bbeb820d71f32108f61fdaf18bc526e1d23954168a67759ef51"
 dependencies = [
  "anstream",
  "anstyle",
@@ -174,15 +183,15 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
 
 [[package]]
 name = "hermit-abi"
-version = "0.5.0"
+version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fbd780fe5cc30f81464441920d82ac8740e2e46b29a6fad543ddd075229ce37e"
+checksum = "f154ce46856750ed433c8649605bf7ed2de3bc35fd9d2a9f30cddd873c80cb08"
 
 [[package]]
 name = "iana-time-zone"
-version = "0.1.62"
+version = "0.1.63"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2fd658b06e56721792c5df4475705b6cda790e9298d19d2f8af083457bcd127"
+checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8"
 dependencies = [
  "android_system_properties",
  "core-foundation-sys",
@@ -230,11 +239,21 @@ dependencies = [
 ]
 
 [[package]]
+name = "keymaps"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2a522bbaa39bddd54945580e369ed37113ea96f4cb8f0322be0d5e04aa4d7293"
+dependencies = [
+ "thiserror",
+]
+
+[[package]]
 name = "lf-make-map"
 version = "0.1.0"
 dependencies = [
  "anyhow",
  "clap",
+ "keymaps",
  "log",
  "stderrlog",
  "walkdir",
@@ -242,9 +261,9 @@ dependencies = [
 
 [[package]]
 name = "libc"
-version = "0.2.171"
+version = "0.2.172"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
+checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
 
 [[package]]
 name = "log"
@@ -268,10 +287,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
 
 [[package]]
+name = "once_cell_polyfill"
+version = "1.70.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
+
+[[package]]
 name = "proc-macro2"
-version = "1.0.94"
+version = "1.0.95"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
+checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
 dependencies = [
  "unicode-ident",
 ]
@@ -287,9 +312,9 @@ dependencies = [
 
 [[package]]
 name = "rustversion"
-version = "1.0.20"
+version = "1.0.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2"
+checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d"
 
 [[package]]
 name = "same-file"
@@ -327,9 +352,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
 
 [[package]]
 name = "syn"
-version = "2.0.100"
+version = "2.0.101"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
+checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -346,6 +371,26 @@ dependencies = [
 ]
 
 [[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"
@@ -446,11 +491,37 @@ dependencies = [
 
 [[package]]
 name = "windows-core"
-version = "0.52.0"
+version = "0.61.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
+checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
 dependencies = [
- "windows-targets",
+ "windows-implement",
+ "windows-interface",
+ "windows-link",
+ "windows-result",
+ "windows-strings",
+]
+
+[[package]]
+name = "windows-implement"
+version = "0.60.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "windows-interface"
+version = "0.59.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
 ]
 
 [[package]]
@@ -460,6 +531,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
 
 [[package]]
+name = "windows-result"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
+dependencies = [
+ "windows-link",
+]
+
+[[package]]
+name = "windows-strings"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
+dependencies = [
+ "windows-link",
+]
+
+[[package]]
 name = "windows-sys"
 version = "0.59.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/pkgs/by-name/lf/lf-make-map/Cargo.toml b/pkgs/by-name/lf/lf-make-map/Cargo.toml
index d2427d73..2adc4797 100644
--- a/pkgs/by-name/lf/lf-make-map/Cargo.toml
+++ b/pkgs/by-name/lf/lf-make-map/Cargo.toml
@@ -1,14 +1,25 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 [package]
 name = "lf-make-map"
 description = "An automatic lf cd mapping generator"
 version = "0.1.0"
-edition = "2021"
+edition = "2024"
 
 # 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", "env"] }
+anyhow = "1.0.98"
+clap = { version = "4.5.39", features = ["derive", "env"] }
+keymaps = "1.1.1"
 log = "0.4.27"
 stderrlog = "0.6.0"
 walkdir = "2.5.0"
diff --git a/pkgs/by-name/lf/lf-make-map/README.md b/pkgs/by-name/lf/lf-make-map/README.md
index 0c57cede..4d5dc95c 100644
--- a/pkgs/by-name/lf/lf-make-map/README.md
+++ b/pkgs/by-name/lf/lf-make-map/README.md
@@ -1,3 +1,15 @@
+<!--
+nixos-config - My current NixOS configuration
+
+Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+SPDX-License-Identifier: GPL-3.0-or-later
+
+This file is part of my nixos-config.
+
+You should have received a copy of the License along with this program.
+If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+-->
+
 # Lf make map
 
 > An automatic lf cd mapping generator
diff --git a/pkgs/by-name/lf/lf-make-map/flake.lock b/pkgs/by-name/lf/lf-make-map/flake.lock
index c9c523d9..280e8a51 100644
--- a/pkgs/by-name/lf/lf-make-map/flake.lock
+++ b/pkgs/by-name/lf/lf-make-map/flake.lock
@@ -1,63 +1,12 @@
 {
   "nodes": {
-    "crane": {
-      "locked": {
-        "lastModified": 1742394900,
-        "narHash": "sha256-vVOAp9ahvnU+fQoKd4SEXB2JG2wbENkpqcwlkIXgUC0=",
-        "owner": "ipetkov",
-        "repo": "crane",
-        "rev": "70947c1908108c0c551ddfd73d4f750ff2ea67cd",
-        "type": "github"
-      },
-      "original": {
-        "owner": "ipetkov",
-        "repo": "crane",
-        "type": "github"
-      }
-    },
-    "flake-compat": {
-      "flake": false,
-      "locked": {
-        "lastModified": 1733328505,
-        "narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=",
-        "owner": "edolstra",
-        "repo": "flake-compat",
-        "rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec",
-        "type": "github"
-      },
-      "original": {
-        "owner": "edolstra",
-        "repo": "flake-compat",
-        "type": "github"
-      }
-    },
-    "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": 1743076231,
-        "narHash": "sha256-yQugdVfi316qUfqzN8JMaA2vixl+45GxNm4oUfXlbgw=",
+        "lastModified": 1748406211,
+        "narHash": "sha256-B3BsCRbc+x/d0WiG1f+qfSLUy+oiIfih54kalWBi+/M=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "6c5963357f3c1c840201eda129a99d455074db04",
+        "rev": "3d1f29646e4b57ed468d60f9d286cde23a8d1707",
         "type": "github"
       },
       "original": {
@@ -69,68 +18,7 @@
     },
     "root": {
       "inputs": {
-        "crane": "crane",
-        "flake-compat": "flake-compat",
-        "flake-utils": "flake-utils",
-        "nixpkgs": "nixpkgs",
-        "rust-overlay": "rust-overlay",
-        "systems": "systems",
-        "treefmt-nix": "treefmt-nix"
-      }
-    },
-    "rust-overlay": {
-      "inputs": {
-        "nixpkgs": [
-          "nixpkgs"
-        ]
-      },
-      "locked": {
-        "lastModified": 1743215516,
-        "narHash": "sha256-52qbrkG65U1hyrQWltgHTgH4nm0SJL+9TWv2UDCEPNI=",
-        "owner": "oxalica",
-        "repo": "rust-overlay",
-        "rev": "524463199fdee49338006b049bc376b965a2cfed",
-        "type": "github"
-      },
-      "original": {
-        "owner": "oxalica",
-        "repo": "rust-overlay",
-        "type": "github"
-      }
-    },
-    "systems": {
-      "locked": {
-        "lastModified": 1680978846,
-        "narHash": "sha256-Gtqg8b/v49BFDpDetjclCYXm8mAnTrUzR0JnE2nv5aw=",
-        "owner": "nix-systems",
-        "repo": "x86_64-linux",
-        "rev": "2ecfcac5e15790ba6ce360ceccddb15ad16d08a8",
-        "type": "github"
-      },
-      "original": {
-        "owner": "nix-systems",
-        "repo": "x86_64-linux",
-        "type": "github"
-      }
-    },
-    "treefmt-nix": {
-      "inputs": {
-        "nixpkgs": [
-          "nixpkgs"
-        ]
-      },
-      "locked": {
-        "lastModified": 1743081648,
-        "narHash": "sha256-WRAylyYptt6OX5eCEBWyTwOEqEtD6zt33rlUkr6u3cE=",
-        "owner": "numtide",
-        "repo": "treefmt-nix",
-        "rev": "29a3d7b768c70addce17af0869f6e2bd8f5be4b7",
-        "type": "github"
-      },
-      "original": {
-        "owner": "numtide",
-        "repo": "treefmt-nix",
-        "type": "github"
+        "nixpkgs": "nixpkgs"
       }
     }
   },
diff --git a/pkgs/by-name/lf/lf-make-map/flake.lock.license b/pkgs/by-name/lf/lf-make-map/flake.lock.license
new file mode 100644
index 00000000..eae6a84c
--- /dev/null
+++ b/pkgs/by-name/lf/lf-make-map/flake.lock.license
@@ -0,0 +1,9 @@
+nixos-config - My current NixOS configuration
+
+Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+SPDX-License-Identifier: GPL-3.0-or-later
+
+This file is part of my nixos-config.
+
+You should have received a copy of the License along with this program.
+If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
diff --git a/pkgs/by-name/lf/lf-make-map/flake.nix b/pkgs/by-name/lf/lf-make-map/flake.nix
index dc8c24cc..20925aca 100644
--- a/pkgs/by-name/lf/lf-make-map/flake.nix
+++ b/pkgs/by-name/lf/lf-make-map/flake.nix
@@ -1,125 +1,34 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 {
   description = "An automatic lf cd mapping generator";
 
   inputs = {
     nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
+  };
 
-    treefmt-nix = {
-      url = "github:numtide/treefmt-nix";
-      inputs = {
-        nixpkgs.follows = "nixpkgs";
-      };
-    };
-
-    crane = {
-      url = "github:ipetkov/crane";
-      inputs = {
-        nixpkgs.follows = "nixpkgs";
-      };
-    };
-    rust-overlay = {
-      url = "github:oxalica/rust-overlay";
-      inputs = {
-        nixpkgs.follows = "nixpkgs";
-        flake-utils.follows = "flake-utils";
-      };
-    };
-
-    # inputs for following
-    systems = {
-      url = "github:nix-systems/x86_64-linux"; # only evaluate for this system
-    };
-    flake-compat = {
-      url = "github:edolstra/flake-compat";
-      flake = false;
-    };
-    flake-utils = {
-      url = "github:numtide/flake-utils";
-      inputs = {
-        systems.follows = "systems";
-      };
+  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
+      ];
     };
   };
-
-  outputs = {
-    self,
-    nixpkgs,
-    flake-utils,
-    treefmt-nix,
-    crane,
-    rust-overlay,
-    ...
-  }:
-    flake-utils.lib.eachDefaultSystem (system: let
-      pkgs = import nixpkgs {
-        inherit system;
-        overlays = [(import rust-overlay)];
-      };
-
-      nightly = false;
-      rust_minimal =
-        if nightly
-        then pkgs.rust-bin.selectLatestNightlyWith (toolchain: toolchain.minimal)
-        else pkgs.rust-bin.stable.latest.minimal;
-      rust_default =
-        if nightly
-        then pkgs.rust-bin.selectLatestNightlyWith (toolchain: toolchain.default)
-        else pkgs.rust-bin.stable.latest.default;
-
-      cargo_toml = craneLib.cleanCargoToml {cargoToml = ./Cargo.toml;};
-      pname = cargo_toml.package.name;
-
-      craneLib = (crane.mkLib pkgs).overrideToolchain rust_minimal;
-      craneBuild = craneLib.buildPackage {
-        src = craneLib.cleanCargoSource ./.;
-
-        doCheck = true;
-      };
-
-      manual = pkgs.stdenv.mkDerivation {
-        name = "${pname}-manual";
-        inherit (cargo_toml.package) version;
-
-        src = ./docs;
-        nativeBuildInputs = with pkgs; [pandoc];
-
-        buildPhase = ''
-          mkdir --parents $out/docs;
-
-          pandoc "./${pname}.1.md" -s -t man > $out/docs/${pname}.1
-        '';
-
-        installPhase = ''
-          install -D $out/docs/${pname}.1  $out/share/man/man1/${pname};
-        '';
-      };
-
-      treefmtEval = import ./treefmt.nix {inherit treefmt-nix pkgs;};
-    in {
-      packages.default = pkgs.symlinkJoin {
-        inherit (cargo_toml.package) name;
-
-        paths = [manual craneBuild];
-      };
-
-      checks = {
-        inherit craneBuild;
-        formatting = treefmtEval.config.build.check self;
-      };
-
-      formatter = treefmtEval.config.build.wrapper;
-
-      devShells.default = pkgs.mkShell {
-        packages = with pkgs; [
-          cocogitto
-
-          rust_default
-          cargo-edit
-
-          licensure
-        ];
-      };
-    });
 }
 # vim: ts=2
 
diff --git a/pkgs/by-name/lf/lf-make-map/package.nix b/pkgs/by-name/lf/lf-make-map/package.nix
index 8404927f..8f77c843 100644
--- a/pkgs/by-name/lf/lf-make-map/package.nix
+++ b/pkgs/by-name/lf/lf-make-map/package.nix
@@ -1,3 +1,12 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 {rustPlatform}:
 rustPlatform.buildRustPackage {
   pname = "lf-make-map";
diff --git a/pkgs/by-name/lf/lf-make-map/src/cli.rs b/pkgs/by-name/lf/lf-make-map/src/cli.rs
index a398e451..70746984 100644
--- a/pkgs/by-name/lf/lf-make-map/src/cli.rs
+++ b/pkgs/by-name/lf/lf-make-map/src/cli.rs
@@ -1,3 +1,13 @@
+// nixos-config - My current NixOS configuration
+//
+// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+// This file is part of my nixos-config.
+//
+// You should have received a copy of the License along with this program.
+// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 use std::path::PathBuf;
 
 use clap::{ArgAction, Parser, Subcommand};
diff --git a/pkgs/by-name/lf/lf-make-map/src/main.rs b/pkgs/by-name/lf/lf-make-map/src/main.rs
index aaf79b20..d5d934e1 100644
--- a/pkgs/by-name/lf/lf-make-map/src/main.rs
+++ b/pkgs/by-name/lf/lf-make-map/src/main.rs
@@ -1,13 +1,23 @@
+// nixos-config - My current NixOS configuration
+//
+// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+// This file is part of my nixos-config.
+//
+// You should have received a copy of the License along with this program.
+// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 use std::path::{Path, PathBuf};
 
 use anyhow::{Context, Result};
 use clap::Parser;
 use cli::{Args, Command};
 use log::trace;
-use mapping::map_tree::MappingTree;
+use mapping::map_key::MapKey;
 use walkdir::{DirEntry, WalkDir};
 
-use crate::mapping::MapKey;
+use crate::mapping::MappingsTrie;
 
 mod cli;
 mod mapping;
@@ -24,7 +34,7 @@ fn main() -> anyhow::Result<()> {
         .timestamp(stderrlog::Timestamp::Off)
         .init()?;
 
-    let mut mappings = MappingTree::new();
+    let mut mappings = MappingsTrie::new();
 
     let relevant_directories = match &args.command {
         Command::Visualize { options } => &options.relevant_directories,
@@ -32,68 +42,62 @@ fn main() -> anyhow::Result<()> {
     };
 
     for dir in relevant_directories {
-        trace!("Processing '{}'..", dir.display());
-        let path = strip_path(&dir, &args.home_name)?;
+        trace!("START Processing '{}'..", dir.display());
+        let path = strip_path(dir, &args.home_name)?;
 
         mappings
             .include(path_to_str(path)?)
             .with_context(|| format!("Failed to include path: '{}'", path.display()))?;
+        trace!("END Finished processing {}.", dir.display());
+    }
+
+    trace!("Generated mappings for the relevant directories. Starting expanding to max depth.");
+    if log::log_enabled!(log::Level::Trace) {
+        eprintln!("{mappings}");
     }
 
     let home = path_to_str(&args.home_name)?.to_owned();
 
     let mut current_depth = 1;
     while current_depth != args.depth {
-        for (key, value) in mappings.iter(false) {
-            trace!(
-                "Adding to child ('{}' -> '{}')",
-                MapKey::display(&key),
-                value
-            );
-
-            let mut local_mappings = MappingTree::new();
-            for dir in WalkDir::new(extend(&home, &value)?)
+        for (keys, child) in mappings.0.iter().filter(|(_, child)| child.expendable) {
+            trace!("Adding to child '{}' ('{}')", MapKey::display(&keys), child);
+
+            let mut local_mappings = MappingsTrie::new();
+            for dir in WalkDir::new(extend(&home, &child.path)?)
                 .min_depth(1)
                 .max_depth(1)
                 .into_iter()
                 .filter_entry(|e| is_dir(e) && !is_hidden(e))
             {
-                let directory = dir
-                    .with_context(|| format!("Failed to read dir ('{}')", home.clone() + &value))?;
-                let path_to_strip = &PathBuf::from(extend(&home, &value)?);
-                let path = strip_path(&directory.path(), &path_to_strip)?;
+                let directory = dir.with_context(|| {
+                    format!("Failed to read dir ('{}')", home.clone() + &child.path)
+                })?;
+                let path_to_strip = &PathBuf::from(extend(&home, &child.path)?);
+                let path = strip_path(directory.path(), path_to_strip)?;
                 trace!(
-                    "Including: '{}' (after stripping '{}' from '{}' -> '{}' + '/' + '{}')",
+                    "Including: '{}' (after stripping '{}' from '{}')",
                     path.display(),
-                    directory.path().display(),
                     path_to_strip.display(),
-                    home,
-                    value
+                    directory.path().display(),
                 );
 
                 let gen_key = MapKey::new_ones_from_path(path_to_str(path)?, 1);
                 local_mappings
                     .insert(
                         &gen_key,
-                        path_to_str(strip_path(&directory.path(), &PathBuf::from(&home))?)?,
+                        path_to_str(strip_path(directory.path(), &PathBuf::from(&home))?)?,
                     )
                     .with_context(|| format!("Failed to include path: '{}'", path.display()))?;
             }
 
-            trace!("{}", local_mappings);
-
-            trace!(
-                "'{}' -> '{:#?}'",
-                MapKey::display(&key),
-                local_mappings.root_node()
-            );
-            mappings.interleave(&key, local_mappings.root_node().to_owned())?;
+            mappings.add_trie(&keys, local_mappings)?;
         }
         current_depth += 1;
     }
 
     match args.command {
-        Command::Visualize { .. } => println!("{}", mappings),
+        Command::Visualize { .. } => println!("{}", mappings.0),
         Command::Generate { .. } => println!("{}", mappings.to_lf_mappings(args.home_name)),
     }
 
@@ -120,7 +124,7 @@ fn is_dir(entry: &DirEntry) -> bool {
 }
 
 fn strip_path<'a>(path: &'a Path, to_strip: &Path) -> Result<&'a Path> {
-    path.strip_prefix(&to_strip).with_context(|| {
+    path.strip_prefix(to_strip).with_context(|| {
         format!(
             "'{}' is not under the specified home path ('{}')!",
             path.display(),
diff --git a/pkgs/by-name/lf/lf-make-map/src/mapping/lf_mapping.rs b/pkgs/by-name/lf/lf-make-map/src/mapping/lf_mapping.rs
new file mode 100644
index 00000000..f8a6182e
--- /dev/null
+++ b/pkgs/by-name/lf/lf-make-map/src/mapping/lf_mapping.rs
@@ -0,0 +1,35 @@
+// nixos-config - My current NixOS configuration
+//
+// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+// This file is part of my nixos-config.
+//
+// You should have received a copy of the License along with this program.
+// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+use std::path::PathBuf;
+
+use crate::mapping::MapKey;
+
+use super::MappingsTrie;
+
+impl MappingsTrie {
+    pub fn to_lf_mappings(&self, home_path: PathBuf) -> String {
+        let mut raw = self
+            .0
+            .iter()
+            .map(|(key, value)| {
+                format!(
+                    "map g{} cd \"{}\"\n",
+                    MapKey::display(&key),
+                    home_path.join(&value.path).display()
+                )
+            })
+            .collect::<Vec<String>>();
+
+        raw.sort();
+
+        raw.into_iter().collect()
+    }
+}
diff --git a/pkgs/by-name/lf/lf-make-map/src/mapping/map_key.rs b/pkgs/by-name/lf/lf-make-map/src/mapping/map_key.rs
new file mode 100644
index 00000000..10b612fd
--- /dev/null
+++ b/pkgs/by-name/lf/lf-make-map/src/mapping/map_key.rs
@@ -0,0 +1,274 @@
+// nixos-config - My current NixOS configuration
+//
+// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+// This file is part of my nixos-config.
+//
+// You should have received a copy of the License along with this program.
+// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+use std::fmt::Write;
+
+use anyhow::bail;
+use log::debug;
+
+#[derive(Clone, Debug)]
+pub struct MapKey {
+    pub key: char,
+
+    pub(crate) resolution: usize,
+
+    /// Part of the path, used to derive the key
+    pub(crate) part_path: String,
+}
+
+impl std::hash::Hash for MapKey {
+    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
+        self.key.hash(state)
+    }
+}
+
+impl Eq for MapKey {}
+impl PartialEq for MapKey {
+    fn eq(&self, other: &Self) -> bool {
+        self.key == other.key
+    }
+}
+
+impl Ord for MapKey {
+    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
+        self.key.cmp(&other.key)
+    }
+}
+impl PartialOrd for MapKey {
+    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
+        Some(self.cmp(other))
+    }
+}
+
+impl MapKey {
+    pub fn new_from_part_path(part_path: &str, resolution: usize) -> Vec<Self> {
+        let key = Self::part_path_to_key(part_path, resolution);
+
+        key.chars()
+            .map(|ch| Self {
+                key: ch,
+                resolution,
+                part_path: part_path.to_owned(),
+            })
+            .collect()
+    }
+
+    pub fn new_ones_from_path(path: &str, number_of_chars: usize) -> Vec<Self> {
+        let key: Vec<MapKey> = path
+            .split('/')
+            .flat_map(|part| Self::new_from_part_path(part, number_of_chars))
+            .collect();
+
+        debug!(
+            "Generated full MapKeys: '{}' -> '{}'",
+            path,
+            MapKey::display(&key)
+        );
+        key
+    }
+
+    pub fn increment(&self, target_resolution: usize) -> Vec<Self> {
+        let new_resolution = target_resolution;
+
+        // debug!("Incrementing: '{}' ('{}')", &self, &self.part_path);
+
+        let added_chars = if new_resolution < self.part_path.len() {
+            MapKey::part_path_to_key(&self.part_path, new_resolution)
+        } else {
+            let mut generated_chars =
+                MapKey::part_path_to_key(&self.part_path, self.part_path.len());
+
+            generated_chars.extend(
+                (0..(new_resolution - self.part_path.len()))
+                    .into_iter()
+                    .map(|_| self.part_path.chars().last().expect("This will exists")),
+            );
+
+            generated_chars
+        };
+
+        let part_path = self.part_path.clone();
+        let output: Vec<Self> = added_chars
+            .chars()
+            .enumerate()
+            .map(|(res, ch)| MapKey {
+                key: ch,
+                resolution: res + 1,
+                part_path: part_path.clone(),
+            })
+            .collect();
+
+        // debug!("Finished increment: '{}' ('{}')", MapKey::display(&output), output[0].part_path);
+        output
+    }
+
+    pub fn display(values: &[Self]) -> String {
+        values.iter().map(|value| value.key.clone()).collect()
+    }
+
+    fn part_path_to_key(part: &str, number_of_chars: usize) -> String {
+        fn make(pat: char, part: &str, number_of_chars: usize) -> String {
+            let mut acc = String::new();
+
+            if !part.split(pat).all(|part| part.len() > 0) {
+                panic!(
+                    "\
+Can't turn this path '{}' to a mapping.
+This should not happen, please report the bug!",
+                    part
+                )
+            }
+
+            let mut last_working = None;
+            for i in 0..number_of_chars {
+                for str in part.split(pat) {
+                    if acc.len() != number_of_chars {
+                        acc.push(match str.chars().nth(i) {
+                            Some(ch) => ch,
+                            None => {
+                                if let Some(last) = last_working {
+                                    str.chars().nth(last).expect("This should always exist")
+                                } else {
+                                    last_working = Some(i - 1);
+                                    str.chars().nth(i - 1).expect("This should always exist")
+                                }
+                            }
+                        })
+                    }
+                }
+            }
+
+            acc
+        }
+
+        let value = if part.contains('_') && !part.starts_with('_') && !part.ends_with('_') {
+            make('_', part, number_of_chars)
+        } else if part.contains('-') && !part.starts_with('-') && !part.ends_with('-') {
+            make('-', part, number_of_chars)
+        } else {
+            part.chars().take(number_of_chars).collect::<String>()
+        };
+
+        assert_eq!(
+            value.len(),
+            number_of_chars,
+            "'{}' does not have expected length of: {}",
+            value,
+            number_of_chars
+        );
+        value
+    }
+
+    /// Checks whether a tiebreak via the [`Self::increment`] function can result in unique keys.
+    pub fn can_tiebreak_with(&self, other: &Self) -> anyhow::Result<()> {
+        /// Check whether the `input` &str is composed of only one character.
+        /// If so, returns this character, otherwise returns None.
+        fn reduce_string(input: &str) -> Option<char> {
+            let first_char = input
+                .chars()
+                .take(1)
+                .last()
+                .expect("Should contain one char");
+
+            if input.chars().all(|ch| ch == first_char) {
+                Some(first_char)
+            } else {
+                None
+            }
+        }
+
+        /// Check whether `a` is a subset of `b` or `b` is a subset of `a`.
+        fn is_subset_either(a: &str, b: &str) -> bool {
+            /// Checks if `subset` is a subset of `set`.
+            ///
+            /// # Examples
+            /// ```
+            /// let a = "a";
+            /// let b = "aa";
+            /// assert!(is_subset(a, b))
+            /// ```
+            ///
+            /// ```
+            /// let a = "abc";
+            /// let b = "def";
+            /// assert!(!is_subset(a, b))
+            /// ```
+            fn is_subset(subset: &str, set: &str) -> bool {
+                let prefix: String = set.chars().take(subset.len()).collect();
+                let suffix: String = set.chars().skip(subset.len()).collect();
+
+                if prefix == subset {
+                    let clean_suffix = reduce_string(&suffix);
+                    if let Some(ch) = clean_suffix {
+                        ch == subset.chars().last().expect("Will exists")
+                    } else {
+                        false
+                    }
+                } else {
+                    false
+                }
+            }
+
+            match a.len().cmp(&b.len()) {
+                std::cmp::Ordering::Less => {
+                    // `b` is the longer string. As such we need to check if `a` is a subset of `b`.
+                    is_subset(a, b)
+                }
+                std::cmp::Ordering::Greater => {
+                    // `a` is the longer string. As such we need to check if `b` is a subset of `a`.
+                    is_subset(b, a)
+                }
+                std::cmp::Ordering::Equal => a == b,
+            }
+        }
+
+        if reduce_string(&other.part_path)
+            .is_some_and(|a| Some(a) == reduce_string(&self.part_path))
+        {
+            bail!(
+                "\
+The foreign_key ('{}', path_part: '{}' -> '{}') and our_key ('{}', path_part: '{}' -> '{}') \
+have an identical path_part (when duplicated chars are removed)!
+I cannot extended them via incrementation.
+Please rename the paths to fix this.
+                        ",
+                other,
+                &other.part_path,
+                reduce_string(&other.part_path).expect("Is some here"),
+                self,
+                &self.part_path,
+                reduce_string(&self.part_path).expect("Is some here"),
+            );
+        }
+
+        if is_subset_either(&other.part_path, &self.part_path) {
+            bail!(
+                "\
+The foreign_key ('{}', path_part: '{}') and our_key ('{}', path_part: '{}') \
+are subsets of one another!
+A discrimination through incrementation will not work!
+Please rename the paths to fix this.
+                        ",
+                other,
+                &other.part_path,
+                self,
+                &self.part_path,
+            );
+        }
+
+        Ok(())
+    }
+}
+
+impl std::fmt::Display for MapKey {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        f.write_char(self.key)
+    }
+}
diff --git a/pkgs/by-name/lf/lf-make-map/src/mapping/map_tree/display.rs b/pkgs/by-name/lf/lf-make-map/src/mapping/map_tree/display.rs
deleted file mode 100644
index 65302e1e..00000000
--- a/pkgs/by-name/lf/lf-make-map/src/mapping/map_tree/display.rs
+++ /dev/null
@@ -1,91 +0,0 @@
-use std::fmt::Display;
-
-use crate::mapping::{
-    map_tree::{Node, NodeValue},
-    MapKey,
-};
-
-use super::MappingTree;
-
-impl Display for MappingTree {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        fn write_node(
-            f: &mut std::fmt::Formatter<'_>,
-            node: &Node,
-            indention: String,
-            location: Vec<MapKey>,
-            is_last: bool,
-            is_root: bool,
-        ) -> std::fmt::Result {
-            let node_value = match &node.value {
-                NodeValue::Parent { children: _ } => "<Parent>".to_owned(),
-                NodeValue::Child { path, extandable } => {
-                    path.to_owned() + if *extandable { " [exten.]" } else { " [stop]" }
-                }
-            };
-
-            let new_idention = indention.clone()
-                + if is_root {
-                    ""
-                } else {
-                    match is_last {
-                        true => "    ",
-                        false => "│   ",
-                    }
-                };
-
-            let bullet = match is_last {
-                true => String::from("└── "),
-                false => String::from("├── "),
-            };
-
-            if is_root {
-                write!(f, ": {}\n", node_value)?;
-            } else {
-                write!(
-                    f,
-                    "{}{}\x1b[1;33m{}\x1b[0m: {}\n",
-                    indention,
-                    bullet,
-                    MapKey::display(&location),
-                    node_value,
-                )?;
-            };
-
-            match &node.value {
-                NodeValue::Parent { children } => {
-                    let mut children_vec: Vec<(&MapKey, &Node)> = children.iter().collect();
-                    children_vec.sort_by(|(a, _), (b, _)| a.key.cmp(&b.key));
-
-                    let mut counter = 1;
-                    for (key, child) in &children_vec {
-                        let mut new_location = location.clone();
-                        new_location.push((*key).to_owned());
-
-                        write_node(
-                            f,
-                            child,
-                            new_idention.clone(),
-                            new_location.clone(),
-                            counter == children_vec.len(),
-                            false,
-                        )?;
-                        counter += 1;
-                    }
-                }
-                NodeValue::Child {
-                    path: _,
-                    extandable: _,
-                } => {
-                    // Do nothing and stop the recursion
-                }
-            }
-
-            Ok(())
-        }
-
-        write_node(f, &self.root, String::new(), vec![], false, true)?;
-
-        Ok(())
-    }
-}
diff --git a/pkgs/by-name/lf/lf-make-map/src/mapping/map_tree/iterator.rs b/pkgs/by-name/lf/lf-make-map/src/mapping/map_tree/iterator.rs
deleted file mode 100644
index 4364bb2b..00000000
--- a/pkgs/by-name/lf/lf-make-map/src/mapping/map_tree/iterator.rs
+++ /dev/null
@@ -1,53 +0,0 @@
-use crate::mapping::MapKey;
-
-use super::{MappingTree, Node, NodeValue};
-
-pub struct MappingTreeIterator {
-    children: Vec<(Vec<MapKey>, String)>,
-}
-
-impl MappingTreeIterator {
-    pub fn new(tree: &MappingTree, ignore_extendable: bool) -> Self {
-        let children = extract_child(vec![], &tree.root, ignore_extendable);
-
-        Self { children }
-    }
-}
-
-fn extract_child(
-    current_key: Vec<MapKey>,
-    node: &Node,
-    ignore_extendable: bool,
-) -> Vec<(Vec<MapKey>, String)> {
-    match &node.value {
-        NodeValue::Parent { children } => children
-            .iter()
-            .map(|(key, value)| {
-                let mut new_key = current_key.clone();
-                new_key.push(key.to_owned());
-
-                extract_child(new_key, value, ignore_extendable)
-            })
-            .flatten()
-            .collect(),
-        NodeValue::Child { path, extandable } => {
-            if ignore_extendable {
-                vec![(current_key, path.to_string())]
-            } else {
-                if *extandable {
-                    vec![(current_key, path.to_string())]
-                } else {
-                    vec![]
-                }
-            }
-        }
-    }
-}
-
-impl Iterator for MappingTreeIterator {
-    type Item = (Vec<MapKey>, String);
-
-    fn next(&mut self) -> Option<Self::Item> {
-        self.children.pop()
-    }
-}
diff --git a/pkgs/by-name/lf/lf-make-map/src/mapping/map_tree/lf_mapping.rs b/pkgs/by-name/lf/lf-make-map/src/mapping/map_tree/lf_mapping.rs
deleted file mode 100644
index ba485dc2..00000000
--- a/pkgs/by-name/lf/lf-make-map/src/mapping/map_tree/lf_mapping.rs
+++ /dev/null
@@ -1,24 +0,0 @@
-use std::path::PathBuf;
-
-use crate::mapping::MapKey;
-
-use super::MappingTree;
-
-impl MappingTree {
-    pub fn to_lf_mappings(self, home_path: PathBuf) -> String {
-        let mut raw = self
-            .iter(true)
-            .map(|(key, value)| {
-                format!(
-                    "map g{} cd \"{}\"\n",
-                    MapKey::display(&key),
-                    home_path.join(&value).display()
-                )
-            })
-            .collect::<Vec<String>>();
-
-        raw.sort();
-
-        raw.into_iter().collect()
-    }
-}
diff --git a/pkgs/by-name/lf/lf-make-map/src/mapping/map_tree/mod.rs b/pkgs/by-name/lf/lf-make-map/src/mapping/map_tree/mod.rs
deleted file mode 100644
index 35e6d91d..00000000
--- a/pkgs/by-name/lf/lf-make-map/src/mapping/map_tree/mod.rs
+++ /dev/null
@@ -1,402 +0,0 @@
-use std::{collections::HashMap, mem};
-
-use anyhow::{bail, Result};
-use log::debug;
-
-use self::iterator::MappingTreeIterator;
-
-use super::MapKey;
-
-pub mod display;
-pub mod iterator;
-pub mod lf_mapping;
-
-/// A prefix tree
-#[derive(Debug)]
-pub struct MappingTree {
-    root: Node,
-}
-
-#[derive(Clone, Debug, PartialEq, Eq)]
-pub enum NodeValue {
-    Parent { children: HashMap<MapKey, Node> },
-    Child { path: String, extandable: bool },
-}
-
-#[derive(Clone, Debug, PartialEq, Eq)]
-pub struct Node {
-    value: NodeValue,
-}
-
-impl MappingTree {
-    pub fn new() -> Self {
-        Self {
-            root: Node::new_parent(),
-        }
-    }
-
-    pub fn root_node(&self) -> &Node {
-        &self.root
-    }
-
-    pub fn iter(&self, ignore_extendable: bool) -> MappingTreeIterator {
-        MappingTreeIterator::new(&self, ignore_extendable)
-    }
-
-    /// Returns the node at the key, otherwise None. The node can be changed
-    pub fn get_mut(&mut self, key: &[MapKey]) -> Option<&mut Node> {
-        let mut current_node = &mut self.root;
-        for ch in key.iter() {
-            if let NodeValue::Parent { children } = &mut current_node.value {
-                current_node = children.get_mut(&ch)?
-            } else {
-                return None;
-            }
-        }
-
-        Some(current_node)
-    }
-
-    /// Returns the node at the key, otherwise the last node that matched.
-    pub fn try_get(&self, key: &[MapKey]) -> (&Node, Vec<MapKey>) {
-        let mut current_node = &self.root;
-        let mut current_key = vec![];
-
-        for ch in key.iter() {
-            if let NodeValue::Parent { children } = &current_node.value {
-                current_node = if let Some(node) = children.get(&ch) {
-                    let (key, _value) = children
-                        .get_key_value(&ch)
-                        .expect("This exists, we checked");
-                    current_key.push(key.clone());
-
-                    node
-                } else {
-                    return (current_node, current_key);
-                };
-            } else {
-                return (current_node, current_key);
-            }
-        }
-
-        (current_node, current_key)
-    }
-
-    pub fn include(&mut self, path: &str) -> Result<()> {
-        let associated_key = MapKey::new_ones_from_path(path, 1);
-        self.insert(&associated_key, path)
-    }
-
-    pub fn insert(&mut self, key: &[MapKey], path: &str) -> Result<()> {
-        self.insert_node(key, Node::new_child(path.to_owned()))
-    }
-
-    pub fn interleave(&mut self, key: &[MapKey], node: Node) -> Result<()> {
-        let want_to_be_parent = self.get_mut(&key).expect("This value exists");
-        let (parent_value, _parent_children) = if let NodeValue::Parent { children } = node.value {
-            (
-                NodeValue::Parent {
-                    children: children.clone(),
-                },
-                children,
-            )
-        } else {
-            unreachable!("This value will be a parent")
-        };
-
-        let child_value = mem::replace(&mut want_to_be_parent.value, parent_value);
-        assert!(matches!(
-            child_value,
-            NodeValue::Child {
-                path: _,
-                extandable: _
-            }
-        ));
-
-        let child_value = if let NodeValue::Child {
-            path,
-            extandable: _,
-        } = child_value
-        {
-            NodeValue::Child {
-                path,
-                extandable: false,
-            }
-        } else {
-            unreachable!("This is only a child value")
-        };
-
-        let child = Node { value: child_value };
-
-        let mut new_key = key.to_vec();
-        new_key.push(MapKey {
-            key: '.',
-            part_path: ".".to_owned(),
-            resolution: 1,
-        });
-        self.insert_node(&new_key, child)?;
-        Ok(())
-    }
-
-    pub fn insert_node(&mut self, key: &[MapKey], node: Node) -> Result<()> {
-        let (_node, found_key) = self.try_get(key).clone();
-
-        if found_key != key {
-            let needed_nodes_key = key
-                .strip_prefix(&found_key[..])
-                .expect("The node's location is a prefix");
-
-            let needed_nodes_length = needed_nodes_key.iter().count();
-
-            let mut current_node = self
-                .get_mut(&found_key[..])
-                .expect("This should always exists");
-            let mut current_location = found_key.clone();
-            let mut counter = 1;
-
-            for ch in needed_nodes_key.iter() {
-                current_location.push(ch.to_owned());
-
-                let next_node = if counter == needed_nodes_length {
-                    node.clone()
-                } else {
-                    Node::new_parent()
-                };
-
-                current_node = match &current_node.value {
-                    NodeValue::Parent { children } => {
-                        assert_eq!(children.get(&ch), None);
-
-                        let children =
-                            if let NodeValue::Parent { children } = &mut current_node.value {
-                                children
-                            } else {
-                                unreachable!("This is a parent, we cheched")
-                            };
-
-                        children.insert(ch.to_owned(), next_node);
-                        children.get_mut(&ch).expect("Was just inserted")
-                    }
-                    NodeValue::Child {
-                        path,
-                        extandable: _,
-                    } => {
-                        // A node that should be a parent was classified
-                        // as child before:
-                        //
-                        //  1. Remove the child node and replace it with a parent one.
-                        //  2. Add the child node to the parent node as child, but with a '.' as MapKey.
-                        //  3. Add the original node also as child to the parent node.
-
-                        let mut children = HashMap::new();
-                        let move_child_node = Node::new_child(path.to_owned());
-
-                        children.insert(
-                            MapKey {
-                                key: '.',
-                                part_path: ".".to_owned(),
-                                resolution: 1,
-                            },
-                            move_child_node,
-                        );
-                        children.insert(ch.to_owned(), next_node);
-
-                        current_node.value = NodeValue::Parent { children };
-
-                        let children =
-                            if let NodeValue::Parent { children } = &mut current_node.value {
-                                children
-                            } else {
-                                unreachable!("We just inserted the parent value.")
-                            };
-
-                        children.get_mut(&ch).expect("Was just inserted")
-                    }
-                };
-
-                counter += 1;
-            }
-        } else {
-            fn reduce_string(a: &str) -> Option<char> {
-                let first_char = a.chars().take(1).last().expect("Should contain one char");
-
-                if a.chars().all(|ch| ch == first_char) {
-                    return Some(first_char);
-                } else {
-                    return None;
-                }
-            }
-            fn check_subset(a: &str, b: &str) -> bool {
-                if a.len() > b.len() {
-                    let a_prefix: String = a.chars().take(b.len()).collect();
-                    let a_suffix: String = a.chars().skip(b.len()).collect();
-
-                    if a_prefix == b {
-                        let clean_suffix = reduce_string(&a_suffix);
-                        if let Some(ch) = clean_suffix {
-                            ch == b.chars().last().expect("Will match")
-                        } else {
-                            false
-                        }
-                    } else {
-                        false
-                    }
-                } else if b.len() > a.len() {
-                    let b_prefix: String = b.chars().take(a.len()).collect();
-                    let b_suffix: String = b.chars().skip(a.len()).collect();
-
-                    if b_prefix == a {
-                        let clean_suffix = reduce_string(&b_suffix);
-                        if let Some(ch) = clean_suffix {
-                            ch == a.chars().last().expect("Will match")
-                        } else {
-                            false
-                        }
-                    } else {
-                        false
-                    }
-                } else {
-                    a == b
-                }
-            }
-
-            // Another node was already inserted with the same key!
-            // So we simple increase the resolution of the other node and this node, until their
-            // keys are not the same anymore.
-            // This only includes the last segment of the `MapKey`
-            //
-            // 1. Change both keys, until they are not equal any more
-            // 2. Move the wrongly placed node to the new place.
-            // 3. Insert our node.
-            let mut foreign_key = vec![found_key.last().expect("This will exist").clone()];
-            let mut our_key = vec![key.last().expect("This will exist").clone()];
-
-            debug!(
-                "'{}' ('{}') and '{}' ('{}') are the same, try to find a better combination!",
-                MapKey::display(&our_key),
-                our_key[0].part_path,
-                MapKey::display(&foreign_key),
-                foreign_key[0].part_path,
-            );
-
-            // The 'a' and 'b' stuff is here, to ensure that both returning None will not match
-            // this condition.
-            if reduce_string(&foreign_key[0].part_path).unwrap_or('a')
-                == reduce_string(&our_key[0].part_path).unwrap_or('b')
-            {
-                bail!(
-                    "\
-The foreign_key ('{}', path_part: '{}' -> '{}') and our_key ('{}', path_part: '{}' -> '{}') \
-have an identical path_part (when duplicated chars are removed)!
-I cannot extended them via incrementation.
-Please rename the paths to fix this.
-                        ",
-                    MapKey::display(&foreign_key),
-                    &foreign_key[0].part_path,
-                    reduce_string(&foreign_key[0].part_path).expect("Is some here"),
-                    MapKey::display(&our_key),
-                    &our_key[0].part_path,
-                    reduce_string(&our_key[0].part_path).expect("Is some here"),
-                );
-            }
-
-            if check_subset(&foreign_key[0].part_path, &our_key[0].part_path) {
-                bail!(
-                    "\
-The foreign_key ('{}', path_part: '{}') and our_key ('{}', path_part: '{}') \
-are subsets of one another!
-A discrimination through incrementation will not work!
-Please rename the paths to fix this.
-                        ",
-                    MapKey::display(&foreign_key),
-                    &foreign_key[0].part_path,
-                    MapKey::display(&our_key),
-                    &our_key[0].part_path,
-                );
-            }
-
-            while our_key == foreign_key {
-                our_key = our_key[0].increment(our_key[our_key.len() - 1].resolution + 1);
-                foreign_key =
-                    foreign_key[0].increment(foreign_key[foreign_key.len() - 1].resolution + 1);
-                debug!(
-                    "Now its: '{}' ('{}') and '{}' ('{}')",
-                    MapKey::display(&our_key),
-                    our_key[0].part_path,
-                    MapKey::display(&foreign_key),
-                    foreign_key[0].part_path,
-                );
-            }
-
-            debug!(
-                "Found a better one: '{}' ('{}') and '{}' ('{}')",
-                MapKey::display(&our_key),
-                our_key[0].part_path,
-                MapKey::display(&foreign_key),
-                foreign_key[0].part_path,
-            );
-
-            let parent = self
-                .get_mut(&found_key[..&found_key.len() - 1])
-                .expect("This will exist");
-
-            if let NodeValue::Parent { children } = &mut parent.value {
-                if let NodeValue::Child {
-                    path: _,
-                    extandable: _,
-                } = children
-                    .get(found_key.last().expect("Exists"))
-                    .expect("This node also exists")
-                    .value
-                {
-                    let old = children
-                        .remove(found_key.last().expect("This will exist"))
-                        .expect("This will be there");
-
-                    let full_foreign_key: Vec<_> = found_key
-                        .clone()
-                        .into_iter()
-                        .rev()
-                        .skip(1)
-                        .rev()
-                        .chain(foreign_key.clone().into_iter())
-                        .collect();
-                    self.insert_node(&full_foreign_key, old.clone())?;
-                }
-
-                let full_our_key: Vec<_> = key
-                    .to_vec()
-                    .into_iter()
-                    .rev()
-                    .skip(1)
-                    .rev()
-                    .chain(our_key.clone().into_iter())
-                    .collect();
-
-                self.insert_node(&full_our_key, node.clone())?;
-            } else {
-                unreachable!("This node will be a parent");
-            }
-        }
-
-        Ok(())
-    }
-}
-
-impl Node {
-    pub fn new_child(path: String) -> Self {
-        Self {
-            value: NodeValue::Child {
-                path,
-                extandable: true,
-            },
-        }
-    }
-    pub fn new_parent() -> Self {
-        Self {
-            value: NodeValue::Parent {
-                children: HashMap::new(),
-            },
-        }
-    }
-}
diff --git a/pkgs/by-name/lf/lf-make-map/src/mapping/mod.rs b/pkgs/by-name/lf/lf-make-map/src/mapping/mod.rs
index 114fdca0..21392388 100644
--- a/pkgs/by-name/lf/lf-make-map/src/mapping/mod.rs
+++ b/pkgs/by-name/lf/lf-make-map/src/mapping/mod.rs
@@ -1,156 +1,231 @@
-use std::{
-    fmt::{Display, Write},
-    hash::Hash,
-};
-
-use log::debug;
-
-pub mod map_tree;
-
-#[derive(Clone, Debug, Eq)]
-pub struct MapKey {
-    pub key: char,
+// nixos-config - My current NixOS configuration
+//
+// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+// This file is part of my nixos-config.
+//
+// You should have received a copy of the License along with this program.
+// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+use anyhow::Result;
+use keymaps::map_tree::{Node, Trie};
+use log::{Level, debug, log_enabled, trace};
+use map_key::MapKey;
+
+pub mod lf_mapping;
+pub mod map_key;
+
+#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
+pub struct MapChild {
+    pub path: String,
+    pub expendable: bool,
+}
 
-    resolution: usize,
+impl std::fmt::Display for MapChild {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        f.write_str(&self.path)?;
+        if !self.expendable {
+            f.write_str(" [stop]")?;
+        }
 
-    /// Part of the path, used to derive the key
-    part_path: String,
+        Ok(())
+    }
 }
 
-impl Hash for MapKey {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.key.hash(state)
+pub struct MappingsTrie(pub Trie<MapKey, MapChild>);
+impl std::fmt::Display for MappingsTrie {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        self.0.fmt(f)
     }
 }
 
-impl PartialEq for MapKey {
-    fn eq(&self, other: &Self) -> bool {
-        self.key == other.key
+impl MappingsTrie {
+    pub fn new() -> Self {
+        Self(Trie::new())
     }
-}
 
-impl MapKey {
-    pub fn new_from_part_path(part_path: &str, resolution: usize) -> Vec<Self> {
-        let key = Self::part_path_to_key(&part_path, resolution);
-
-        key.chars()
-            .map(|ch| Self {
-                key: ch,
-                resolution,
-                part_path: part_path.to_owned(),
-            })
-            .collect()
+    pub(crate) fn include(&mut self, path: &str) -> Result<()> {
+        let associated_key = MapKey::new_ones_from_path(path, 1);
+        self.insert(&associated_key, path)
     }
 
-    pub fn new_ones_from_path(path: &str, number_of_chars: usize) -> Vec<Self> {
-        let key: Vec<MapKey> = path
-            .split('/')
-            .map(|part| Self::new_from_part_path(part, number_of_chars))
-            .flatten()
-            .collect();
-
-        debug!(
-            "Generated full MapKeys: '{}' -> '{}'",
-            path,
-            MapKey::display(&key)
-        );
-        key
+    pub(crate) fn insert(&mut self, keys: &[MapKey], path: &str) -> Result<()> {
+        let value = Node::new_child(MapChild {
+            path: path.to_owned(),
+            expendable: true,
+        });
+        self.insert_node(keys, value)
     }
 
-    pub fn increment(&self, target_resolution: usize) -> Vec<Self> {
-        let new_resolution = target_resolution;
+    pub(crate) fn insert_node(
+        &mut self,
+        keys: &[MapKey],
+        node: Node<MapKey, MapChild>,
+    ) -> Result<()> {
+        if let Err(err) = self.0.insert_node(keys, &node) {
+            match err {
+                keymaps::error::TrieInsert::KeyAlreadySet(found_keys) => {
+                    // Another node was already inserted with the same key!
+                    // So we simple increase the resolution of the other node and this node, until their
+                    // keys are no longer equal.
+                    // This only includes the last segment of the `MapKey`
+                    //
+                    // 1. Change both keys, until they are not equal any more
+                    // 2. Move the wrongly placed node to the new place.
+                    // 3. Insert our node.
+                    assert_eq!(keys, found_keys);
+
+                    let mut foreign_keys =
+                        vec![found_keys.last().expect("This will exist").clone()];
+                    let mut our_keys = vec![keys.last().expect("This will exist").clone()];
+
+                    debug!(
+                        "'{}' ('{}') and '{}' ('{}') are the same, trying to find a better combination!",
+                        MapKey::display(&our_keys),
+                        our_keys[0].part_path,
+                        MapKey::display(&foreign_keys),
+                        foreign_keys[0].part_path,
+                    );
+
+                    our_keys[0].can_tiebreak_with(&foreign_keys[0])?;
+
+                    while our_keys == foreign_keys {
+                        our_keys =
+                            our_keys[0].increment(our_keys[our_keys.len() - 1].resolution + 1);
+                        foreign_keys = foreign_keys[0]
+                            .increment(foreign_keys[foreign_keys.len() - 1].resolution + 1);
+                        debug!(
+                            "Now its: '{}' ('{}') and '{}' ('{}')",
+                            MapKey::display(&our_keys),
+                            our_keys[0].part_path,
+                            MapKey::display(&foreign_keys),
+                            foreign_keys[0].part_path,
+                        );
+                    }
+                    debug!(
+                        "Found a better one: '{}' ('{}') and '{}' ('{}')",
+                        MapKey::display(&our_keys),
+                        our_keys[0].part_path,
+                        MapKey::display(&foreign_keys),
+                        foreign_keys[0].part_path,
+                    );
+
+                    let parent_keys = &found_keys[..&found_keys.len() - 1];
+
+                    {
+                        if self
+                            .0
+                            .get(&found_keys)
+                            .expect("This will exist")
+                            .value()
+                            .is_some()
+                        {
+                            // This is a child, we must replace it with a parent.
+                            let other_node = self
+                                .0
+                                .replace_node(&found_keys, Node::new_parent())
+                                .expect("This node exists");
+
+                            {
+                                let mut full_foreign_keys = parent_keys.to_vec();
+                                full_foreign_keys.append(&mut foreign_keys);
+                                self.insert_node(&full_foreign_keys, other_node)?;
+                            }
+                        }
+                    }
 
-        // debug!("Incrementing: '{}' ('{}')", &self, &self.part_path);
+                    {
+                        let mut full_our_keys = parent_keys.to_vec();
+                        full_our_keys.append(&mut our_keys);
+                        self.insert_node(&full_our_keys, node)?;
+                    }
 
-        let added_chars = if new_resolution < self.part_path.len() {
-            MapKey::part_path_to_key(&self.part_path, new_resolution)
+                    Ok(())
+                }
+                keymaps::error::TrieInsert::KeyIncludesChild {
+                    child_key: key,
+                    child_value,
+                } => {
+                    // A node that should be a parent was classified
+                    // as child before:
+                    //
+                    //  1. Remove the child node and replace it with a parent one.
+                    //  2. Add the child node to the parent node as child, but with a '.' as MapKey.
+                    //  3. Add the original node also as child to the parent node.
+
+                    assert_eq!(key, keys);
+
+                    let (fetched_child_value, mut child_key) = self.0.try_get(keys);
+                    assert_eq!(fetched_child_value.value(), Some(&child_value));
+
+                    trace!(
+                        "Replacing child ('{}') with a parent, so that we can continue from this point.",
+                        MapKey::display(&child_key)
+                    );
+
+                    let child = self
+                        .0
+                        .replace_node(&child_key, Node::new_parent())
+                        .expect("Node exists");
+                    assert_eq!(child.value(), Some(&child_value));
+
+                    child_key.push(MapKey {
+                        key: '.',
+                        part_path: ".".to_owned(),
+                        resolution: 1,
+                    });
+                    self.0
+                        .insert_node(&child_key, &child)
+                        .expect("We just created a parent here");
+
+                    // Recursive call, because this key could have hit the previous child directly
+                    // (thus it will now trigger the `KeyAlreadySet` error.)
+                    self.insert_node(keys, node)
+                }
+            }
         } else {
-            let mut generated_chars =
-                MapKey::part_path_to_key(&self.part_path, self.part_path.len());
-
-            generated_chars.extend(
-                (0..(new_resolution - self.part_path.len()))
-                    .into_iter()
-                    .map(|_| self.part_path.chars().last().expect("This will exists")),
-            );
-
-            generated_chars
-        };
-
-        let part_path = self.part_path.clone();
-        let output: Vec<Self> = added_chars
-            .chars()
-            .enumerate()
-            .map(|(res, ch)| MapKey {
-                key: ch,
-                resolution: res + 1,
-                part_path: part_path.clone(),
-            })
-            .collect();
-
-        // debug!("Finished increment: '{}' ('{}')", MapKey::display(&output), output[0].part_path);
-        output
+            Ok(())
+        }
     }
 
-    pub fn display(values: &[Self]) -> String {
-        values.iter().map(|value| value.key.clone()).collect()
-    }
-    fn part_path_to_key(part: &str, number_of_chars: usize) -> String {
-        fn make(pat: char, part: &str, number_of_chars: usize) -> String {
-            let mut acc = String::new();
-
-            if !part.split(pat).all(|part| part.len() > 0) {
-                panic!(
-                    "\
-Can't turn this path '{}' to a mapping.
-This should not happen, please report the bug!",
-                    part
-                )
-            }
+    /// Add a new [`MappingsTrie`] at the position `keys` into this Trie.
+    pub(crate) fn add_trie(&mut self, keys: &[MapKey], trie: Self) -> Result<()> {
+        if log_enabled!(Level::Trace) {
+            trace!("Adding mappings under '{}':", MapKey::display(keys));
+            eprintln!("{trie}");
 
-            let mut last_working = None;
-            for i in 0..number_of_chars {
-                for str in part.split(pat) {
-                    if acc.len() != number_of_chars {
-                        acc.push(match str.chars().nth(i) {
-                            Some(ch) => ch,
-                            None => {
-                                if let Some(last) = last_working {
-                                    str.chars().nth(last).expect("This should always exist")
-                                } else {
-                                    last_working = Some(i - 1);
-                                    str.chars().nth(i - 1).expect("This should always exist")
-                                }
-                            }
-                        })
-                    }
-                }
-            }
+            trace!("Self is:");
+            eprintln!("{self}");
+        }
+
+        let replaced = self
+            .0
+            .replace_node(keys, trie.0.root_node().to_owned())
+            .expect("This value exists");
 
-            acc
+        if log_enabled!(Level::Trace) {
+            trace!("After replace adding the new trie");
+            eprintln!("{self}");
         }
 
-        let value = if part.contains('_') && !part.starts_with('_') && !part.ends_with('_') {
-            make('_', part, number_of_chars)
-        } else if part.contains('-') && !part.starts_with('-') && !part.ends_with('-') {
-            make('-', part, number_of_chars)
-        } else {
-            part.chars().take(number_of_chars).collect::<String>()
-        };
-
-        assert_eq!(
-            value.len(),
-            number_of_chars,
-            "'{}' does not have expected length of: {}",
-            value,
-            number_of_chars
-        );
-        value
-    }
-}
+        {
+            let mut new_keys = keys.to_vec();
+            new_keys.push(MapKey {
+                key: '.',
+                part_path: ".".to_owned(),
+                resolution: 1,
+            });
+
+            let mut value = replaced.value().expect("Is a child").clone();
+            value.expendable = false;
+
+            trace!("Re-inserting '{}' into self.", MapKey::display(keys));
+            self.0
+                .insert_node(&new_keys, &Node::new_child(value))
+                .expect("This key is not used.");
+        }
 
-impl Display for MapKey {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        f.write_char(self.key)
+        Ok(())
     }
 }
diff --git a/pkgs/by-name/lf/lf-make-map/tests/base.sh b/pkgs/by-name/lf/lf-make-map/tests/base.sh
new file mode 100755
index 00000000..c7694985
--- /dev/null
+++ b/pkgs/by-name/lf/lf-make-map/tests/base.sh
@@ -0,0 +1,25 @@
+#! /usr/bin/env sh
+
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+cd "$(dirname "$0")" || exit 2
+
+cargo build
+execute_make_maps() {
+    ../target/debug/lf-make-map "$@"
+}
+
+fd . cases --max-depth 1 --type directory | while read -r case; do
+    echo "Executing '$case/test.sh'"
+
+    # shellcheck source=/dev/null
+    LOCATION="$case/test.sh" . "$case/test.sh"
+done
diff --git a/pkgs/by-name/lf/lf-make-map/tests/cases/child_insert/test.sh b/pkgs/by-name/lf/lf-make-map/tests/cases/child_insert/test.sh
new file mode 100755
index 00000000..90ebe1ce
--- /dev/null
+++ b/pkgs/by-name/lf/lf-make-map/tests/cases/child_insert/test.sh
@@ -0,0 +1,27 @@
+#! /usr/bin/env sh
+
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+test="$(mktemp --directory)"
+
+cleanup() {
+    rm --recursive "$test"
+}
+trap cleanup EXIT
+
+cat <<EOF | while read -r name; do mkdir --parents "$test/media/books/${name}"; done
+Andre A
+Anton B
+Andon C
+Anton D
+EOF
+
+execute_make_maps --home-name "$test" --depth 100 generate "$test"/* >/dev/null
diff --git a/pkgs/by-name/lf/lf-make-map/tests/cases/simple/output.old b/pkgs/by-name/lf/lf-make-map/tests/cases/simple/output.old
new file mode 100644
index 00000000..90591f16
--- /dev/null
+++ b/pkgs/by-name/lf/lf-make-map/tests/cases/simple/output.old
@@ -0,0 +1,46 @@
+map gdd. cd "/tmp/tmp.DfcgjemfCG/d"
+map gddcc. cd "/tmp/tmp.DfcgjemfCG/d/c"
+map gddccb. cd "/tmp/tmp.DfcgjemfCG/d/c/b"
+map gddccbc. cd "/tmp/tmp.DfcgjemfCG/d/c/b/c"
+map gddccbcf. cd "/tmp/tmp.DfcgjemfCG/d/c/b/c/file.test"
+map gddccd. cd "/tmp/tmp.DfcgjemfCG/d/c/d"
+map gddccdf. cd "/tmp/tmp.DfcgjemfCG/d/c/d/f"
+map gddccdff. cd "/tmp/tmp.DfcgjemfCG/d/c/d/f/file.test2"
+map gddcco. cd "/tmp/tmp.DfcgjemfCG/d/c/other"
+map gddccof. cd "/tmp/tmp.DfcgjemfCG/d/c/other/file.test3"
+map gddct. cd "/tmp/tmp.DfcgjemfCG/d/cll_the-things"
+map gddcto. cd "/tmp/tmp.DfcgjemfCG/d/cll_the-things/other"
+map gddctof. cd "/tmp/tmp.DfcgjemfCG/d/cll_the-things/other/file.test4"
+map gddm. cd "/tmp/tmp.DfcgjemfCG/d/mcybe some whitespcce"
+map gddmt. cd "/tmp/tmp.DfcgjemfCG/d/mcybe some whitespcce/test.file5"
+map gdi. cd "/tmp/tmp.DfcgjemfCG/dir"
+map gdicc. cd "/tmp/tmp.DfcgjemfCG/dir/c"
+map gdiccb. cd "/tmp/tmp.DfcgjemfCG/dir/c/b"
+map gdiccbc. cd "/tmp/tmp.DfcgjemfCG/dir/c/b/c"
+map gdiccbcf. cd "/tmp/tmp.DfcgjemfCG/dir/c/b/c/file.test"
+map gdiccd. cd "/tmp/tmp.DfcgjemfCG/dir/c/d"
+map gdiccdf. cd "/tmp/tmp.DfcgjemfCG/dir/c/d/f"
+map gdiccdff. cd "/tmp/tmp.DfcgjemfCG/dir/c/d/f/file.test2"
+map gdicco. cd "/tmp/tmp.DfcgjemfCG/dir/c/other"
+map gdiccof. cd "/tmp/tmp.DfcgjemfCG/dir/c/other/file.test3"
+map gdict. cd "/tmp/tmp.DfcgjemfCG/dir/cll_the-things"
+map gdicto. cd "/tmp/tmp.DfcgjemfCG/dir/cll_the-things/other"
+map gdictof. cd "/tmp/tmp.DfcgjemfCG/dir/cll_the-things/other/file.test4"
+map gdim. cd "/tmp/tmp.DfcgjemfCG/dir/mcybe some whitespcce"
+map gdimt. cd "/tmp/tmp.DfcgjemfCG/dir/mcybe some whitespcce/test.file5"
+map gdo. cd "/tmp/tmp.DfcgjemfCG/dor"
+map gdocc. cd "/tmp/tmp.DfcgjemfCG/dor/c"
+map gdoccb. cd "/tmp/tmp.DfcgjemfCG/dor/c/b"
+map gdoccbc. cd "/tmp/tmp.DfcgjemfCG/dor/c/b/c"
+map gdoccbcf. cd "/tmp/tmp.DfcgjemfCG/dor/c/b/c/file.test"
+map gdoccd. cd "/tmp/tmp.DfcgjemfCG/dor/c/d"
+map gdoccdf. cd "/tmp/tmp.DfcgjemfCG/dor/c/d/f"
+map gdoccdff. cd "/tmp/tmp.DfcgjemfCG/dor/c/d/f/file.test2"
+map gdocco. cd "/tmp/tmp.DfcgjemfCG/dor/c/other"
+map gdoccof. cd "/tmp/tmp.DfcgjemfCG/dor/c/other/file.test3"
+map gdoct. cd "/tmp/tmp.DfcgjemfCG/dor/cll_the-things"
+map gdocto. cd "/tmp/tmp.DfcgjemfCG/dor/cll_the-things/other"
+map gdoctof. cd "/tmp/tmp.DfcgjemfCG/dor/cll_the-things/other/file.test4"
+map gdom. cd "/tmp/tmp.DfcgjemfCG/dor/mcybe some whitespcce"
+map gdomt. cd "/tmp/tmp.DfcgjemfCG/dor/mcybe some whitespcce/test.file5"
+
diff --git a/pkgs/by-name/lf/lf-make-map/tests/cases/simple/output.old.license b/pkgs/by-name/lf/lf-make-map/tests/cases/simple/output.old.license
new file mode 100644
index 00000000..eae6a84c
--- /dev/null
+++ b/pkgs/by-name/lf/lf-make-map/tests/cases/simple/output.old.license
@@ -0,0 +1,9 @@
+nixos-config - My current NixOS configuration
+
+Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+SPDX-License-Identifier: GPL-3.0-or-later
+
+This file is part of my nixos-config.
+
+You should have received a copy of the License along with this program.
+If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
diff --git a/pkgs/by-name/lf/lf-make-map/tests/cases/simple/test.sh b/pkgs/by-name/lf/lf-make-map/tests/cases/simple/test.sh
new file mode 100755
index 00000000..6e127d28
--- /dev/null
+++ b/pkgs/by-name/lf/lf-make-map/tests/cases/simple/test.sh
@@ -0,0 +1,49 @@
+#! /usr/bin/env sh
+
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+# We need to hard code this, so that our output matches the golden sample.
+base="/tmp/tmp.DfcgjemfCG"
+test="$(mktemp --directory)"
+
+[ -d "$base" ] && {
+    echo "$base already exists!"
+    exit 1
+}
+
+mkdir "$base"
+
+cleanup() {
+    rm --recursive "$base" "$test"
+}
+trap cleanup EXIT
+
+mkdir --parents "$base/dir/c/b/c/file.test"
+mkdir --parents "$base/dir/c/d/f/file.test2"
+mkdir --parents "$base/dir/c/other/file.test3"
+mkdir --parents "$base/dir/cll_the-things/other/file.test4"
+mkdir --parents "$base/dir/mcybe some whitespcce/test.file5"
+
+mkdir --parents "$base/dor/c/b/c/file.test"
+mkdir --parents "$base/dor/c/d/f/file.test2"
+mkdir --parents "$base/dor/c/other/file.test3"
+mkdir --parents "$base/dor/cll_the-things/other/file.test4"
+mkdir --parents "$base/dor/mcybe some whitespcce/test.file5"
+
+mkdir --parents "$base/d/c/b/c/file.test"
+mkdir --parents "$base/d/c/d/f/file.test2"
+mkdir --parents "$base/d/c/other/file.test3"
+mkdir --parents "$base/d/cll_the-things/other/file.test4"
+mkdir --parents "$base/d/mcybe some whitespcce/test.file5"
+
+execute_make_maps --home-name "$base" --depth 100 generate "$base"/* >"$test/output.new"
+
+diff "$test/output.new" "$(dirname "$LOCATION")/output.old"
diff --git a/pkgs/by-name/lf/lf-make-map/update.sh b/pkgs/by-name/lf/lf-make-map/update.sh
index 7d517e8b..23d90a86 100755
--- a/pkgs/by-name/lf/lf-make-map/update.sh
+++ b/pkgs/by-name/lf/lf-make-map/update.sh
@@ -1,4 +1,14 @@
 #!/usr/bin/env sh
 
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 [ "$1" = "upgrade" ] && cargo upgrade
 cargo update
diff --git a/pkgs/by-name/ll/ll/ll.sh b/pkgs/by-name/ll/ll/ll.sh
deleted file mode 100755
index 73328e3e..00000000
--- a/pkgs/by-name/ll/ll/ll.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
-last_directory="$(mktemp)"
-
-command lf -last-dir-path="$last_directory" "$@"
-
-dir="$(cat "$last_directory")"
-if cd "$dir"; then
-    [ -d "$XDG_RUNTIME_DIR/ll" ] || mkdir "$XDG_RUNTIME_DIR/ll"
-    echo "$dir" >"$XDG_RUNTIME_DIR/ll/last_directory"
-else
-    die "$dir does not exist!"
-fi
-
-rm "$last_directory"
-# vim: ft=sh
diff --git a/pkgs/by-name/ll/ll/package.nix b/pkgs/by-name/ll/ll/package.nix
deleted file mode 100644
index 4c13b40e..00000000
--- a/pkgs/by-name/ll/ll/package.nix
+++ /dev/null
@@ -1,9 +0,0 @@
-{sysLib}:
-sysLib.writeShellScript {
-  name = "ll";
-  src = ./ll.sh;
-  generateCompletions = false;
-
-  # `ll` must be able to change the path of the running shell.
-  wrap = false;
-}
diff --git a/pkgs/by-name/lm/lm/lm.sh b/pkgs/by-name/lm/lm/lm.sh
deleted file mode 100755
index d5fdca10..00000000
--- a/pkgs/by-name/lm/lm/lm.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
-if [ -f "$XDG_RUNTIME_DIR/ll/last_directory" ]; then
-    last_dir="$(cat "$XDG_RUNTIME_DIR/ll/last_directory")"
-    cd "$last_dir" || die "$last_dir does not exist!"
-else
-    msg "No last directory saved (try using ll instead)."
-fi
-# vim: ft=sh
diff --git a/pkgs/by-name/lm/lm/package.nix b/pkgs/by-name/lm/lm/package.nix
deleted file mode 100644
index ef417cd2..00000000
--- a/pkgs/by-name/lm/lm/package.nix
+++ /dev/null
@@ -1,9 +0,0 @@
-{sysLib}:
-sysLib.writeShellScript {
-  name = "lm";
-  src = ./lm.sh;
-  generateCompletions = false;
-
-  # `ll` must be able to change the path of the running shell.
-  wrap = false;
-}
diff --git a/pkgs/by-name/lo/lock/lock.sh b/pkgs/by-name/lo/lock/lock.sh
index 4c5e1c01..1c068e57 100755
--- a/pkgs/by-name/lo/lock/lock.sh
+++ b/pkgs/by-name/lo/lock/lock.sh
@@ -1,3 +1,13 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 # shellcheck shell=bash
 
 context="$(task _get rc.context)"
diff --git a/pkgs/by-name/lo/lock/package.nix b/pkgs/by-name/lo/lock/package.nix
index a59fbdd0..572ebb0b 100644
--- a/pkgs/by-name/lo/lock/package.nix
+++ b/pkgs/by-name/lo/lock/package.nix
@@ -1,3 +1,12 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 {
   writeShellApplication,
   taskwarrior3,
diff --git a/pkgs/by-name/mp/mpp-beetrm/mpp-beetrm.sh b/pkgs/by-name/mp/mpp-beetrm/mpp-beetrm.sh
index 3209503c..83784743 100755
--- a/pkgs/by-name/mp/mpp-beetrm/mpp-beetrm.sh
+++ b/pkgs/by-name/mp/mpp-beetrm/mpp-beetrm.sh
@@ -1,7 +1,14 @@
 #!/usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 
 beet remove --delete \
     title:"$(mpc --format '%title%' current)" \
diff --git a/pkgs/by-name/mp/mpp-beetrm/package.nix b/pkgs/by-name/mp/mpp-beetrm/package.nix
index 24b56606..00672838 100644
--- a/pkgs/by-name/mp/mpp-beetrm/package.nix
+++ b/pkgs/by-name/mp/mpp-beetrm/package.nix
@@ -1,15 +1,24 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 {
-  sysLib,
+  writeShellApplication,
+  # Dependencies
   mpc,
   beets,
 }:
-sysLib.writeShellScript {
+writeShellApplication {
   name = "mpp-beetrm";
-  src = ./mpp-beetrm.sh;
-  generateCompletions = false;
-  keepPath = false;
+  text = builtins.readFile ./mpp-beetrm.sh;
+  inheritPath = false;
 
-  dependencies = [
+  runtimeInputs = [
     mpc
     beets
   ];
diff --git a/pkgs/by-name/mp/mpp-lyrics/mpp-lyrics.sh b/pkgs/by-name/mp/mpp-lyrics/mpp-lyrics.sh
index 004c67c7..fa1cac49 100755
--- a/pkgs/by-name/mp/mpp-lyrics/mpp-lyrics.sh
+++ b/pkgs/by-name/mp/mpp-lyrics/mpp-lyrics.sh
@@ -1,11 +1,21 @@
 #!/usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 
-(
-    cd "%MPD_MUSIC_DIR" || die "No music dir!"
-    exiftool "$(mpc --format '%file%' current)" -json | jq '.[0].Lyrics' -r | less
-)
+die() {
+    echo "Error: $1"
+    exit 1
+}
+
+cd "$XDG_MUSIC_DIR/beets" || die "No music dir!"
+exiftool "$(mpc --format '%file%' current)" -json | jq '.[0].Lyrics' --raw-output | less
 
 # vim: ft=sh
diff --git a/pkgs/by-name/mp/mpp-lyrics/package.nix b/pkgs/by-name/mp/mpp-lyrics/package.nix
index 76b590c7..0b6d8993 100644
--- a/pkgs/by-name/mp/mpp-lyrics/package.nix
+++ b/pkgs/by-name/mp/mpp-lyrics/package.nix
@@ -1,23 +1,27 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 {
-  sysLib,
+  writeShellApplication,
+  # Dependencies
   exiftool,
   mpc,
   jq,
   less,
   locale, # dependency of less
-  mpd_music_dir ? "\${XDG_MUSIC_DIR}",
 }:
-sysLib.writeShellScript {
+writeShellApplication {
   name = "mpp-lyrics";
-  src = ./mpp-lyrics.sh;
-  generateCompletions = false;
-  keepPath = false;
+  text = builtins.readFile ./mpp-lyrics.sh;
+  inheritPath = false;
 
-  replacementStrings = {
-    MPD_MUSIC_DIR = mpd_music_dir;
-  };
-
-  dependencies = [
+  runtimeInputs = [
     exiftool
     mpc
     jq
diff --git a/pkgs/by-name/mp/mpp-searchadd/mpp-searchadd.sh b/pkgs/by-name/mp/mpp-searchadd/mpp-searchadd.sh
index 3fe9a6b6..d76e73b8 100755
--- a/pkgs/by-name/mp/mpp-searchadd/mpp-searchadd.sh
+++ b/pkgs/by-name/mp/mpp-searchadd/mpp-searchadd.sh
@@ -1,14 +1,18 @@
 #!/usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 
-tracks="$(mktmp)"
-beet list "$@" --path >"$tracks"
-
-while read -r track; do
+beet list "$@" --path | while read -r track; do
     mpc add "$track"
-done <"$tracks"
+done
 
 mpc playlist
 # vim: ft=sh
diff --git a/pkgs/by-name/mp/mpp-searchadd/package.nix b/pkgs/by-name/mp/mpp-searchadd/package.nix
index a98472d1..91ff05e9 100644
--- a/pkgs/by-name/mp/mpp-searchadd/package.nix
+++ b/pkgs/by-name/mp/mpp-searchadd/package.nix
@@ -1,15 +1,24 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 {
-  sysLib,
+  writeShellApplication,
+  # Dependencies.
   mpc,
   beets,
 }:
-sysLib.writeShellScript {
+writeShellApplication {
   name = "mpp-searchadd";
-  src = ./mpp-searchadd.sh;
-  generateCompletions = false;
-  keepPath = false;
+  text = builtins.readFile ./mpp-searchadd.sh;
+  inheritPath = false;
 
-  dependencies = [
+  runtimeInputs = [
     mpc
     beets
   ];
diff --git a/pkgs/by-name/mp/mpp/mpp.sh b/pkgs/by-name/mp/mpp/mpp.sh
index 538a56ee..3ac98ddb 100755
--- a/pkgs/by-name/mp/mpp/mpp.sh
+++ b/pkgs/by-name/mp/mpp/mpp.sh
@@ -1,9 +1,16 @@
 #!/usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 
-case "$1" in
+case "${1-}" in
 "searchadd")
     shift 1
     mpp-searchadd "$@"
diff --git a/pkgs/by-name/mp/mpp/package.nix b/pkgs/by-name/mp/mpp/package.nix
index 9c5315b0..f0e454f7 100644
--- a/pkgs/by-name/mp/mpp/package.nix
+++ b/pkgs/by-name/mp/mpp/package.nix
@@ -1,20 +1,35 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 {
-  sysLib,
-  mpc,
-  fd,
+  writeShellApplication,
   symlinkJoin,
   stdenv,
+  # Dependencies
+  mpc,
+  mpp-searchadd,
+  mpp-lyrics,
+  mpp-beetrm,
+  # Build dependencies
+  fd,
   zsh,
 }: let
-  script = sysLib.writeShellScript {
+  script = writeShellApplication {
     name = "mpp";
-    src = ./mpp.sh;
-    generateCompletions = false;
-    # We source the wrappers from the environment, to ensure that they have the same
-    # configurations (e.g. MPD_MUSIC_DIR in `mpc-lyrics`)
-    keepPath = true;
-    dependencies = [
+    text = builtins.readFile ./mpp.sh;
+    inheritPath = false;
+
+    runtimeInputs = [
       mpc
+      mpp-searchadd
+      mpp-lyrics
+      mpp-beetrm
     ];
   };
 
@@ -55,6 +70,8 @@
       fd "." --hidden --type file | while read -r file_path; do
         sed --in-place 's/mpc/mpp/g' "$file_path"
       done
+
+      # TODO(@bpeetz): Also change this in man-pages. <2025-05-20>
     '';
 
     installPhase = ''
@@ -64,6 +81,8 @@
   };
 in
   symlinkJoin {
-    name = "mpp-merged";
+    name = "mpp";
     paths = [script mpcShare];
+
+    inherit (script) meta;
   }
diff --git a/pkgs/by-name/ri/river-mk-keymap/.envrc b/pkgs/by-name/ri/river-mk-keymap/.envrc
index fdd3e9d8..294de504 100644
--- a/pkgs/by-name/ri/river-mk-keymap/.envrc
+++ b/pkgs/by-name/ri/river-mk-keymap/.envrc
@@ -1,3 +1,13 @@
 #!/usr/bin/env sh
 
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 use flake
diff --git a/pkgs/by-name/ri/river-mk-keymap/.gitignore b/pkgs/by-name/ri/river-mk-keymap/.gitignore
index 2d5df85d..f255eebd 100644
--- a/pkgs/by-name/ri/river-mk-keymap/.gitignore
+++ b/pkgs/by-name/ri/river-mk-keymap/.gitignore
@@ -1,2 +1,12 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 /target
 .direnv
diff --git a/pkgs/by-name/ri/river-mk-keymap/Cargo.lock b/pkgs/by-name/ri/river-mk-keymap/Cargo.lock
index 7fb009ef..129b88b4 100644
--- a/pkgs/by-name/ri/river-mk-keymap/Cargo.lock
+++ b/pkgs/by-name/ri/river-mk-keymap/Cargo.lock
@@ -1,5 +1,14 @@
 # This file is automatically @generated by Cargo.
 # It is not intended for manual editing.
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 version = 4
 
 [[package]]
@@ -43,26 +52,26 @@ dependencies = [
 
 [[package]]
 name = "anstyle-wincon"
-version = "3.0.7"
+version = "3.0.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e"
+checksum = "6680de5231bd6ee4c6191b8a1325daa282b415391ec9d3a37bd34f2060dc73fa"
 dependencies = [
  "anstyle",
- "once_cell",
+ "once_cell_polyfill",
  "windows-sys",
 ]
 
 [[package]]
 name = "anyhow"
-version = "1.0.97"
+version = "1.0.98"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
+checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
 
 [[package]]
 name = "clap"
-version = "4.5.34"
+version = "4.5.39"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e958897981290da2a852763fe9cdb89cd36977a5d729023127095fa94d95e2ff"
+checksum = "fd60e63e9be68e5fb56422e397cf9baddded06dae1d2e523401542383bc72a9f"
 dependencies = [
  "clap_builder",
  "clap_derive",
@@ -70,9 +79,9 @@ dependencies = [
 
 [[package]]
 name = "clap_builder"
-version = "4.5.34"
+version = "4.5.39"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "83b0f35019843db2160b5bb19ae09b4e6411ac33fc6a712003c33e03090e2489"
+checksum = "89cc6392a1f72bbeb820d71f32108f61fdaf18bc526e1d23954168a67759ef51"
 dependencies = [
  "anstream",
  "anstyle",
@@ -124,9 +133,9 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
 
 [[package]]
 name = "keymaps"
-version = "1.0.0"
+version = "1.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6cec33e805ecc09c4e4f91ca26e536978ad1ae28f2e1dc02fadafeec6d2f8504"
+checksum = "2a522bbaa39bddd54945580e369ed37113ea96f4cb8f0322be0d5e04aa4d7293"
 dependencies = [
  "serde",
  "thiserror",
@@ -139,16 +148,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
 
 [[package]]
-name = "once_cell"
-version = "1.21.3"
+name = "once_cell_polyfill"
+version = "1.70.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
+checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.94"
+version = "1.0.95"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
+checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
 dependencies = [
  "unicode-ident",
 ]
@@ -219,9 +228,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
 
 [[package]]
 name = "syn"
-version = "2.0.100"
+version = "2.0.101"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
+checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
 dependencies = [
  "proc-macro2",
  "quote",
diff --git a/pkgs/by-name/ri/river-mk-keymap/Cargo.toml b/pkgs/by-name/ri/river-mk-keymap/Cargo.toml
index f14411f2..583fcb92 100644
--- a/pkgs/by-name/ri/river-mk-keymap/Cargo.toml
+++ b/pkgs/by-name/ri/river-mk-keymap/Cargo.toml
@@ -1,3 +1,13 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 [package]
 name = "river-mk-keymap"
 version = "0.1.0"
@@ -6,9 +16,9 @@ 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"] }
+anyhow = "1.0.98"
+clap = { version = "4.5.39", features = ["derive"] }
+keymaps = { version = "1.1.1", features = ["serde", "mouse-keys"] }
 serde = { version = "1.0.219", features = ["derive"] }
 serde_json = "1.0.140"
 
diff --git a/pkgs/by-name/ri/river-mk-keymap/TODO.license b/pkgs/by-name/ri/river-mk-keymap/TODO.license
new file mode 100644
index 00000000..eae6a84c
--- /dev/null
+++ b/pkgs/by-name/ri/river-mk-keymap/TODO.license
@@ -0,0 +1,9 @@
+nixos-config - My current NixOS configuration
+
+Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+SPDX-License-Identifier: GPL-3.0-or-later
+
+This file is part of my nixos-config.
+
+You should have received a copy of the License along with this program.
+If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
diff --git a/pkgs/by-name/ri/river-mk-keymap/contrib/example.json.license b/pkgs/by-name/ri/river-mk-keymap/contrib/example.json.license
new file mode 100644
index 00000000..eae6a84c
--- /dev/null
+++ b/pkgs/by-name/ri/river-mk-keymap/contrib/example.json.license
@@ -0,0 +1,9 @@
+nixos-config - My current NixOS configuration
+
+Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+SPDX-License-Identifier: GPL-3.0-or-later
+
+This file is part of my nixos-config.
+
+You should have received a copy of the License along with this program.
+If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
diff --git a/pkgs/by-name/ri/river-mk-keymap/flake.lock b/pkgs/by-name/ri/river-mk-keymap/flake.lock
index 82448387..280e8a51 100644
--- a/pkgs/by-name/ri/river-mk-keymap/flake.lock
+++ b/pkgs/by-name/ri/river-mk-keymap/flake.lock
@@ -2,11 +2,11 @@
   "nodes": {
     "nixpkgs": {
       "locked": {
-        "lastModified": 1743076231,
-        "narHash": "sha256-yQugdVfi316qUfqzN8JMaA2vixl+45GxNm4oUfXlbgw=",
+        "lastModified": 1748406211,
+        "narHash": "sha256-B3BsCRbc+x/d0WiG1f+qfSLUy+oiIfih54kalWBi+/M=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "6c5963357f3c1c840201eda129a99d455074db04",
+        "rev": "3d1f29646e4b57ed468d60f9d286cde23a8d1707",
         "type": "github"
       },
       "original": {
diff --git a/pkgs/by-name/ri/river-mk-keymap/flake.lock.license b/pkgs/by-name/ri/river-mk-keymap/flake.lock.license
new file mode 100644
index 00000000..eae6a84c
--- /dev/null
+++ b/pkgs/by-name/ri/river-mk-keymap/flake.lock.license
@@ -0,0 +1,9 @@
+nixos-config - My current NixOS configuration
+
+Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+SPDX-License-Identifier: GPL-3.0-or-later
+
+This file is part of my nixos-config.
+
+You should have received a copy of the License along with this program.
+If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
diff --git a/pkgs/by-name/ri/river-mk-keymap/flake.nix b/pkgs/by-name/ri/river-mk-keymap/flake.nix
index 95a14456..e15e99fa 100644
--- a/pkgs/by-name/ri/river-mk-keymap/flake.nix
+++ b/pkgs/by-name/ri/river-mk-keymap/flake.nix
@@ -1,3 +1,12 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 {
   description = "A smart way to configure river keybindings";
 
diff --git a/pkgs/by-name/ri/river-mk-keymap/package.nix b/pkgs/by-name/ri/river-mk-keymap/package.nix
index d9519d48..7d6d4f3a 100644
--- a/pkgs/by-name/ri/river-mk-keymap/package.nix
+++ b/pkgs/by-name/ri/river-mk-keymap/package.nix
@@ -1,3 +1,12 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 {rustPlatform}:
 rustPlatform.buildRustPackage {
   pname = "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
index 55b87e1a..e3c49310 100644
--- a/pkgs/by-name/ri/river-mk-keymap/src/cli.rs
+++ b/pkgs/by-name/ri/river-mk-keymap/src/cli.rs
@@ -1,3 +1,13 @@
+// nixos-config - My current NixOS configuration
+//
+// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+// This file is part of my nixos-config.
+//
+// You should have received a copy of the License along with this program.
+// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 use std::path::PathBuf;
 
 use clap::Parser;
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
index a4ac0ebd..e948ccfe 100644
--- 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
@@ -1,3 +1,13 @@
+// nixos-config - My current NixOS configuration
+//
+// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+// This file is part of my nixos-config.
+//
+// You should have received a copy of the License along with this program.
+// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 use std::process::Command;
 
 use keymaps::key_repr::{KeyValue, MediaKeyCode, MouseKeyValue};
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
index 84a16c9d..2c82ee05 100644
--- 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
@@ -1,3 +1,13 @@
+// nixos-config - My current NixOS configuration
+//
+// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+// This file is part of my nixos-config.
+//
+// You should have received a copy of the License along with this program.
+// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 use std::{collections::HashMap, fmt::Display, ops::Deref, str::FromStr};
 
 use anyhow::Context;
diff --git a/pkgs/by-name/ri/river-mk-keymap/src/main.rs b/pkgs/by-name/ri/river-mk-keymap/src/main.rs
index 5cb99f74..63955f7f 100644
--- a/pkgs/by-name/ri/river-mk-keymap/src/main.rs
+++ b/pkgs/by-name/ri/river-mk-keymap/src/main.rs
@@ -1,3 +1,13 @@
+// nixos-config - My current NixOS configuration
+//
+// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+// This file is part of my nixos-config.
+//
+// You should have received a copy of the License along with this program.
+// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 use std::fs;
 
 use anyhow::Context;
diff --git a/pkgs/by-name/ri/river-mk-keymap/update.sh b/pkgs/by-name/ri/river-mk-keymap/update.sh
index 9268caf2..8e36e13e 100755
--- a/pkgs/by-name/ri/river-mk-keymap/update.sh
+++ b/pkgs/by-name/ri/river-mk-keymap/update.sh
@@ -1,3 +1,14 @@
 #!/bin/sh
 
-cargo update && cargo upgrade
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+[ "$1" = "upgrade" ] && cargo upgrade
+cargo update
diff --git a/pkgs/by-name/ri/river-start/package.nix b/pkgs/by-name/ri/river-start/package.nix
deleted file mode 100644
index ab986708..00000000
--- a/pkgs/by-name/ri/river-start/package.nix
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-  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
deleted file mode 100755
index 4587ff96..00000000
--- a/pkgs/by-name/ri/river-start/river-start.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#! /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 12bb3968..34054b0f 100644
--- a/pkgs/by-name/sc/screenshot_persistent/package.nix
+++ b/pkgs/by-name/sc/screenshot_persistent/package.nix
@@ -1,3 +1,12 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 {
   writeShellApplication,
   grim,
diff --git a/pkgs/by-name/sc/screenshot_persistent/screenshot_persistent.sh b/pkgs/by-name/sc/screenshot_persistent/screenshot_persistent.sh
index 2bea69e3..0eeb75c0 100755
--- a/pkgs/by-name/sc/screenshot_persistent/screenshot_persistent.sh
+++ b/pkgs/by-name/sc/screenshot_persistent/screenshot_persistent.sh
@@ -1,3 +1,13 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 # shellcheck shell=bash
 
 tmp="$(mktemp)"
diff --git a/pkgs/by-name/sc/screenshot_temporary/package.nix b/pkgs/by-name/sc/screenshot_temporary/package.nix
index f3739b01..49bbeeb7 100644
--- a/pkgs/by-name/sc/screenshot_temporary/package.nix
+++ b/pkgs/by-name/sc/screenshot_temporary/package.nix
@@ -1,15 +1,24 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 {
-  sysLib,
+  writeShellApplication,
+  # Dependencies
   grim,
   slurp,
   wl-clipboard,
 }:
-sysLib.writeShellScript {
+writeShellApplication {
   name = "screenshot_temporary";
-  src = ./screenshot_temporary.sh;
-  generateCompletions = false;
-  keepPath = false;
-  dependencies = [
+  text = builtins.readFile ./screenshot_temporary.sh;
+  inheritPath = false;
+  runtimeInputs = [
     grim
     slurp
     wl-clipboard
diff --git a/pkgs/by-name/sc/screenshot_temporary/screenshot_temporary.sh b/pkgs/by-name/sc/screenshot_temporary/screenshot_temporary.sh
index 8968ca79..db1a79b7 100755
--- a/pkgs/by-name/sc/screenshot_temporary/screenshot_temporary.sh
+++ b/pkgs/by-name/sc/screenshot_temporary/screenshot_temporary.sh
@@ -1,7 +1,14 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 
 grim -g "$(slurp)" | wl-copy
 
diff --git a/pkgs/by-name/sn/snap-sync-forked/package.nix b/pkgs/by-name/sn/snap-sync-forked/package.nix
deleted file mode 100644
index b3f40b24..00000000
--- a/pkgs/by-name/sn/snap-sync-forked/package.nix
+++ /dev/null
@@ -1,36 +0,0 @@
-{
-  sysLib,
-  bash,
-  btrfs-progs,
-  coreutils,
-  gawk,
-  gnugrep,
-  snapper,
-  util-linux,
-  # optional
-  libnotify,
-  openssh,
-  pv,
-  rsync,
-  sudo,
-}:
-sysLib.writeShellScript {
-  name = "snap-sync-forked";
-  src = ./snap-sync-forked.sh;
-  dependencies = [
-    bash
-    btrfs-progs
-    coreutils
-    gawk
-    gnugrep
-    snapper
-    util-linux
-
-    # optional:
-    libnotify
-    openssh
-    pv
-    rsync
-    sudo
-  ];
-}
diff --git a/pkgs/by-name/sn/snap-sync-forked/snap-sync-forked.sh b/pkgs/by-name/sn/snap-sync-forked/snap-sync-forked.sh
deleted file mode 100755
index 3d9c1ac9..00000000
--- a/pkgs/by-name/sn/snap-sync-forked/snap-sync-forked.sh
+++ /dev/null
@@ -1,534 +0,0 @@
-#!/usr/bin/env bash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
-#
-# snap-sync
-# https://github.com/wesbarnett/snap-sync
-# Copyright (C) 2016-2021 Wes Barnett
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-
-# -------------------------------------------------------------------------
-
-# Takes snapshots of each snapper configuration. It then sends the snapshot to
-# a location on an external drive. After the initial transfer, it does
-# incremental snapshots on later calls. It's important not to delete the
-# snapshot created on your system since that will be used to determine the
-# difference for the next incremental snapshot.
-
-set -o errtrace
-
-version="0.7"
-name="snap-sync"
-
-printf "\nsnap-sync version %s, Copyright (C) 2016-2021 Wes Barnett\n" "$version"
-printf "snap-sync comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. See the license for more information. \n\n"
-
-# The following line is modified by the Makefile or
-# find_snapper_config script
-SNAPPER_CONFIG=/etc/sysconfig/snapper
-
-donotify=0
-if ! command -v notify-send &>/dev/null; then
-    donotify=1
-fi
-
-doprogress=0
-if ! command -v pv &>/dev/null; then
-    doprogress=1
-fi
-
-error() {
-    printf "==> ERROR: %s\n" "$@"
-    notify_error 'Error' 'Check journal for more information.'
-} >&2
-
-die() {
-    error "$@"
-    exit 1
-}
-
-traperror() {
-    printf "Exited due to error on line %s.\n" "$1"
-    printf "exit status: %s\n" "$2"
-    printf "command: %s\n" "$3"
-    printf "bash line: %s\n" "$4"
-    printf "function name: %s\n" "$5"
-    exit 1
-}
-
-trapkill() {
-    die "Exited due to user intervention."
-}
-
-trap 'traperror ${LINENO} $? "$BASH_COMMAND" $BASH_LINENO "${FUNCNAME[@]}"' ERR
-trap trapkill SIGTERM SIGINT
-
-usage() {
-    cat <<EOF
-$name $version
-Usage: $name [options]
-
-Options:
- -c, --config <config>    snapper configuration to backup
- -d, --description <desc> snapper description
- -h, --help               print this message
- -n, --noconfirm          do not ask for confirmation
- -k, --keepold            keep old incremental snapshots instead of deleting them
-                          after backup is performed
- -p, --port <port>        remote port; used with '--remote'.
- -q, --quiet              do not send notifications; instead print them.
- -r, --remote <address>   ip address of a remote machine to backup to
- --sudo                   use sudo on the remote machine
- -s, --subvolid <subvlid> subvolume id of the mounted BTRFS subvolume to back up to
- -u, --UUID <UUID>        UUID of the mounted BTRFS subvolume to back up to
-
-See 'man snap-sync' for more details.
-EOF
-}
-
-ssh=""
-sudo=0
-while [[ $# -gt 0 ]]; do
-    key="$1"
-    case $key in
-    -d | --description)
-        description="$2"
-        shift 2
-        ;;
-    -c | --config)
-        selected_configs="$2"
-        shift 2
-        ;;
-    -u | --UUID)
-        uuid_cmdline="$2"
-        shift 2
-        ;;
-    -s | --subvolid)
-        subvolid_cmdline="$2"
-        shift 2
-        ;;
-    -k | --keepold)
-        keep="yes"
-        shift
-        ;;
-    -n | --noconfirm)
-        noconfirm="yes"
-        shift
-        ;;
-    -h | --help)
-        usage
-        exit 1
-        ;;
-    -q | --quiet)
-        donotify=1
-        shift
-        ;;
-    -r | --remote)
-        remote=$2
-        shift 2
-        ;;
-    -p | --port)
-        port=$2
-        shift 2
-        ;;
-    --sudo)
-        sudo=1
-        shift
-        ;;
-    *)
-        die "Unknown option: '$key'. Run '$name -h' for valid options."
-        ;;
-    esac
-done
-
-notify() {
-    for u in $(users | tr ' ' '\n' | sort -u); do
-        sudo -u "$u" DISPLAY=:0 \
-            DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$(sudo -u "$u" id -u)/bus" \
-            notify-send -a $name "$1" "$2" --icon="dialog-$3"
-    done
-}
-
-notify_info() {
-    if [[ $donotify -eq 0 ]]; then
-        notify "$1" "$2" "information"
-    else
-        printf '%s\n' "$1: $2"
-    fi
-}
-
-notify_error() {
-    if [[ $donotify -eq 0 ]]; then
-        notify "$1" "$2" "error"
-    else
-        printf '%s\n' "$1: $2"
-    fi
-}
-
-[[ $EUID -ne 0 ]] && die "Script must be run as root. See '$name -h' for a description of options"
-! [[ -f $SNAPPER_CONFIG ]] && die "$SNAPPER_CONFIG does not exist."
-
-description=${description:-"latest incremental backup"}
-uuid_cmdline=${uuid_cmdline:-"none"}
-subvolid_cmdline=${subvolid_cmdline:-"5"}
-noconfirm=${noconfirm:-"no"}
-
-if [[ -z $remote ]]; then
-    if ! command -v rsync &>/dev/null; then
-        die "--remote specified but rsync command not found"
-    fi
-fi
-
-if [[ $uuid_cmdline != "none" ]]; then
-    if [[ -z $remote ]]; then
-        notify_info "Backup started" "Starting backups to $uuid_cmdline subvolid=$subvolid_cmdline..."
-    else
-        notify_info "Backup started" "Starting backups to $uuid_cmdline subvolid $subvolid_cmdline at $remote..."
-    fi
-else
-    if [[ -z $remote ]]; then
-        notify_info "Backup started" "Starting backups. Use command line menu to select disk."
-    else
-        notify_info "Backup started" "Starting backups. Use command line menu to select disk on $remote."
-    fi
-fi
-
-if [[ -n $remote ]]; then
-    ssh="ssh $remote"
-    if [[ -n $port ]]; then
-        ssh="$ssh -p $port"
-    fi
-    if [[ $sudo -eq 1 ]]; then
-        ssh="$ssh sudo"
-    fi
-fi
-
-if [[ "$($ssh findmnt -n -v --target / -o FSTYPE)" == "btrfs" ]]; then
-    EXCLUDE_UUID=$($ssh findmnt -n -v -t btrfs --target / -o UUID)
-    TARGETS=$($ssh findmnt -n -v -t btrfs -o UUID,TARGET --list | grep -v "$EXCLUDE_UUID" | awk '{print $2}')
-    UUIDS=$($ssh findmnt -n -v -t btrfs -o UUID,TARGET --list | grep -v "$EXCLUDE_UUID" | awk '{print $1}')
-else
-    TARGETS=$($ssh findmnt -n -v -t btrfs -o TARGET --list)
-    UUIDS=$($ssh findmnt -n -v -t btrfs -o UUID --list)
-fi
-
-declare -a TARGETS_ARRAY
-declare -a UUIDS_ARRAY
-declare -a SUBVOLIDS_ARRAY
-
-i=0
-for x in $TARGETS; do
-    SUBVOLIDS_ARRAY[i]=$($ssh btrfs subvolume show "$x" | awk '/Subvolume ID:/ { print $3 }')
-    TARGETS_ARRAY[i]=$x
-    i=$((i + 1))
-done
-
-i=0
-disk=-1
-disk_count=0
-for x in $UUIDS; do
-    UUIDS_ARRAY[i]=$x
-    if [[ $x == "$uuid_cmdline" && ${SUBVOLIDS_ARRAY[$((i))]} == "$subvolid_cmdline" ]]; then
-        disk=$i
-        disk_count=$((disk_count + 1))
-    fi
-    i=$((i + 1))
-done
-
-if [[ ${#UUIDS_ARRAY[$@]} -eq 0 ]]; then
-    die "No external btrfs subvolumes found to backup to. Run '$name -h' for more options."
-fi
-
-if [[ $disk_count -gt 1 ]]; then
-    printf "Multiple mount points were found with UUID %s and subvolid %s.\n" "$uuid_cmdline" "$subvolid_cmdline"
-    disk="-1"
-fi
-
-if [[ $disk == -1 ]]; then
-    if [[ $disk_count == 0 && $uuid_cmdline != "none" ]]; then
-        error "A device with UUID $uuid_cmdline and subvolid $subvolid_cmdline was not found to be mounted, or it is not a BTRFS device."
-    fi
-    if [[ -z $ssh ]]; then
-        printf "Select a mounted BTRFS device on your local machine to backup to.\nFor more options, exit and run '%s -h'.\n" "$name"
-    else
-        printf "Select a mounted BTRFS device on %s to backup to.\nFor more options, exit and run '%s -h'.\n" "$remote" "$name"
-    fi
-    while [[ $disk -lt 0 || $disk -gt $i ]]; do
-        for x in "${!TARGETS_ARRAY[@]}"; do
-            printf "%4s) %s (uuid=%s, subvolid=%s)\n" "$((x + 1))" "${TARGETS_ARRAY[$x]}" "${UUIDS_ARRAY[$x]}" "${SUBVOLIDS_ARRAY[$x]}"
-        done
-        printf "%4s) Exit\n" "0"
-        read -e -r -p "Enter a number: " disk
-        if ! [[ $disk == ?(-)+([0-9]) ]] || [[ $disk -lt 0 || $disk -gt $i ]]; then
-            printf "\nNo disk selected. Select a disk to continue.\n"
-            disk=-1
-        fi
-    done
-    if [[ $disk == 0 ]]; then
-        exit 0
-    fi
-    disk=$((disk - 1))
-fi
-
-selected_subvolid="${SUBVOLIDS_ARRAY[$((disk))]}"
-selected_uuid="${UUIDS_ARRAY[$((disk))]}"
-selected_mnt="${TARGETS_ARRAY[$((disk))]}"
-printf "\nYou selected the disk with uuid=%s, subvolid=%s.\n" "$selected_uuid" "$selected_subvolid"
-if [[ -z $ssh ]]; then
-    printf "The disk is mounted at '%s'.\n" "$selected_mnt"
-else
-    printf "The disk is mounted at '%s:%s'.\n" "$remote" "$selected_mnt"
-fi
-
-# shellcheck source=/dev/null
-source "$SNAPPER_CONFIG"
-
-if [[ -z $selected_configs ]]; then
-    printf "\nInteractively cycling through all snapper configurations...\n"
-fi
-selected_configs=${selected_configs:-$SNAPPER_CONFIGS}
-
-declare -a BACKUPDIRS_ARRAY
-declare -a MYBACKUPDIR_ARRAY
-declare -a OLD_NUM_ARRAY
-declare -a OLD_SNAP_ARRAY
-declare -a NEW_NUM_ARRAY
-declare -a NEW_SNAP_ARRAY
-declare -a NEW_INFO_ARRAY
-declare -a BACKUPLOC_ARRAY
-declare -a CONT_BACKUP_ARRAY
-
-# Initial configuration of where backup directories are
-i=0
-for x in $selected_configs; do
-
-    if [[ "$(snapper -c "$x" list --disable-used-space -t single | awk '/'"subvolid=$selected_subvolid, uuid=$selected_uuid"'/ {cnt++} END {print cnt}')" -gt 1 ]]; then
-        error "More than one snapper entry found with UUID $selected_uuid subvolid $selected_subvolid for configuration $x. Skipping configuration $x."
-        continue
-    fi
-
-    if [[ "$(snapper -c "$x" list --disable-used-space -t single | awk '/'$name' backup in progress/ {cnt++} END {print cnt}')" -gt 0 ]]; then
-        printf "\nNOTE: Previous failed %s backup snapshots found for '%s'.\n" "$name" "$x"
-        if [[ $noconfirm == "yes" ]]; then
-            printf "'noconfirm' option passed. Failed backups will not be deleted.\n"
-        else
-            read -e -r -p "Delete failed backup snapshot(s)? (These local snapshots from failed backups are not used.) [y/N]? " delete_failed
-            while [[ -n $delete_failed && $delete_failed != [Yy]"es" &&
-                $delete_failed != [Yy] && $delete_failed != [Nn]"o" &&
-                $delete_failed != [Nn] ]]; do
-                read -e -r -p "Delete failed backup snapshot(s)? (These local snapshots from failed backups are not used.) [y/N] " delete_failed
-                if [[ -n $delete_failed && $delete_failed != [Yy]"es" &&
-                    $delete_failed != [Yy] && $delete_failed != [Nn]"o" &&
-                    $delete_failed != [Nn] ]]; then
-                    printf "Select 'y' or 'N'.\n"
-                fi
-            done
-            if [[ $delete_failed == [Yy]"es" || $delete_failed == [Yy] ]]; then
-                # explicit split list of snapshots (on whitespace) into multiple arguments
-                # shellcheck disable=SC2046
-                snapper -c "$x" delete $(snapper -c "$x" list --disable-used-space | awk '/'$name' backup in progress/ {print $1}')
-            fi
-        fi
-    fi
-
-    SNAP_SYNC_EXCLUDE=no
-
-    if [[ -f "/etc/snapper/configs/$x" ]]; then
-        # shellcheck source=/dev/null
-        source "/etc/snapper/configs/$x"
-    else
-        die "Selected snapper configuration $x does not exist."
-    fi
-
-    if [[ $SNAP_SYNC_EXCLUDE == "yes" ]]; then
-        continue
-    fi
-
-    printf "\n"
-
-    old_num=$(snapper -c "$x" list --disable-used-space -t single | awk '/'"subvolid=$selected_subvolid, uuid=$selected_uuid"'/ {print $1}')
-    old_snap=$SUBVOLUME/.snapshots/$old_num/snapshot
-
-    OLD_NUM_ARRAY[i]=$old_num
-    OLD_SNAP_ARRAY[i]=$old_snap
-
-    if [[ -z $old_num ]]; then
-        printf "No backups have been performed for '%s' on this disk.\n" "$x"
-        read -e -r -p "Enter name of subvolume to store backups, relative to $selected_mnt (to be created if not existing): " mybackupdir
-        printf "This will be the initial backup for snapper configuration '%s' to this disk. This could take awhile.\n" "$x"
-        BACKUPDIR="$selected_mnt/$mybackupdir"
-        $ssh test -d "$BACKUPDIR" || $ssh btrfs subvolume create "$BACKUPDIR"
-    else
-        mybackupdir=$(snapper -c "$x" list --disable-used-space -t single | awk -F"|" '/'"subvolid=$selected_subvolid, uuid=$selected_uuid"'/ {print $5}' | awk -F "," '/backupdir/ {print $1}' | awk -F"=" '{print $2}')
-        BACKUPDIR="$selected_mnt/$mybackupdir"
-        $ssh test -d "$BACKUPDIR" || die "%s is not a directory on %s.\n" "$BACKUPDIR" "$selected_uuid"
-    fi
-    BACKUPDIRS_ARRAY[i]="$BACKUPDIR"
-    MYBACKUPDIR_ARRAY[i]="$mybackupdir"
-
-    printf "Creating new local snapshot for '%s' configuration...\n" "$x"
-    new_num=$(snapper -c "$x" create --print-number -d "$name backup in progress")
-    new_snap=$SUBVOLUME/.snapshots/$new_num/snapshot
-    new_info=$SUBVOLUME/.snapshots/$new_num/info.xml
-    sync
-    backup_location=$BACKUPDIR/$x/$new_num/
-    if [[ -z $ssh ]]; then
-        printf "Will backup %s to %s\n" "$new_snap" "$backup_location/snapshot"
-    else
-        printf "Will backup %s to %s\n" "$new_snap" "$remote":"$backup_location/snapshot"
-    fi
-
-    if ($ssh test -d "$backup_location/snapshot"); then
-        printf "WARNING: Backup directory '%s' already exists. This configuration will be skipped!\n" "$backup_location/snapshot"
-        printf "Move or delete destination directory and try backup again.\n"
-    fi
-
-    NEW_NUM_ARRAY[i]="$new_num"
-    NEW_SNAP_ARRAY[i]="$new_snap"
-    NEW_INFO_ARRAY[i]="$new_info"
-    BACKUPLOC_ARRAY[i]="$backup_location"
-
-    cont_backup="K"
-    CONT_BACKUP_ARRAY[i]="yes"
-    if [[ $noconfirm == "yes" ]]; then
-        cont_backup="yes"
-    else
-        while [[ -n $cont_backup && $cont_backup != [Yy]"es" &&
-            $cont_backup != [Yy] && $cont_backup != [Nn]"o" &&
-            $cont_backup != [Nn] ]]; do
-            read -e -r -p "Proceed with backup of '$x' configuration [Y/n]? " cont_backup
-            if [[ -n $cont_backup && $cont_backup != [Yy]"es" &&
-                $cont_backup != [Yy] && $cont_backup != [Nn]"o" &&
-                $cont_backup != [Nn] ]]; then
-                printf "Select 'Y' or 'n'.\n"
-            fi
-        done
-    fi
-
-    if [[ $cont_backup != [Yy]"es" && $cont_backup != [Yy] && -n $cont_backup ]]; then
-        CONT_BACKUP_ARRAY[i]="no"
-        printf "Not backing up '%s' configuration.\n" "$x"
-        snapper -c "$x" delete "$new_num"
-    fi
-
-    i=$((i + 1))
-
-done
-
-# Actual backing up
-printf "\nPerforming backups...\n"
-i=-1
-for x in $selected_configs; do
-
-    i=$((i + 1))
-
-    SNAP_SYNC_EXCLUDE=no
-
-    if [[ -f "/etc/snapper/configs/$x" ]]; then
-        # shellcheck source=/dev/null
-        source "/etc/snapper/configs/$x"
-    else
-        die "Selected snapper configuration $x does not exist."
-    fi
-
-    cont_backup=${CONT_BACKUP_ARRAY[$i]}
-    if [[ $cont_backup == "no" || $SNAP_SYNC_EXCLUDE == "yes" ]]; then
-        notify_info "Backup in progress" "NOTE: Skipping $x configuration."
-        continue
-    fi
-
-    notify_info "Backup in progress" "Backing up $x configuration."
-
-    printf "\n"
-
-    old_num="${OLD_NUM_ARRAY[$i]}"
-    old_snap="${OLD_SNAP_ARRAY[$i]}"
-    BACKUPDIR="${BACKUPDIRS_ARRAY[$i]}"
-    mybackupdir="${MYBACKUPDIR_ARRAY[$i]}"
-    new_num="${NEW_NUM_ARRAY[$i]}"
-    new_snap="${NEW_SNAP_ARRAY[$i]}"
-    new_info="${NEW_INFO_ARRAY[$i]}"
-    backup_location="${BACKUPLOC_ARRAY[$i]}"
-
-    if ($ssh test -d "$backup_location/snapshot"); then
-        printf "ERROR: Backup directory '%s' already exists. Skipping backup of this configuration!\n" "$backup_location/snapshot"
-        continue
-    fi
-
-    $ssh mkdir -p "$backup_location"
-
-    if [[ -z $old_num ]]; then
-        printf "Sending first snapshot for '%s' configuration...\n" "$x"
-        if [[ $doprogress -eq 0 ]]; then
-            btrfs send "$new_snap" | pv | $ssh btrfs receive "$backup_location" &>/dev/null
-        else
-            btrfs send "$new_snap" | $ssh btrfs receive "$backup_location" &>/dev/null
-        fi
-    else
-
-        printf "Sending incremental snapshot for '%s' configuration...\n" "$x"
-        # Sends the difference between the new snapshot and old snapshot to the
-        # backup location. Using the -c flag instead of -p tells it that there
-        # is an identical subvolume to the old snapshot at the receiving
-        # location where it can get its data. This helps speed up the transfer.
-
-        if [[ $doprogress -eq 0 ]]; then
-            btrfs send -c "$old_snap" "$new_snap" | pv | $ssh btrfs receive "$backup_location"
-        else
-            btrfs send -c "$old_snap" "$new_snap" | $ssh btrfs receive "$backup_location"
-        fi
-
-        if [[ $keep == "yes" ]]; then
-            printf "Modifying data for old local snapshot for '%s' configuration...\n" "$x"
-            snapper -v -c "$x" modify -d "old snap-sync snapshot (you may remove)" -u "backupdir=,subvolid=,uuid=" -c "number" "$old_num"
-        else
-            printf "Deleting old snapshot for %s...\n" "$x"
-            snapper -c "$x" delete "$old_num"
-        fi
-
-    fi
-
-    if [[ -z $remote ]]; then
-        cp "$new_info" "$backup_location"
-    else
-        if [[ -z $port ]]; then
-            rsync -avzq "$new_info" "$remote":"$backup_location"
-        else
-            rsync -avzqe "ssh -p $port" "$new_info" "$remote":"$backup_location"
-        fi
-    fi
-
-    # It's important not to change this userdata in the snapshots, since that's how
-    # we find the previous one.
-
-    userdata="backupdir=$mybackupdir, subvolid=$selected_subvolid, uuid=$selected_uuid"
-
-    # Tag new snapshot as the latest
-    printf "Tagging local snapshot as latest backup for '%s' configuration...\n" "$x"
-    snapper -v -c "$x" modify -d "$description" -u "$userdata" "$new_num"
-
-    printf "Backup complete for '%s' configuration.\n" "$x"
-
-done
-
-printf "\nDone!\n"
-
-if [[ $uuid_cmdline != "none" ]]; then
-    notify_info "Finished" "Backups to $uuid_cmdline complete!"
-else
-    notify_info "Finished" "Backups complete!"
-fi
diff --git a/pkgs/by-name/st/stamp/package.nix b/pkgs/by-name/st/stamp/package.nix
index 703f73e3..871d531c 100644
--- a/pkgs/by-name/st/stamp/package.nix
+++ b/pkgs/by-name/st/stamp/package.nix
@@ -1,20 +1,29 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 {
-  sysLib,
-  findutils,
+  writeShellApplication,
+  # Dependencies
+  coreutils,
   fd,
-  reuse,
   git,
+  reuse,
 }:
-sysLib.writeShellScript {
+writeShellApplication {
   name = "stamp";
-  src = ./stamp.sh;
-  generateCompletions = false;
-  keepPath = false;
+  text = builtins.readFile ./stamp.sh;
+  inheritPath = false;
 
-  dependencies = [
-    findutils
+  runtimeInputs = [
+    coreutils
     fd
-    reuse
     git
+    reuse
   ];
 }
diff --git a/pkgs/by-name/st/stamp/stamp.sh b/pkgs/by-name/st/stamp/stamp.sh
index 0aa6c281..5f17b2aa 100755
--- a/pkgs/by-name/st/stamp/stamp.sh
+++ b/pkgs/by-name/st/stamp/stamp.sh
@@ -1,7 +1,19 @@
 #!/usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+die() {
+    echo "Error: $1"
+    exit 1
+}
 
 help() {
     cat <<EOF
diff --git a/pkgs/by-name/tr/tree-sitter-yts/package.nix b/pkgs/by-name/tr/tree-sitter-yts/package.nix
index 3a97530d..62ecf063 100644
--- a/pkgs/by-name/tr/tree-sitter-yts/package.nix
+++ b/pkgs/by-name/tr/tree-sitter-yts/package.nix
@@ -1,3 +1,12 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 # taken from nixpgks: pkgs/development/tools/parsing/tree-sitter/grammar.nix
 {
   yt,
diff --git a/pkgs/by-name/ts/tskm/.envrc b/pkgs/by-name/ts/tskm/.envrc
index d21a17fc..2c7bb7c9 100644
--- a/pkgs/by-name/ts/tskm/.envrc
+++ b/pkgs/by-name/ts/tskm/.envrc
@@ -1,7 +1,14 @@
 #!/usr/bin/env sh
 
-SHELL_COMPLETION_DIR="$(pwd)/target/shell"
-export SHELL_COMPLETION_DIR
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 
 export TSKM_PROJECT_FILE=/home/soispha/repos/nix/config/modules/common/projects.json
 
diff --git a/pkgs/by-name/ts/tskm/.gitignore b/pkgs/by-name/ts/tskm/.gitignore
index 2d5df85d..f255eebd 100644
--- a/pkgs/by-name/ts/tskm/.gitignore
+++ b/pkgs/by-name/ts/tskm/.gitignore
@@ -1,2 +1,12 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 /target
 .direnv
diff --git a/pkgs/by-name/ts/tskm/Cargo.lock b/pkgs/by-name/ts/tskm/Cargo.lock
index 68823d3c..0c339a9a 100644
--- a/pkgs/by-name/ts/tskm/Cargo.lock
+++ b/pkgs/by-name/ts/tskm/Cargo.lock
@@ -1,5 +1,14 @@
 # This file is automatically @generated by Cargo.
 # It is not intended for manual editing.
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 version = 4
 
 [[package]]
@@ -10,9 +19,9 @@ checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
 
 [[package]]
 name = "ahash"
-version = "0.8.11"
+version = "0.8.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
+checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75"
 dependencies = [
  "cfg-if",
  "once_cell",
@@ -76,20 +85,20 @@ dependencies = [
 
 [[package]]
 name = "anstyle-wincon"
-version = "3.0.7"
+version = "3.0.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e"
+checksum = "6680de5231bd6ee4c6191b8a1325daa282b415391ec9d3a37bd34f2060dc73fa"
 dependencies = [
  "anstyle",
- "once_cell",
+ "once_cell_polyfill",
  "windows-sys",
 ]
 
 [[package]]
 name = "anyhow"
-version = "1.0.97"
+version = "1.0.98"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
+checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
 
 [[package]]
 name = "autocfg"
@@ -99,9 +108,9 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
 
 [[package]]
 name = "bitflags"
-version = "2.9.0"
+version = "2.9.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
+checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
 
 [[package]]
 name = "bumpalo"
@@ -117,9 +126,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
 
 [[package]]
 name = "cc"
-version = "1.2.17"
+version = "1.2.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a"
+checksum = "16595d3be041c03b09d08d0858631facccee9221e579704070e6e9e4915d3bc7"
 dependencies = [
  "shlex",
 ]
@@ -132,9 +141,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
 [[package]]
 name = "chrono"
-version = "0.4.40"
+version = "0.4.41"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c"
+checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d"
 dependencies = [
  "android-tzdata",
  "iana-time-zone",
@@ -147,9 +156,9 @@ dependencies = [
 
 [[package]]
 name = "clap"
-version = "4.5.34"
+version = "4.5.39"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e958897981290da2a852763fe9cdb89cd36977a5d729023127095fa94d95e2ff"
+checksum = "fd60e63e9be68e5fb56422e397cf9baddded06dae1d2e523401542383bc72a9f"
 dependencies = [
  "clap_builder",
  "clap_derive",
@@ -157,9 +166,9 @@ dependencies = [
 
 [[package]]
 name = "clap_builder"
-version = "4.5.34"
+version = "4.5.39"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "83b0f35019843db2160b5bb19ae09b4e6411ac33fc6a712003c33e03090e2489"
+checksum = "89cc6392a1f72bbeb820d71f32108f61fdaf18bc526e1d23954168a67759ef51"
 dependencies = [
  "anstream",
  "anstyle",
@@ -169,11 +178,14 @@ dependencies = [
 
 [[package]]
 name = "clap_complete"
-version = "4.5.47"
+version = "4.5.51"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c06f5378ea264ad4f82bbc826628b5aad714a75abf6ece087e923010eb937fb6"
+checksum = "8d2267df7f3c8e74e38268887ea5235d4dfadd39bfff2d56ab82d61776be355e"
 dependencies = [
  "clap",
+ "clap_lex",
+ "is_executable",
+ "shlex",
 ]
 
 [[package]]
@@ -280,9 +292,9 @@ dependencies = [
 
 [[package]]
 name = "getrandom"
-version = "0.2.15"
+version = "0.2.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
+checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
 dependencies = [
  "cfg-if",
  "libc",
@@ -291,9 +303,9 @@ dependencies = [
 
 [[package]]
 name = "getrandom"
-version = "0.3.2"
+version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0"
+checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
 dependencies = [
  "cfg-if",
  "libc",
@@ -327,15 +339,15 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
 
 [[package]]
 name = "hermit-abi"
-version = "0.5.0"
+version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fbd780fe5cc30f81464441920d82ac8740e2e46b29a6fad543ddd075229ce37e"
+checksum = "f154ce46856750ed433c8649605bf7ed2de3bc35fd9d2a9f30cddd873c80cb08"
 
 [[package]]
 name = "iana-time-zone"
-version = "0.1.62"
+version = "0.1.63"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2fd658b06e56721792c5df4475705b6cda790e9298d19d2f8af083457bcd127"
+checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8"
 dependencies = [
  "android_system_properties",
  "core-foundation-sys",
@@ -357,21 +369,22 @@ dependencies = [
 
 [[package]]
 name = "icu_collections"
-version = "1.5.0"
+version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526"
+checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47"
 dependencies = [
  "displaydoc",
+ "potential_utf",
  "yoke",
  "zerofrom",
  "zerovec",
 ]
 
 [[package]]
-name = "icu_locid"
-version = "1.5.0"
+name = "icu_locale_core"
+version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637"
+checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a"
 dependencies = [
  "displaydoc",
  "litemap",
@@ -381,30 +394,10 @@ dependencies = [
 ]
 
 [[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"
+version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f"
+checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979"
 dependencies = [
  "displaydoc",
  "icu_collections",
@@ -412,68 +405,55 @@ dependencies = [
  "icu_properties",
  "icu_provider",
  "smallvec",
- "utf16_iter",
- "utf8_iter",
- "write16",
  "zerovec",
 ]
 
 [[package]]
 name = "icu_normalizer_data"
-version = "1.5.1"
+version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7"
+checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3"
 
 [[package]]
 name = "icu_properties"
-version = "1.5.1"
+version = "2.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5"
+checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b"
 dependencies = [
  "displaydoc",
  "icu_collections",
- "icu_locid_transform",
+ "icu_locale_core",
  "icu_properties_data",
  "icu_provider",
- "tinystr",
+ "potential_utf",
+ "zerotrie",
  "zerovec",
 ]
 
 [[package]]
 name = "icu_properties_data"
-version = "1.5.1"
+version = "2.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2"
+checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632"
 
 [[package]]
 name = "icu_provider"
-version = "1.5.0"
+version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9"
+checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af"
 dependencies = [
  "displaydoc",
- "icu_locid",
- "icu_provider_macros",
+ "icu_locale_core",
  "stable_deref_trait",
  "tinystr",
  "writeable",
  "yoke",
  "zerofrom",
+ "zerotrie",
  "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"
@@ -486,9 +466,9 @@ dependencies = [
 
 [[package]]
 name = "idna_adapter"
-version = "1.2.0"
+version = "1.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71"
+checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344"
 dependencies = [
  "icu_normalizer",
  "icu_properties",
@@ -506,6 +486,15 @@ dependencies = [
 ]
 
 [[package]]
+name = "is_executable"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4a1b5bad6f9072935961dfbf1cced2f3d129963d091b6f69f007fe04e758ae2"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
 name = "is_terminal_polyfill"
 version = "1.70.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -529,9 +518,9 @@ dependencies = [
 
 [[package]]
 name = "libc"
-version = "0.2.171"
+version = "0.2.172"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
+checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
 
 [[package]]
 name = "libredox"
@@ -555,9 +544,9 @@ dependencies = [
 
 [[package]]
 name = "litemap"
-version = "0.7.5"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856"
+checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956"
 
 [[package]]
 name = "log"
@@ -570,9 +559,6 @@ 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"
@@ -582,9 +568,9 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
 
 [[package]]
 name = "miniz_oxide"
-version = "0.8.7"
+version = "0.8.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff70ce3e48ae43fa075863cef62e8b43b71a4f2382229920e0df362592919430"
+checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a"
 dependencies = [
  "adler2",
 ]
@@ -605,6 +591,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
 
 [[package]]
+name = "once_cell_polyfill"
+version = "1.70.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
+
+[[package]]
 name = "option-ext"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -623,10 +615,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
 
 [[package]]
+name = "potential_utf"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585"
+dependencies = [
+ "zerovec",
+]
+
+[[package]]
 name = "proc-macro2"
-version = "1.0.94"
+version = "1.0.95"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
+checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
 dependencies = [
  "unicode-ident",
 ]
@@ -652,7 +653,7 @@ version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b"
 dependencies = [
- "getrandom 0.2.15",
+ "getrandom 0.2.16",
  "libredox",
  "thiserror",
 ]
@@ -673,9 +674,9 @@ dependencies = [
 
 [[package]]
 name = "rustversion"
-version = "1.0.20"
+version = "1.0.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2"
+checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d"
 
 [[package]]
 name = "ryu"
@@ -732,9 +733,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
 
 [[package]]
 name = "smallvec"
-version = "1.14.0"
+version = "1.15.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd"
+checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9"
 
 [[package]]
 name = "stable_deref_trait"
@@ -743,18 +744,11 @@ 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",
@@ -788,9 +782,9 @@ dependencies = [
 
 [[package]]
 name = "syn"
-version = "2.0.100"
+version = "2.0.101"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
+checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -799,9 +793,9 @@ dependencies = [
 
 [[package]]
 name = "synstructure"
-version = "0.13.1"
+version = "0.13.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
+checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -869,9 +863,9 @@ dependencies = [
 
 [[package]]
 name = "tinystr"
-version = "0.7.6"
+version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f"
+checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b"
 dependencies = [
  "displaydoc",
  "zerovec",
@@ -896,16 +890,6 @@ dependencies = [
 ]
 
 [[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"
@@ -924,12 +908,6 @@ dependencies = [
 ]
 
 [[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"
@@ -943,12 +921,14 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
 
 [[package]]
 name = "uuid"
-version = "1.16.0"
+version = "1.17.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9"
+checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d"
 dependencies = [
- "getrandom 0.3.2",
+ "getrandom 0.3.3",
+ "js-sys",
  "serde",
+ "wasm-bindgen",
 ]
 
 [[package]]
@@ -1047,6 +1027,22 @@ dependencies = [
 ]
 
 [[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
 name = "winapi-util"
 version = "0.1.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1056,12 +1052,44 @@ dependencies = [
 ]
 
 [[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
 name = "windows-core"
-version = "0.52.0"
+version = "0.61.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
+checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
 dependencies = [
- "windows-targets",
+ "windows-implement",
+ "windows-interface",
+ "windows-link",
+ "windows-result",
+ "windows-strings",
+]
+
+[[package]]
+name = "windows-implement"
+version = "0.60.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "windows-interface"
+version = "0.59.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
 ]
 
 [[package]]
@@ -1071,6 +1099,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
 
 [[package]]
+name = "windows-result"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
+dependencies = [
+ "windows-link",
+]
+
+[[package]]
+name = "windows-strings"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
+dependencies = [
+ "windows-link",
+]
+
+[[package]]
 name = "windows-sys"
 version = "0.59.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1153,22 +1199,16 @@ dependencies = [
 ]
 
 [[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"
+version = "0.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
+checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb"
 
 [[package]]
 name = "yoke"
-version = "0.7.5"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40"
+checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc"
 dependencies = [
  "serde",
  "stable_deref_trait",
@@ -1178,9 +1218,9 @@ dependencies = [
 
 [[package]]
 name = "yoke-derive"
-version = "0.7.5"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154"
+checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1190,18 +1230,18 @@ dependencies = [
 
 [[package]]
 name = "zerocopy"
-version = "0.7.35"
+version = "0.8.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
+checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb"
 dependencies = [
  "zerocopy-derive",
 ]
 
 [[package]]
 name = "zerocopy-derive"
-version = "0.7.35"
+version = "0.8.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
+checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1230,10 +1270,21 @@ dependencies = [
 ]
 
 [[package]]
+name = "zerotrie"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595"
+dependencies = [
+ "displaydoc",
+ "yoke",
+ "zerofrom",
+]
+
+[[package]]
 name = "zerovec"
-version = "0.10.4"
+version = "0.11.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079"
+checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428"
 dependencies = [
  "yoke",
  "zerofrom",
@@ -1242,9 +1293,9 @@ dependencies = [
 
 [[package]]
 name = "zerovec-derive"
-version = "0.10.3"
+version = "0.11.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6"
+checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f"
 dependencies = [
  "proc-macro2",
  "quote",
diff --git a/pkgs/by-name/ts/tskm/Cargo.toml b/pkgs/by-name/ts/tskm/Cargo.toml
index 41fc5888..413530eb 100644
--- a/pkgs/by-name/ts/tskm/Cargo.toml
+++ b/pkgs/by-name/ts/tskm/Cargo.toml
@@ -1,3 +1,13 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 [package]
 name = "tskm"
 version = "0.1.0"
@@ -6,17 +16,18 @@ 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"
+anyhow = { version = "1.0.98", default-features = false }
+clap = { version = "4.5.39", features = [ "derive", "std", "color", "help", "usage", "error-context", "suggestions", ], default-features = false }
+clap_complete = { version = "4.5.51", features = ["unstable-dynamic"] }
+dirs = { version = "6.0.0", default-features = false }
+log = { version = "0.4.27", default-features = false }
+lz4_flex = { version = "0.11.3", features = ["std"], default-features = false }
+serde = { version = "1.0.219", features = ["derive"], default-features = false }
+serde_json = { version = "1.0.140", default-features = false }
+stderrlog = { version = "0.6.0", default-features = false }
 taskchampion = { version = "2.0.3", default-features = false }
-url = { version = "2.5.4", features = ["serde"] }
-walkdir = "2.5.0"
+url = { version = "2.5.4", features = ["serde"], default-features = false }
+walkdir = { version = "2.5.0", default-features = false }
 
 [profile.release]
 lto = true
@@ -77,15 +88,3 @@ 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
deleted file mode 100644
index e3b60bb9..00000000
--- a/pkgs/by-name/ts/tskm/build.rs
+++ /dev/null
@@ -1,52 +0,0 @@
-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
index 82448387..280e8a51 100644
--- a/pkgs/by-name/ts/tskm/flake.lock
+++ b/pkgs/by-name/ts/tskm/flake.lock
@@ -2,11 +2,11 @@
   "nodes": {
     "nixpkgs": {
       "locked": {
-        "lastModified": 1743076231,
-        "narHash": "sha256-yQugdVfi316qUfqzN8JMaA2vixl+45GxNm4oUfXlbgw=",
+        "lastModified": 1748406211,
+        "narHash": "sha256-B3BsCRbc+x/d0WiG1f+qfSLUy+oiIfih54kalWBi+/M=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "6c5963357f3c1c840201eda129a99d455074db04",
+        "rev": "3d1f29646e4b57ed468d60f9d286cde23a8d1707",
         "type": "github"
       },
       "original": {
diff --git a/pkgs/by-name/ts/tskm/flake.lock.license b/pkgs/by-name/ts/tskm/flake.lock.license
new file mode 100644
index 00000000..eae6a84c
--- /dev/null
+++ b/pkgs/by-name/ts/tskm/flake.lock.license
@@ -0,0 +1,9 @@
+nixos-config - My current NixOS configuration
+
+Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+SPDX-License-Identifier: GPL-3.0-or-later
+
+This file is part of my nixos-config.
+
+You should have received a copy of the License along with this program.
+If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
diff --git a/pkgs/by-name/ts/tskm/flake.nix b/pkgs/by-name/ts/tskm/flake.nix
index 5a5f628b..583d4923 100644
--- a/pkgs/by-name/ts/tskm/flake.nix
+++ b/pkgs/by-name/ts/tskm/flake.nix
@@ -1,3 +1,12 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 {
   description = "This is the core interface to the system-integrated task management";
 
diff --git a/pkgs/by-name/ts/tskm/package.nix b/pkgs/by-name/ts/tskm/package.nix
index 3d320772..d75afe6e 100644
--- a/pkgs/by-name/ts/tskm/package.nix
+++ b/pkgs/by-name/ts/tskm/package.nix
@@ -1,3 +1,12 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 {
   rustPlatform,
   installShellFiles,
@@ -19,10 +28,6 @@ rustPlatform.buildRustPackage (finalAttrs: {
     lockFile = ./Cargo.lock;
   };
 
-  env = {
-    SHELL_COMPLETION_DIR = "./shell";
-  };
-
   buildInputs = [
     taskwarrior3
     git
@@ -38,9 +43,9 @@ rustPlatform.buildRustPackage (finalAttrs: {
 
   postInstall = ''
     installShellCompletion --cmd tskm \
-      --bash ./shell/tskm.bash \
-      --fish ./shell/tskm.fish \
-      --zsh ./shell/_tskm
+      --bash <(COMPLETE=bash $out/bin/tskm) \
+      --fish <(COMPLETE=fish $out/bin/tskm) \
+      --zsh <(COMPLETE=zsh $out/bin/tskm)
 
     # NOTE: We cannot clear the path, because we need access to the $EDITOR. <2025-04-04>
     wrapProgram $out/bin/tskm \
diff --git a/pkgs/by-name/ts/tskm/src/cli.rs b/pkgs/by-name/ts/tskm/src/cli.rs
index 1c72b3c2..ac8f8ee9 100644
--- a/pkgs/by-name/ts/tskm/src/cli.rs
+++ b/pkgs/by-name/ts/tskm/src/cli.rs
@@ -1,13 +1,26 @@
-use std::path::PathBuf;
+// nixos-config - My current NixOS configuration
+//
+// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+// This file is part of my nixos-config.
+//
+// You should have received a copy of the License along with this program.
+// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+use std::{ffi::OsStr, path::PathBuf};
 
 use anyhow::{bail, Result};
-use clap::{ArgAction, Parser, Subcommand};
+use clap::{builder::StyledStr, ArgAction, Parser, Subcommand};
+use clap_complete::{ArgValueCompleter, CompletionCandidate};
 use url::Url;
 
 use crate::{
-    interface::{input::Input, project::ProjectName},
-    state::State,
-    task,
+    interface::{
+        input::{Input, Tag},
+        project::ProjectName,
+    },
+    state, task,
 };
 
 #[derive(Parser, Debug)]
@@ -17,8 +30,10 @@ use crate::{
 /// `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 {
@@ -79,14 +94,14 @@ 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)]
+        #[arg(value_parser = task_from_working_set_id, add = ArgValueCompleter::new(complete_task_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 mut state = state::State::new_ro()?;
 
     let Some(task) = task::Task::from_working_set(id, &mut state)? else {
         bail!("Working set id '{id}' is not valid!")
@@ -104,7 +119,7 @@ pub enum OpenCommand {
     /// 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)]
+        #[arg(value_parser = task::Project::from_project_string, add = ArgValueCompleter::new(complete_project))]
         project: task::Project,
 
         /// The URL to open.
@@ -123,7 +138,7 @@ pub enum OpenCommand {
     /// List all open tabs in the project.
     ListTabs {
         /// The project to open.
-        #[arg(value_parser = task::Project::from_project_string)]
+        #[arg(value_parser = task::Project::from_project_string, add = ArgValueCompleter::new(complete_project))]
         project: Option<task::Project>,
     },
 }
@@ -133,21 +148,161 @@ pub enum InputCommand {
     /// Add URLs as inputs to be categorized.
     Add { inputs: Vec<Input> },
     /// Remove URLs
-    Remove { inputs: Vec<Input> },
+    Remove {
+        #[arg(add = ArgValueCompleter::new(complete_input_url))]
+        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 },
+    File {
+        /// The file to read from.
+        file: PathBuf,
+
+        /// Additional tags to apply to every read URL in the file.
+        #[arg(add = ArgValueCompleter::new(complete_tag))]
+        tags: Vec<Tag>,
+    },
 
     /// 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)]
+        #[arg(value_parser = task::Project::from_project_string, add = ArgValueCompleter::new(complete_project))]
         project: task::Project,
     },
 
     /// List all the previously added inputs.
     List,
 }
+
+fn complete_task_id(current: &OsStr) -> Vec<CompletionCandidate> {
+    fn format_task(
+        task: task::Task,
+        current: &str,
+        state: &mut state::State,
+    ) -> Option<CompletionCandidate> {
+        let id = {
+            let Ok(base) = task.working_set_id(state) else {
+                return None;
+            };
+            base.to_string()
+        };
+
+        if !id.starts_with(current) {
+            return None;
+        }
+
+        let description = {
+            let Ok(base) = task.description(state) else {
+                return None;
+            };
+            StyledStr::from(base)
+        };
+
+        Some(CompletionCandidate::new(id).help(Some(description)))
+    }
+
+    let mut output = vec![];
+
+    let Some(current) = current.to_str() else {
+        return output;
+    };
+
+    let Ok(mut state) = state::State::new_ro() else {
+        return output;
+    };
+
+    let Ok(pending) = state.replica().pending_tasks() else {
+        return output;
+    };
+
+    let Ok(current_project) = task::Project::get_current() else {
+        return output;
+    };
+
+    if let Some(current_project) = current_project {
+        for t in pending {
+            let task = task::Task::from(&t);
+            if let Ok(project) = task.project(&mut state) {
+                if project == current_project {
+                    if let Some(out) = format_task(task, current, &mut state) {
+                        output.push(out);
+                    }
+                }
+            }
+        }
+    } else {
+        for t in pending {
+            let task = task::Task::from(&t);
+            if let Some(out) = format_task(task, current, &mut state) {
+                output.push(out);
+            }
+        }
+    }
+
+    output
+}
+fn complete_project(current: &OsStr) -> Vec<CompletionCandidate> {
+    let mut output = vec![];
+
+    let Some(current) = current.to_str() else {
+        return output;
+    };
+
+    let Ok(all) = task::Project::all() else {
+        return output;
+    };
+
+    for a in all {
+        if a.to_project_display().starts_with(current) {
+            output.push(CompletionCandidate::new(a.to_project_display()));
+        }
+    }
+
+    output
+}
+fn complete_input_url(current: &OsStr) -> Vec<CompletionCandidate> {
+    let mut output = vec![];
+
+    let Some(current) = current.to_str() else {
+        return output;
+    };
+
+    let Ok(all) = Input::all() else {
+        return output;
+    };
+
+    for a in all {
+        if a.to_string().starts_with(current) {
+            output.push(CompletionCandidate::new(a.to_string()));
+        }
+    }
+
+    output
+}
+fn complete_tag(current: &OsStr) -> Vec<CompletionCandidate> {
+    let mut output = vec![];
+
+    let Some(current) = current.to_str() else {
+        return output;
+    };
+
+    if !current.starts_with('+') {
+        output.push(CompletionCandidate::new(format!("+{current}")));
+    }
+
+    output
+}
+
+#[cfg(test)]
+mod test {
+    use clap::CommandFactory;
+
+    use super::CliArgs;
+    #[test]
+    fn verify_cli() {
+        CliArgs::command().debug_assert();
+    }
+}
diff --git a/pkgs/by-name/ts/tskm/src/interface/input/handle.rs b/pkgs/by-name/ts/tskm/src/interface/input/handle.rs
index 0ff0e56e..09827fca 100644
--- a/pkgs/by-name/ts/tskm/src/interface/input/handle.rs
+++ b/pkgs/by-name/ts/tskm/src/interface/input/handle.rs
@@ -1,4 +1,15 @@
+// nixos-config - My current NixOS configuration
+//
+// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+// This file is part of my nixos-config.
+//
+// You should have received a copy of the License along with this program.
+// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 use std::{
+    collections::HashSet,
     fs, process,
     str::FromStr,
     thread::{self, sleep},
@@ -33,10 +44,23 @@ pub fn handle(command: InputCommand) -> Result<()> {
                 })?;
             }
         }
-        InputCommand::File { file } => {
-            let file = fs::read_to_string(file)?;
-            for line in file.lines() {
-                let input = Input::from_str(line)?;
+        InputCommand::File { file, tags } => {
+            let file = fs::read_to_string(&file)
+                .with_context(|| format!("Failed to read input file '{}'", file.display()))?;
+
+            let mut tag_set = HashSet::with_capacity(tags.len());
+            for tag in tags {
+                tag_set.insert(tag);
+            }
+
+            for line in file.lines().map(str::trim) {
+                if line.is_empty() {
+                    continue;
+                }
+
+                let mut input = Input::from_str(line)?;
+                input.tags = input.tags.union(&tag_set).cloned().collect();
+
                 input.commit().with_context(|| {
                     format!("Failed to add input ('{input}') to the input storage.")
                 })?;
diff --git a/pkgs/by-name/ts/tskm/src/interface/input/mod.rs b/pkgs/by-name/ts/tskm/src/interface/input/mod.rs
index 9ece7a3a..747ba349 100644
--- a/pkgs/by-name/ts/tskm/src/interface/input/mod.rs
+++ b/pkgs/by-name/ts/tskm/src/interface/input/mod.rs
@@ -1,10 +1,15 @@
+// nixos-config - My current NixOS configuration
+//
+// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+// This file is part of my nixos-config.
+//
+// You should have received a copy of the License along with this program.
+// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 use std::{
-    collections::HashSet,
-    fmt::Display,
-    fs::{self, read_to_string, File},
-    io::Write,
-    path::PathBuf,
-    process::Command,
+    collections::HashSet, fmt::Display, fs, io::Write, path::PathBuf, process::Command,
     str::FromStr,
 };
 
@@ -16,28 +21,37 @@ pub mod handle;
 pub use handle::handle;
 
 #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
-pub struct NoWhitespaceString(String);
+pub struct Tag(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.")
+impl Tag {
+    pub fn new(input: &str) -> Result<Self> {
+        Self::from_str(input)
+    }
+}
+
+impl FromStr for Tag {
+    type Err = anyhow::Error;
+
+    fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
+        if let Some(tag) = s.strip_prefix('+') {
+            if tag.contains(' ') {
+                bail!("Your tag '{s}' should not whitespace.")
+            }
+
+            Ok(Self(tag.to_owned()))
         } else {
-            Self(input)
+            bail!("Your tag '{s}' does not start with the required '+'");
         }
     }
 }
 
-impl Display for NoWhitespaceString {
+impl Display for Tag {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        self.0.fmt(f)
+        write!(f, "+{}", self.0)
     }
 }
 
-impl NoWhitespaceString {
+impl Tag {
     #[must_use]
     pub fn as_str(&self) -> &str {
         &self.0
@@ -47,7 +61,7 @@ impl NoWhitespaceString {
 #[derive(Debug, Clone)]
 pub struct Input {
     url: Url,
-    tags: HashSet<NoWhitespaceString>,
+    tags: HashSet<Tag>,
 }
 
 impl FromStr for Input {
@@ -61,13 +75,7 @@ impl FromStr for Input {
                 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 '+'");
-                            }
-                        })
+                        .map(Tag::new)
                         .collect::<Result<_, _>>()?
                 },
             })
@@ -91,13 +99,9 @@ impl Display for Input {
                 self.url,
                 self.tags
                     .iter()
-                    .fold(String::new(), |mut acc, tag| {
-                        acc.push('+');
-                        acc.push_str(tag.as_str());
-                        acc.push(' ');
-                        acc
-                    })
-                    .trim()
+                    .map(ToString::to_string)
+                    .collect::<Vec<_>>()
+                    .join(" ")
             )
         }
     }
@@ -113,7 +117,10 @@ impl Input {
     fn url_path(url: &Url) -> Result<PathBuf> {
         let base_path = Self::base_path();
 
-        let url_path = base_path.join(url.to_string());
+        let url_path = base_path
+            .join(url.scheme())
+            .join(url.host_str().unwrap_or("<No Host>"))
+            .join(url.path().trim_matches('/'));
         fs::create_dir_all(&url_path)
             .with_context(|| format!("Failed to open file: '{}'", url_path.display()))?;
 
@@ -132,17 +139,12 @@ impl Input {
     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)
+        let mut file = fs::OpenOptions::new()
+            .create(true)
+            .append(true)
+            .open(&url_path)
             .with_context(|| format!("Failed to open file: '{}'", url_path.display()))?;
-        writeln!(file, "{url_content}{self}")?;
+        writeln!(file, "{self}")?;
 
         Self::git_commit(&format!("Add new url: '{self}'"))?;
 
@@ -173,27 +175,6 @@ impl Input {
         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
@@ -217,41 +198,51 @@ impl Input {
                 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_value_file = entry.path();
+            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 url_values = fs::read_to_string(PathBuf::from(url_value_file))?;
 
-                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))?;
+            output.extend(
                 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 });
+                    .map(Self::from_str)
+                    .collect::<Result<Vec<Self>, _>>()?
+                    .into_iter(),
+            );
         }
 
         Ok(output)
     }
+
+    /// Commit your changes
+    fn git_commit(message: &str) -> Result<()> {
+        if !Self::base_path().join(".git").exists() {
+            let status = Command::new("git")
+                .args(["init"])
+                .current_dir(Self::base_path())
+                .status()?;
+            if !status.success() {
+                bail!("Git init failed!");
+            }
+        }
+
+        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(())
+    }
 }
diff --git a/pkgs/by-name/ts/tskm/src/interface/mod.rs b/pkgs/by-name/ts/tskm/src/interface/mod.rs
index 1a0d934c..513ca317 100644
--- a/pkgs/by-name/ts/tskm/src/interface/mod.rs
+++ b/pkgs/by-name/ts/tskm/src/interface/mod.rs
@@ -1,3 +1,13 @@
+// nixos-config - My current NixOS configuration
+//
+// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+// This file is part of my nixos-config.
+//
+// You should have received a copy of the License along with this program.
+// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 pub mod input;
 pub mod neorg;
 pub mod open;
diff --git a/pkgs/by-name/ts/tskm/src/interface/neorg/handle.rs b/pkgs/by-name/ts/tskm/src/interface/neorg/handle.rs
index 577de02c..194e3926 100644
--- a/pkgs/by-name/ts/tskm/src/interface/neorg/handle.rs
+++ b/pkgs/by-name/ts/tskm/src/interface/neorg/handle.rs
@@ -1,11 +1,21 @@
+// nixos-config - My current NixOS configuration
+//
+// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+// This file is part of my nixos-config.
+//
+// You should have received a copy of the License along with this program.
+// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 use std::{
     env,
-    fs::{self, read_to_string, File, OpenOptions},
+    fs::{self, File, OpenOptions, read_to_string},
     io::Write,
     process::Command,
 };
 
-use anyhow::{bail, Context, Result};
+use anyhow::{Context, Result, bail};
 
 use crate::{cli::NeorgCommand, state::State};
 
@@ -13,10 +23,10 @@ pub fn handle(command: NeorgCommand, state: &mut State) -> Result<()> {
     match command {
         NeorgCommand::Task { id } => {
             let project = id.project(state)?;
-            let path = dirs::data_local_dir()
+            let base = dirs::data_local_dir()
                 .expect("This should exists")
-                .join("tskm/notes")
-                .join(project.get_neorg_path()?);
+                .join("tskm/notes");
+            let path = base.join(project.get_neorg_path()?);
 
             fs::create_dir_all(path.parent().expect("This should exist"))?;
 
@@ -69,11 +79,7 @@ pub fn handle(command: NeorgCommand, state: &mut State) -> Result<()> {
                     .args([
                         "commit",
                         "--message",
-                        format!(
-                            "chore({}): Update",
-                            path.parent().expect("Should have a parent").display()
-                        )
-                        .as_str(),
+                        format!("chore({}): Update", project.get_neorg_path()?.display()).as_str(),
                         "--no-gpg-sign",
                     ])
                     .current_dir(path.parent().expect("Will exist"))
diff --git a/pkgs/by-name/ts/tskm/src/interface/neorg/mod.rs b/pkgs/by-name/ts/tskm/src/interface/neorg/mod.rs
index dc5cdf19..6bed1e39 100644
--- a/pkgs/by-name/ts/tskm/src/interface/neorg/mod.rs
+++ b/pkgs/by-name/ts/tskm/src/interface/neorg/mod.rs
@@ -1,18 +1,35 @@
+// nixos-config - My current NixOS configuration
+//
+// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+// This file is part of my nixos-config.
+//
+// You should have received a copy of the License along with this program.
+// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 use std::path::PathBuf;
 
 use anyhow::Result;
 
-use crate::task::{run_task, Project};
+use crate::task::{Project, run_task};
 
 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(),
         ])?;
-        Ok(PathBuf::from(project_path.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
index 15c7ac4d..82f468b3 100644
--- a/pkgs/by-name/ts/tskm/src/interface/open/handle.rs
+++ b/pkgs/by-name/ts/tskm/src/interface/open/handle.rs
@@ -1,3 +1,13 @@
+// nixos-config - My current NixOS configuration
+//
+// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+// This file is part of my nixos-config.
+//
+// You should have received a copy of the License along with this program.
+// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 use std::{
     fs,
     net::{IpAddr, Ipv4Addr},
@@ -5,8 +15,8 @@ use std::{
     process,
 };
 
-use anyhow::{bail, Context, Result};
-use log::{error, info};
+use anyhow::{Context, Result, bail};
+use log::{error, info, warn};
 use url::Url;
 
 use crate::{cli::OpenCommand, rofi, state::State, task};
@@ -159,35 +169,45 @@ fn open_in_browser(
         if let Some(url) = url {
             args.push(url.to_string());
         } else {
-            let (ip, pid): (IpAddr, u32) = {
-                let link = fs::read_link(
-                    dirs::home_dir()
-                        .expect("Exists")
-                        .join(".mozilla/firefox")
-                        .join(selected_project.to_project_display())
-                        .join("lock"),
-                )?;
-                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"),
-                )
-            };
+            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");
 
-            assert_eq!(ip, Ipv4Addr::new(127, 0, 0, 1));
-            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());
+                    (
+                        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 {
-                // 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.
+                // There is no lock file and thus no instance already open.
             }
         };
 
diff --git a/pkgs/by-name/ts/tskm/src/interface/open/mod.rs b/pkgs/by-name/ts/tskm/src/interface/open/mod.rs
index 2dc75957..a4060fa3 100644
--- a/pkgs/by-name/ts/tskm/src/interface/open/mod.rs
+++ b/pkgs/by-name/ts/tskm/src/interface/open/mod.rs
@@ -1,3 +1,13 @@
+// nixos-config - My current NixOS configuration
+//
+// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+// This file is part of my nixos-config.
+//
+// You should have received a copy of the License along with this program.
+// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 use std::{collections::HashMap, fs::File, io};
 
 use anyhow::{Context, Result};
diff --git a/pkgs/by-name/ts/tskm/src/interface/project/handle.rs b/pkgs/by-name/ts/tskm/src/interface/project/handle.rs
index 2b01f5d1..6d44b340 100644
--- a/pkgs/by-name/ts/tskm/src/interface/project/handle.rs
+++ b/pkgs/by-name/ts/tskm/src/interface/project/handle.rs
@@ -1,6 +1,16 @@
+// nixos-config - My current NixOS configuration
+//
+// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+// This file is part of my nixos-config.
+//
+// You should have received a copy of the License along with this program.
+// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 use std::{env, fs::File, io::Write};
 
-use anyhow::{anyhow, Context, Result};
+use anyhow::{Context, Result, anyhow};
 use log::trace;
 
 use crate::{cli::ProjectCommand, task};
@@ -60,10 +70,12 @@ pub fn handle(command: ProjectCommand) -> Result<()> {
 
                     let new_definition = ProjectDefinition::default();
 
-                    assert!(definition
-                        .subprojects
-                        .insert(segment.clone(), new_definition)
-                        .is_none());
+                    assert!(
+                        definition
+                            .subprojects
+                            .insert(segment.clone(), new_definition)
+                            .is_none()
+                    );
 
                     definition = definition
                         .subprojects
diff --git a/pkgs/by-name/ts/tskm/src/interface/project/mod.rs b/pkgs/by-name/ts/tskm/src/interface/project/mod.rs
index 62069746..8a7fa1b0 100644
--- a/pkgs/by-name/ts/tskm/src/interface/project/mod.rs
+++ b/pkgs/by-name/ts/tskm/src/interface/project/mod.rs
@@ -1,3 +1,13 @@
+// nixos-config - My current NixOS configuration
+//
+// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+// This file is part of my nixos-config.
+//
+// You should have received a copy of the License along with this program.
+// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 use std::collections::HashMap;
 
 use anyhow::Result;
diff --git a/pkgs/by-name/ts/tskm/src/main.rs b/pkgs/by-name/ts/tskm/src/main.rs
index f4416c6d..dc425dcc 100644
--- a/pkgs/by-name/ts/tskm/src/main.rs
+++ b/pkgs/by-name/ts/tskm/src/main.rs
@@ -1,8 +1,21 @@
+// nixos-config - My current NixOS configuration
+//
+// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+// This file is part of my nixos-config.
+//
+// You should have received a copy of the License along with this program.
+// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 use anyhow::Result;
-use clap::Parser;
-use state::State;
+use clap::{CommandFactory, Parser};
 
-use crate::interface::{input, neorg, open, project};
+use crate::{
+    cli::{CliArgs, Command},
+    interface::{input, neorg, open, project},
+    state::State,
+};
 
 pub mod cli;
 pub mod interface;
@@ -10,38 +23,9 @@ 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.
+    clap_complete::CompleteEnv::with_factory(CliArgs::command).complete();
+
     let args = CliArgs::parse();
 
     stderrlog::new()
@@ -50,7 +34,6 @@ fn main() -> Result<(), anyhow::Error> {
         .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");
 
diff --git a/pkgs/by-name/ts/tskm/src/rofi/mod.rs b/pkgs/by-name/ts/tskm/src/rofi/mod.rs
index a0591b7f..37c2eafa 100644
--- a/pkgs/by-name/ts/tskm/src/rofi/mod.rs
+++ b/pkgs/by-name/ts/tskm/src/rofi/mod.rs
@@ -1,3 +1,13 @@
+// nixos-config - My current NixOS configuration
+//
+// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+// This file is part of my nixos-config.
+//
+// You should have received a copy of the License along with this program.
+// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 use std::{
     io::Write,
     process::{Command, Stdio},
diff --git a/pkgs/by-name/ts/tskm/src/state.rs b/pkgs/by-name/ts/tskm/src/state.rs
index 175a7f03..ae71764e 100644
--- a/pkgs/by-name/ts/tskm/src/state.rs
+++ b/pkgs/by-name/ts/tskm/src/state.rs
@@ -1,7 +1,17 @@
+// nixos-config - My current NixOS configuration
+//
+// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+// This file is part of my nixos-config.
+//
+// You should have received a copy of the License along with this program.
+// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 use std::path::PathBuf;
 
 use anyhow::Result;
-use taskchampion::{storage::AccessMode, Replica, StorageConfig};
+use taskchampion::{Replica, StorageConfig, storage::AccessMode};
 
 pub struct State {
     replica: Replica,
diff --git a/pkgs/by-name/ts/tskm/src/task/mod.rs b/pkgs/by-name/ts/tskm/src/task/mod.rs
index 03a12faa..04efbec5 100644
--- a/pkgs/by-name/ts/tskm/src/task/mod.rs
+++ b/pkgs/by-name/ts/tskm/src/task/mod.rs
@@ -1,13 +1,23 @@
+// nixos-config - My current NixOS configuration
+//
+// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+// This file is part of my nixos-config.
+//
+// You should have received a copy of the License along with this program.
+// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 use std::{
     fmt::Display,
-    fs::{self, read_to_string, File},
+    fs::{self, File, read_to_string},
     path::PathBuf,
     process::Command,
     str::FromStr,
     sync::OnceLock,
 };
 
-use anyhow::{bail, Context, Result};
+use anyhow::{Context, Result, bail};
 use log::{debug, info, trace};
 use taskchampion::Tag;
 
@@ -66,6 +76,14 @@ impl Task {
     pub fn uuid(&self) -> &taskchampion::Uuid {
         &self.uuid
     }
+    #[must_use]
+    pub fn working_set_id(&self, state: &mut State) -> Result<usize> {
+        Ok(state
+            .replica()
+            .working_set()?
+            .by_uuid(self.uuid)
+            .expect("The task should be in the working set"))
+    }
 
     fn as_task(&self, state: &mut State) -> Result<taskchampion::Task> {
         Ok(state
@@ -121,7 +139,7 @@ impl Task {
                 .expect("Every task should have a project")
                 .to_owned()
         };
-        let project = Project::from_project_string(output.as_str())
+        let project = Project::from_project_string(output.as_str().trim())
             .expect("This comes from tw, it should be valid");
         Ok(project)
     }
diff --git a/pkgs/by-name/ts/tskm/update.sh b/pkgs/by-name/ts/tskm/update.sh
index 9268caf2..8e36e13e 100755
--- a/pkgs/by-name/ts/tskm/update.sh
+++ b/pkgs/by-name/ts/tskm/update.sh
@@ -1,3 +1,14 @@
 #!/bin/sh
 
-cargo update && cargo upgrade
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+[ "$1" = "upgrade" ] && cargo upgrade
+cargo update
diff --git a/pkgs/by-name/up/update-sys/package.nix b/pkgs/by-name/up/update-sys/package.nix
deleted file mode 100644
index 8777f82d..00000000
--- a/pkgs/by-name/up/update-sys/package.nix
+++ /dev/null
@@ -1,29 +0,0 @@
-{
-  sysLib,
-  git,
-  nixos-rebuild,
-  sudo,
-  openssh,
-  coreutils,
-  mktemp,
-  gnugrep,
-  gnused,
-  systemd,
-}:
-sysLib.writeShellScript {
-  name = "update-sys";
-  src = ./update-sys.sh;
-  generateCompletions = true;
-  keepPath = false;
-  dependencies = [
-    git
-    nixos-rebuild
-    sudo
-    openssh
-    coreutils
-    mktemp
-    gnugrep
-    gnused
-    systemd
-  ];
-}
diff --git a/pkgs/by-name/up/update-sys/update-sys.sh b/pkgs/by-name/up/update-sys/update-sys.sh
deleted file mode 100755
index d28247f6..00000000
--- a/pkgs/by-name/up/update-sys/update-sys.sh
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
-help() {
-    cat <<EOF
-This is a NixOS System flake update manager.
-
-USAGE:
-    $NAME [--branch <branchname>] [--help]
-
-OPTIONS:
-    --branch | -b  BRANCHNAME
-                                select a branch to update from.
-
-    --mode   | -m  MODE
-                                select a mode to update with
-
-    --help   | -h
-                                output this help.
-ARGUMENTS:
-    BRANCHNAME := [[ git branch --list --format '%(refname:short)' ]]
-                                The name of the branch to deploy the config from
-
-    MODE := switch|boot|test|build|dry-build|dry-activate|edit|repl|build-vm|build-vm-with-bootloader
-                                See the 'nixos-rebuild' manpage for more information about these modes.
-EOF
-    exit "$1"
-}
-default_branch=$(mktmp)
-BRANCH=""
-
-while [ "$#" -gt 0 ]; do
-    case "$1" in
-    "--help" | "-h")
-        help 0
-        ;;
-    "--branch" | "-b")
-        if [ -n "$2" ]; then
-            BRANCH="$2"
-        else
-            error "$1 requires an argument"
-            help 1
-        fi
-        shift 2
-        ;;
-    "--mode" | "-m")
-        if [ -n "$2" ]; then
-            MODE="$2"
-        else
-            error "$1 requires an argument"
-            help 1
-        fi
-        shift 2
-        ;;
-    *)
-        error "the option $1 does not exist!"
-        help 1
-        ;;
-    esac
-done
-
-cd /etc/nixos || die "No /etc/nixos"
-msg "Starting system update..."
-git remote update origin --prune >/dev/null 2>&1
-if ! [ "$BRANCH" = "" ]; then
-    git switch "$BRANCH" >/dev/null 2>&1 && msg2 "Switched to branch '$BRANCH'"
-fi
-msg2 "Updating git repository..."
-git pull --rebase
-
-git remote show origin | grep 'HEAD' | cut -d':' -f2 | sed -e 's/^ *//g' -e 's/ *$//g' >"$default_branch" &
-
-msg2 "Updating system..."
-if [ -n "$MODE" ]; then
-    nixos-rebuild "$MODE"
-else
-    nixos-rebuild switch
-fi
-
-git switch "$(cat "$default_branch")" >/dev/null 2>&1 && msg2 "Switched to branch '$(cat "$default_branch")'"
-msg "Finished Update!"
-
-# vim: ft=sh
diff --git a/pkgs/by-name/ya/yambar-modules/.envrc b/pkgs/by-name/ya/yambar-modules/.envrc
deleted file mode 100644
index 2f9f1a81..00000000
--- a/pkgs/by-name/ya/yambar-modules/.envrc
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/usr/bin/env sh
-use flake
diff --git a/pkgs/by-name/ya/yambar-modules/.gitignore b/pkgs/by-name/ya/yambar-modules/.gitignore
deleted file mode 100644
index ea8c4bf7..00000000
--- a/pkgs/by-name/ya/yambar-modules/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/target
diff --git a/pkgs/by-name/ya/yambar-modules/Cargo.lock b/pkgs/by-name/ya/yambar-modules/Cargo.lock
deleted file mode 100644
index 6b689d29..00000000
--- a/pkgs/by-name/ya/yambar-modules/Cargo.lock
+++ /dev/null
@@ -1,131 +0,0 @@
-# This file is automatically @generated by Cargo.
-# It is not intended for manual editing.
-version = 3
-
-[[package]]
-name = "cfg-if"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
-
-[[package]]
-name = "core-foundation-sys"
-version = "0.8.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
-
-[[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 = "libc"
-version = "0.2.167"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc"
-
-[[package]]
-name = "ntapi"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4"
-dependencies = [
- "winapi",
-]
-
-[[package]]
-name = "once_cell"
-version = "1.20.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
-
-[[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 = "sysinfo"
-version = "0.28.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b4c2f3ca6693feb29a89724516f016488e9aafc7f37264f898593ee4b942f31b"
-dependencies = [
- "cfg-if",
- "core-foundation-sys",
- "libc",
- "ntapi",
- "once_cell",
- "rayon",
- "winapi",
-]
-
-[[package]]
-name = "winapi"
-version = "0.3.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
-dependencies = [
- "winapi-i686-pc-windows-gnu",
- "winapi-x86_64-pc-windows-gnu",
-]
-
-[[package]]
-name = "winapi-i686-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
-
-[[package]]
-name = "winapi-x86_64-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
-
-[[package]]
-name = "yambar-modules"
-version = "0.1.0"
-dependencies = [
- "sysinfo",
-]
diff --git a/pkgs/by-name/ya/yambar-modules/Cargo.toml b/pkgs/by-name/ya/yambar-modules/Cargo.toml
deleted file mode 100644
index 8e3995fe..00000000
--- a/pkgs/by-name/ya/yambar-modules/Cargo.toml
+++ /dev/null
@@ -1,9 +0,0 @@
-[package]
-name = "yambar-modules"
-version = "0.1.0"
-edition = "2021"
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
-sysinfo = "0.28.4"
diff --git a/pkgs/by-name/ya/yambar-modules/flake.lock b/pkgs/by-name/ya/yambar-modules/flake.lock
deleted file mode 100644
index 8043448e..00000000
--- a/pkgs/by-name/ya/yambar-modules/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": 1732617236,
-        "narHash": "sha256-PYkz6U0bSEaEB1al7O1XsqVNeSNS+s3NVclJw7YC43w=",
-        "owner": "NixOS",
-        "repo": "nixpkgs",
-        "rev": "af51545ec9a44eadf3fe3547610a5cdd882bc34e",
-        "type": "github"
-      },
-      "original": {
-        "owner": "NixOS",
-        "ref": "nixpkgs-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/ya/yambar-modules/flake.nix b/pkgs/by-name/ya/yambar-modules/flake.nix
deleted file mode 100644
index e3d0cd49..00000000
--- a/pkgs/by-name/ya/yambar-modules/flake.nix
+++ /dev/null
@@ -1,32 +0,0 @@
-{
-  description = "Extension modules for yambar(1)";
-
-  inputs = {
-    nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
-    flake-utils.url = "github:numtide/flake-utils";
-  };
-
-  outputs = {
-    nixpkgs,
-    flake-utils,
-    ...
-  }:
-    flake-utils.lib.eachDefaultSystem (system: let
-      pkgs = nixpkgs.legacyPackages."${system}";
-    in {
-      devShells.default = pkgs.mkShell {
-        packages = with pkgs; [
-          # rust stuff
-          cargo
-          clippy
-          rustc
-          rustfmt
-
-          cargo-edit
-          cargo-expand
-        ];
-      };
-    });
-}
-# vim: ts=2
-
diff --git a/pkgs/by-name/ya/yambar-modules/package.nix b/pkgs/by-name/ya/yambar-modules/package.nix
deleted file mode 100644
index 79281429..00000000
--- a/pkgs/by-name/ya/yambar-modules/package.nix
+++ /dev/null
@@ -1,14 +0,0 @@
-{rustPlatform}:
-rustPlatform.buildRustPackage {
-  pname = "yambar-modules";
-  version = "0.1.0";
-
-  src = ./.;
-  cargoLock = {
-    lockFile = ./Cargo.lock;
-  };
-
-  meta = {
-    mainProgram = "yambar-modules";
-  };
-}
diff --git a/pkgs/by-name/ya/yambar-modules/src/cpu.rs b/pkgs/by-name/ya/yambar-modules/src/cpu.rs
deleted file mode 100644
index 5a6dd084..00000000
--- a/pkgs/by-name/ya/yambar-modules/src/cpu.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-use std::{thread, time::Duration};
-
-use sysinfo::{CpuExt, System, SystemExt};
-
-pub fn cpu() {
-    let mut sys = System::new();
-
-    loop {
-        sys.refresh_cpu();
-        let cpu_usage: f32 = sys.cpus().iter().map(|cpu| cpu.cpu_usage()).sum();
-        println!(
-            "cpu|range:0-100|{:.0}",
-            cpu_usage / sys.cpus().iter().count() as f32
-        );
-        println!();
-
-        // Sleeping to give the system time to run for long
-        // enough to have useful information.
-        thread::sleep(Duration::from_secs(3));
-    }
-}
diff --git a/pkgs/by-name/ya/yambar-modules/src/main.rs b/pkgs/by-name/ya/yambar-modules/src/main.rs
deleted file mode 100644
index 315c3be7..00000000
--- a/pkgs/by-name/ya/yambar-modules/src/main.rs
+++ /dev/null
@@ -1,26 +0,0 @@
-use std::{env::args, process};
-
-mod cpu;
-mod memory;
-
-fn main() {
-    let args: Vec<String> = args().collect();
-
-    if args.len() != 2 {
-        eprintln!("Usage: yambar-modules cpu|memory");
-        process::exit(1);
-    }
-
-    match args[1].as_str() {
-        "cpu" => {
-            cpu::cpu();
-        }
-        "memory" => {
-            memory::memory();
-        }
-        other => {
-            eprintln!("'{other}' is not a valid command. Only 'cpu' or 'memory'.");
-            process::exit(1);
-        }
-    }
-}
diff --git a/pkgs/by-name/ya/yambar-modules/src/memory.rs b/pkgs/by-name/ya/yambar-modules/src/memory.rs
deleted file mode 100644
index 6da714cc..00000000
--- a/pkgs/by-name/ya/yambar-modules/src/memory.rs
+++ /dev/null
@@ -1,29 +0,0 @@
-use std::{thread, time::Duration};
-
-use sysinfo::{System, SystemExt};
-
-pub fn memory() {
-    let mut sys = System::new();
-
-    loop {
-        sys.refresh_memory();
-
-        let memory_percentage: f64 =
-            100 as f64 * (sys.used_memory() as f64 / sys.total_memory() as f64);
-
-        println!("memperc|string|{:.0}", memory_percentage);
-        if sys.total_swap() > 0 {
-            let swap_percentage: f64 =
-                100 as f64 * (sys.used_swap() as f64 / sys.total_swap() as f64);
-            println!("swapperc|string|{:.0}", swap_percentage);
-            println!("swapstate|bool|true");
-        } else {
-            println!("swapstate|bool|false");
-        }
-        println!("");
-
-        // Sleeping to give the system time to run for long
-        // enough to have useful information.
-        thread::sleep(Duration::from_secs(3));
-    }
-}
diff --git a/pkgs/by-name/yt/yt/package.nix b/pkgs/by-name/yt/yt/package.nix
index 3c780374..d73776c5 100644
--- a/pkgs/by-name/yt/yt/package.nix
+++ b/pkgs/by-name/yt/yt/package.nix
@@ -1,3 +1,12 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 {
   fetchgit,
   ffmpeg,
diff --git a/pkgs/default.nix b/pkgs/default.nix
index 41bb654f..9a3ac842 100644
--- a/pkgs/default.nix
+++ b/pkgs/default.nix
@@ -1,23 +1,21 @@
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 {
   pkgs,
-  sysLib,
-  nixLib,
+  libraries,
 }: let
   inherit (pkgs) lib;
 
-  maybeMergeMessage = "the ./pkgs/by-name set";
-  mMM = maybeMergeMessage;
-  callPackage =
-    lib.callPackageWith
-    (nixLib.warnMerge
-      (nixLib.warnMerge
-        pkgs
-        myPkgs
-        mMM)
-      {inherit sysLib;}
-      mMM);
+  callPackage = lib.callPackageWith (libraries.extra.warnMerge pkgs myPkgs "the ./pkgs/by-name set");
 
-  myPkgs = nixLib.mkByName {
+  myPkgs = libraries.extra.mkByName {
     baseDirectory = ./by-name;
     fileName = "package.nix";
     finalizeFunction = name: value: callPackage value {};
diff --git a/pkgs/update_pkgs.sh b/pkgs/update_pkgs.sh
index 3e33b720..d046ee76 100755
--- a/pkgs/update_pkgs.sh
+++ b/pkgs/update_pkgs.sh
@@ -1,5 +1,15 @@
 #!/usr/bin/env sh
 
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
 die() {
     printf "\033[31;1mError: \033[0m%s\n" "$1"
     exit 1