about summary refs log tree commit diff stats
path: root/modules/by-name
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--modules/by-name/fi/firefox/extensions.json (renamed from modules/home.legacy/conf/firefox/config/extensions/extensions.json)6
-rw-r--r--modules/by-name/fi/firefox/module.nix234
-rw-r--r--modules/by-name/fi/firefox/profile.nix180
-rw-r--r--modules/by-name/fi/firefox/search_engines/default.nix (renamed from modules/home.legacy/conf/firefox/config/search/engines/default.nix)42
-rw-r--r--modules/by-name/fi/firefox/search_engines/logos/arch_linux.svg (renamed from modules/home.legacy/conf/firefox/config/search/engines/logos/arch_linux.svg)0
-rw-r--r--modules/by-name/fi/firefox/search_engines/logos/brave.svg (renamed from modules/home.legacy/conf/firefox/config/search/engines/logos/brave.svg)0
-rw-r--r--modules/by-name/fi/firefox/search_engines/logos/google_scholar.ico (renamed from modules/home.legacy/conf/firefox/config/search/engines/logos/google_scholar.ico)bin3871 -> 3871 bytes
-rw-r--r--modules/by-name/fi/firefox/search_engines/logos/rust_std.svg (renamed from modules/home.legacy/conf/firefox/config/search/engines/logos/rust_std.svg)0
-rw-r--r--modules/by-name/fi/firefox/search_engines/logos/rust_tokio.png (renamed from modules/home.legacy/conf/firefox/config/search/engines/logos/rust_tokio.png)bin3551 -> 3551 bytes
-rw-r--r--modules/by-name/fi/firefox/search_engines/logos/wikipedia.svg (renamed from modules/home.legacy/conf/firefox/config/search/engines/logos/wikipedia.svg)0
-rwxr-xr-xmodules/by-name/fi/firefox/update_extensions.sh12
-rw-r--r--modules/by-name/fi/firefox/userChrome.css (renamed from modules/home.legacy/conf/firefox/config/chrome/userChrome.css)0
-rw-r--r--modules/by-name/ho/home-manager/module.nix4
-rw-r--r--modules/by-name/lf/lf/commands/default.nix7
-rwxr-xr-xmodules/by-name/lf/lf/commands/scripts/open.sh15
-rwxr-xr-xmodules/by-name/lf/lf/commands/scripts/trash_clear.sh4
-rwxr-xr-xmodules/by-name/lf/lf/commands/scripts/trash_restore.sh4
-rw-r--r--modules/by-name/lf/lf/ctpv/default.nix41
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/any.sh9
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/application/archive/atool.sh5
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/application/dll/dll.sh5
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/application/epub/default.nix10
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/application/epub/epub.sh5
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/application/pdf/default.nix1
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/application/pdf/pdf.sh5
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/application/pgp/pgp.sh5
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/application/sqlite/sqlite.sh5
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/application/x-bittorrent/torrent.sh5
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/application/x-pem-file/default.nix11
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/application/x-pem-file/pem.sh8
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/audio/audio.sh5
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/audio/default.nix1
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/default.nix9
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/font/default.nix1
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/font/font.sh5
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/image/image.sh5
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/image/svg+xml/svg.sh5
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/image/x-xcf/xcf.sh5
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/inode/ls.sh5
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/inode/symlink.sh5
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/libreoffice.sh5
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/text/bat.sh5
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/text/diff/delta.sh5
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/text/glow.sh5
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/text/html/default.nix13
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/text/html/elinks.sh18
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/text/json/jq.sh5
-rw-r--r--modules/by-name/lf/lf/ctpv/prev/video/video.sh5
-rw-r--r--modules/by-name/li/libvirtd/module.nix4
-rw-r--r--modules/by-name/ni/nix/module.nix4
-rw-r--r--modules/by-name/nv/nvim/plgs/telescope/extensions/bibtex/default.nix7
-rw-r--r--modules/by-name/ri/river/module.nix2
-rw-r--r--modules/by-name/ta/taskwarrior/module.nix162
-rw-r--r--modules/by-name/ta/taskwarrior/nord.theme (renamed from modules/home.legacy/conf/taskwarrior/nord.theme)0
-rw-r--r--modules/by-name/ta/taskwarrior/secrets/ca.cert161
-rw-r--r--modules/by-name/ta/taskwarrior/secrets/credentials15
-rw-r--r--modules/by-name/ta/taskwarrior/secrets/private.key449
-rw-r--r--modules/by-name/ta/taskwarrior/secrets/public.cert83
-rw-r--r--modules/by-name/ti/timewarrior/module.nix88
-rw-r--r--modules/by-name/ti/timewarrior/nord.theme (renamed from modules/home.legacy/conf/timewarrior/nord.theme)0
-rwxr-xr-xmodules/by-name/ti/timewarrior/taskwarrior_hooks/on-modify.track-timewarrior.py124
-rwxr-xr-xmodules/by-name/ti/timewarrior/taskwarrior_hooks/on-modify.track-total-active-time.py (renamed from modules/home.legacy/conf/taskwarrior/hooks/scripts/on-modify_track-total-active-time.py)43
-rw-r--r--modules/by-name/ts/tskm/module.nix127
-rwxr-xr-xmodules/by-name/ts/tskm/taskwarrior_hooks/enforce-projects.sh12
64 files changed, 1024 insertions, 987 deletions
diff --git a/modules/home.legacy/conf/firefox/config/extensions/extensions.json b/modules/by-name/fi/firefox/extensions.json
index 298c570d..062f1a5e 100644
--- a/modules/home.legacy/conf/firefox/config/extensions/extensions.json
+++ b/modules/by-name/fi/firefox/extensions.json
@@ -19,9 +19,9 @@
     "addonId": "{b11bea1f-a888-4332-8d8a-cec2be7d24b9}",
     "default_area": "navbar",
     "pname": "torproject-snowflake",
-    "sha256": "sha256:4028bad3bef6610a985edda954d5c4f1487480a8f32f230d9edf88d97c8dd88e",
-    "url": "https://addons.mozilla.org/firefox/downloads/file/4379590/torproject_snowflake-0.9.2.xpi",
-    "version": "0.9.2"
+    "sha256": "sha256:615c0d570f41e721a91fc4f334377a61732171b65eb1a4429d78681e85bc8878",
+    "url": "https://addons.mozilla.org/firefox/downloads/file/4458115/torproject_snowflake-0.9.3.xpi",
+    "version": "0.9.3"
   },
   "tridactyl-vim": {
     "addonId": "tridactyl.vim@cmcaine.co.uk",
diff --git a/modules/by-name/fi/firefox/module.nix b/modules/by-name/fi/firefox/module.nix
new file mode 100644
index 00000000..17bfa049
--- /dev/null
+++ b/modules/by-name/fi/firefox/module.nix
@@ -0,0 +1,234 @@
+{
+  lib,
+  config,
+  pkgs,
+  ...
+}: let
+  cfg = config.soispha.programs.firefox;
+
+  mkAllowedExtension = extension:
+    lib.attrsets.nameValuePair extension.addonId {
+      installation_mode = "normal_installed";
+      updates_disabled = true;
+      inherit (extension) default_area;
+      install_url = "file://${builtins.fetchurl {
+        inherit
+          (extension)
+          url
+          sha256
+          ;
+      }}";
+    };
+
+  allowedExtensions =
+    builtins.listToAttrs
+    (builtins.map mkAllowedExtension (builtins.attrValues
+        cfg.extensions));
+
+  mkBlockedExtension = id:
+    lib.attrsets.nameValuePair id {
+      install_mode = "blocked";
+    };
+  blockedExtensions = builtins.listToAttrs (builtins.map mkBlockedExtension [
+    # these are the default search engines
+    "addons-search-detection@mozilla.com"
+    "amazon@search.mozilla.org"
+    "bing@search.mozilla.org"
+    "ddg@search.mozilla.org"
+    "google@search.mozilla.org"
+    "wikipedia@search.mozilla.org"
+  ]);
+
+  mkProfile = import ./profile.nix {inherit config pkgs;};
+in {
+  options.soispha.programs.firefox = {
+    enable = lib.mkEnableOption "firefox";
+
+    profiles = lib.mkOption {
+      type = lib.types.attrsOf (lib.types.submodule {
+        options = {
+          id = lib.mkOption {
+            type = lib.types.int;
+            description = "The id of this profile.";
+          };
+          name = lib.mkOption {
+            type = lib.types.str;
+            description = "The name of this profile";
+          };
+        };
+      });
+      description = "A list of profies to create besides the default `default` profile.";
+      default = {};
+      apply = value:
+        lib.attrsets.mapAttrs' (name: value: lib.attrsets.nameValuePair name (mkProfile value))
+        value;
+    };
+
+    extensions = lib.mkOption {
+      type = lib.types.attrsOf (
+        lib.types.submodule {
+          options = {
+            addonId = lib.mkOption {
+              type = lib.types.str;
+              example = "addon@darkreader.org";
+              description = "The addon id of this extension";
+            };
+            default_area = lib.mkOption {
+              type = lib.types.enum ["navbar" "menupanel"];
+              example = "navbar";
+              description = ''
+                Where to put this extension by default.
+                `navbar` means into the top-left bar as icon.
+                `menupanel` means hidden behind a “all extensions” button.
+              '';
+            };
+            pname = lib.mkOption {
+              type = lib.types.str;
+              example = "darkreader";
+              description = "The package name of this extension";
+            };
+            sha256 = lib.mkOption {
+              type = lib.types.str;
+              example = "sha256:f565b2263a71626a0310380915b7aef90be8cc6fe16ea43ac1a0846efedc2e4c";
+              description = "The fetchurl copatible hash of this extension";
+            };
+            url = lib.mkOption {
+              type = lib.types.str;
+              example = "https://addons.mozilla.org/firefox/downloads/file/4439735/darkreader-4.9.103.xpi";
+              description = "The download url of this extension.";
+            };
+            version = lib.mkOption {
+              type = lib.types.str;
+              example = "4.9.103";
+              description = "The version of this extension";
+            };
+          };
+        }
+      );
+
+      default = builtins.fromJSON (builtins.readFile ./extensions.json);
+
+      description = ''
+        A list of the extensions that should be installed.
+        You can use a tool like `generate_extensions` to generate this config.
+      '';
+    };
+  };
+
+  config = lib.mkIf cfg.enable {
+    programs.firefox = {
+      enable = true;
+      preferencesStatus = "locked";
+
+      languagePacks = ["en-CA" "de" "sv-SE"];
+
+      nativeMessagingHosts.packages = [
+        pkgs.tridactyl-native
+        pkgs.keepassxc
+      ];
+
+      # NOTE: See https://mozilla.github.io/policy-templates for documentation <2023-10-21>
+      policies = {
+        # NixOS manages this already
+        DisableAppUpdate = true;
+
+        DisableFirefoxAccounts = true;
+        DisableFirefoxScreenshots = true;
+
+        # KeepassXC does this for me
+        DisableMasterPasswordCreation = true;
+
+        # I use a self-hosted services for that
+        DisablePocket = true;
+
+        # I don't want to lose my data
+        DisableProfileRefresh = true;
+
+        DisableDeveloperTools = false;
+
+        DisplayBookmarksToolbar = "newtab";
+        DisplayMenuBar = "default-off";
+
+        DNSOverHTTPS = {
+          Enabled = true;
+          Locked = false;
+        };
+        # The concept of a "default browser" does not apply to my NixOS config
+        DontCheckDefaultBrowser = true;
+
+        ExtensionSettings =
+          {
+            "*" = {
+              # Blocking the extension install here, also blocks the 'about:debugging' page
+
+              # blocked_install_message = ''
+              #   You can't install a extension manually,
+              #   please specify it in your NixOS configuration
+              # '';
+              installation_mode = "allowed";
+            };
+          }
+          // allowedExtensions
+          // blockedExtensions;
+        RequestedLocales = config.programs.firefox.languagePacks;
+
+        ExtensionUpdate = false;
+
+        HardwareAcceleration = true;
+
+        # KeepassXC and such things
+        OfferToSaveLogins = false;
+        PasswordManagerEnabled = false;
+
+        PDFjs = {
+          Enabled = true;
+          # Don't honor documents right to be un-copy-able
+          EnablePermissions = false;
+        };
+
+        SearchBar = "unified";
+      };
+
+      # Beware, that we already set them per-profile in the home-manager config.
+      preferences = {};
+    };
+
+    home-manager.users.soispha = {
+      home.sessionVariables = {
+        # Improve touch input and make scrolling smother
+        MOZ_USE_XINPUT2 = "1";
+
+        # Tell Firefox to use Wayland
+        MOZ_ENABLE_WAYLAND = 1;
+
+        # Tell GTK to use portals
+        GTK_USE_PORTAL = 1;
+
+        BROWSER = "firefox";
+      };
+
+      programs.firefox = {
+        enable = true;
+        arkenfox = {
+          enable = true;
+          version = "133.0";
+        };
+
+        # We use the NixOS module to provide us a package.
+        # HACK: Extract the package from the system-path to get a version for
+        # arkenfox-nixos to compare to. <2025-04-02>
+        package = lib.lists.findSingle (x: builtins.hasAttr "pname" x && x.pname == "firefox") "none" "multiple" config.environment.systemPackages;
+
+        profiles =
+          {
+            default = mkProfile {
+              isDefault = true;
+              id = 0;
+              name = "default";
+            };
+          }
+          // cfg.profiles;
+      };
+    };
+  };
+}
diff --git a/modules/by-name/fi/firefox/profile.nix b/modules/by-name/fi/firefox/profile.nix
new file mode 100644
index 00000000..195c2075
--- /dev/null
+++ b/modules/by-name/fi/firefox/profile.nix
@@ -0,0 +1,180 @@
+{
+  config,
+  pkgs,
+}: preConfig: ({
+    userChrome = ./userChrome.css;
+
+    bookmarks = {
+      force = true;
+      settings = [];
+    };
+
+    search = {
+      default = "brave-search";
+      privateDefault = "brave-search";
+      force = true;
+      engines = import ./search_engines {inherit pkgs;};
+
+      order = [
+        # DEFAULT
+        "brave-search"
+
+        # NIX
+        "nix-packages"
+        "nix-options"
+        "nixpkgs-issues"
+        "homemanager-options"
+        "nixos-wiki"
+        "nixpkgs-pull-request-tracker"
+
+        # RUST
+        "rust-std"
+        "rust-tokio"
+
+        # OTHER
+        "google-scholar"
+        "wikipedia"
+        "arch-wiki"
+      ];
+    };
+
+    settings = {
+      "browser.download.dir" = "${config.home-manager.users.soispha.xdg.userDirs.download}";
+      # "browser.download.useDownloadDir" = true;
+      # "browser.download.folderList" = 2;
+
+      # QoL
+      "general.autoScroll" = false;
+      "browser.tabs.insertAfterCurrent" = true;
+      "browser.tabs.loadInBackground" = true;
+      "browser.ctrlTab.recentlyUsedOrder" = false;
+      "browser.search.widget.inNavBar" = true;
+      "findbar.highlightAll" = true;
+
+      "devtools.toolbox.host" = "right";
+      "devtools.toolsidebar-width.inspector" = 700;
+
+      # Keep translations useful
+      "browser.translations.automaticallyPopup" = true;
+      "browser.translations.neverTranslateLanguages" = "de";
+
+      # Improve Tab UI
+      "browser.tabs.inTitlebar" = 1;
+      "browser.toolbars.bookmarks.visibility" = "never";
+      "browser.places.importBookmarksHTML" = true;
+
+      # Theme
+      "extensions.activeThemeID" = "firefox-alpenglow@mozilla.org";
+      "extensions.extensions.activeThemeID" = "firefox-alpenglow@mozilla.org";
+
+      # disable updates (pretty pointless with nix)
+      "extensions.update.autoUpdateDefault" = false;
+      "extensions.update.enabled" = false;
+      "app.update.channel" = "default";
+      "browser.shell.checkDefaultBrowser" = false;
+
+      # Allow my custom css
+      "toolkit.legacyUserProfileCustomizations.stylesheets" = true;
+    };
+
+    arkenfox = {
+      enable = true;
+      "0000".enable = true;
+      "0100" = {
+        enable = true;
+        "0102"."browser.startup.page".value = 3;
+        "0103"."browser.startup.homepage".value = "file:///home/dt/home.html";
+        "0104"."browser.newtabpage.enabled".value = true;
+      };
+      "0200" = {
+        enable = true;
+      };
+      "0300" = {
+        enable = true;
+      };
+      "0400" = {
+        enable = false;
+      };
+      "0600" = {
+        enable = true;
+      };
+      "0700" = {
+        enable = true;
+        "0710"."network.trr.mode" = {
+          enable = true;
+          value = 3;
+        };
+      };
+      "0800" = {
+        enable = true;
+      };
+      "0900" = {
+        enable = true;
+      };
+      "1000" = {
+        enable = true;
+        "1001"."browser.cache.disk.enable".value = true;
+        "1003"."browser.sessionstore.privacy_level".value = 0;
+      };
+      "1200" = {
+        enable = true;
+        "1241"."security.mixed_content.block_display_content".enable = true;
+      };
+      "1600" = {
+        enable = true;
+      };
+      "1700" = {
+        enable = true;
+      };
+      "2000" = {
+        enable = true;
+      };
+      "2400" = {
+        enable = true;
+      };
+      "2600" = {
+        enable = true;
+        "2603" = {
+          "browser.download.start_downloads_in_tmp_dir".value = false;
+          "browser.helperApps.deleteTempFileOnExit".value = false;
+        };
+        "2615"."permissions.default.shortcuts" = {
+          value = 2;
+          enable = true;
+        };
+      };
+      "2700" = {
+        enable = true;
+      };
+      "2800" = {
+        enable = false;
+        "2810"."privacy.sanitize.sanitizeOnShutdown".value = false;
+      };
+      "4000" = {
+        enable = true;
+      };
+      "4500" = {
+        enable = true;
+      };
+      "5000" = {
+        enable = true;
+        "5003"."signon.rememberSignons" = {
+          enable = true;
+          value = false;
+        };
+      };
+      "6000" = {
+        enable = true;
+      };
+      "7000" = {
+        enable = true;
+      };
+      "8000" = {
+        enable = true;
+      };
+      "9000" = {
+        enable = true;
+      };
+    };
+  }
+  // preConfig)
diff --git a/modules/home.legacy/conf/firefox/config/search/engines/default.nix b/modules/by-name/fi/firefox/search_engines/default.nix
index 1c2045eb..51a447e1 100644
--- a/modules/home.legacy/conf/firefox/config/search/engines/default.nix
+++ b/modules/by-name/fi/firefox/search_engines/default.nix
@@ -1,81 +1,95 @@
 {pkgs, ...}: {
   # DEFAULT
-  "Brave Search" = {
+  brave-search = {
+    name = "Brave Search";
     urls = [{template = "https://search.brave.com/search?q={searchTerms}";}];
     icon = ./logos/brave.svg;
     definedAliases = ["@bs"];
   };
 
   # NIX
-  "Nix Packages" = {
+  nix-packages = {
+    name = "Nix packages";
     urls = [{template = "https://search.nixos.org/packages?type=packages&query={searchTerms}";}];
     icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg";
     definedAliases = ["@np"];
   };
 
-  "Nix functions" = {
+  nix-functions = {
+    name = "Nix functions";
     urls = [{template = "https://noogle.dev/q?term={searchTerms}";}];
     icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg";
     definedAliases = ["@ng"];
   };
 
-  "NixOS Options" = {
+  nixos-options = {
+    name = "NixOS options";
     urls = [{template = "https://search.nixos.org/options?type=options&query={searchTerms}";}];
     icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg";
     definedAliases = ["@no"];
   };
-  "HomeManager Options" = {
+  homemanager-options = {
+    name = "Home-Manager options";
     urls = [{template = "https://home-manager-options.extranix.com/?query={searchTerms}&release=master";}];
     icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg";
     definedAliases = ["@nh"];
   };
 
-  "Nixpkgs issues" = {
+  nixpkgs-issues = {
+    name = "Nixpkgs issues";
     urls = [{template = "https://github.com/NixOS/nixpkgs/issues?q=is%3Aissue+is%3Aopen+{searchTerms}";}];
     icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg";
     definedAliases = ["@ni"];
   };
-  "Nixpkgs pull requests" = {
+  nixpkgs-pull-requests = {
+    name = "Nixpkgs pull requests";
     urls = [{template = "https://github.com/NixOS/nixpkgs/pulls?q=is%3Apr+is%3Aopen+{searchTerms}";}];
     icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg";
     definedAliases = ["@nr"];
   };
 
-  "Nixpkgs pull requests tracker" = {
+  nixpkgs-pull-requests-tracker = {
+    name = "Nixpkgs pull requests tracker";
     urls = [{template = "https://nixpk.gs/pr-tracker.html?pr={searchTerms}";}];
     icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg";
     definedAliases = ["@nt"];
   };
-  "NixOS Wiki" = {
+  nixos-wiki = {
+    name = "NixOS Wiki";
     urls = [{template = "https://wiki.nixos.org/w/index.php?search={searchTerms}";}];
     icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg";
     definedAliases = ["@nw"];
   };
 
   # RUST
-  "Rust std" = {
+  rust-std = {
+    name = "Rust std";
     urls = [{template = "https://doc.rust-lang.org/std/?search={searchTerms}";}];
     icon = ./logos/rust_std.svg;
     definedAliases = ["@rs"];
   };
-  "Rust tokio" = {
+  rust-tokio = {
+    name = "Rust tokio";
     urls = [{template = "https://docs.rs/tokio/latest/tokio/index.html?search={searchTerms}";}];
     icon = ./logos/rust_tokio.png;
     definedAliases = ["@rt"];
   };
 
   # OTHER
-  "Google Scholar" = {
+  google-scholar = {
+    name = "Google Scholar";
     urls = [{template = "https://scholar.google.com/scholar?hl=en&q={searchTerms}";}];
     icon = ./logos/google_scholar.ico;
     definedAliases = ["@gs"];
   };
-  "Wikipedia" = {
+  wikipedia = {
+    name = "Wikipedia";
     urls = [{template = "https://en.wikipedia.org/wiki/{searchTerms}";}];
     icon = ./logos/wikipedia.svg;
     definedAliases = ["@wp"];
   };
-  "Arch Wiki" = {
+  arch-wiki = {
+    name = "Arch Wiki";
     urls = [{template = "https://wiki.archlinux.org/index.php?search={searchTerms}";}];
     icon = ./logos/arch_linux.svg;
     definedAliases = ["@aw"];
diff --git a/modules/home.legacy/conf/firefox/config/search/engines/logos/arch_linux.svg b/modules/by-name/fi/firefox/search_engines/logos/arch_linux.svg
index 949b5c5f..949b5c5f 100644
--- a/modules/home.legacy/conf/firefox/config/search/engines/logos/arch_linux.svg
+++ b/modules/by-name/fi/firefox/search_engines/logos/arch_linux.svg
diff --git a/modules/home.legacy/conf/firefox/config/search/engines/logos/brave.svg b/modules/by-name/fi/firefox/search_engines/logos/brave.svg
index 09dd2e42..09dd2e42 100644
--- a/modules/home.legacy/conf/firefox/config/search/engines/logos/brave.svg
+++ b/modules/by-name/fi/firefox/search_engines/logos/brave.svg
diff --git a/modules/home.legacy/conf/firefox/config/search/engines/logos/google_scholar.ico b/modules/by-name/fi/firefox/search_engines/logos/google_scholar.ico
index 85d0c664..85d0c664 100644
--- a/modules/home.legacy/conf/firefox/config/search/engines/logos/google_scholar.ico
+++ b/modules/by-name/fi/firefox/search_engines/logos/google_scholar.ico
Binary files differdiff --git a/modules/home.legacy/conf/firefox/config/search/engines/logos/rust_std.svg b/modules/by-name/fi/firefox/search_engines/logos/rust_std.svg
index 0091b5a8..0091b5a8 100644
--- a/modules/home.legacy/conf/firefox/config/search/engines/logos/rust_std.svg
+++ b/modules/by-name/fi/firefox/search_engines/logos/rust_std.svg
diff --git a/modules/home.legacy/conf/firefox/config/search/engines/logos/rust_tokio.png b/modules/by-name/fi/firefox/search_engines/logos/rust_tokio.png
index f1de55ff..f1de55ff 100644
--- a/modules/home.legacy/conf/firefox/config/search/engines/logos/rust_tokio.png
+++ b/modules/by-name/fi/firefox/search_engines/logos/rust_tokio.png
Binary files differdiff --git a/modules/home.legacy/conf/firefox/config/search/engines/logos/wikipedia.svg b/modules/by-name/fi/firefox/search_engines/logos/wikipedia.svg
index dc32f984..dc32f984 100644
--- a/modules/home.legacy/conf/firefox/config/search/engines/logos/wikipedia.svg
+++ b/modules/by-name/fi/firefox/search_engines/logos/wikipedia.svg
diff --git a/modules/by-name/fi/firefox/update_extensions.sh b/modules/by-name/fi/firefox/update_extensions.sh
new file mode 100755
index 00000000..efcc83c6
--- /dev/null
+++ b/modules/by-name/fi/firefox/update_extensions.sh
@@ -0,0 +1,12 @@
+#!/usr/bin/env sh
+
+# The `generate_extensions` binary is provided in the devshell.
+
+generate_extensions \
+    darkreader:navbar \
+    keepassxc-browser:navbar \
+    vhack-libredirect:navbar \
+    torproject-snowflake:navbar \
+    tridactyl-vim:menupanel \
+    ublock-origin:menupanel \
+    >"$(dirname "$0")"/extensions.json
diff --git a/modules/home.legacy/conf/firefox/config/chrome/userChrome.css b/modules/by-name/fi/firefox/userChrome.css
index 0b3aff77..0b3aff77 100644
--- a/modules/home.legacy/conf/firefox/config/chrome/userChrome.css
+++ b/modules/by-name/fi/firefox/userChrome.css
diff --git a/modules/by-name/ho/home-manager/module.nix b/modules/by-name/ho/home-manager/module.nix
index f5304170..5da40834 100644
--- a/modules/by-name/ho/home-manager/module.nix
+++ b/modules/by-name/ho/home-manager/module.nix
@@ -8,7 +8,6 @@
   system,
   # bins
   # TODO: Integrate these <2024-05-22>
-  river_init_lesser,
   shell_library,
   qmk_firmware,
   # external deps
@@ -17,6 +16,7 @@
   impermanence,
   nix-index-database,
   nixVim,
+  arkenfox-nixos,
   ...
 }: let
   cfg = config.soispha.home-manager;
@@ -42,7 +42,6 @@ in {
           # extra information
           system
           # bins
-          river_init_lesser
           shell_library
           qmk_firmware
           # external deps
@@ -51,6 +50,7 @@ in {
           impermanence
           nixVim
           nix-index-database
+          arkenfox-nixos
           ;
       };
     };
diff --git a/modules/by-name/lf/lf/commands/default.nix b/modules/by-name/lf/lf/commands/default.nix
index 6c21be12..0c42607b 100644
--- a/modules/by-name/lf/lf/commands/default.nix
+++ b/modules/by-name/lf/lf/commands/default.nix
@@ -7,7 +7,7 @@
     pkgs.writeShellApplication {
       inherit name;
       text = builtins.readFile ./base.sh + builtins.readFile ./scripts/${name}.sh;
-      runtimeInputs = [pkgs.lf pkgs.mktemp] ++ dependencies;
+      runtimeInputs = [pkgs.lf pkgs.mktemp pkgs.coreutils] ++ dependencies;
       inheritPath = keepPath;
     }
     + "/bin/${name}";
@@ -124,6 +124,11 @@ in {
     dependencies = [pkgs.gnused];
   };
 
+  open = async {
+    name = "open";
+    dependencies = [pkgs.handlr-regex];
+  };
+
   trash = pipe {
     name = "trash";
     dependencies = [pkgs.trash-cli];
diff --git a/modules/by-name/lf/lf/commands/scripts/open.sh b/modules/by-name/lf/lf/commands/scripts/open.sh
new file mode 100755
index 00000000..b494074f
--- /dev/null
+++ b/modules/by-name/lf/lf/commands/scripts/open.sh
@@ -0,0 +1,15 @@
+# shellcheck shell=sh
+
+# shellcheck disable=SC2269
+f="$f"
+# shellcheck disable=SC2269
+fx="$fx"
+# shellcheck disable=SC2269
+fs="$fs"
+# shellcheck disable=SC2269
+id="$id"
+
+# TODO: For some reason, `xdg-utils` tries to open firefox with it's default profile for
+# _everything_. Using `handlr-regex` sort-of solves this. <2025-04-04>
+handlr open "$f"
+# vim: ft=sh
diff --git a/modules/by-name/lf/lf/commands/scripts/trash_clear.sh b/modules/by-name/lf/lf/commands/scripts/trash_clear.sh
index faa3c553..a41dce27 100755
--- a/modules/by-name/lf/lf/commands/scripts/trash_clear.sh
+++ b/modules/by-name/lf/lf/commands/scripts/trash_clear.sh
@@ -1,8 +1,8 @@
 # shellcheck shell=sh
 
-while read -r file; do
+while IFS="$(printf '\n')" read -r file; do
     set -- "$@" "$(pwd)/$file"
-done <"$(conceal list | fzf --multi --ansi | awk '{for(i=3; i<=NF; i++) {print $i}}' | tmp)"
+done <"$(conceal list | fzf --multi --ansi | awk '{$1="";$2=""; print $0}' | sed 's/^\s*//' | tmp)"
 
 [ "$#" -ne 0 ] && trash empty --match=exact "$@"
 
diff --git a/modules/by-name/lf/lf/commands/scripts/trash_restore.sh b/modules/by-name/lf/lf/commands/scripts/trash_restore.sh
index f685345f..cc2d4890 100755
--- a/modules/by-name/lf/lf/commands/scripts/trash_restore.sh
+++ b/modules/by-name/lf/lf/commands/scripts/trash_restore.sh
@@ -9,9 +9,9 @@ fs="$fs"
 # shellcheck disable=SC2269
 id="$id"
 
-while read -r file; do
+while IFS="$(printf '\n')" read -r file; do
     set -- "$@" "$(pwd)/$file"
-done <"$(conceal list | fzf --multi --ansi | awk '{for(i=3; i<=NF; i++) {print $i}}' | tmp)"
+done <"$(conceal list | fzf --multi --ansi | awk '{$1="";$2=""; print $0}' | sed 's/^\s*//' | tmp)"
 
 [ "$#" -ne 0 ] && trash restore --match=exact "$@"
 # vim: ft=sh
diff --git a/modules/by-name/lf/lf/ctpv/default.nix b/modules/by-name/lf/lf/ctpv/default.nix
index 3748eca4..98438fba 100644
--- a/modules/by-name/lf/lf/ctpv/default.nix
+++ b/modules/by-name/lf/lf/ctpv/default.nix
@@ -1,5 +1,4 @@
 {
-  sysLib,
   lib,
   config,
   pkgs,
@@ -8,15 +7,15 @@
   functionCall = {
     name,
     dependencies,
-    replacementStrings,
     scriptPath,
-    ...
+    environment,
   }:
-    sysLib.writeShellScript {
+    pkgs.writeShellApplication {
       inherit name;
-      src = scriptPath;
-      keepPath = false;
-      inherit replacementStrings dependencies;
+      text = builtins.readFile ./helpers.sh + builtins.readFile scriptPath;
+      inheritPath = false;
+      runtimeInputs = dependencies;
+      runtimeEnv = environment;
     }
     + "/bin/${name}";
 
@@ -24,8 +23,8 @@
     matches,
     priority,
     dependencies,
-    replacementStrings,
     previewer,
+    environment,
   }: let
     mkMimePath = val: let
       split = lib.strings.splitString "/" val;
@@ -49,7 +48,7 @@
       inherit
         name
         dependencies
-        replacementStrings
+        environment
         ;
       scriptPath = previewer;
     };
@@ -93,6 +92,12 @@
         };
       };
 
+      environment = lib.mkOption {
+        type = lib.types.attrsOf lib.types.str;
+        default = {};
+        description = "Environment variables to set for the script";
+      };
+
       previewer = lib.mkOption {
         type = lib.types.pathInStore;
         description = "The path to the preview script or binary";
@@ -104,13 +109,6 @@
         default = 0;
         description = "The priority to use this previewer.";
       };
-      replacementStrings = lib.mkOption {
-        type = lib.types.attrsOf (lib.types.either lib.types.str lib.types.pathInStore);
-        default = {
-          HELPERS = ./helpers.sh;
-        };
-        description = "Arbitrary strings to replace in the shell script.";
-      };
       dependencies = lib.mkOption {
         type = lib.types.listOf lib.types.package;
         default = [];
@@ -153,17 +151,6 @@ in {
 
     package = lib.mkPackageOption pkgs "ctpv-64-types" {};
 
-    # TODO: This is necessary, as the `./prev` dir is imported separately and as such
-    # cannot access the `./helpers.sh` file in it's parent directory.
-    # This separate import should ideally be removed. <2024-12-15>
-    helpers = lib.mkOption {
-      default = ./helpers.sh;
-      type = lib.types.pathInStore;
-
-      internal = true;
-      readOnly = true;
-    };
-
     previewers = lib.mkOption {
       description = ''
         The previewers to add to the config file.
diff --git a/modules/by-name/lf/lf/ctpv/prev/any.sh b/modules/by-name/lf/lf/ctpv/prev/any.sh
index 38dfd538..0b0ee573 100644
--- a/modules/by-name/lf/lf/ctpv/prev/any.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/any.sh
@@ -1,8 +1,5 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 # shellcheck disable=SC2269
@@ -19,8 +16,6 @@ extension="$e"
 # shellcheck disable=SC2269
 mime="$m"
 
-. %HELPERS
-
 is_not_printable() {
     grep --text --quiet '[^[:print:]]' "$1"
 }
@@ -33,8 +28,8 @@ case "$mime" in
 *)
     echo "(ctpv did not recognize this file, with extension: '$extension' and mime: '$mime')"
 
-    directory_storage="%STORAGE_DIRECTORY/$mime"
-    mkdir --parents "$(dirname "%STORAGE_DIRECTORY/$mime")"
+    directory_storage="$STORAGE_DIRECTORY/$mime"
+    mkdir --parents "$(dirname "$STORAGE_DIRECTORY/$mime")"
 
     printf "%s -- %s\n" "$f" "$extension" >>"$directory_storage"
     ;;
diff --git a/modules/by-name/lf/lf/ctpv/prev/application/archive/atool.sh b/modules/by-name/lf/lf/ctpv/prev/application/archive/atool.sh
index 5f4baac7..3aebfbb3 100644
--- a/modules/by-name/lf/lf/ctpv/prev/application/archive/atool.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/application/archive/atool.sh
@@ -1,11 +1,6 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 
-. %HELPERS
-
 atool --list -- "$f"
diff --git a/modules/by-name/lf/lf/ctpv/prev/application/dll/dll.sh b/modules/by-name/lf/lf/ctpv/prev/application/dll/dll.sh
index 678506eb..e365fe0a 100644
--- a/modules/by-name/lf/lf/ctpv/prev/application/dll/dll.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/application/dll/dll.sh
@@ -1,8 +1,5 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 # shellcheck disable=SC2269
@@ -14,6 +11,4 @@ m="$m"
 # shellcheck disable=SC2269
 h="$h"
 
-. %HELPERS
-
 preview_xxd "$f"
diff --git a/modules/by-name/lf/lf/ctpv/prev/application/epub/default.nix b/modules/by-name/lf/lf/ctpv/prev/application/epub/default.nix
index 40510a78..b4df845a 100644
--- a/modules/by-name/lf/lf/ctpv/prev/application/epub/default.nix
+++ b/modules/by-name/lf/lf/ctpv/prev/application/epub/default.nix
@@ -5,11 +5,11 @@
       matches.mime = ["application/epub+zip"];
       matches.extension = ["epub"];
       priority = 1;
-      dependencies = with pkgs; [
-        bk
-        epub-thumbnailer
-        chafa
-        gnused
+      dependencies = [
+        pkgs.bk
+        pkgs.epub-thumbnailer
+        pkgs.chafa
+        pkgs.gnused
       ];
     };
   };
diff --git a/modules/by-name/lf/lf/ctpv/prev/application/epub/epub.sh b/modules/by-name/lf/lf/ctpv/prev/application/epub/epub.sh
index 703e7dad..cad95860 100644
--- a/modules/by-name/lf/lf/ctpv/prev/application/epub/epub.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/application/epub/epub.sh
@@ -1,8 +1,5 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 # shellcheck disable=SC2269
@@ -16,8 +13,6 @@ h="$h"
 # shellcheck disable=SC2269
 cache_f="$cache_f"
 
-. %HELPERS
-
 epub() {
     epub-thumbnailer "$f" "$cache_f" 20000
 }
diff --git a/modules/by-name/lf/lf/ctpv/prev/application/pdf/default.nix b/modules/by-name/lf/lf/ctpv/prev/application/pdf/default.nix
index d3061ea8..24112737 100644
--- a/modules/by-name/lf/lf/ctpv/prev/application/pdf/default.nix
+++ b/modules/by-name/lf/lf/ctpv/prev/application/pdf/default.nix
@@ -8,6 +8,7 @@
         pkgs.poppler_utils # for `pdftoppm`
         pkgs.chafa
         pkgs.gnused
+        pkgs.coreutils
       ];
     };
   };
diff --git a/modules/by-name/lf/lf/ctpv/prev/application/pdf/pdf.sh b/modules/by-name/lf/lf/ctpv/prev/application/pdf/pdf.sh
index 2f807b1a..4d99f4b0 100644
--- a/modules/by-name/lf/lf/ctpv/prev/application/pdf/pdf.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/application/pdf/pdf.sh
@@ -1,15 +1,10 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 # shellcheck disable=SC2269
 cache_f="$cache_f"
 
-. %HELPERS
-
 pdf() {
     pdftoppm -f 1 -l 1 \
         -scale-to-x 1920 \
diff --git a/modules/by-name/lf/lf/ctpv/prev/application/pgp/pgp.sh b/modules/by-name/lf/lf/ctpv/prev/application/pgp/pgp.sh
index a4eefd96..4747a8c4 100644
--- a/modules/by-name/lf/lf/ctpv/prev/application/pgp/pgp.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/application/pgp/pgp.sh
@@ -1,13 +1,8 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 # shellcheck disable=SC2269
 w="$w"
 
-. %HELPERS
-
 hide_script_env sq inspect --certifications -- "$f"
diff --git a/modules/by-name/lf/lf/ctpv/prev/application/sqlite/sqlite.sh b/modules/by-name/lf/lf/ctpv/prev/application/sqlite/sqlite.sh
index 07e77a93..62c1abec 100644
--- a/modules/by-name/lf/lf/ctpv/prev/application/sqlite/sqlite.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/application/sqlite/sqlite.sh
@@ -1,15 +1,10 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 # shellcheck disable=SC2269
 w="$w"
 
-. %HELPERS
-
 echo "SQLite database. Schema:"
 echo
 
diff --git a/modules/by-name/lf/lf/ctpv/prev/application/x-bittorrent/torrent.sh b/modules/by-name/lf/lf/ctpv/prev/application/x-bittorrent/torrent.sh
index 16cfcbcd..f1da355a 100644
--- a/modules/by-name/lf/lf/ctpv/prev/application/x-bittorrent/torrent.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/application/x-bittorrent/torrent.sh
@@ -1,13 +1,8 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 # shellcheck disable=SC2269
 cache_f="$cache_f"
 
-. %HELPERS
-
 transmission-show -- "$f"
diff --git a/modules/by-name/lf/lf/ctpv/prev/application/x-pem-file/default.nix b/modules/by-name/lf/lf/ctpv/prev/application/x-pem-file/default.nix
new file mode 100644
index 00000000..a6a32808
--- /dev/null
+++ b/modules/by-name/lf/lf/ctpv/prev/application/x-pem-file/default.nix
@@ -0,0 +1,11 @@
+{pkgs, ...}: {
+  soispha.programs.lf.ctpv.previewers = {
+    pem = {
+      previewer = ./pem.sh;
+      matches.mime = ["application/x-pem-file"];
+      dependencies = [
+        pkgs.openssl
+      ];
+    };
+  };
+}
diff --git a/modules/by-name/lf/lf/ctpv/prev/application/x-pem-file/pem.sh b/modules/by-name/lf/lf/ctpv/prev/application/x-pem-file/pem.sh
new file mode 100644
index 00000000..76ee3002
--- /dev/null
+++ b/modules/by-name/lf/lf/ctpv/prev/application/x-pem-file/pem.sh
@@ -0,0 +1,8 @@
+#! /usr/bin/env dash
+
+# shellcheck disable=SC2269
+f="$f"
+# shellcheck disable=SC2269
+cache_f="$cache_f"
+
+openssl x509 -in "$f" -text -noout
diff --git a/modules/by-name/lf/lf/ctpv/prev/audio/audio.sh b/modules/by-name/lf/lf/ctpv/prev/audio/audio.sh
index c5abc646..2e9e147c 100644
--- a/modules/by-name/lf/lf/ctpv/prev/audio/audio.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/audio/audio.sh
@@ -1,15 +1,10 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 # shellcheck disable=SC2269
 cache_f="$cache_f"
 
-. %HELPERS
-
 audio() {
     ffmpegthumbnailer -i "$f" -s 0 -q 5 -t 10 -o "$cache_f" 2>/dev/null
 }
diff --git a/modules/by-name/lf/lf/ctpv/prev/audio/default.nix b/modules/by-name/lf/lf/ctpv/prev/audio/default.nix
index 0c60e9d5..20df04b3 100644
--- a/modules/by-name/lf/lf/ctpv/prev/audio/default.nix
+++ b/modules/by-name/lf/lf/ctpv/prev/audio/default.nix
@@ -9,6 +9,7 @@
 
         pkgs.chafa
         pkgs.gnused
+        pkgs.coreutils
       ];
     };
   };
diff --git a/modules/by-name/lf/lf/ctpv/prev/default.nix b/modules/by-name/lf/lf/ctpv/prev/default.nix
index b59430f8..3e54e88a 100644
--- a/modules/by-name/lf/lf/ctpv/prev/default.nix
+++ b/modules/by-name/lf/lf/ctpv/prev/default.nix
@@ -10,18 +10,15 @@ in {
       previewer = ./any.sh;
       priority = -1;
       matches.mime = ["*/*"];
-      replacementStrings = {
-        # FIXME: This declaration replaces the default (although it should be merged with
-        # the default value.) There must be a way, so that repeating the default values is
-        # not needed. <2024-12-15>
-        HELPERS = cfg.ctpv.helpers;
-
+      environment = {
         STORAGE_DIRECTORY = "${cfg.ctpv.xdgDataHome}/ctpv/missing_previews";
       };
 
       dependencies = [
         pkgs.tinyxxd # For xxd
         pkgs.bat
+        pkgs.gnugrep
+        pkgs.coreutils
       ];
     };
   };
diff --git a/modules/by-name/lf/lf/ctpv/prev/font/default.nix b/modules/by-name/lf/lf/ctpv/prev/font/default.nix
index 306e7892..48bcb7ad 100644
--- a/modules/by-name/lf/lf/ctpv/prev/font/default.nix
+++ b/modules/by-name/lf/lf/ctpv/prev/font/default.nix
@@ -13,6 +13,7 @@
         pkgs.fontforge # for `fontimage`
         pkgs.chafa
         pkgs.gnused
+        pkgs.coreutils
       ];
     };
   };
diff --git a/modules/by-name/lf/lf/ctpv/prev/font/font.sh b/modules/by-name/lf/lf/ctpv/prev/font/font.sh
index 4065557e..9e5ef3c1 100644
--- a/modules/by-name/lf/lf/ctpv/prev/font/font.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/font/font.sh
@@ -1,15 +1,10 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 # shellcheck disable=SC2269
 cache_f="$cache_f"
 
-. %HELPERS
-
 font() {
     fontimage -o "$cache_f.png" "$f" 2>/dev/null &&
         mv -- "$cache_f.png" "$cache_f"
diff --git a/modules/by-name/lf/lf/ctpv/prev/image/image.sh b/modules/by-name/lf/lf/ctpv/prev/image/image.sh
index b5b97668..42c99c23 100644
--- a/modules/by-name/lf/lf/ctpv/prev/image/image.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/image/image.sh
@@ -1,11 +1,6 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 
-. %HELPERS
-
 send_image "$f"
diff --git a/modules/by-name/lf/lf/ctpv/prev/image/svg+xml/svg.sh b/modules/by-name/lf/lf/ctpv/prev/image/svg+xml/svg.sh
index 04a06f56..ce588ada 100644
--- a/modules/by-name/lf/lf/ctpv/prev/image/svg+xml/svg.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/image/svg+xml/svg.sh
@@ -1,15 +1,10 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 # shellcheck disable=SC2269
 cache_f="$cache_f"
 
-. %HELPERS
-
 svg() {
     magick "$f" "jpg:$cache_f"
 }
diff --git a/modules/by-name/lf/lf/ctpv/prev/image/x-xcf/xcf.sh b/modules/by-name/lf/lf/ctpv/prev/image/x-xcf/xcf.sh
index 1603e337..abb83a89 100644
--- a/modules/by-name/lf/lf/ctpv/prev/image/x-xcf/xcf.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/image/x-xcf/xcf.sh
@@ -1,15 +1,10 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 # shellcheck disable=SC2269
 cache_f="$cache_f"
 
-. %HELPERS
-
 xcf() {
     # TODO: Add this (currently it fails, as gimp lacks the `python-fu` evaluator) <2024-11-25>
     true
diff --git a/modules/by-name/lf/lf/ctpv/prev/inode/ls.sh b/modules/by-name/lf/lf/ctpv/prev/inode/ls.sh
index f73bd1c2..f5b95d13 100644
--- a/modules/by-name/lf/lf/ctpv/prev/inode/ls.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/inode/ls.sh
@@ -1,8 +1,5 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 # shellcheck disable=SC2269
@@ -10,6 +7,4 @@ cache_d="$cache_d"
 # shellcheck disable=SC2269
 cache_f="$cache_f"
 
-. %HELPERS
-
 ls --color --group-directories-first -- "$f"
diff --git a/modules/by-name/lf/lf/ctpv/prev/inode/symlink.sh b/modules/by-name/lf/lf/ctpv/prev/inode/symlink.sh
index b30957d0..fb0dea8f 100644
--- a/modules/by-name/lf/lf/ctpv/prev/inode/symlink.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/inode/symlink.sh
@@ -1,13 +1,8 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 
-. %HELPERS
-
 #
 # do nothing because in src/ctpv.c some kind of a "preview"
 # is already printed
diff --git a/modules/by-name/lf/lf/ctpv/prev/libreoffice.sh b/modules/by-name/lf/lf/ctpv/prev/libreoffice.sh
index ec57da0b..9407aade 100644
--- a/modules/by-name/lf/lf/ctpv/prev/libreoffice.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/libreoffice.sh
@@ -1,8 +1,5 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 # shellcheck disable=SC2269
@@ -10,8 +7,6 @@ cache_d="$cache_d"
 # shellcheck disable=SC2269
 cache_f="$cache_f"
 
-. %HELPERS
-
 doc() {
     # File produced by libreoffice
     jpg="$(printf '%s\n' "$f" | sed 's|^.*/||; s|\..*$||')"
diff --git a/modules/by-name/lf/lf/ctpv/prev/text/bat.sh b/modules/by-name/lf/lf/ctpv/prev/text/bat.sh
index be952aea..a466c9c7 100644
--- a/modules/by-name/lf/lf/ctpv/prev/text/bat.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/text/bat.sh
@@ -1,13 +1,8 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 # shellcheck disable=SC2269
 w="$w"
 
-. %HELPERS
-
 preview_bat "$f"
diff --git a/modules/by-name/lf/lf/ctpv/prev/text/diff/delta.sh b/modules/by-name/lf/lf/ctpv/prev/text/diff/delta.sh
index 6a4e9a4e..3f8b5631 100644
--- a/modules/by-name/lf/lf/ctpv/prev/text/diff/delta.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/text/diff/delta.sh
@@ -1,11 +1,6 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 
-. %HELPERS
-
 delta <"$f"
diff --git a/modules/by-name/lf/lf/ctpv/prev/text/glow.sh b/modules/by-name/lf/lf/ctpv/prev/text/glow.sh
index 301fe675..30f2af78 100644
--- a/modules/by-name/lf/lf/ctpv/prev/text/glow.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/text/glow.sh
@@ -1,15 +1,10 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 # shellcheck disable=SC2269
 w="$w"
 
-. %HELPERS
-
 # Specify the style, to force `glow` to output colors.
 # tracking issue: https://github.com/charmbracelet/glow/issues/654
 # We can't use `hide_script_env` because of some bespoke reason. (It just forces glow to
diff --git a/modules/by-name/lf/lf/ctpv/prev/text/html/default.nix b/modules/by-name/lf/lf/ctpv/prev/text/html/default.nix
deleted file mode 100644
index 2a7a9a9f..00000000
--- a/modules/by-name/lf/lf/ctpv/prev/text/html/default.nix
+++ /dev/null
@@ -1,13 +0,0 @@
-{pkgs, ...}: {
-  # TODO: I might want to use lynx/w3m instead <2024-11-24>
-  soispha.programs.lf.ctpv.previewers = {
-    elinks = {
-      previewer = ./elinks.sh;
-      priority = 1;
-      matches.mime = ["text/html"];
-      dependencies = [
-        pkgs.elinks
-      ];
-    };
-  };
-}
diff --git a/modules/by-name/lf/lf/ctpv/prev/text/html/elinks.sh b/modules/by-name/lf/lf/ctpv/prev/text/html/elinks.sh
deleted file mode 100644
index ca0de22e..00000000
--- a/modules/by-name/lf/lf/ctpv/prev/text/html/elinks.sh
+++ /dev/null
@@ -1,18 +0,0 @@
-#! /usr/bin/env dash
-
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
-# shellcheck disable=SC2269
-f="$f"
-# shellcheck disable=SC2269
-w="$w"
-
-. %HELPERS
-
-elinks \
-    -dump 1 -dump-width "$w" \
-    -no-references -no-numbering <"$f"
-
-# lynx -dump -nonumbers -nolist -width="$w" -- "$f"
-# w3m -dump "$f"
diff --git a/modules/by-name/lf/lf/ctpv/prev/text/json/jq.sh b/modules/by-name/lf/lf/ctpv/prev/text/json/jq.sh
index bf807d1d..c7090ccb 100644
--- a/modules/by-name/lf/lf/ctpv/prev/text/json/jq.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/text/json/jq.sh
@@ -1,11 +1,6 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 
-. %HELPERS
-
 jq --color-output . <"$f"
diff --git a/modules/by-name/lf/lf/ctpv/prev/video/video.sh b/modules/by-name/lf/lf/ctpv/prev/video/video.sh
index e42e3612..d1972187 100644
--- a/modules/by-name/lf/lf/ctpv/prev/video/video.sh
+++ b/modules/by-name/lf/lf/ctpv/prev/video/video.sh
@@ -1,15 +1,10 @@
 #! /usr/bin/env dash
 
-# shellcheck source=/dev/null
-SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
-
 # shellcheck disable=SC2269
 f="$f"
 # shellcheck disable=SC2269
 cache_f="$cache_f"
 
-. %HELPERS
-
 video() {
     ffmpegthumbnailer -i "$f" -o "$cache_f" -s 0 -t 50% 2>/dev/null
 }
diff --git a/modules/by-name/li/libvirtd/module.nix b/modules/by-name/li/libvirtd/module.nix
index 5c519550..3481ef3b 100644
--- a/modules/by-name/li/libvirtd/module.nix
+++ b/modules/by-name/li/libvirtd/module.nix
@@ -1,4 +1,6 @@
-{pkgs, ...}: {
+{...}: {
+  # FIXME(@bpeetz): Do something with this module. <2025-04-04>
+
   # virtualisation = {
   # spiceUSBRedirection.enable = true; # TODO: this allows usb access to any user, which shouldn't be that bad
   #    cores = 8;
diff --git a/modules/by-name/ni/nix/module.nix b/modules/by-name/ni/nix/module.nix
index 767ab076..48834b2d 100644
--- a/modules/by-name/ni/nix/module.nix
+++ b/modules/by-name/ni/nix/module.nix
@@ -7,6 +7,8 @@
   system,
   ...
 }: {
+  # TODO(@bpeetz): Modularize <2025-02-08>
+
   nix = {
     package = pkgs.lix;
 
@@ -52,7 +54,7 @@
 
       fallback = true; # Build from source, if binary can't be substituted
 
-      keep-failed = true; # keep failed tmp build dirs
+      keep-failed = false; # keep failed tmp build dirs
       pure-eval = true; # restrict file system and network access to hash
 
       sandbox-fallback = false; # Don't disable the sandbox, if the kernel doesn't support it
diff --git a/modules/by-name/nv/nvim/plgs/telescope/extensions/bibtex/default.nix b/modules/by-name/nv/nvim/plgs/telescope/extensions/bibtex/default.nix
index 202b3f92..8eee9a27 100644
--- a/modules/by-name/nv/nvim/plgs/telescope/extensions/bibtex/default.nix
+++ b/modules/by-name/nv/nvim/plgs/telescope/extensions/bibtex/default.nix
@@ -1,9 +1,4 @@
-{
-  pkgs,
-  config,
-  lib,
-  ...
-}: let
+{config, ...}: let
   cfg = config.soispha.programs.nvim;
 in {
   # TODO: Re-enable this, once the plugin is merged into nixpkgs <2025-03-29>
diff --git a/modules/by-name/ri/river/module.nix b/modules/by-name/ri/river/module.nix
index c8fb973c..139e8b66 100644
--- a/modules/by-name/ri/river/module.nix
+++ b/modules/by-name/ri/river/module.nix
@@ -109,7 +109,7 @@ in {
         '';
 
         description = ''
-          Configuration for river_init_lesser via `keys.json`.
+          Configuration for river's rules.
         '';
       };
 
diff --git a/modules/by-name/ta/taskwarrior/module.nix b/modules/by-name/ta/taskwarrior/module.nix
index 0a942820..c5549ac9 100644
--- a/modules/by-name/ta/taskwarrior/module.nix
+++ b/modules/by-name/ta/taskwarrior/module.nix
@@ -1,44 +1,146 @@
 {
   lib,
   config,
+  pkgs,
   ...
 }: let
   cfg = config.soispha.programs.taskwarrior;
+
+  hooksDir =
+    pkgs.runCommandNoCCLocal "mk-taskwarrior-hooks" {}
+    (''
+        mkdir "$out"
+      ''
+      + (builtins.concatStringsSep "\n"
+        (lib.attrsets.mapAttrsToList
+          (name: value: ''
+            ln --symbolic "${lib.getExe value.executable}" "$out/${value.mode}_${name}"
+          '')
+          cfg.hooks)));
+
+  mkHook = mode: deps: path: {
+    inherit mode;
+
+    executable = pkgs.writeShellApplication {
+      name = "add-hook-${builtins.baseNameOf path}";
+      runtimeInputs = [pkgs.taskwarrior3 pkgs.coreutils pkgs.gnugrep] ++ deps;
+      inheritPath = false;
+      text =
+        # bash
+        ''
+          die() {
+            echo "$@">&2
+            exit 1
+          }
+
+          enable_hook_dbg() {
+              # TODO: We should probably be smarter with the debug detection <2025-04-04>
+              if echo "$2" | grep --quiet 'rc.debug.hooks='; then
+                set -x
+                mkdir --parents "$HOME/.cache/task"
+                exec >>"$HOME/.cache/task/hook.log.$1"
+                exec 2>>"$HOME/.cache/task/hook.log.$1"
+              fi
+          }
+
+          addedCall() {
+           ${builtins.readFile path}
+          }
+
+          ${
+            if mode == "on-modify"
+            then "read -r old_task"
+            else "old_task=NULL"
+          }
+          read -r new_task
+          # We don't change the task, thus immediately return the JSON
+          echo "$new_task"
+
+          enable_hook_dbg "$@"
+          addedCall "$new_task" "$old_task"
+
+          exit 0
+        '';
+    };
+  };
 in {
   options.soispha.programs.taskwarrior = {
-    enable = lib.mkEnableOption "taskwarrior-secrets";
+    enable = lib.mkEnableOption "taskwarrior";
+
+    includeFiles = lib.mkOption {
+      type = lib.types.attrsOf lib.types.path;
+      description = "Extra files to include in the taskwarrior config";
+      default = {};
+      apply = value:
+        builtins.concatStringsSep "\n"
+        (builtins.map (path: "include ${path}")
+          (builtins.attrValues value));
+    };
+
+    hooks = lib.mkOption {
+      description = "Map hook names to their values";
+      type = lib.types.attrsOf (lib.types.submodule {
+        options = {
+          mode = lib.mkOption {
+            type = lib.types.enum ["on-add" "on-modify"];
+            description = "The type of the hook";
+          };
+          executable = lib.mkOption {
+            type = lib.types.package;
+            description = "The executable to call.";
+          };
+        };
+      });
+    };
   };
 
-  # HACK: Migrating the whole `taskwarrior` setup is right now unrealistic, as the module is
-  # tightly coupled with the `firefox` module, and `neorg` script.
-  # But to work around the  fact that setting the `age` secrets in the legacy module is
-  # impossible, this module was created as work-around until the `taskwarrior` module can
-  # be fully migrated. <2024-10-18>
-  config = lib.mkIf cfg.enable {
-    age.secrets = {
-      taskserverPrivate = {
-        file = ./secrets/private.key;
-        mode = "700";
-        owner = "soispha";
-        group = "users";
-      };
-      taskserverPublic = {
-        file = ./secrets/public.cert;
-        mode = "700";
-        owner = "soispha";
-        group = "users";
-      };
-      taskserverCA = {
-        file = ./secrets/ca.cert;
-        mode = "700";
-        owner = "soispha";
-        group = "users";
+  config = {
+    lib.taskwarrior = {
+      inherit mkHook;
+    };
+
+    home-manager.users.soispha = lib.mkIf cfg.enable {
+      services.taskwarrior-sync = {
+        enable = true;
+        package = pkgs.taskwarrior3;
       };
-      taskserverCredentials = {
-        file = ./secrets/credentials;
-        mode = "700";
-        owner = "soispha";
-        group = "users";
+
+      programs.taskwarrior = {
+        enable = true;
+        colorTheme = ./nord.theme;
+        package = pkgs.taskwarrior3;
+        extraConfig = cfg.includeFiles;
+
+        config = {
+          complete.all.tags = true;
+          list.all = {
+            projects = true;
+            tags = true;
+          };
+
+          regex = true;
+          weekstart = "Monday";
+
+          uda = {
+            total_active_time = {
+              type = "duration";
+              label = "Total active time";
+            };
+          };
+
+          alias = {
+            mod = "modify";
+          };
+          color = true;
+
+          hooks.location = "${hooksDir}";
+
+          urgency.uda.priority = {
+            H.coefficient = 6.0;
+            M.coefficient = 0;
+            L.coefficient = -1.8;
+          };
+        };
       };
     };
   };
diff --git a/modules/home.legacy/conf/taskwarrior/nord.theme b/modules/by-name/ta/taskwarrior/nord.theme
index 2897418f..2897418f 100644
--- a/modules/home.legacy/conf/taskwarrior/nord.theme
+++ b/modules/by-name/ta/taskwarrior/nord.theme
diff --git a/modules/by-name/ta/taskwarrior/secrets/ca.cert b/modules/by-name/ta/taskwarrior/secrets/ca.cert
deleted file mode 100644
index 81528a2a..00000000
--- a/modules/by-name/ta/taskwarrior/secrets/ca.cert
+++ /dev/null
@@ -1,161 +0,0 @@
------BEGIN AGE ENCRYPTED FILE-----
-YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4dVVkOWlYNjJQSFZYbExM
-bENvUTFzbmdPQ0ljR2V1TlJXYUZFVnNMS3owCjNmaE5pNnZqN0FXRUtFQzZYR0xQ
-NWh0L0NLVDlEeWlvdlB1T2dwRmkybXcKLT4gc3NoLWVkMjU1MTkgelpFb25nIHR3
-TmJzS2Q4WDN4KzVkVXgyMzhiYmdId0wwSzJndmZJQUlzYm9MTW5zR3cKRmswT3RN
-QTR2VjYvVXY4TnJCNEVrY0V1c3FEK3hGMkppeWh0bEUzdEdMRQotPiBzc2gtZWQy
-NTUxOSA3SGZGVXcgY2R5WUVpdlJCVjBxR0lTMmFnY0plV0J4NUFWTk1XWnllbjlt
-OS8xS3FIVQo4MytXd054Rm5neTFsREpWTFdJc2xzLzdDckZ5M2tOelNhakMxanlY
-cTQ4Ci0+IE1Dci1ncmVhc2UgfSYwZlg0YlcKQUlENkdEalVMZ0VzTXFlUHB1Yzhr
-VWZwb1FMZFdtbm1HU01VMWtLVnB4MmlyUQotLS0gUTh6RGZ4NVRaQXppQ1ozbmlS
-U1FqSVRDOEQzZDc0NUtyN3JMMmhER1U3TQrE19bvLibjcNcMzhiPZxX9K38Lr4Xo
-TXxkclMNX1EKveHCqG8rzkkquPJar5M5PAo7UL+zXBaB63XCbuscUv1jTiTFYN7V
-hVEAoj1rpcsDslhchpra3TZWuQZuhDJw+2Ig0qaCQWCzqi+e0j6oTAwZWyo3lIB1
-jt1xik+2QAxdMae2i3CBpPdwlyWGN5rpX+CgFQg3SKpOtaE5T924GJTBdm6jSfR6
-91tNoU+8cR82tHlR1NrhoKFPqw4xKZhrIhe+WW5IqK2SB7IRsnS7hiYz+UzDQu/9
-Bvfd2RO07JH1wCphnH7l+YmTVyZSydm1gPzBwGnRtWrxZa4B6xYatTWT8CQZyg0k
-suKe9EVYb6A9+UzrfjwNKIm+1aTyy7NUPTtbJ0Qjn3NoNMZIdONXqPQnT2iSFy4G
-ym4ZvkIRoyjh3dzd3csVvHIAsdWyyUL3uvri+HeHuaTtiSpyUl5hzHnjQyKgubI4
-rIfrSYtqsA76scj8HsMQ9DaQsGnEtIbvUAHemTKKVDnozY1vrO2RNg4CtAyRRfbl
-DnITU9S5V5CzMZdnUnq0qeVyKG/amPnDuEhk/IyaaLOM7T7Zl2PuT6T+Dckmj6GV
-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
------END AGE ENCRYPTED FILE-----
diff --git a/modules/by-name/ta/taskwarrior/secrets/credentials b/modules/by-name/ta/taskwarrior/secrets/credentials
deleted file mode 100644
index f3aaf502..00000000
--- a/modules/by-name/ta/taskwarrior/secrets/credentials
+++ /dev/null
@@ -1,15 +0,0 @@
------BEGIN AGE ENCRYPTED FILE-----
-YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqdGQ3a0pWb3lvZXFWbTFQ
-UG1JbGREZW9SS3ZuWXJhbTdvTTBqZUdhN0Q0CjF1cnJFM1d2ZFNyRW44Rzlvamlz
-VWQycXhmWnB4L1hiSE5qbFozWFlGMU0KLT4gc3NoLWVkMjU1MTkgelpFb25nIEFk
-bVQ3U3BsU1FkeWxBY0sySTV2UkxocXJpVXMyd1FrMXA3YUR0NWtTR1kKeUtHODVy
-aXE3aXh4WkFmYTJtdlZyZ1A1QlhYZGZuTUYxYVVlblRUV1BqOAotPiBzc2gtZWQy
-NTUxOSA3SGZGVXcgdGR4cFMya3p6TEx5cnhYcWNXR2FlVEk3UTBEcHQ3Y3RmK0lY
-YlpwRXJGcwpwZUVqODB3SUZUdTlQVW4yaWlZaTE0RE9OT1dLanZlSGV6cnlJRElQ
-UjBBCi0+ICFALWdyZWFzZSB0MFU2IDZoIEJPWUZIP1sKN1l2dzdWN1JDbEhEeXBq
-THV0cWJIV1RLalVsVVp3RCtwbk5NS2pnd3kxS1RhNTNaa3pqWXZFVm9FM2N2cFp5
-TQpYR2MKLS0tIEhLQWdwL0VoT1ZGNU5UUWs0SVVqK0ZQTndkTURPb0VtNEtJN3or
-S0Q0K1UKRfhyrcVb0EbsKj9gL5kqaIpfrsWd2cizrVQ67y9ZOwWilWgk/gkoXadf
-q7QeYjnWsHeIVtSZIaHSa8+9pvKAwiYW+B6DjRi7EXkCYz8zGeanMuoKA4by5Q9x
-VMKJlWk7c0WIzSuviw==
------END AGE ENCRYPTED FILE-----
diff --git a/modules/by-name/ta/taskwarrior/secrets/private.key b/modules/by-name/ta/taskwarrior/secrets/private.key
deleted file mode 100644
index 64f925fb..00000000
--- a/modules/by-name/ta/taskwarrior/secrets/private.key
+++ /dev/null
@@ -1,449 +0,0 @@
------BEGIN AGE ENCRYPTED FILE-----
-YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBncVlhL2RhS3JNaWFIKzl5
-VFV2Y3dZRkE2SlFvV25wd2NRU0NVN1Z0T2pBCmpRM2FJSUpPMGpQRE5EZHR5NElu
-UlBLcE9EWVBRSHA4eTRTNHpDaDdIOHMKLT4gc3NoLWVkMjU1MTkgelpFb25nIGlC
-cGR2aytobjcxV0xJMUc4d1VseUN2K3NoMEx4UnIzRGZvOTZoNHJVaGMKYWV3TVAw
-RWJzN3NnOHo3QnZSL3JvbTFxWG9zQmtISzRIMDJXVXg4U1kvZwotPiBzc2gtZWQy
-NTUxOSA3SGZGVXcgV0E4b05Kc3FwRXdFT3Y4c1VmTi83QXFxSXViVVVORTRMMms0
-cVpzMEd6ZwphazBuREVxSWxMcFJUYUplQXFOQkVjM2hUSytMUmN0d1dsM21lOGE1
-SkhNCi0+IE57XS1ncmVhc2UKN0RPSGRMOG5YSUZNblphWXg3MUxyNVVyS2RocnAw
-SFlsbG5PZzlWNndtL016WnFraXhWNHhaV1hwK3F1NCtDVQpSMm5vcjk5M282UUk1
-c1BjMHdCSjlkdmxQM1NKdzFVUG53Ci0tLSBlbE9TSUV2Tmxlc1FhaWZZU0hWQVdX
-SnNnWFUvWEcwSmppdCsvQUxWVGlvCqDjHDzuQfNWNpnVCLFdErXs5Xp1tedq+HIK
-/os5NEoGXikwdJTi0QMbBJwe/jKtf6WNEz/CX/sNCRg2qHGLZFFOuTZ+daIhfx3U
-kO3rA0pZzN1nyVwZhWSs63SOnooAUjfMzIcnDnu0qfGKXUAf1VmKxrqx5r/g4Sk3
-pYj383uWylTkrCo1OA4Hq02ynCosS+rDtyMb+mO8v2MxhG/r5noMO9YbBA7DOKtv
-Rp2Ji8vdrvUnsLMBWBZsdFr0mpg7adoraCRIerpbJAG5LpA3QsHS8rjymn9RDLH3
-CogNs5NcYEjIj2sf+1/pLUqlUb6BEog/4QLD9aRIoQECwNTIMHRtwq09V3YkOEB+
-UXCTnfdDyqj+DlADFfRmu82P32E/VcS9MH0WHSKuVCiNa6Vzljowrt9JUXVxXKbs
-+ae8+qnQA/rOInWMG94ypFBH+fcYuso0rFSLU40MSUZtZmBHa1TYJ0md4U5V7Fnp
-0OpL7PNnoxh1fdlTwDJ7zGOUyijTl15dPbAdzSiqm0mYmXms0BzPkubOMbAsiKmu
-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
-Mfoar9/TM+perLNXW3/cOII8+LiNVz8y+Vc=
------END AGE ENCRYPTED FILE-----
diff --git a/modules/by-name/ta/taskwarrior/secrets/public.cert b/modules/by-name/ta/taskwarrior/secrets/public.cert
deleted file mode 100644
index d20ef291..00000000
--- a/modules/by-name/ta/taskwarrior/secrets/public.cert
+++ /dev/null
@@ -1,83 +0,0 @@
------BEGIN AGE ENCRYPTED FILE-----
-YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkQVJNM1RDMEp0NkM1dzlF
-UE42amNBaERmanAyUDNFSlFlUWszb3hiMWtVCllKSml4QVBGT293U3lmaEo2YVVn
-TGdRcllMOFI5WXJsL3ZvdnpIeS9UZjgKLT4gc3NoLWVkMjU1MTkgelpFb25nIEVE
-WnJYU28wdThLWEJlYlpSeDM5eklZR05aR0dpVnN0QjFCU3hueW9NR0UKSXhlV2oy
-b3BWaDQ0K1R2YVZhbjVjZHkyWTQwNGZ6K09QcHJwcFN2S2doRQotPiBzc2gtZWQy
-NTUxOSA3SGZGVXcgemg3dWV3emhNSjdIOVRqYk1mSHdMUnk4bnpBUWZZTkZlY0tG
-aUVkWUt6bwpDRmhKNlU3NGNCQzdNQmsvUndQQ3c2VHRab0h2NDl6MVdlb1BncnRo
-ME1NCi0+ID0tZ3JlYXNlCk9OOVlwMmlONmN1aUNScmNwT3drVHBUc1dqb0FuNUU3
-UWoxNy9SRUp3NDFXRFh6WE0zdUVJMnVCemVkUmtpamcKd3BEb1VtajcxUQotLS0g
-YVo1S1JLQmQrZkIzMmE1YlFCMGlHNElaSXdCR0VBU3pNYS8xSGtFRlpwWQp2we4U
-b9JZk9snxRROCHh9w0nfIDwqGsR8+mFScXDHZAT5pji2nlJncjOToUUf6kqDY3EH
-+UzfvxUZrzF0LZxhlJEApmeo5ObuexQqtm6M4mg8Sx+3XoTHM/07xWB464eKSyGw
-4xBzR0Lj21XUBdfbM3gBAY2J4kvZwPyD0ygun+x+JesJFWgkezh5Vn/oY7bCtgE5
-VjFKR7+kSltBeK7PiqafiukuF/0KRsTDg02FryCCH4nGcjeZeqhs5k2B/56Mxd89
-MD1K/tw4lkvrZ09gLdCN7bY8d72WMQ+Qbilrf5InJsLaUn3dloeyQgJiR9LUkwP0
-b1jZWsUgWOeHfwKUhFoPW4b8VVT8PV3SaLgeoCtoW3ZME+Yv3T7NJZupq57KGcYo
-XgDl8XOG2GjL2UIqp7i7cQFt8KuZxRs2259e8Jf1shyHr34Qw18UpL01++DkZbS3
-f6SucDAbak57CS+qHxLzTqtZT6kLQhfY3yF8QTXcdVC7hMbGNar8TaqIe6SQ1HCT
-HHFRHZ4hj/VVdVlaOLHBvIokFkZE85tTiyjW/llkyfQWH2z+Dwctou6nUBzPgNNF
-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
-dw==
------END AGE ENCRYPTED FILE-----
diff --git a/modules/by-name/ti/timewarrior/module.nix b/modules/by-name/ti/timewarrior/module.nix
new file mode 100644
index 00000000..f33d02be
--- /dev/null
+++ b/modules/by-name/ti/timewarrior/module.nix
@@ -0,0 +1,88 @@
+{
+  config,
+  lib,
+  pkgs,
+  ...
+}: let
+  cfg = config.soispha.programs.timewarrior;
+
+  track_timewarrior = pkgs.stdenv.mkDerivation {
+    name = "track-timewarrior";
+    nativeBuildInputs = [
+      pkgs.makeWrapper
+    ];
+    buildInputs = [
+      pkgs.timewarrior
+      pkgs.taskwarrior3
+      pkgs.python3
+    ];
+    dontUnpack = true;
+    installPhase = ''
+      install -Dm755 ${./taskwarrior_hooks/on-modify.track-timewarrior.py} $out/bin/track-timewarrior
+      wrapProgram $out/bin/track-timewarrior \
+      --set PATH ${lib.makeBinPath [pkgs.taskwarrior3 pkgs.timewarrior]}
+    '';
+
+    meta.mainProgram = "track-timewarrior";
+  };
+  track_total_active_time = pkgs.stdenv.mkDerivation {
+    name = "track-total-active-time";
+    nativeBuildInputs = [
+      pkgs.makeWrapper
+    ];
+    buildInputs = [
+      pkgs.taskwarrior3
+      pkgs.python3
+    ];
+    dontUnpack = true;
+    installPhase = ''
+      install -Dm755 ${./taskwarrior_hooks/on-modify.track-total-active-time.py} $out/bin/track-total-active-time
+      wrapProgram $out/bin/track-total-active-time \
+      --set PATH ${lib.makeBinPath [pkgs.taskwarrior3]}
+    '';
+
+    meta.mainProgram = "track-total-active-time";
+  };
+in {
+  options.soispha.programs.timewarrior = {
+    enable = lib.mkEnableOption "timewarrior";
+  };
+  config = lib.mkIf cfg.enable {
+    soispha.programs.taskwarrior = {
+      hooks = {
+        track-timewarrior = {
+          mode = "on-modify";
+          executable = track_timewarrior;
+        };
+        track-total-active-time = {
+          mode = "on-modify";
+          executable = track_total_active_time;
+        };
+      };
+    };
+
+    home-manager.users.soispha = {
+      home.packages = [
+        pkgs.timewarrior
+      ];
+
+      xdg.configFile."timewarrior/timewarrior.cfg".text = ''
+        # source: https://github.com/arcticicestudio/igloo
+        #+----+
+        #+ UI +
+        #+----+
+        import ${./nord.theme}
+        color = true
+
+        #+---------+
+        #+ Reports +
+        #+---------+
+        define reports:
+          day:
+            lines = 10
+            month = true
+            week = true
+      '';
+    };
+  };
+}
diff --git a/modules/home.legacy/conf/timewarrior/nord.theme b/modules/by-name/ti/timewarrior/nord.theme
index da3c387a..da3c387a 100644
--- a/modules/home.legacy/conf/timewarrior/nord.theme
+++ b/modules/by-name/ti/timewarrior/nord.theme
diff --git a/modules/by-name/ti/timewarrior/taskwarrior_hooks/on-modify.track-timewarrior.py b/modules/by-name/ti/timewarrior/taskwarrior_hooks/on-modify.track-timewarrior.py
new file mode 100755
index 00000000..0bef8bc2
--- /dev/null
+++ b/modules/by-name/ti/timewarrior/taskwarrior_hooks/on-modify.track-timewarrior.py
@@ -0,0 +1,124 @@
+#!/usr/bin/env python3
+
+###############################################################################
+#
+# Copyright 2016 - 2021, 2023, Gothenburg Bit Factory
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+# https://www.opensource.org/licenses/mit-license.php
+#
+###############################################################################
+
+import json
+import subprocess
+import sys
+
+# Hook should extract all the following for use as Timewarrior tags:
+#   UUID
+#   Project
+#   Tags
+#   Description
+#   UDAs
+
+try:
+    input_stream = sys.stdin.buffer
+except AttributeError:
+    input_stream = sys.stdin
+
+
+MAX_ACTIVE = 1
+
+
+def extract_tags_from(json_obj) -> [str]:
+    # Extract attributes for use as tags.
+    tags = [json_obj["description"]]
+
+    if "project" in json_obj:
+        tags.append(json_obj["project"])
+
+    if "tags" in json_obj:
+        if type(json_obj["tags"]) is str:
+            # Usage of tasklib (e.g. in taskpirate) converts the tag list into a string
+            # If this is the case, convert it back into a list first
+            # See https://github.com/tbabej/taskpirate/issues/11
+            tags.extend(json_obj["tags"].split(","))
+        else:
+            tags.extend(json_obj["tags"])
+
+    return tags
+
+
+def extract_annotation_from(json_obj):
+    if "annotations" not in json_obj:
+        return "''"
+
+    return json_obj["annotations"][0]["description"]
+
+
+def main(old, new):
+    start_or_stop = ""
+
+    # Started task.
+    if "start" in new and "start" not in old:
+        # Prevent this task from starting if "task +ACTIVE count" is greater than "MAX_ACTIVE".
+        p = subprocess.Popen(
+            ["task", "+ACTIVE", "status:pending", "count", "rc.verbose:off"],
+            stdout=subprocess.PIPE,
+        )
+        out, err = p.communicate()
+        count = int(out.rstrip())
+        if count >= MAX_ACTIVE:
+            print(
+                f"Only {MAX_ACTIVE} task(s) can be active at a time.",
+            )
+            sys.exit(1)
+        else:
+            start_or_stop = "start"
+
+    # Stopped task.
+    elif ("start" not in new or "end" in new) and "start" in old:
+        start_or_stop = "stop"
+
+    if start_or_stop:
+        tags = extract_tags_from(new)
+
+        subprocess.call(["timew", start_or_stop] + tags + [":yes"])
+
+    # Modifications to task other than start/stop
+    elif "start" in new and "start" in old:
+        old_tags = extract_tags_from(old)
+        new_tags = extract_tags_from(new)
+
+        if old_tags != new_tags:
+            subprocess.call(["timew", "untag", "@1"] + old_tags + [":yes"])
+            subprocess.call(["timew", "tag", "@1"] + new_tags + [":yes"])
+
+        old_annotation = extract_annotation_from(old)
+        new_annotation = extract_annotation_from(new)
+
+        if old_annotation != new_annotation:
+            subprocess.call(["timew", "annotate", "@1", new_annotation])
+
+
+if __name__ == "__main__":
+    old = json.loads(input_stream.readline().decode("utf-8", errors="replace"))
+    new = json.loads(input_stream.readline().decode("utf-8", errors="replace"))
+    print(json.dumps(new))
+    main(old, new)
diff --git a/modules/home.legacy/conf/taskwarrior/hooks/scripts/on-modify_track-total-active-time.py b/modules/by-name/ti/timewarrior/taskwarrior_hooks/on-modify.track-total-active-time.py
index d5b380d0..0b6be082 100755
--- a/modules/home.legacy/conf/taskwarrior/hooks/scripts/on-modify_track-total-active-time.py
+++ b/modules/by-name/ti/timewarrior/taskwarrior_hooks/on-modify.track-total-active-time.py
@@ -20,37 +20,24 @@ By default, this plugin allows to have one task active at a time. This can be ch
 ``1``.
 
 Note:
-    This hook requires Python 3 and the `taskw`_ package to be installed which provides the python bindings for Taskwarrior!
-    Also note that this hook is only compatible with Taskwarrior version greater or equal to 2.4!
+    Note that this hook is only compatible with Taskwarrior version greater or equal to 2.4!
 
 This hook is a fork from `kostajh/taskwarrior-time-tracking-hook`_
 
-.. _taskw:
-   https://pypi.python.org/pypi/taskw
 .. _kostajh/taskwarrior-time-tracking-hook:
    https://github.com/kostajh/taskwarrior-time-tracking-hook
 """
 
 import datetime
 import json
-import re
 import sys
 import subprocess
-from taskw import TaskWarrior
 from typing import TypeVar
 
 TIME_FORMAT = "%Y%m%dT%H%M%SZ"
 UDA_KEY = "total_active_time"
 
-w = TaskWarrior(config_filename=sys.argv[4].replace("rc:", ""))
-config = w.load_config(config_filename=sys.argv[4].replace("rc:", ""))
-if "max_active_tasks" in config:
-    MAX_ACTIVE = int(config["max_active_tasks"])
-else:
-    MAX_ACTIVE = 1
-
-"""Compiled regular expression for the duration as ISO-8601 formatted string."""
-ISO8601DURATION = re.compile("P((\d*)Y)?((\d*)M)?((\d*)D)?T((\d*)H)?((\d*)M)?((\d*)S)?")
+MAX_ACTIVE = 1
 
 """The duration type either as integer (in seconds), as ISO-8601 formatted string ("PT1H10M31S") or the seconds suffixed with "seconds"."""
 DurationType = TypeVar("DurationType", str, int)
@@ -63,31 +50,7 @@ def duration_str_to_time_delta(duration_str: DurationType) -> datetime.timedelta
     :return: The duration as timedelta object
     """
     if duration_str.startswith("P"):
-        match = ISO8601DURATION.match(duration_str)
-        if match:
-            year = match.group(2)
-            month = match.group(4)
-            day = match.group(6)
-            hour = match.group(8)
-            minute = match.group(10)
-            second = match.group(12)
-            value = 0
-            if second:
-                value += int(second)
-            if minute:
-                value += int(minute) * 60
-            if hour:
-                value += int(hour) * 3600
-            if day:
-                value += int(day) * 3600 * 24
-            if month:
-                # Assume a month is 30 days for now.
-                value += int(month) * 3600 * 24 * 30
-            if year:
-                # Assume a year is 365 days for now.
-                value += int(year) * 3600 * 24 * 365
-        else:
-            value = int(duration_str)
+        value = datetime.fromisoformat(duration_str)
     elif duration_str.endswith("seconds"):
         value = int(duration_str.rstrip("seconds"))
     else:
diff --git a/modules/by-name/ts/tskm/module.nix b/modules/by-name/ts/tskm/module.nix
new file mode 100644
index 00000000..51be48fe
--- /dev/null
+++ b/modules/by-name/ts/tskm/module.nix
@@ -0,0 +1,127 @@
+{
+  lib,
+  config,
+  pkgs,
+  ...
+}: let
+  cfg = config.soispha.programs.tskm;
+
+  allProjectNames = lib.lists.flatten (lib.attrsets.mapAttrsToList mkProject cfg.projects);
+
+  projectList = builtins.concatStringsSep "\n" allProjectNames;
+  mkProject = name: value: let
+    subprojects = lib.attrsets.mapAttrsToList (newName: mkProject "${name}.${newName}") value.subprojects;
+  in
+    [name] ++ subprojects;
+
+  firefoxProfiles = builtins.listToAttrs (lib.imap0 (index: name:
+    lib.attrsets.nameValuePair name {
+      inherit name;
+      # Add one here, so that we can have the default profile at id 0.
+      id = index + 1;
+    })
+  allProjectNames);
+
+  contexts =
+    builtins.concatStringsSep "\n"
+    (lib.lists.flatten
+      (lib.attrsets.mapAttrsToList mkContext cfg.projects));
+  mkContext = name: value: let
+    subprojects =
+      lib.attrsets.mapAttrsToList
+      (newName: newValue: let
+        finalValue =
+          if newValue.prefix == ""
+          then newValue // {inherit (value) prefix;}
+          else newValue;
+      in
+        mkContext "${name}.${newName}" finalValue)
+      value.subprojects;
+    contextName = builtins.replaceStrings ["."] ["_"] name;
+  in
+    [
+      ''
+        context.${contextName}.rc.neorg_path=${value.prefix}/index.norg
+        context.${contextName}.read=project:${name}
+        context.${contextName}.write=project:${name}
+      ''
+    ]
+    ++ subprojects;
+
+  contextsFile =
+    pkgs.writeText "contexts-file" contexts;
+
+  projectType = lib.types.submodule {
+    options = {
+      name = lib.mkOption {
+        type = lib.types.str;
+        example = "timesinks";
+        description = "The name of this project";
+      };
+
+      prefix = lib.mkOption {
+        type = lib.types.str;
+        default = "";
+        example = "programming/zig";
+        description = ''
+          A prefix to append to the project neorg path.
+          This can be used to group similar project's neorg directories together. '
+        '';
+      };
+
+      subprojects = lib.mkOption {
+        type = lib.types.attrsOf projectType;
+        description = ''
+          A list of subprojects.
+          These can also contain subprojects.
+        '';
+        default = {};
+      };
+    };
+  };
+in {
+  options.soispha.programs.tskm = {
+    enable = lib.mkEnableOption "tskm";
+
+    projects = lib.mkOption {
+      type = lib.types.attrsOf projectType;
+    };
+  };
+
+  config = lib.mkIf cfg.enable {
+    soispha.programs = {
+      firefox.profiles = firefoxProfiles;
+      taskwarrior = {
+        includeFiles = {
+          tskm-contexts = contextsFile;
+        };
+        hooks = {
+          enforce-projects =
+            config.lib.taskwarrior.mkHook "on-add" [
+              pkgs.jq
+              pkgs.gnugrep
+              pkgs.tskm
+            ]
+            ./taskwarrior_hooks/enforce-projects.sh;
+        };
+      };
+    };
+
+    home-manager.users.soispha = {
+      home.sessionVariables = {
+        # TODO: Remove this hard-coded path with a reference. <2025-04-04>
+        "TSKM_PROJECT_FILE" = "/home/soispha/repos/nix/config/modules/common/projects.json";
+      };
+
+      programs.nixvim = {
+        plugins.neorg.settings.load."core.dirman".config.workspaces = {
+          tskm = "~/.local/share/tskm/notes";
+        };
+      };
+
+      xdg.configFile."tskm/projects.list" = {
+        text = projectList;
+      };
+    };
+  };
+}
diff --git a/modules/by-name/ts/tskm/taskwarrior_hooks/enforce-projects.sh b/modules/by-name/ts/tskm/taskwarrior_hooks/enforce-projects.sh
new file mode 100755
index 00000000..217e6052
--- /dev/null
+++ b/modules/by-name/ts/tskm/taskwarrior_hooks/enforce-projects.sh
@@ -0,0 +1,12 @@
+#!/usr/bin/env sh
+
+new_task="$1"
+
+project="$(echo "$new_task" | jq '.project' --raw-output)"
+[ "$project" = "null" ] && die "No project supplied!"
+
+if ! tskm projects list | grep -q "^$project$"; then
+    die "The project '$project' is not (yet) registered, registered projects: $(tskm projects list | tr '\n' ',')"
+fi
+
+# vim: ft=sh