commit 50825215246f5721e7d6f5e2eff394ceddc223bc Author: KptltD00M Date: Tue Jun 16 23:03:39 2026 +0200 Add new server modules and configurations for various services - Introduced `default-creds` module for managing default credentials with Umami integration. - Added `fail2ban` module for brute-force attack protection with configurable ban times. - Created `firewall` module to enable and configure basic firewall settings. - Implemented `gitea` module for self-hosted Git service with PostgreSQL backend. - Developed `glance` module for a customizable dashboard with various widgets and themes. - Added `iknowyou` module for a self-hosted password manager with production and demo environments. - Introduced `kernel-hardening` module for enhancing kernel security settings. - Created `mazanoke` module for a simple web application with Nginx integration. - Added `mealie` module for a self-hosted meal planning application. - Implemented `stirling-pdf` module for PDF generation service. - Developed `umami` module for self-hosted analytics with secret management. - Added `ssh` module for secure SSH configuration with user restrictions. - Introduced `nixy` theme for a customized aesthetic experience across services. diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..2a645db --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,15 @@ +# These are supported funding model platforms + +github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: anotherhadi +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry +polar: # Replace with a single Polar username +buy_me_a_coffee: # Replace with a single Buy Me a Coffee username +thanks_dev: # Replace with a single thanks.dev username +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/.github/assets/README_template.md b/.github/assets/README_template.md new file mode 100644 index 0000000..d08e74a --- /dev/null +++ b/.github/assets/README_template.md @@ -0,0 +1,134 @@ +
+ nixy logo +
+ +
+ +# Nixy + +
+
+ + + + + + + + + + + + +
+
+ +**Nixy simplifies and unifies** the Hyprland ecosystem with a modular, easily +customizable setup. It provides a structured way to manage your system +configuration and dotfiles with minimal effort. It includes _home-manager_, +_secrets_, and _custom theming_ all in one place. + +**Features:** + +- 💻 Hyprland & Caelestia: Preconfigured Hyprland ecosystem with Caelestia-shell (Ty to both projects!) +- 🎨 Consistent Theming: Base16 & Stylix-powered themes +- ⌨️ Vim-like Everywhere: Unified keybindings (Hyprland, nvim, vimium, etc.) + +## Table of Content + +{md_table_of_content} + +## Screenshots + +![Home](.github/assets/rose-pine/home.png) +![Flake & Spotify](.github/assets/rose-pine/flake-spotify.png) +![Browser and notification center](.github/assets/rose-pine/browser-and-notifications.png) + +## Architecture + +### 🏠 /home (User-level configuration) + +Contains **dotfiles and settings** that apply to your user environment. + +**Subfolders:** + +- `programs` is a collection of apps configured with home-manager +- `system` is some "desktop environment" configuration + +### 🐧 /nixos + +Those are the system-level configurations. (audio, bluetooth, gpu, bootloader, +...) + +### 🎨 /themes + +This folder contains all system themes. Mainly +[stylix](https://stylix.danth.me/) configurations. Check out the available +themes and learn how to create your own in [THEMES.md](docs/THEMES.md) + +### 💻 /hosts + +This directory contains host-specific configurations. Each host includes: + +- `configuration.nix` for system-wide settings +- `home.nix` for user-level configuration +- `variables.nix` for global variables +- `secrets/` for sensitive data + +### 🖥️ /server-modules + +This folder contains server-related nixos modules. (bitwarden, nextcloud, ...) + +## Installation + +1. [Fork](https://github.com/anotherhadi/nixy/fork) this repo and clone it to + your system: + +```sh +git clone https://github.com/anotherhadi/nixy ~/.config/nixos +``` + +2. Copy the `hosts/laptop` folder, rename it to match your system’s hostname, + and update `variables.nix` with your machine’s settings. +3. Copy your `hardware-configuration.nix` into your new host's folder to ensure + proper hardware support. +4. Register your new host in `flake.nix` by adding it under nixosConfigurations. + +> [!IMPORTANT] +> `# CHANGEME` comments are placed throughout the config to +> indicate necessary modifications. Use the following command to quickly locate +> them: +> +> ```sh +> rg "CHANGEME" ~/.config/nixos +> ``` + +> [!TIP] +> When you add new files, don't forget to run `git add .` to add them to the git +> repository + +5. Build the system + +```sh +sudo nixos-rebuild switch --flake ~/.config/nixos#yourhostname +``` + +## Documentation + +- [SERVER](docs/SERVER.md): Check out the server documentation +- [THEMES](docs/THEMES.md): How themes work and how to create your own +- [WALLPAPERS](https://github.com/anotherhadi/awesome-wallpapers): An awesome + collection of wallpapers +- [NEOVIM](docs/NEOVIM.md): How to use the Neovim config in your own flake +- [GROUPS](docs/GROUPS.md): Reusable package groups (dev, cybersecurity) + +- [CONTRIBUTING](docs/CONTRIBUTING.md): How to contribute +- [LICENSE](LICENSE): MIT License + +--- + +
+ github | + gitlab (mirror) | + gitea (mirror) +
"$README_FILE" +echo "$readme_content" >>"$README_FILE" +sed 's/\r//' "$README_FILE" >"/tmp/readme.md" +mv "/tmp/readme.md" "$README_FILE" diff --git a/.github/workflows/update-readme.yml b/.github/workflows/update-readme.yml new file mode 100644 index 0000000..8f2238b --- /dev/null +++ b/.github/workflows/update-readme.yml @@ -0,0 +1,31 @@ +on: + push: + paths: + - '.github/assets/README_template.md' +permissions: + contents: write +jobs: + update-readme: + runs-on: ubuntu-latest + defaults: + run: + working-directory: ./ + steps: + - name: Check out the repository to the runner + uses: actions/checkout@v4 + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: '^1.23' + - name: Install required dependencies + run: | + go install github.com/anotherhadi/markdown-table-of-contents@latest + - name: Run a script + run: | + chmod +x ./.github/scripts/create_readme.sh + ./.github/scripts/create_readme.sh + git config user.name github-actions + git config user.email github-actions@github.com + git add . + git commit -m "Update README.md (auto)" && git push + exit 0 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1be5a96 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.sops.yaml +.claude/ +old/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..7ce7478 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Hadi + +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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..0afe625 --- /dev/null +++ b/README.md @@ -0,0 +1,144 @@ +[//]: # (This file is autogenerated) +
+ nixy logo +
+ +
+ +# Nixy + +
+
+ + + + + + + + + + + + +
+
+ +**Nixy simplifies and unifies** the Hyprland ecosystem with a modular, easily +customizable setup. It provides a structured way to manage your system +configuration and dotfiles with minimal effort. It includes _home-manager_, +_secrets_, and _custom theming_ all in one place. + +**Features:** + +- 💻 Hyprland & Caelestia: Preconfigured Hyprland ecosystem with Caelestia-shell (Ty to both projects!) +- 🎨 Consistent Theming: Base16 & Stylix-powered themes +- ⌨️ Vim-like Everywhere: Unified keybindings (Hyprland, nvim, vimium, etc.) + +## Table of Content + +- [Table of Content](#table-of-content) +- [Screenshots](#screenshots) +- [Architecture](#architecture) + - [🏠 /home (User-level configuration)](#-home-user-level-configuration) + - [🐧 /nixos](#-nixos) + - [🎨 /themes](#-themes) + - [💻 /hosts](#-hosts) + - [🖥️ /server-modules](#-server-modules) +- [Installation](#installation) +- [Documentation](#documentation) + +## Screenshots + +![Home](.github/assets/rose-pine/home.png) +![Flake & Spotify](.github/assets/rose-pine/flake-spotify.png) +![Browser and notification center](.github/assets/rose-pine/browser-and-notifications.png) + +## Architecture + +### 🏠 /home (User-level configuration) + +Contains **dotfiles and settings** that apply to your user environment. + +**Subfolders:** + +- `programs` is a collection of apps configured with home-manager +- `system` is some "desktop environment" configuration + +### 🐧 /nixos + +Those are the system-level configurations. (audio, bluetooth, gpu, bootloader, +...) + +### 🎨 /themes + +This folder contains all system themes. Mainly +[stylix](https://stylix.danth.me/) configurations. Check out the available +themes and learn how to create your own in [THEMES.md](docs/THEMES.md) + +### 💻 /hosts + +This directory contains host-specific configurations. Each host includes: + +- `configuration.nix` for system-wide settings +- `home.nix` for user-level configuration +- `variables.nix` for global variables +- `secrets/` for sensitive data + +### 🖥️ /server-modules + +This folder contains server-related nixos modules. (bitwarden, nextcloud, ...) + +## Installation + +1. [Fork](https://github.com/anotherhadi/nixy/fork) this repo and clone it to + your system: + +```sh +git clone https://github.com/anotherhadi/nixy ~/.config/nixos +``` + +2. Copy the `hosts/laptop` folder, rename it to match your system’s hostname, + and update `variables.nix` with your machine’s settings. +3. Copy your `hardware-configuration.nix` into your new host's folder to ensure + proper hardware support. +4. Register your new host in `flake.nix` by adding it under nixosConfigurations. + +> [!IMPORTANT] +> `# CHANGEME` comments are placed throughout the config to +> indicate necessary modifications. Use the following command to quickly locate +> them: +> +> ```sh +> rg "CHANGEME" ~/.config/nixos +> ``` + +> [!TIP] +> When you add new files, don't forget to run `git add .` to add them to the git +> repository + +5. Build the system + +```sh +sudo nixos-rebuild switch --flake ~/.config/nixos#yourhostname +``` + +## Documentation + +- [SERVER](docs/SERVER.md): Check out the server documentation +- [THEMES](docs/THEMES.md): How themes work and how to create your own +- [WALLPAPERS](https://github.com/anotherhadi/awesome-wallpapers): An awesome + collection of wallpapers +- [NEOVIM](docs/NEOVIM.md): How to use the Neovim config in your own flake +- [GROUPS](docs/GROUPS.md): Reusable package groups (dev, cybersecurity) + +- [CONTRIBUTING](docs/CONTRIBUTING.md): How to contribute +- [LICENSE](LICENSE): MIT License + +--- + +
+ github | + gitlab (mirror) | + gitea (mirror) +
[!TIP] +> To update the README, change the `./.github/assets/README_template.md` + +> [!IMPORTANT] +> Don't push your host's folder diff --git a/docs/GROUPS.md b/docs/GROUPS.md new file mode 100644 index 0000000..a8b6ac4 --- /dev/null +++ b/docs/GROUPS.md @@ -0,0 +1,44 @@ +# Groups + +Groups are curated sets of packages exposed as flake outputs. Each group has two forms: + +- **`homeManagerModules.`** — full home-manager module (packages + files + systemd units) +- **`packages.`** — standalone environment for `nix shell` (packages only) + +## Available groups + +- dev (go, bun, air, ...) +- cybersecurity (nmap, john, dirb, ffuf, ...) + +For the Cybersecurity group, the home-manager module also sets up: + +- `~/Cyber/wordlists/` with SecLists, fuzz4bounty, and hashcat rules +- `~/Cyber/tmp/` as a temporary workspace + +## Use in another flake + +Add this repo as an input: + +```nix +inputs.nixy.url = "github:anotherhadi/nixy"; +``` + +Import the home-manager module in your home configuration: + +```nix +{ inputs, ... }: { + imports = [ + inputs.nixy.homeManagerModules.cybersecurity + # inputs.nixy.homeManagerModules.dev + ]; +} +``` + +## Quick shell without installing + +```sh +nix shell github:anotherhadi/nixy#cybersecurity +nix shell github:anotherhadi/nixy#dev +``` + +This drops you into a shell with all tools in `PATH`. No home-manager required, no wordlists or systemd units. diff --git a/docs/NEOVIM.md b/docs/NEOVIM.md new file mode 100644 index 0000000..fdd46c4 --- /dev/null +++ b/docs/NEOVIM.md @@ -0,0 +1,40 @@ +# Neovim + +The Neovim configuration is built with [nvf](https://github.com/notashelf/nvf) and exposed as a standalone flake output. +It can be used in three ways: run it directly, import it into another flake's home-manager setup, or use it as part of this config. + +## Run directly + +No installation needed: + +```sh +nix run github:anotherhadi/nixy#nvim +``` + +## Use in another flake + +Add this repo as an input: + +```nix +inputs.nixy.url = "github:anotherhadi/nixy"; +``` + +Then import the home-manager module in your home configuration: + +```nix +{ inputs, ... }: { + imports = [ inputs.nixy.homeManagerModules.nvim ]; +} +``` + +## What's included + +| File | Description | +| --------------- | ---------------------------------------------------------------------- | +| `options.nix` | Core settings: theme (catppuccin mocha), clipboard, indentation, folds | +| `languages.nix` | LSP, treesitter, formatters, diagnostics, and per-language config | +| `keymaps.nix` | All key mappings (leader: `space`) | +| `picker.nix` | Snacks picker + oil.nvim | +| `snacks.nix` | Snacks extras: image preview, zen mode, git signs, statuscolumn | +| `utils.nix` | Bufferline, lualine, copilot, lazygit, toggleterm, autocomplete | +| `mini.nix` | Mini.nvim suite: pairs, comment, icons, indentscope, diff, git | diff --git a/docs/SERVER.md b/docs/SERVER.md new file mode 100644 index 0000000..4d4e817 --- /dev/null +++ b/docs/SERVER.md @@ -0,0 +1,29 @@ +# SERVER + +## Overview + +This document describes the architecture and setup of the self-hosted **NixOS server**, which is securely accessible via **a Cloudflare Tunnel**. +The server is designed for private, secure, and easily manageable self-hosting of various services. + +![server dashboard](../.github/assets/server_dashboard.png) + +## **Why This Setup?** + +- **Private & Secure**: Services are only accessible through Cloudflare's access control, preventing exposure to the "public internet". +- **Domain-based Access**: A custom domain maps to the server's tunnel, making service access simple and consistent. +- **Modular & Declarative**: Everything is managed through NixOS modules (except for access control), ensuring reproducibility and easy configuration. + +## **Self-Hosted Services** + +The server hosts several key applications: + +- **NGINX**: Reverse proxy for routing traffic to services via my domain name. +- **AdGuard Home**: A self-hosted DNS ad blocker for network-wide ad and tracker filtering. +- **Glance**: An awesome dashboard! (See the screenshot above) +- **Arr Stack (Radarr, Sonarr, etc.)**: Automated media management tools for handling movies and TV shows. (legaly ofc) +- **Mealie**: A self-hosted recipe manager and meal planner with a clean user interface. +- **Stirling-PDF**: A powerful, locally hosted web application for editing, merging, and converting PDF files. +- **CyberChef**: The "Cyber Swiss Army Knife" for data analysis, decoding, and encryption tasks. +- **Mazanoke**: A utility service for image processing, specialized in format conversion and downgrading/optimization. +- **SSH**: Secure remote access configuration for server management. (via browser too) +- **Security related stuff**: Cloudflared, Fail2Ban, Firewall diff --git a/docs/THEMES.md b/docs/THEMES.md new file mode 100644 index 0000000..06a84fd --- /dev/null +++ b/docs/THEMES.md @@ -0,0 +1,17 @@ +# Themes + +Themes are defined in `themes`. Those themes define the colors, fonts, icons, etc, used by Hyprland and the apps/programs installed. +You can change the selected theme by changing the import statement of your host's variables.nix file. + +## Create your theme + +Create a copy of one of the existing themes and change the variables. +Wallpapers are loaded from the [hadi's awesome-wallpapers](https://github.com/anotherhadi/awesome-wallpapers) repo. + +## Gallery + +### Rose-pine + +![Home](../.github/assets/rose-pine/home.png) +![Flake & Spotify](../.github/assets/rose-pine/flake-spotify.png) +![Browser and notification center](../.github/assets/rose-pine/browser-and-notifications.png) diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..365867f --- /dev/null +++ b/flake.lock @@ -0,0 +1,1931 @@ +{ + "nodes": { + "aquamarine": { + "inputs": { + "hyprutils": [ + "hyprland", + "hyprutils" + ], + "hyprwayland-scanner": [ + "hyprland", + "hyprwayland-scanner" + ], + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1778857089, + "narHash": "sha256-TclWRW2SdFeETLaiTG4BA8C8C4m/LppQEldncqyTzAQ=", + "owner": "hyprwm", + "repo": "aquamarine", + "rev": "ab2b0af63fbc9fb779d684f19149b790978be8a8", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "aquamarine", + "type": "github" + } + }, + "awesome-wallpapers": { + "inputs": { + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1780174698, + "narHash": "sha256-fYHv6Z03ysxIe8saRNYHWi7njWcT7AfPNGNEm5JJIQQ=", + "owner": "anotherhadi", + "repo": "awesome-wallpapers", + "rev": "6edc4aeb12d517e3aaad239e579c89b080f07dab", + "type": "github" + }, + "original": { + "owner": "anotherhadi", + "repo": "awesome-wallpapers", + "type": "github" + } + }, + "base16": { + "inputs": { + "fromYaml": "fromYaml" + }, + "locked": { + "lastModified": 1755819240, + "narHash": "sha256-qcMhnL7aGAuFuutH4rq9fvAhCpJWVHLcHVZLtPctPlo=", + "owner": "SenchoPens", + "repo": "base16.nix", + "rev": "75ed5e5e3fce37df22e49125181fa37899c3ccd6", + "type": "github" + }, + "original": { + "owner": "SenchoPens", + "repo": "base16.nix", + "type": "github" + } + }, + "base16-fish": { + "flake": false, + "locked": { + "lastModified": 1765809053, + "narHash": "sha256-XCUQLoLfBJ8saWms2HCIj4NEN+xNsWBlU1NrEPcQG4s=", + "owner": "tomyun", + "repo": "base16-fish", + "rev": "86cbea4dca62e08fb7fd83a70e96472f92574782", + "type": "github" + }, + "original": { + "owner": "tomyun", + "repo": "base16-fish", + "rev": "86cbea4dca62e08fb7fd83a70e96472f92574782", + "type": "github" + } + }, + "base16-helix": { + "flake": false, + "locked": { + "lastModified": 1776754714, + "narHash": "sha256-E3OAK27smtATTmX45uoTSRsVD+Y+ZiVVfgM/tjpbtYg=", + "owner": "tinted-theming", + "repo": "base16-helix", + "rev": "4d508123037e7851ad36ebf7d9c48b0e9e1eb581", + "type": "github" + }, + "original": { + "owner": "tinted-theming", + "repo": "base16-helix", + "type": "github" + } + }, + "base16-vim": { + "flake": false, + "locked": { + "lastModified": 1732806396, + "narHash": "sha256-e0bpPySdJf0F68Ndanwm+KWHgQiZ0s7liLhvJSWDNsA=", + "owner": "tinted-theming", + "repo": "base16-vim", + "rev": "577fe8125d74ff456cf942c733a85d769afe58b7", + "type": "github" + }, + "original": { + "owner": "tinted-theming", + "repo": "base16-vim", + "rev": "577fe8125d74ff456cf942c733a85d769afe58b7", + "type": "github" + } + }, + "blog": { + "inputs": { + "bun2nix": "bun2nix", + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1780522780, + "narHash": "sha256-1gM3dJtcTx4Bmpi8sg7HSysSY1/Cv+VgdBwwsM/pW1s=", + "owner": "anotherhadi", + "repo": "blog", + "rev": "198112501a57e6a80464357118e4c864f7504d70", + "type": "github" + }, + "original": { + "owner": "anotherhadi", + "repo": "blog", + "type": "github" + } + }, + "bun2nix": { + "inputs": { + "flake-parts": "flake-parts", + "import-tree": "import-tree", + "nixpkgs": [ + "blog", + "nixpkgs" + ], + "systems": "systems", + "treefmt-nix": "treefmt-nix" + }, + "locked": { + "lastModified": 1770895533, + "narHash": "sha256-v3QaK9ugy9bN9RXDnjw0i2OifKmz2NnKM82agtqm/UY=", + "owner": "nix-community", + "repo": "bun2nix", + "rev": "c843f477b15f51151f8c6bcc886954699440a6e1", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "bun2nix", + "type": "github" + } + }, + "bun2nix_2": { + "inputs": { + "flake-parts": "flake-parts_2", + "import-tree": "import-tree_2", + "nixpkgs": [ + "default-creds", + "nixpkgs" + ], + "systems": "systems_2", + "treefmt-nix": "treefmt-nix_2" + }, + "locked": { + "lastModified": 1770895533, + "narHash": "sha256-v3QaK9ugy9bN9RXDnjw0i2OifKmz2NnKM82agtqm/UY=", + "owner": "nix-community", + "repo": "bun2nix", + "rev": "c843f477b15f51151f8c6bcc886954699440a6e1", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "bun2nix", + "type": "github" + } + }, + "bun2nix_3": { + "inputs": { + "flake-parts": "flake-parts_3", + "import-tree": "import-tree_3", + "nixpkgs": [ + "iknowyou", + "nixpkgs" + ], + "systems": "systems_4", + "treefmt-nix": "treefmt-nix_3" + }, + "locked": { + "lastModified": 1770895533, + "narHash": "sha256-v3QaK9ugy9bN9RXDnjw0i2OifKmz2NnKM82agtqm/UY=", + "owner": "nix-community", + "repo": "bun2nix", + "rev": "c843f477b15f51151f8c6bcc886954699440a6e1", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "bun2nix", + "type": "github" + } + }, + "caelestia-cli": { + "inputs": { + "caelestia-shell": "caelestia-shell", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1780375472, + "narHash": "sha256-Q8RAJoYlakA6B2I5DVcuxzNbhCNU1nnIjqQZYP1KGrM=", + "owner": "caelestia-dots", + "repo": "cli", + "rev": "d1c8c8fc09738d1b40576e97c274b4a11a2e0ac7", + "type": "github" + }, + "original": { + "owner": "caelestia-dots", + "repo": "cli", + "type": "github" + } + }, + "caelestia-cli_2": { + "inputs": { + "caelestia-shell": [ + "caelestia-shell" + ], + "nixpkgs": [ + "caelestia-shell", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1779768519, + "narHash": "sha256-2n/447oNfAZrl1yncafLPgXMx5tuTF6T2B+zI/zFYkI=", + "owner": "caelestia-dots", + "repo": "cli", + "rev": "64a5507e74f6c7d0c29f9131964412f8f8c4dd89", + "type": "github" + }, + "original": { + "owner": "caelestia-dots", + "repo": "cli", + "type": "github" + } + }, + "caelestia-shell": { + "inputs": { + "caelestia-cli": [ + "caelestia-cli" + ], + "nixpkgs": [ + "caelestia-cli", + "nixpkgs" + ], + "quickshell": "quickshell" + }, + "locked": { + "lastModified": 1780196414, + "narHash": "sha256-iXmyWULTZuRd68xRL79e9GyYL9FZ6gfh6zl1PPlWX2A=", + "owner": "caelestia-dots", + "repo": "shell", + "rev": "63bb82762bb29ac9b7fcd5b97839abae721ce860", + "type": "github" + }, + "original": { + "owner": "caelestia-dots", + "repo": "shell", + "type": "github" + } + }, + "caelestia-shell_2": { + "inputs": { + "caelestia-cli": "caelestia-cli_2", + "nixpkgs": [ + "nixpkgs" + ], + "quickshell": "quickshell_2" + }, + "locked": { + "lastModified": 1780196414, + "narHash": "sha256-iXmyWULTZuRd68xRL79e9GyYL9FZ6gfh6zl1PPlWX2A=", + "owner": "caelestia-dots", + "repo": "shell", + "rev": "63bb82762bb29ac9b7fcd5b97839abae721ce860", + "type": "github" + }, + "original": { + "owner": "caelestia-dots", + "repo": "shell", + "type": "github" + } + }, + "crane": { + "locked": { + "lastModified": 1779130139, + "narHash": "sha256-BLrtr42azquO7MdGFU5a7KiMl3YpFlTeIXqy1fT5GlQ=", + "owner": "ipetkov", + "repo": "crane", + "rev": "edb38893982a3338972bb4a2ec7ce7c29ba10fd9", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, + "default-creds": { + "inputs": { + "bun2nix": "bun2nix_2", + "nixpkgs": "nixpkgs_3" + }, + "locked": { + "lastModified": 1780323652, + "narHash": "sha256-Ol1ygle0M95z0gOIYGD9WK4gl5xsWi7TvS7IgnK/WJQ=", + "owner": "anotherhadi", + "repo": "default-creds", + "rev": "98b207fe54e07086346f5d77c7a5ec6044e67cca", + "type": "github" + }, + "original": { + "owner": "anotherhadi", + "repo": "default-creds", + "type": "github" + } + }, + "firefox-gnome-theme": { + "flake": false, + "locked": { + "lastModified": 1779670703, + "narHash": "sha256-UdfMivNMwCCqQsYDg5pSz8X2IOaOrIZLIIy+Bg3CO2o=", + "owner": "rafaelmardojai", + "repo": "firefox-gnome-theme", + "rev": "942159e73e40bf785816f7f1f5feed9ef3d7c8f9", + "type": "github" + }, + "original": { + "owner": "rafaelmardojai", + "repo": "firefox-gnome-theme", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1767039857, + "narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=", + "owner": "NixOS", + "repo": "flake-compat", + "rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_2": { + "flake": false, + "locked": { + "lastModified": 1777699697, + "narHash": "sha256-Eg9b/rq/ECYwNwEXs5i9wHyhxNI0JrYx2srdI2uZMaQ=", + "ref": "refs/heads/main", + "rev": "382052b74656a369c5408822af3f2501e9b1af81", + "revCount": 94, + "type": "git", + "url": "https://git.lix.systems/lix-project/flake-compat.git" + }, + "original": { + "type": "git", + "url": "https://git.lix.systems/lix-project/flake-compat.git" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1769996383, + "narHash": "sha256-AnYjnFWgS49RlqX7LrC4uA+sCCDBj0Ry/WOJ5XWAsa0=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "57928607ea566b5db3ad13af0e57e921e6b12381", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_2": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib_2" + }, + "locked": { + "lastModified": 1769996383, + "narHash": "sha256-AnYjnFWgS49RlqX7LrC4uA+sCCDBj0Ry/WOJ5XWAsa0=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "57928607ea566b5db3ad13af0e57e921e6b12381", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_3": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib_3" + }, + "locked": { + "lastModified": 1769996383, + "narHash": "sha256-AnYjnFWgS49RlqX7LrC4uA+sCCDBj0Ry/WOJ5XWAsa0=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "57928607ea566b5db3ad13af0e57e921e6b12381", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_4": { + "inputs": { + "nixpkgs-lib": [ + "nvf", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1778716662, + "narHash": "sha256-m1Yf0wZ8j1OHjTc2UwHwyQRSnNeSgLJOd7q5Y45hzi4=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "f7c1a2d347e4c52d5fb8d10cb4d94b5884e546fb", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_5": { + "inputs": { + "nixpkgs-lib": [ + "stylix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1778716662, + "narHash": "sha256-m1Yf0wZ8j1OHjTc2UwHwyQRSnNeSgLJOd7q5Y45hzi4=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "f7c1a2d347e4c52d5fb8d10cb4d94b5884e546fb", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "fromYaml": { + "flake": false, + "locked": { + "lastModified": 1731966426, + "narHash": "sha256-lq95WydhbUTWig/JpqiB7oViTcHFP8Lv41IGtayokA8=", + "owner": "SenchoPens", + "repo": "fromYaml", + "rev": "106af9e2f715e2d828df706c386a685698f3223b", + "type": "github" + }, + "original": { + "owner": "SenchoPens", + "repo": "fromYaml", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "hyprland", + "pre-commit-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709087332, + "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "gnome-shell": { + "flake": false, + "locked": { + "lastModified": 1767737596, + "narHash": "sha256-eFujfIUQDgWnSJBablOuG+32hCai192yRdrNHTv0a+s=", + "owner": "GNOME", + "repo": "gnome-shell", + "rev": "ef02db02bf0ff342734d525b5767814770d85b49", + "type": "github" + }, + "original": { + "owner": "GNOME", + "repo": "gnome-shell", + "rev": "ef02db02bf0ff342734d525b5767814770d85b49", + "type": "github" + } + }, + "helium-browser": { + "inputs": { + "nixpkgs": "nixpkgs_4" + }, + "locked": { + "lastModified": 1780054154, + "narHash": "sha256-VbHwck8XGyZ77uHfY9adqE0qrilRshWUdFwB6etEIt4=", + "owner": "oxcl", + "repo": "nix-flake-helium-browser", + "rev": "47e435ce0b81c012683bd2b1a4101285e1f46183", + "type": "github" + }, + "original": { + "owner": "oxcl", + "repo": "nix-flake-helium-browser", + "type": "github" + } + }, + "home-manager": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1780593650, + "narHash": "sha256-CHo7k65YTL3HY+WQVedDTupji+LMgNlKCdrtRHZFAK4=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "447fd9ff62501dae7206dfe180ee89f8de27b7d5", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, + "hyprcursor": { + "inputs": { + "hyprlang": [ + "hyprland", + "hyprlang" + ], + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1776511930, + "narHash": "sha256-fCpwFiTW0rT7oKJqr3cqHMnkwypSwQKpbtUEtxdkgrM=", + "owner": "hyprwm", + "repo": "hyprcursor", + "rev": "39435900785d0c560c6ae8777d29f28617d031ef", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprcursor", + "type": "github" + } + }, + "hyprgraphics": { + "inputs": { + "hyprutils": [ + "hyprland", + "hyprutils" + ], + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1776426399, + "narHash": "sha256-RUESLKNikIeEq9ymGJ6nmcDXiSFQpUW1IhJ245nL3xM=", + "owner": "hyprwm", + "repo": "hyprgraphics", + "rev": "68d064434787cf1ed4a2fe257c03c5f52f33cf84", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprgraphics", + "type": "github" + } + }, + "hyprland": { + "inputs": { + "aquamarine": "aquamarine", + "hyprcursor": "hyprcursor", + "hyprgraphics": "hyprgraphics", + "hyprland-guiutils": "hyprland-guiutils", + "hyprland-protocols": "hyprland-protocols", + "hyprlang": "hyprlang", + "hyprutils": "hyprutils", + "hyprwayland-scanner": "hyprwayland-scanner", + "hyprwire": "hyprwire", + "nixpkgs": "nixpkgs_5", + "pre-commit-hooks": "pre-commit-hooks", + "systems": "systems_3", + "xdph": "xdph" + }, + "locked": { + "lastModified": 1780589398, + "narHash": "sha256-TTSRAf2EIP6Wy3aiaXhfj2qDtCuO/hN7PWVEEufNSiU=", + "ref": "refs/heads/main", + "rev": "7c721d5c012752fd8719d66ef59d290845d6638e", + "revCount": 7417, + "submodules": true, + "type": "git", + "url": "https://github.com/hyprwm/Hyprland" + }, + "original": { + "submodules": true, + "type": "git", + "url": "https://github.com/hyprwm/Hyprland" + } + }, + "hyprland-guiutils": { + "inputs": { + "aquamarine": [ + "hyprland", + "aquamarine" + ], + "hyprgraphics": [ + "hyprland", + "hyprgraphics" + ], + "hyprlang": [ + "hyprland", + "hyprlang" + ], + "hyprtoolkit": "hyprtoolkit", + "hyprutils": [ + "hyprland", + "hyprutils" + ], + "hyprwayland-scanner": [ + "hyprland", + "hyprwayland-scanner" + ], + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1776426575, + "narHash": "sha256-KI6nIfVihn/DPaeB5Et46Xg3dkNHrrEtUd5LBBVomB0=", + "owner": "hyprwm", + "repo": "hyprland-guiutils", + "rev": "a968d211048e3ed538e47b84cb3649299578f19d", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprland-guiutils", + "type": "github" + } + }, + "hyprland-protocols": { + "inputs": { + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1772460177, + "narHash": "sha256-/6G/MsPvtn7bc4Y32pserBT/Z4SUUdBd4XYJpOEKVR4=", + "owner": "hyprwm", + "repo": "hyprland-protocols", + "rev": "1cb6db5fd6bb8aee419f4457402fa18293ace917", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprland-protocols", + "type": "github" + } + }, + "hyprlang": { + "inputs": { + "hyprutils": [ + "hyprland", + "hyprutils" + ], + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1777320127, + "narHash": "sha256-Qu+Wf2Bp5qUjyn2YpZNq8a7JyzTGowhT1knrwE38a9U=", + "owner": "hyprwm", + "repo": "hyprlang", + "rev": "090117506ddc3d7f26e650ff344d378c2ec329cc", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprlang", + "type": "github" + } + }, + "hyprtoolkit": { + "inputs": { + "aquamarine": [ + "hyprland", + "hyprland-guiutils", + "aquamarine" + ], + "hyprgraphics": [ + "hyprland", + "hyprland-guiutils", + "hyprgraphics" + ], + "hyprlang": [ + "hyprland", + "hyprland-guiutils", + "hyprlang" + ], + "hyprutils": [ + "hyprland", + "hyprland-guiutils", + "hyprutils" + ], + "hyprwayland-scanner": [ + "hyprland", + "hyprland-guiutils", + "hyprwayland-scanner" + ], + "nixpkgs": [ + "hyprland", + "hyprland-guiutils", + "nixpkgs" + ], + "systems": [ + "hyprland", + "hyprland-guiutils", + "systems" + ] + }, + "locked": { + "lastModified": 1772462885, + "narHash": "sha256-5pHXrQK9zasMnIo6yME6EOXmWGFMSnCITcfKshhKJ9I=", + "owner": "hyprwm", + "repo": "hyprtoolkit", + "rev": "9af245a69fa6b286b88ddfc340afd288e00a6998", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprtoolkit", + "type": "github" + } + }, + "hyprutils": { + "inputs": { + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1779475241, + "narHash": "sha256-Nw4DN0A5krWNcPBvuWe5Gz2yuxsUUPiDgtu6SVPJQeU=", + "owner": "hyprwm", + "repo": "hyprutils", + "rev": "3cd3972b2ee658a14d2610d8494e09259e530124", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprutils", + "type": "github" + } + }, + "hyprwayland-scanner": { + "inputs": { + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1777159683, + "narHash": "sha256-Jxixw6wZphUp+nHYxOKUYSckL17QMBx2d5Zp0rJHr1g=", + "owner": "hyprwm", + "repo": "hyprwayland-scanner", + "rev": "b8632713a6beaf28b56f2a7b0ab2fb7088dbb404", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprwayland-scanner", + "type": "github" + } + }, + "hyprwire": { + "inputs": { + "hyprutils": [ + "hyprland", + "hyprutils" + ], + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1778410714, + "narHash": "sha256-o6RzFj4nJXaPRY7EM01siuCQeT41RfwwmcmFQqwFJJg=", + "owner": "hyprwm", + "repo": "hyprwire", + "rev": "85148a8e612808cf5ddb25d0b3c5840f3498a7dc", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprwire", + "type": "github" + } + }, + "iknowyou": { + "inputs": { + "bun2nix": "bun2nix_3", + "nixpkgs": "nixpkgs_6", + "nur-osint": "nur-osint" + }, + "locked": { + "lastModified": 1779949739, + "narHash": "sha256-axo7EprQSm8yYL4P6Ye9EZGEz/bdh8HHkmBlRIQzzvM=", + "owner": "anotherhadi", + "repo": "iknowyou", + "rev": "bb778b43747b7e703e2c311a898198c4a89ac12a", + "type": "github" + }, + "original": { + "owner": "anotherhadi", + "repo": "iknowyou", + "type": "github" + } + }, + "import-tree": { + "locked": { + "lastModified": 1763762820, + "narHash": "sha256-ZvYKbFib3AEwiNMLsejb/CWs/OL/srFQ8AogkebEPF0=", + "owner": "vic", + "repo": "import-tree", + "rev": "3c23749d8013ec6daa1d7255057590e9ca726646", + "type": "github" + }, + "original": { + "owner": "vic", + "repo": "import-tree", + "type": "github" + } + }, + "import-tree_2": { + "locked": { + "lastModified": 1763762820, + "narHash": "sha256-ZvYKbFib3AEwiNMLsejb/CWs/OL/srFQ8AogkebEPF0=", + "owner": "vic", + "repo": "import-tree", + "rev": "3c23749d8013ec6daa1d7255057590e9ca726646", + "type": "github" + }, + "original": { + "owner": "vic", + "repo": "import-tree", + "type": "github" + } + }, + "import-tree_3": { + "locked": { + "lastModified": 1763762820, + "narHash": "sha256-ZvYKbFib3AEwiNMLsejb/CWs/OL/srFQ8AogkebEPF0=", + "owner": "vic", + "repo": "import-tree", + "rev": "3c23749d8013ec6daa1d7255057590e9ca726646", + "type": "github" + }, + "original": { + "owner": "vic", + "repo": "import-tree", + "type": "github" + } + }, + "mnw": { + "locked": { + "lastModified": 1778541201, + "narHash": "sha256-n0twkzWexzjsoDycOTvvQNuGEdg62UiNHYcFCduYpKI=", + "owner": "Gerg-L", + "repo": "mnw", + "rev": "1a3573fc9d2486738fe0b2cacc5cd10dd5f3a445", + "type": "github" + }, + "original": { + "owner": "Gerg-L", + "repo": "mnw", + "type": "github" + } + }, + "ndg": { + "inputs": { + "nixpkgs": [ + "nvf", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1779233504, + "narHash": "sha256-YIKEyzh0NFQlD0O92LQQNMoVCDwV8yw1Xz0Iu+4ZC5U=", + "owner": "feel-co", + "repo": "ndg", + "rev": "86f6644411a64d5413711895b7cf6e0e1be465b6", + "type": "github" + }, + "original": { + "owner": "feel-co", + "ref": "refs/tags/v2.8.0", + "repo": "ndg", + "type": "github" + } + }, + "nix-index-database": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1780210899, + "narHash": "sha256-4axz3OBPTKa6LIkXV8n0lc63MQU+et2CB5DGobEAi6k=", + "owner": "nix-community", + "repo": "nix-index-database", + "rev": "97df9dc0b7c924344b793a15c1e8e4522ebb854e", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nix-index-database", + "type": "github" + } + }, + "nixarr": { + "inputs": { + "nixpkgs": "nixpkgs_7", + "treefmt-nix": "treefmt-nix_4", + "vpnconfinement": "vpnconfinement", + "website-builder": "website-builder" + }, + "locked": { + "lastModified": 1780503763, + "narHash": "sha256-e2PD1oowOjebEAaWsiQ9g0FQA9OYaUWj7vLwUvDE6EM=", + "owner": "rasmus-kirk", + "repo": "nixarr", + "rev": "6c1eb23334e06bd3fd8d3d8782c64e5c3ac13097", + "type": "github" + }, + "original": { + "owner": "rasmus-kirk", + "repo": "nixarr", + "type": "github" + } + }, + "nixos-hardware": { + "inputs": { + "nixpkgs": "nixpkgs_8" + }, + "locked": { + "lastModified": 1780310866, + "narHash": "sha256-fPBRVf6A5xlACYcOI59shGrjURuvwu0lRsDoSCEXt/I=", + "owner": "NixOS", + "repo": "nixos-hardware", + "rev": "4ed851c979641e28597a05086332d75cdc9e395f", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "master", + "repo": "nixos-hardware", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1774106199, + "narHash": "sha256-US5Tda2sKmjrg2lNHQL3jRQ6p96cgfWh3J1QBliQ8Ws=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "6c9a78c09ff4d6c21d0319114873508a6ec01655", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "lastModified": 1769909678, + "narHash": "sha256-cBEymOf4/o3FD5AZnzC3J9hLbiZ+QDT/KDuyHXVJOpM=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "72716169fe93074c333e8d0173151350670b824c", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" + } + }, + "nixpkgs-lib_2": { + "locked": { + "lastModified": 1769909678, + "narHash": "sha256-cBEymOf4/o3FD5AZnzC3J9hLbiZ+QDT/KDuyHXVJOpM=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "72716169fe93074c333e8d0173151350670b824c", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" + } + }, + "nixpkgs-lib_3": { + "locked": { + "lastModified": 1769909678, + "narHash": "sha256-cBEymOf4/o3FD5AZnzC3J9hLbiZ+QDT/KDuyHXVJOpM=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "72716169fe93074c333e8d0173151350670b824c", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" + } + }, + "nixpkgs-stable": { + "locked": { + "lastModified": 1779796641, + "narHash": "sha256-ZsIrKmhp4vbBXoXXmR/tBXA/UCsAQiJL9vsgZEduhVY=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "25f538306313eae3927264466c70d7001dcea1df", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-25.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_10": { + "locked": { + "lastModified": 1778869304, + "narHash": "sha256-30sZNZoA1cqF5JNO9fVX+wgiQYjB7HJqqJ4ztCDeBZE=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "d233902339c02a9c334e7e593de68855ad26c4cb", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_11": { + "locked": { + "lastModified": 1780749050, + "narHash": "sha256-3av0pIjlOWQ6rDbNOmpUSvbNnJkGORQKKjb4LtCZsIY=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "a799d3e3886da994fa307f817a6bc705ae538eeb", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_12": { + "locked": { + "lastModified": 1778869304, + "narHash": "sha256-30sZNZoA1cqF5JNO9fVX+wgiQYjB7HJqqJ4ztCDeBZE=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "d233902339c02a9c334e7e593de68855ad26c4cb", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_13": { + "locked": { + "lastModified": 1775888245, + "narHash": "sha256-nwASzrRDD1JBEu/o8ekKYEXm/oJW6EMCzCRdrwcLe90=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "13043924aaa7375ce482ebe2494338e058282925", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_14": { + "locked": { + "lastModified": 1780243769, + "narHash": "sha256-x5UQuRsH3MqI0U9afaXSNqzTPSeZlRLvFAav2Ux1pNw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "331800de5053fcebacf6813adb5db9c9dca22a0c", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1776548001, + "narHash": "sha256-ZSK0NL4a1BwVbbTBoSnWgbJy9HeZFXLYQizjb2DPF24=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "b12141ef619e0a9c1c84dc8c684040326f27cdcc", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1772773019, + "narHash": "sha256-E1bxHxNKfDoQUuvriG71+f+s/NT0qWkImXsYZNFFfCs=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "aca4d95fce4914b3892661bcb80b8087293536c6", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_4": { + "locked": { + "lastModified": 1777578337, + "narHash": "sha256-Ad49moKWeXtKBJNy2ebiTQUEgdLyvGmTeykAQ9xM+Z4=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "15f4ee454b1dce334612fa6843b3e05cf546efab", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_5": { + "locked": { + "lastModified": 1779357205, + "narHash": "sha256-cCO8aTqss5x9Ky8GWkpY0Hy5fyTZEbtifSUV8QjSzic=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "f83fc3c307e74bc5fd5adb7eb6b8b13ffd2a36e1", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_6": { + "locked": { + "lastModified": 1775710090, + "narHash": "sha256-ar3rofg+awPB8QXDaFJhJ2jJhu+KqN/PRCXeyuXR76E=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "4c1018dae018162ec878d42fec712642d214fdfa", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_7": { + "locked": { + "lastModified": 1775595990, + "narHash": "sha256-OEf7YqhF9IjJFYZJyuhAypgU+VsRB5lD4DuiMws5Ltc=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "4e92bbcdb030f3b4782be4751dc08e6b6cb6ccf2", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-25.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_8": { + "locked": { + "lastModified": 1767892417, + "narHash": "sha256-8bW3q88CEg2u4hSP66Vf4lpbLonHz7hqDNBMcCY7E9U=", + "rev": "3497aa5c9457a9d88d71fa93a4a8368816fbeeba", + "type": "tarball", + "url": "https://releases.nixos.org/nixos/unstable/nixos-26.05pre924538.3497aa5c9457/nixexprs.tar.xz" + }, + "original": { + "type": "tarball", + "url": "https://channels.nixos.org/nixos-unstable/nixexprs.tar.xz" + } + }, + "nixpkgs_9": { + "locked": { + "lastModified": 1780243769, + "narHash": "sha256-x5UQuRsH3MqI0U9afaXSNqzTPSeZlRLvFAav2Ux1pNw=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "331800de5053fcebacf6813adb5db9c9dca22a0c", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "notashelf-tuigreet": { + "inputs": { + "crane": "crane", + "nixpkgs": "nixpkgs_10", + "rust-overlay": "rust-overlay" + }, + "locked": { + "lastModified": 1780583973, + "narHash": "sha256-ZZk1ccebBjK3pzHVsDU4+fvX/c1fePZ3Tic96/OkfpA=", + "owner": "NotAShelf", + "repo": "tuigreet", + "rev": "dc41006d4a4366f732a1a75a20b989fc1e42c0a6", + "type": "github" + }, + "original": { + "owner": "NotAShelf", + "repo": "tuigreet", + "type": "github" + } + }, + "nur": { + "inputs": { + "flake-parts": [ + "stylix", + "flake-parts" + ], + "nixpkgs": [ + "stylix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1780281641, + "narHash": "sha256-M/+hUKoKbHXpV0xGVfELbN1Ds1aoe3pL5p5/t46YhVo=", + "owner": "nix-community", + "repo": "NUR", + "rev": "30f9ae2f04174de63ba8bcf3580ca90843b28a01", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "NUR", + "type": "github" + } + }, + "nur-anotherhadi": { + "inputs": { + "nixpkgs": "nixpkgs_11" + }, + "locked": { + "lastModified": 1781028989, + "narHash": "sha256-wN9iKLIUrD1xOTKB2GXsTBlXYsByL/Tk0hk/KPh0/vw=", + "owner": "anotherhadi", + "repo": "nur-packages", + "rev": "afedd9b527fc7f0e418e6384fa581d8bb7564675", + "type": "github" + }, + "original": { + "owner": "anotherhadi", + "repo": "nur-packages", + "type": "github" + } + }, + "nur-osint": { + "inputs": { + "nixpkgs": [ + "iknowyou", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1775935554, + "narHash": "sha256-7StMiQf3HSBruAxZ2/ZYJhhNEp1KbglGVijQBrurqiM=", + "owner": "anotherhadi", + "repo": "nur-osint", + "rev": "460e377522a43d3d968be20bec2cf40a72013904", + "type": "github" + }, + "original": { + "owner": "anotherhadi", + "repo": "nur-osint", + "type": "github" + } + }, + "nvf": { + "inputs": { + "flake-compat": "flake-compat_2", + "flake-parts": "flake-parts_4", + "mnw": "mnw", + "ndg": "ndg", + "nixpkgs": "nixpkgs_12", + "systems": "systems_5" + }, + "locked": { + "lastModified": 1780511420, + "narHash": "sha256-Ib44d47GTijSfCtcxFDliP3C9uUiLDYaAE/nVH8TQoY=", + "owner": "notashelf", + "repo": "nvf", + "rev": "29f7eb8491d9833ee55006ab11169130a60c2652", + "type": "github" + }, + "original": { + "owner": "notashelf", + "repo": "nvf", + "type": "github" + } + }, + "pre-commit-hooks": { + "inputs": { + "flake-compat": "flake-compat", + "gitignore": "gitignore", + "nixpkgs": [ + "hyprland", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1778507602, + "narHash": "sha256-kTwur1wV+01SdqskVMSo6JMEpg71ps3HpbFY2GsflKs=", + "owner": "cachix", + "repo": "git-hooks.nix", + "rev": "61ab0e80d9c7ab14c256b5b453d8b3fb0189ba0a", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "git-hooks.nix", + "type": "github" + } + }, + "quickshell": { + "inputs": { + "nixpkgs": [ + "caelestia-cli", + "caelestia-shell", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1779430452, + "narHash": "sha256-zTslhsxLqUlRTML506iougTGzyR38Fzhzn7t4KDEuuE=", + "ref": "refs/heads/master", + "rev": "4b4fca3224ab977dc515ac0bb78d00b3dfa71e00", + "revCount": 819, + "type": "git", + "url": "https://git.outfoxxed.me/outfoxxed/quickshell" + }, + "original": { + "type": "git", + "url": "https://git.outfoxxed.me/outfoxxed/quickshell" + } + }, + "quickshell_2": { + "inputs": { + "nixpkgs": [ + "caelestia-shell", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1779430452, + "narHash": "sha256-zTslhsxLqUlRTML506iougTGzyR38Fzhzn7t4KDEuuE=", + "ref": "refs/heads/master", + "rev": "4b4fca3224ab977dc515ac0bb78d00b3dfa71e00", + "revCount": 819, + "type": "git", + "url": "https://git.outfoxxed.me/outfoxxed/quickshell" + }, + "original": { + "type": "git", + "url": "https://git.outfoxxed.me/outfoxxed/quickshell" + } + }, + "root": { + "inputs": { + "awesome-wallpapers": "awesome-wallpapers", + "blog": "blog", + "caelestia-cli": "caelestia-cli", + "caelestia-shell": "caelestia-shell_2", + "default-creds": "default-creds", + "helium-browser": "helium-browser", + "home-manager": "home-manager", + "hyprland": "hyprland", + "iknowyou": "iknowyou", + "nix-index-database": "nix-index-database", + "nixarr": "nixarr", + "nixos-hardware": "nixos-hardware", + "nixpkgs": "nixpkgs_9", + "nixpkgs-stable": "nixpkgs-stable", + "notashelf-tuigreet": "notashelf-tuigreet", + "nur-anotherhadi": "nur-anotherhadi", + "nvf": "nvf", + "sops-nix": "sops-nix", + "stylix": "stylix" + } + }, + "rust-overlay": { + "inputs": { + "nixpkgs": [ + "notashelf-tuigreet", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1778555852, + "narHash": "sha256-55EmwooVAS4UpA0oWd5wilKPRqCiHD5BAej9QiNwheY=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "f29b0f7a9f367e0056b716f8aa137cb41e784444", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "sops-nix": { + "inputs": { + "nixpkgs": "nixpkgs_13" + }, + "locked": { + "lastModified": 1780547341, + "narHash": "sha256-Gq8KNx5A7hBB3uGJaj6eQfLDIz5YdLu92gqBcvHvoUo=", + "owner": "Mic92", + "repo": "sops-nix", + "rev": "9ed65852b6257fbeae4355bc24ecfea307ca759a", + "type": "github" + }, + "original": { + "owner": "Mic92", + "repo": "sops-nix", + "type": "github" + } + }, + "stylix": { + "inputs": { + "base16": "base16", + "base16-fish": "base16-fish", + "base16-helix": "base16-helix", + "base16-vim": "base16-vim", + "firefox-gnome-theme": "firefox-gnome-theme", + "flake-parts": "flake-parts_5", + "gnome-shell": "gnome-shell", + "nixpkgs": "nixpkgs_14", + "nur": "nur", + "systems": "systems_6", + "tinted-kitty": "tinted-kitty", + "tinted-schemes": "tinted-schemes", + "tinted-tmux": "tinted-tmux", + "tinted-zed": "tinted-zed" + }, + "locked": { + "lastModified": 1780584783, + "narHash": "sha256-b4o1AlQpGgpUfieaNz/3gsSzogjoiczmnlbDj0khImY=", + "owner": "danth", + "repo": "stylix", + "rev": "6b6b874d082928aa9557e21516d4fe2f2bb305e1", + "type": "github" + }, + "original": { + "owner": "danth", + "repo": "stylix", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_3": { + "locked": { + "lastModified": 1689347949, + "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=", + "owner": "nix-systems", + "repo": "default-linux", + "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default-linux", + "type": "github" + } + }, + "systems_4": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_5": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_6": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "tinted-kitty": { + "flake": false, + "locked": { + "lastModified": 1735730497, + "narHash": "sha256-4KtB+FiUzIeK/4aHCKce3V9HwRvYaxX+F1edUrfgzb8=", + "owner": "tinted-theming", + "repo": "tinted-kitty", + "rev": "de6f888497f2c6b2279361bfc790f164bfd0f3fa", + "type": "github" + }, + "original": { + "owner": "tinted-theming", + "repo": "tinted-kitty", + "type": "github" + } + }, + "tinted-schemes": { + "flake": false, + "locked": { + "lastModified": 1777806186, + "narHash": "sha256-PDF0/wObw4nIsSBeXVYLsloXOiphXCgIdsrNcVXguKs=", + "owner": "tinted-theming", + "repo": "schemes", + "rev": "0c94645546f4f3ddac77a1a5fce54eb95bf50795", + "type": "github" + }, + "original": { + "owner": "tinted-theming", + "repo": "schemes", + "type": "github" + } + }, + "tinted-tmux": { + "flake": false, + "locked": { + "lastModified": 1778379944, + "narHash": "sha256-wPDFzMGSlARlw0Sfsn48Q2+jPSfk6N0Ng6BC/d+7Q24=", + "owner": "tinted-theming", + "repo": "tinted-tmux", + "rev": "fe0203a198690e71a5ff11e08812a4673de3678d", + "type": "github" + }, + "original": { + "owner": "tinted-theming", + "repo": "tinted-tmux", + "type": "github" + } + }, + "tinted-zed": { + "flake": false, + "locked": { + "lastModified": 1778378178, + "narHash": "sha256-OXPXRIQgGwV77HjYRryOHguh4ALX96jkg+tseLkGgHA=", + "owner": "tinted-theming", + "repo": "base16-zed", + "rev": "9cd816033ff969415b190722cddf134e78a5665f", + "type": "github" + }, + "original": { + "owner": "tinted-theming", + "repo": "base16-zed", + "type": "github" + } + }, + "treefmt-nix": { + "inputs": { + "nixpkgs": [ + "blog", + "bun2nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1770228511, + "narHash": "sha256-wQ6NJSuFqAEmIg2VMnLdCnUc0b7vslUohqqGGD+Fyxk=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "337a4fe074be1042a35086f15481d763b8ddc0e7", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + }, + "treefmt-nix_2": { + "inputs": { + "nixpkgs": [ + "default-creds", + "bun2nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1770228511, + "narHash": "sha256-wQ6NJSuFqAEmIg2VMnLdCnUc0b7vslUohqqGGD+Fyxk=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "337a4fe074be1042a35086f15481d763b8ddc0e7", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + }, + "treefmt-nix_3": { + "inputs": { + "nixpkgs": [ + "iknowyou", + "bun2nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1770228511, + "narHash": "sha256-wQ6NJSuFqAEmIg2VMnLdCnUc0b7vslUohqqGGD+Fyxk=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "337a4fe074be1042a35086f15481d763b8ddc0e7", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + }, + "treefmt-nix_4": { + "inputs": { + "nixpkgs": [ + "nixarr", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1775125835, + "narHash": "sha256-2qYcPgzFhnQWchHo0SlqLHrXpux5i6ay6UHA+v2iH4U=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "75925962939880974e3ab417879daffcba36c4a3", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + }, + "vpnconfinement": { + "locked": { + "lastModified": 1767604552, + "narHash": "sha256-FddhMxnc99KYOZ/S3YNqtDSoxisIhVtJ7L4s8XD2u0A=", + "owner": "Maroka-chan", + "repo": "VPN-Confinement", + "rev": "a6b2da727853886876fd1081d6bb2880752937f3", + "type": "github" + }, + "original": { + "owner": "Maroka-chan", + "repo": "VPN-Confinement", + "type": "github" + } + }, + "website-builder": { + "inputs": { + "nixpkgs": [ + "nixarr", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1771957511, + "narHash": "sha256-MxpsyVQguwmeN40gblvcYLtL4xiriGYB6UyP+JergpQ=", + "owner": "rasmus-kirk", + "repo": "website-builder", + "rev": "896af41c1a01f934799356f1f51cfddff2abda82", + "type": "github" + }, + "original": { + "owner": "rasmus-kirk", + "repo": "website-builder", + "type": "github" + } + }, + "xdph": { + "inputs": { + "hyprland-protocols": [ + "hyprland", + "hyprland-protocols" + ], + "hyprlang": [ + "hyprland", + "hyprlang" + ], + "hyprutils": [ + "hyprland", + "hyprutils" + ], + "hyprwayland-scanner": [ + "hyprland", + "hyprwayland-scanner" + ], + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1778265244, + "narHash": "sha256-8jlPtGSsv/CQY6tVVyLF4Jjd0gnS+Zbn9yk/V13A9nM=", + "owner": "hyprwm", + "repo": "xdg-desktop-portal-hyprland", + "rev": "813ea5ca9a1702a9a2d1f5836bc00172ef698968", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "xdg-desktop-portal-hyprland", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..a35bc0a --- /dev/null +++ b/flake.nix @@ -0,0 +1,77 @@ +{ + # https://github.com/anotherhadi/nixy + description = '' + Nixy simplifies and unifies the Hyprland ecosystem with a modular, easily customizable setup. + It provides a structured way to manage your system configuration and dotfiles with minimal effort. + ''; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-25.11"; + nixos-hardware.url = "github:NixOS/nixos-hardware/master"; + hyprland.url = "git+https://github.com/hyprwm/Hyprland?submodules=1"; + stylix.url = "github:danth/stylix"; + sops-nix.url = "github:Mic92/sops-nix"; + nvf.url = "github:notashelf/nvf"; + notashelf-tuigreet.url = "github:NotAShelf/tuigreet"; + helium-browser.url = "github:oxcl/nix-flake-helium-browser"; + nur-anotherhadi.url = "github:anotherhadi/nur-packages"; + + nix-index-database = { + url = "github:nix-community/nix-index-database"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + home-manager = { + url = "github:nix-community/home-manager"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + caelestia-shell = { + url = "github:caelestia-dots/shell"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + caelestia-cli = { + url = "github:caelestia-dots/cli"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + # Server + nixarr.url = "github:rasmus-kirk/nixarr"; + default-creds.url = "github:anotherhadi/default-creds"; + blog.url = "github:anotherhadi/blog"; + awesome-wallpapers.url = "github:anotherhadi/awesome-wallpapers"; + iknowyou.url = "github:anotherhadi/iknowyou"; + }; + + outputs = inputs @ { + nixpkgs, + nixpkgs-stable, + ... + }: let + system = "x86_64-linux"; + pkgs = nixpkgs.legacyPackages.${system}; + args = { + inherit + inputs + nixpkgs + system + pkgs + ; + pkgs-stable = nixpkgs-stable.legacyPackages.${system}; + pkgs-nur-hadi = inputs.nur-anotherhadi.packages.${system}; + }; + merge = nixpkgs.lib.foldl nixpkgs.lib.recursiveUpdate {}; + in + merge [ + (import ./home/programs/nvf/flake.nix args) + (import ./home/programs/group/flake.nix args) + (import ./home/programs/nixy/flake.nix args) + { + formatter.${system} = pkgs.alejandra; + nixosConfigurations = { + h-laptop = import ./hosts/laptop/flake.nix args; + h-work = import ./hosts/work/flake.nix args; + jack = import ./hosts/server/flake.nix args; + }; + } + ]; +} diff --git a/home/programs/ghostty/default.nix b/home/programs/ghostty/default.nix new file mode 100644 index 0000000..292d0b2 --- /dev/null +++ b/home/programs/ghostty/default.nix @@ -0,0 +1,66 @@ +{ + pkgs, + config, + ... +}: let + cursorShaders = pkgs.fetchFromGitHub { + owner = "sahaj-b"; + repo = "ghostty-cursor-shaders"; + rev = "06d4e90fb5410e9c4d0b3131584060adddf89406"; + hash = "sha256-G/UIr1bKnxn1AcHl/4FL/jou6b7M2VeREslYVELxdmw="; + }; + c = config.lib.stylix.colors; +in { + home.sessionVariables = { + TERMINAL = "ghostty"; + TERM = "ghostty"; + }; + + programs.ghostty = { + enable = true; + installVimSyntax = true; + enableZshIntegration = true; + settings = { + window-padding-x = 10; + confirm-close-surface = false; + window-padding-y = 10; + clipboard-read = "allow"; + clipboard-write = "allow"; + copy-on-select = "clipboard"; + app-notifications = false; + custom-shader = "${cursorShaders}/cursor_warp.glsl"; + custom-shader-animation = "always"; + keybind = [ + # "ctrl+j=goto_split:left" + # "ctrl+i=goto_split:up" + # "ctrl+k=goto_split:down" + # "ctrl+l=goto_split:right" + # "shift+ctrl+h=new_split:left" + # "shift+ctrl+j=new_split:down" + # "shift+ctrl+k=new_split:up" + # "shift+ctrl+l=new_split:right" + "shift+ctrl+tab=new_tab" + ]; + }; + }; + + home.file.".config/ilovetui/config.yaml".text = '' + colors: + base00: "#${c.base00}" # Background + base01: "#${c.base01}" # Lighter Background / Status Bars + base02: "#${c.base02}" # Selection Background + base03: "#${c.base03}" # Comments / Invisibles + base04: "#${c.base04}" # Dark Foreground / Status Bars + base05: "#${c.base05}" # Default Foreground + base06: "#${c.base06}" # Light Foreground + base07: "#${c.base07}" # Light Background + base08: "#${c.base08}" # Variables / Errors / Diff Deleted + base09: "#${c.base09}" # Integers / Constants / Booleans + base0a: "#${c.base0A}" # Classes / Warnings / Search Background + base0b: "#${c.base0B}" # Strings / Success / Diff Inserted + base0c: "#${c.base0C}" # Support / Regex / Escape Characters + base0d: "#${c.base0D}" # Functions / Methods / Headings / Accent + base0e: "#${c.base0E}" # Keywords / Storage / Diff Changed + base0f: "#${c.base0F}" # Embedded / Misc + ''; +} diff --git a/home/programs/git/default.nix b/home/programs/git/default.nix new file mode 100644 index 0000000..49f5e9c --- /dev/null +++ b/home/programs/git/default.nix @@ -0,0 +1,53 @@ +# Git configuration +{config, ...}: let + username = config.var.git.username; + email = config.var.git.email; +in { + programs.git = { + enable = true; + ignores = [ + ".cache/" + ".DS_Store" + ".idea/" + "*.swp" + "*.elc" + "auto-save-list" + ".direnv/" + "node_modules" + "result" + "result-*" + ]; + settings = { + user.name = username; + user.email = email; + init.defaultBranch = "main"; + pull.rebase = "false"; + push.autoSetupRemote = true; + color.ui = "1"; + alias = { + essa = "push --force"; + co = "checkout"; + fuck = "commit --amend -m"; + c = "commit -m"; + ca = "commit -am"; + forgor = "commit --amend --no-edit"; + graph = "log --all --decorate --graph --oneline"; + oops = "checkout --"; + l = "log"; + r = "rebase"; + s = "status --short"; + ss = "status"; + d = "diff"; + ps = "!git push origin $(git rev-parse --abbrev-ref HEAD)"; + pl = "!git pull origin $(git rev-parse --abbrev-ref HEAD)"; + af = "!git add $(git ls-files -m -o --exclude-standard | sk -m)"; + st = "status"; + br = "branch"; + df = "!git hist | peco | awk '{print $2}' | xargs -I {} git diff {}^ {}"; + hist = ''log --pretty=format:"%Cgreen%h %Creset%cd %Cblue[%cn] %Creset%s%C(yellow)%d%C(reset)" --graph --date=relative --decorate --all''; + llog = ''log --graph --name-status --pretty=format:"%C(red)%h %C(reset)(%cd) %C(green)%an %Creset%s %C(yellow)%d%Creset" --date=relative''; + edit-unmerged = "!f() { git ls-files --unmerged | cut -f2 | sort -u ; }; hx `f`"; + }; + }; + }; +} diff --git a/home/programs/git/lazygit.nix b/home/programs/git/lazygit.nix new file mode 100644 index 0000000..d68a595 --- /dev/null +++ b/home/programs/git/lazygit.nix @@ -0,0 +1,38 @@ +# Lazygit is a simple terminal UI for git commands. +{ + config, + lib, + ... +}: let + accent = "#${config.lib.stylix.colors.base0D}"; + muted = "#${config.lib.stylix.colors.base03}"; +in { + programs.lazygit = { + enable = true; + settings = lib.mkForce { + disableStartupPopups = true; + notARepository = "skip"; + promptToReturnFromSubprocess = false; + update.method = "never"; + git = { + commit.signOff = true; + overrideGpg = true; + parseEmoji = true; + }; + gui = { + theme = { + activeBorderColor = [ + accent + "bold" + ]; + inactiveBorderColor = [muted]; + }; + showListFooter = false; + showRandomTip = false; + showCommandLog = false; + showBottomLine = false; + nerdFontsVersion = "3"; + }; + }; + }; +} diff --git a/home/programs/git/signing.nix b/home/programs/git/signing.nix new file mode 100644 index 0000000..4b2ea9b --- /dev/null +++ b/home/programs/git/signing.nix @@ -0,0 +1,15 @@ +# This file is used to sign git commits using an SSH key. +{ + # CHANGEME: change this to your own SSH key. + home.file.".ssh/allowed_signers".text = "* ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIINhWby7lUUXQNKbRu9/UOrGjWDf3fvoAwGHomWv/+lL"; + + programs.git = { + signing.format = "openpgp"; + settings = { + commit.gpgsign = true; + gpg.ssh.allowedSignersFile = "~/.ssh/allowed_signers"; + gpg.format = "ssh"; + user.signingkey = "~/.ssh/key.pub"; + }; + }; +} diff --git a/home/programs/group/basic-apps.nix b/home/programs/group/basic-apps.nix new file mode 100644 index 0000000..e9394fd --- /dev/null +++ b/home/programs/group/basic-apps.nix @@ -0,0 +1,45 @@ +{ + pkgs, + pkgs-stable, + pkgs-nur-hadi, + ... +}: { + home.packages = with pkgs-stable; [ + vlc # Video player + obsidian # Note taking app + textpieces # Manipulate texts + resources # Ressource monitor + gnome-clocks # Clocks app + gnome-text-editor # Basic graphic text editor + ticktick # Todo app + pinta # Image editor + switcheroo # Convert images between different formats + onlyoffice-desktopeditors # Office suite + blanket # Listen to different sounds + signal-desktop # Messaging app + librewolf # Backup browser + + # I love TUIs + caligula # User-friendly, lightweight TUI for disk imaging (ISO, USB BOOT) + browsh # A modern text-based browser that renders anything that a modern browser can. It runs in a terminal and can be used remotely over SSH + dysk # A terminal-based disk usage analyzer + wikiman # Offline search engine for manual pages (arch wiki, tldr) + tealdeer # Fast tldr client + sttr # Minimalist "cyberchef" like. Cross-platform, cli app to perform various operations on string + wiremix # Simple TUI mixer for PipeWire + slides # A terminal-based presentation tool that allows you to create and deliver presentations directly from the command line + pom # Pomodoro timer in your terminal + pkgs.wifitui # TUI for managing wifi + pkgs-nur-hadi.usbguard-tui # TUI for managing USBGuard rules + pkgs-nur-hadi.sheets # Terminal based spreadsheet tool + + # I love CLIs + httpie # Command-line HTTP client, a user-friendly cURL replacement + gh # GitHub + gh-dash # A terminal dashboard for GitHub + figlet # Transform text into ASCII art + pastel # Command-line tool to generate, analyze, convert and manipulate colors + imagemagick # Image manipulation tool + chafa # Image to ANSI/Unicode converter and more. + ]; +} diff --git a/home/programs/group/cybersecurity-packages.nix b/home/programs/group/cybersecurity-packages.nix new file mode 100644 index 0000000..c0e9af5 --- /dev/null +++ b/home/programs/group/cybersecurity-packages.nix @@ -0,0 +1,48 @@ +{ + pkgs, + pkgs-stable, + pkgs-nur-hadi, +}: +(with pkgs-stable; [ + # Web + dirb + ffuf + katana + whatweb + + # Hashes + hashcat + haiti + hydra + john + + # Databases + mariadb + redis + sqlmap + nosqli + + # Network + inetutils + termshark # wireshark in TUI + dnsrecon + whois + dig + nmap + samba + + # Misc + metasploit + nuclei + openvpn + + # Secrets + trufflehog + + # Forensics + binwalk +]) +++ (with pkgs-nur-hadi; [ + spilltea + jwt-tui +]) diff --git a/home/programs/group/cybersecurity.nix b/home/programs/group/cybersecurity.nix new file mode 100644 index 0000000..cc569cb --- /dev/null +++ b/home/programs/group/cybersecurity.nix @@ -0,0 +1,45 @@ +{ + pkgs, + pkgs-stable, + pkgs-nur-hadi, + ... +}: { + home.packages = import ./cybersecurity-packages.nix { + inherit pkgs pkgs-stable pkgs-nur-hadi; + }; + + systemd.user.tmpfiles.rules = [ + "d %h/Cyber/tmp 0755 - - -" + "d %h/Cyber/wordlists 0755 - - -" + "d %h/Cyber/wordlists/rules 0755 - - -" + ]; + + home.file = { + "Cyber/wordlists/seclists".source = pkgs.fetchFromGitHub { + owner = "danielmiessler"; + repo = "SecLists"; + rev = "47aa98053fce8670c6489e4f6fb57dc34881d8bd"; + hash = "sha256-ojXLB/TXap1Qi0MtV5/WJlJpjNIDYx/sLY2KHm0uFKI="; + }; + + "Cyber/wordlists/fuzz4bounty".source = pkgs.fetchFromGitHub { + owner = "0xPugal"; + repo = "fuzz4bounty"; + rev = "a805f6b434033f054312da0ddc2bc3021cc9a3b0"; + hash = "sha256-wMhx1CcxIyw2E7gJXQxXAFc7m5nYt0FXNkoTZqFMQh4="; + }; + + # RULES + "Cyber/wordlists/rules/oneruletorulethemstill".source = pkgs.fetchFromGitHub { + owner = "stealthsploit"; + repo = "oneruletorulethemstill"; + rev = "4bfb7322e189305b5f35bb7fcd4e9cc233c3d3c6"; + hash = "sha256-h7MeymIXS/6wlPRt4lzsIEqOOssP0lDx9nQip65cwZw="; + }; + + "Cyber/wordlists/rules/best64.rule".source = pkgs.fetchurl { + url = "https://raw.githubusercontent.com/CarlosLannister/OwadeReborn/refs/heads/master/owade/fileAnalyze/hashcatLib/best64.rule%7E"; + hash = "sha256-T0XkMHJZQiy63/j25nGTkaiDFjc+blmgEVGTAFgVylU="; + }; + }; +} diff --git a/home/programs/group/dev-packages.nix b/home/programs/group/dev-packages.nix new file mode 100644 index 0000000..cd2701e --- /dev/null +++ b/home/programs/group/dev-packages.nix @@ -0,0 +1,17 @@ +{ + pkgs, + pkgs-stable, +}: +(with pkgs; [ + go + claude-code +]) +++ (with pkgs-stable; [ + nodejs + air + duckdb + python3 + jq + nix-prefetch-github + rsync +]) diff --git a/home/programs/group/dev.nix b/home/programs/group/dev.nix new file mode 100644 index 0000000..9cb187e --- /dev/null +++ b/home/programs/group/dev.nix @@ -0,0 +1,7 @@ +{ + pkgs, + pkgs-stable, + ... +}: { + home.packages = import ./dev-packages.nix {inherit pkgs pkgs-stable;}; +} diff --git a/home/programs/group/flake.nix b/home/programs/group/flake.nix new file mode 100644 index 0000000..934e475 --- /dev/null +++ b/home/programs/group/flake.nix @@ -0,0 +1,22 @@ +{ + inputs, + pkgs, + pkgs-stable, + pkgs-nur-hadi, + system, + ... +}: let + devPackages = import ./dev-packages.nix {inherit pkgs pkgs-stable;}; + cyberPackages = import ./cybersecurity-packages.nix {inherit pkgs pkgs-stable pkgs-nur-hadi;}; +in { + packages.${system} = { + dev = pkgs.buildEnv { + name = "dev-tools"; + paths = devPackages; + }; + cybersecurity = pkgs.buildEnv { + name = "cybersecurity-tools"; + paths = cyberPackages; + }; + }; +} diff --git a/home/programs/group/misc.nix b/home/programs/group/misc.nix new file mode 100644 index 0000000..436a462 --- /dev/null +++ b/home/programs/group/misc.nix @@ -0,0 +1,16 @@ +{ + pkgs-stable, + pkgs-nur-hadi, + inputs, + ... +}: { + home.packages = with pkgs-stable; [ + tty-solitaire + bastet + peaclock + cbonsai + pipes + cmatrix + fastfetch + ]; +} diff --git a/home/programs/helium/bookmarks/default.nix b/home/programs/helium/bookmarks/default.nix new file mode 100644 index 0000000..46e293c --- /dev/null +++ b/home/programs/helium/bookmarks/default.nix @@ -0,0 +1,459 @@ +{ + config, + lib, + pkgs, + ... +}: let + bookmarkList = + (import ./general.nix) + ++ (import ./tools.nix) + ++ (import ./entertainment.nix) + ++ (import ./infosec.nix) + ++ (import ./other.nix) + ++ (import ./jack.nix); + + c = config.lib.stylix.colors; + + stripProtocol = url: lib.removePrefix "https://" (lib.removePrefix "http://" url); + stripDomain = url: builtins.head (lib.splitString "/" (stripProtocol url)); + + mkCard = item: let + domain = stripDomain item.url; + initial = builtins.substring 0 1 item.name; + in '' + +
+ + +
+
+ ${item.name} + ${stripProtocol item.url} +
+
''; + + mkFolderContent = items: let + step = acc: item: + if item ? url + then acc // {pending = acc.pending ++ [item];} + else { + chunks = + acc.chunks + ++ lib.optional (acc.pending != []) { + isCards = true; + items = acc.pending; + } + ++ [ + { + isCards = false; + folder = item; + } + ]; + pending = []; + }; + result = + lib.foldl' step { + chunks = []; + pending = []; + } + items; + chunks = + result.chunks + ++ lib.optional (result.pending != []) { + isCards = true; + items = result.pending; + }; + in + lib.concatMapStrings ( + chunk: + if chunk.isCards + then '' +
+ ${lib.concatMapStrings mkCard chunk.items} +
'' + else mkFolder chunk.folder + ) + chunks; + + mkFolder = folder: let + iconHtml = + if folder ? icon + then '''' + else ""; + in '' +
+ + ${iconHtml}${folder.name} + + +
+ ${mkFolderContent folder.bookmarks} +
+
''; + + grouped = let + step = acc: item: + if item ? url + then acc // {pending = acc.pending ++ [item];} + else { + groups = + acc.groups + ++ lib.optional (acc.pending != []) { + isRoot = true; + items = acc.pending; + } + ++ [ + { + isRoot = false; + inherit item; + } + ]; + pending = []; + }; + result = + lib.foldl' step { + groups = []; + pending = []; + } + bookmarkList; + in + result.groups + ++ lib.optional (result.pending != []) { + isRoot = true; + items = result.pending; + }; + + mkSection = group: + if group.isRoot + then '' +
+
+ ${lib.concatMapStrings mkCard group.items} +
+
'' + else mkFolder group.item; +in { + home.file.".local/share/helium-startpage/index.html".text = '' + + + + + + Bookmarks + + + + +
+

Bookmarks

+ + +
+
+

No results

+ ${lib.concatMapStrings mkSection grouped} +
+ + + + ''; + + systemd.user.services.helium-startpage = { + Unit = { + Description = "Helium startpage HTTP server"; + After = ["network.target"]; + }; + Service = { + Type = "simple"; + ExecStart = "${pkgs.darkhttpd}/bin/darkhttpd %h/.local/share/helium-startpage --port 8888 --addr 127.0.0.1 --no-listing"; + Restart = "on-failure"; + }; + Install.WantedBy = ["default.target"]; + }; +} diff --git a/home/programs/helium/bookmarks/entertainment.nix b/home/programs/helium/bookmarks/entertainment.nix new file mode 100644 index 0000000..945f4e6 --- /dev/null +++ b/home/programs/helium/bookmarks/entertainment.nix @@ -0,0 +1,50 @@ +[ + { + name = "Entertainment"; + icon = "movie"; + bookmarks = [ + { + name = "Youtube"; + url = "https://youtube.com"; + } + { + name = "Jellyfin"; + url = "https://media.hadi.icu"; + } + { + name = "Seerr"; + url = "https://demandemedia.hadi.icu"; + } + { + name = "Social Media"; + icon = "group"; + bookmarks = [ + { + name = "Medium"; + url = "https://medium.com"; + } + { + name = "Bluesky"; + url = "https://bsky.app"; + } + { + name = "Reddit"; + url = "https://reddit.com"; + } + { + name = "Instagram"; + url = "https://instagram.com"; + } + { + name = "Discord"; + url = "https://discord.com/channels/@me/"; + } + { + name = "Gitlab"; + url = "https://gitlab.com/"; + } + ]; + } + ]; + } +] diff --git a/home/programs/helium/bookmarks/general.nix b/home/programs/helium/bookmarks/general.nix new file mode 100644 index 0000000..19bfbd8 --- /dev/null +++ b/home/programs/helium/bookmarks/general.nix @@ -0,0 +1,14 @@ +[ + { + name = "Proton Mail"; + url = "https://mail.proton.me"; + } + { + name = "Proton Drive"; + url = "https://drive.proton.me"; + } + { + name = "Github"; + url = "https://github.com"; + } +] diff --git a/home/programs/helium/bookmarks/infosec.nix b/home/programs/helium/bookmarks/infosec.nix new file mode 100644 index 0000000..1952da0 --- /dev/null +++ b/home/programs/helium/bookmarks/infosec.nix @@ -0,0 +1,56 @@ +[ + { + name = "Infosec"; + icon = "terminal"; + bookmarks = [ + { + name = "Nix 4 Cyber"; + url = "https://n4c.hadi.icu"; + } + { + name = "Infosec Notes - Anotherhadi"; + url = "https://hadi.icu/notes"; + } + { + name = "Cyberchef"; + url = "https://cyberchef.hadi.icu"; + } + { + name = "TryHackMe"; + url = "https://tryhackme.com"; + } + { + name = "Root-Me"; + url = "https://root-me.org"; + } + { + name = "Hack The Box"; + url = "https://hackthebox.com"; + } + { + name = "Iknowyou"; + url = "https://iknowyou-prod.hadi.icu"; + } + { + name = "Exploit-DB"; + url = "https://exploit-db.com"; + } + { + name = "Reverse Shell Generator"; + url = "https://revshells.com"; + } + { + name = "GTFOBins"; + url = "https://gtfobins.org/"; + } + { + name = "Crack Station"; + url = "https://crackstation.net"; + } + { + name = "Osint Tracker"; + url = "https://app.osintracker.com"; + } + ]; + } +] diff --git a/home/programs/helium/bookmarks/jack.nix b/home/programs/helium/bookmarks/jack.nix new file mode 100644 index 0000000..bdcd5d9 --- /dev/null +++ b/home/programs/helium/bookmarks/jack.nix @@ -0,0 +1,80 @@ +[ + { + name = "Jack"; + icon = "dns"; + bookmarks = [ + { + name = "Glance"; + url = "https://home.hadi.icu"; + } + { + name = "Blog"; + url = "https://hadi.icu"; + } + { + name = "Gitea"; + url = "https://git.hadi.icu"; + } + { + name = "Mealie"; + url = "https://mealie.hadi.icu"; + } + { + name = "Wallpapers"; + url = "https://wallpapers.hadi.icu"; + } + { + name = "Default Creds"; + url = "https://default-creds.hadi.icu"; + } + { + name = "Media"; + icon = "subscriptions"; + bookmarks = [ + { + name = "Radarr"; + url = "https://radarr.hadi.icu"; + } + { + name = "Sonarr"; + url = "https://sonarr.hadi.icu"; + } + { + name = "Bazarr"; + url = "https://bazarr.hadi.icu"; + } + { + name = "Prowlarr"; + url = "https://prowlarr.hadi.icu"; + } + { + name = "Transmission"; + url = "https://transmission.hadi.icu"; + } + ]; + } + { + name = "Infrastructure"; + icon = "construction"; + bookmarks = [ + { + name = "AdGuard"; + url = "https://adguard.hadi.icu"; + } + { + name = "Umami"; + url = "https://umami.hadi.icu"; + } + { + name = "Cloudflare"; + url = "https://dash.cloudflare.com"; + } + { + name = "Cloudflare Zero Trust"; + url = "https://one.dash.cloudflare.com"; + } + ]; + } + ]; + } +] diff --git a/home/programs/helium/bookmarks/other.nix b/home/programs/helium/bookmarks/other.nix new file mode 100644 index 0000000..a43ea98 --- /dev/null +++ b/home/programs/helium/bookmarks/other.nix @@ -0,0 +1,50 @@ +[ + { + name = "Other"; + icon = "category"; + bookmarks = [ + { + name = "Documentation"; + icon = "menu_book"; + bookmarks = [ + { + name = "Hyprland Wiki"; + url = "https://wiki.hypr.land"; + } + { + name = "NVF Options"; + url = "https://nvf.notashelf.dev/"; + } + { + name = "Stylix Wiki"; + url = "https://nix-community.github.io/stylix/"; + } + { + name = "Nixpkgs"; + url = "https://github.com/NixOS/nixpkgs"; + } + { + name = "tldr"; + url = "https://tldr.inbrowser.app/"; + } + ]; + } + { + name = "Startpage Config"; + url = "https://www.startpage.com/do/mypage.pl?prfe=45d331deb05471d659dba933e7400df51d952bb103da6f6125c0e769a6be1d65610456a479f495ceeee7e97311cf227d7c1bb198de0ceeb193d8cddf9c455c19a409cc35c3e3f542ee27bd7cecd3"; + } + { + name = "Feedly"; + url = "https://feedly.com"; + } + { + name = "MyNixOS"; + url = "https://mynixos.com"; + } + { + name = "Amazon"; + url = "https://amazon.fr"; + } + ]; + } +] diff --git a/home/programs/helium/bookmarks/tools.nix b/home/programs/helium/bookmarks/tools.nix new file mode 100644 index 0000000..4929cd4 --- /dev/null +++ b/home/programs/helium/bookmarks/tools.nix @@ -0,0 +1,48 @@ +[ + { + name = "Tools"; + icon = "handyman"; + bookmarks = [ + { + name = "Maps"; + url = "https://maps.apple.com"; + } + { + name = "Excalidraw"; + url = "https://excalidraw.com"; + } + { + name = "Cobalt (downloader)"; + url = "https://cobalt.meowing.de"; + } + { + name = "Mazanoke (image)"; + url = "https://mazanoke.hadi.icu"; + } + { + name = "Vert"; + url = "https://vert.sh"; + } + { + name = "Markdown to PDF"; + url = "https://md2file.com"; + } + { + name = "Image to Vector"; + url = "https://www.vectorcascade.com/"; + } + { + name = "PrivateBin"; + url = "https://privatebin.net"; + } + { + name = "Claude"; + url = "https://claude.ai"; + } + { + name = "Gemini"; + url = "https://gemini.google.com"; + } + ]; + } +] diff --git a/home/programs/helium/default.nix b/home/programs/helium/default.nix new file mode 100644 index 0000000..769275c --- /dev/null +++ b/home/programs/helium/default.nix @@ -0,0 +1,138 @@ +{ + inputs, + config, + pkgs, + lib, + ... +}: let + c = config.lib.stylix.colors; + rgb = base: map lib.strings.toInt [c."${base}-rgb-r" c."${base}-rgb-g" c."${base}-rgb-b"]; + + themeId = "abcadngacjlikcpkhleafekcdjmddegk"; + themeKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6t46VoE3mdV1QNMgybpmQLi5PtYHejnNrSj4DkBZyiTzMzs7Yyvg64f78w3QubZA5cTXSQ7FVhVHvv30I8ym/jNzsSN6reh1t4PtKsFjFRugAty8bfKJGD404HZLOFN2z3G9UPVLBBgzDH3DWbb/kcOq60Mlo/QDCIjsieZg0G3EYMl4efoThzYPWoyv0UEoiliwrE/AChxbgipQetUZ48bFhTCsmnYzCze7clssfTobzWtJJG0qFx76LauHKymRS5OTFfgsovKqHUSFJ202Q53vFdUPP/j8PjSPr1kZeg1NYc7Ba3MoA49EwtJf5ol9oYu05EEnSQ5+1AoYVmdE8QIDAQAB"; + + themeManifest = builtins.toJSON { + manifest_version = 2; + name = "Stylix Theme"; + version = "1.0"; + key = themeKey; + theme.colors = { + frame = rgb "base00"; + frame_inactive = rgb "base00"; + frame_incognito = rgb "base00"; + frame_incognito_inactive = rgb "base00"; + toolbar = rgb "base00"; + toolbar_button_icon = rgb "base05"; + control_background = rgb "base00"; + tab_text = rgb "base0D"; + background_tab = rgb "base00"; + tab_background_text = rgb "base04"; + tab_background_text_inactive = rgb "base04"; + ntp_background = rgb "base00"; + ntp_text = rgb "base05"; + }; + }; + + heliumFlags = [ + "--ozone-platform=wayland" + "--enable-features=UseOzonePlatform,VaapiVideoDecoder,VaapiVideoEncoder,CanvasOopRasterization" + "--disable-features=UseChromeOSDirectVideoDecoder,WaylandWpColorManagerV1" + "--enable-accelerated-video-decode" + "--enable-gpu-rasterization" + "--use-gl=egl" + "--no-default-browser-check" + "--show-avatar-button=never" + ]; + + originalPkg = (inputs.helium-browser.packages.${pkgs.stdenv.hostPlatform.system}.helium).override { + flags = heliumFlags; + }; + + patchScript = pkgs.writeShellScript "helium-patch-prefs" '' + PROFILE="$HOME/.config/net.imput.helium/Default" + THEME_DIR="$PROFILE/Extensions/${themeId}/1.0_0" + PREFS="$PROFILE/Preferences" + + mkdir -p "$THEME_DIR" + rm -f "$THEME_DIR/Cached Theme.pak" + printf '%s' '${themeManifest}' > "$THEME_DIR/manifest.json" + + if [ -f "$PREFS" ]; then + tmp=$(mktemp) + ${lib.getExe pkgs.jq} \ + --arg id "${themeId}" \ + --slurpfile manifest "$THEME_DIR/manifest.json" \ + ' + .helium.browser.layout = 3 | + .helium.browser.minimal_location_bar = true | + .helium.browser.show_dynamic_new_tab_button = false | + .helium.browser.rounded_frame = false | + .bookmark_bar.show_tab_groups = false | + .extensions.settings[$id] = { + "active_permissions": {"api": [], "explicit_host": [], "manifest_permissions": [], "scriptable_host": []}, + "creation_flags": 0, + "from_webstore": false, + "install_time": "13300000000000000", + "location": 1, + "manifest": $manifest[0], + "path": ($id + "/1.0_0"), + "state": 1, + "was_installed_by_default": false, + "was_installed_by_oem": false + } | + .extensions.theme = {"id": $id, "use_system": false} + ' "$PREFS" > "$tmp" && mv "$tmp" "$PREFS" + fi + ''; + + baseWrapped = pkgs.symlinkJoin { + name = "helium-wrapped"; + paths = [originalPkg]; + nativeBuildInputs = [pkgs.makeWrapper]; + postBuild = '' + wrapProgram $out/bin/helium \ + --run ${lib.escapeShellArg (toString patchScript)} + ''; + }; + + wrappedPkg = baseWrapped // {override = _: baseWrapped;}; +in { + imports = [ + inputs.helium-browser.homeModules.default + ./bookmarks + ]; + + programs.helium = { + enable = true; + package = lib.mkForce wrappedPkg; + }; + + home.sessionVariables.BROWSER = "${config.programs.helium.package}/bin/helium"; + + xdg.desktopEntries.helium = { + name = "Helium"; + genericName = "Navigateur Web"; + exec = "${config.programs.helium.package}/bin/helium %U"; + icon = "${config.programs.helium.package}/share/icons/hicolor/256x256/apps/helium.png"; + terminal = false; + categories = ["Network" "WebBrowser"]; + mimeType = [ + "text/html" + "text/xml" + "application/xhtml+xml" + "x-scheme-handler/http" + "x-scheme-handler/https" + "x-scheme-handler/ftp" + ]; + }; + + xdg.desktopEntries.helium-private = { + name = "Helium (Private window)"; + genericName = "Navigateur Web"; + exec = "${config.programs.helium.package}/bin/helium --incognito %U"; + icon = "${config.programs.helium.package}/share/icons/hicolor/256x256/apps/helium.png"; + terminal = false; + categories = ["Network" "WebBrowser"]; + mimeType = ["text/html" "text/xml" "application/xhtml+xml"]; + }; +} diff --git a/home/programs/helium/system.nix b/home/programs/helium/system.nix new file mode 100644 index 0000000..616605f --- /dev/null +++ b/home/programs/helium/system.nix @@ -0,0 +1,70 @@ +{...}: let + bookmarkList = + (import ./bookmarks/general.nix) + ++ (import ./bookmarks/tools.nix) + ++ (import ./bookmarks/entertainment.nix) + ++ (import ./bookmarks/infosec.nix) + ++ (import ./bookmarks/other.nix) + ++ (import ./bookmarks/jack.nix); + + toChromium = items: + map (item: + if item ? url + then {inherit (item) name url;} + else { + name = item.name; + children = toChromium item.bookmarks; + }) + items; +in { + stylix.targets.chromium.enable = false; + + programs.helium = { + enable = true; + + policies = { + BrowserSignin = 0; + SyncDisabled = true; + SigninAllowed = false; + + PasswordManagerEnabled = false; + AutofillAddressEnabled = false; + AutofillCreditCardEnabled = false; + SafeBrowsingEnabled = false; + MetricsReportingEnabled = false; + SpellCheckServiceEnabled = false; + DefaultCookiesSetting = 1; + DefaultGeolocationSetting = 2; + DefaultNotificationsSetting = 2; + DefaultPopupsSetting = 2; + + DefaultBrowserSettingEnabled = false; + DeveloperToolsAvailability = 1; + + DnsOverHttpsMode = "secure"; + DnsOverHttpsTemplates = "https://dns.quad9.net/dns-query"; + + DefaultSearchProviderEnabled = true; + DefaultSearchProviderName = "Startpage"; + DefaultSearchProviderSearchURL = "https://www.startpage.com/do/search?q={searchTerms}"; + DefaultSearchProviderSuggestURL = "https://www.startpage.com/do/suggest?q={searchTerms}"; + + NewTabPageLocation = "http://127.0.0.1:8888"; + HomepageIsNewTabPage = false; + HomepageLocation = "http://127.0.0.1:8888"; + ShowHomeButton = false; + RestoreOnStartup = 4; + + BookmarkBarEnabled = false; + ManagedBookmarks = toChromium bookmarkList; + + ExtensionInstallForcelist = [ + "dbepggeogbaibhgnhhndojpepiihcmeb" # Vimiu + "gcknhkkoolaabfmlnjonogaaifnjlfnp" # FoxyProxy + "ghmbeldphafepmbegfdlkpapadhbakde" # Proton Pass + "mdjildafknihdffpkfmmpnpoiajfjnjd" # Consent-O-Matic + "pkehgijcmpdhfbdbbnkijodmdjhbjlgp" # Privacy Badger + ]; + }; + }; +} diff --git a/home/programs/nightshift/default.nix b/home/programs/nightshift/default.nix new file mode 100644 index 0000000..749adc3 --- /dev/null +++ b/home/programs/nightshift/default.nix @@ -0,0 +1,19 @@ +{pkgs, ...}: let + nightshift-toggle = + pkgs.writeShellScriptBin "nightshift-toggle" + # bash + '' + if pidof "hyprsunset"; then + pkill hyprsunset + ${pkgs.libnotify}/bin/notify-send "Night Shift Disabled" "Returning to full spectrum light. Filter disabled." + else + ${pkgs.hyprsunset}/bin/hyprsunset -t 4500 & + ${pkgs.libnotify}/bin/notify-send "Night Shift Activated" "Welcome to the warm side. Blue light filtering is now active." + fi + ''; +in { + home.packages = with pkgs; [ + hyprsunset + nightshift-toggle + ]; +} diff --git a/home/programs/nix-utils/default.nix b/home/programs/nix-utils/default.nix new file mode 100644 index 0000000..a4f9617 --- /dev/null +++ b/home/programs/nix-utils/default.nix @@ -0,0 +1,5 @@ +{inputs, ...}: { + imports = [inputs.nix-index-database.homeModules.default]; + programs.nix-index.enable = true; + programs.nix-index-database.comma.enable = true; +} diff --git a/home/programs/nixy/default.nix b/home/programs/nixy/default.nix new file mode 100644 index 0000000..2be55a3 --- /dev/null +++ b/home/programs/nixy/default.nix @@ -0,0 +1,31 @@ +# - ## Nixy +#- +#- Nixy is a simple script that I use to manage my NixOS system. It's a simple script that provides a menu to rebuild, test, update, collect garbage, clean boot menu, etc. +#- +#- - `nixy` - UI wizard to manage the system. +#- - `nixy rebuild` - Rebuild the system. +#- - `nixy ...` - ... see the script for more commands. +{ + config, + lib, + pkgs, + ... +}: { + options.programs.nixy = { + enable = lib.mkEnableOption "nixy"; + configDirectory = lib.mkOption { + type = lib.types.str; + default = "$HOME/.config/nixos"; + description = "Path to the NixOS configuration directory"; + }; + }; + + config = lib.mkIf config.programs.nixy.enable { + home.packages = [ + (import ./package.nix { + inherit pkgs; + inherit (config.programs.nixy) configDirectory; + }) + ]; + }; +} diff --git a/home/programs/nixy/flake.nix b/home/programs/nixy/flake.nix new file mode 100644 index 0000000..4e559b2 --- /dev/null +++ b/home/programs/nixy/flake.nix @@ -0,0 +1,14 @@ +{ + pkgs, + system, + ... +}: { + packages.${system}.nixy = import ./package.nix { + inherit pkgs; + configDirectory = "$HOME/.config/nixos"; + }; + + homeManagerModules.nixy = { + imports = [./default.nix]; + }; +} diff --git a/home/programs/nixy/package.nix b/home/programs/nixy/package.nix new file mode 100644 index 0000000..565f864 --- /dev/null +++ b/home/programs/nixy/package.nix @@ -0,0 +1,69 @@ +{ + pkgs, + configDirectory, +}: +pkgs.writeShellScriptBin "nixy" +# bash +'' + EXTRA_ARGS="''${@:2}" + + function exec() { + $@ + } + + function ui(){ + DEFAULT_ICON="󰘳" + + # "icon;name;command"[] + apps=( + "󰑓;Rebuild;nixy rebuild" + "󰐊;Test;nixy test" + "󰚰;Update;nixy update" + ";Collect Garbage;nixy gc" + "󰍜;Clean Boot Menu;nixy cb" + ";List generation;nixy listgen" + ) + + # Apply default icons if empty: + for i in "''${!apps[@]}"; do + apps[i]=$(echo "''${apps[i]}" | sed 's/^;/'$DEFAULT_ICON';/') + done + + fzf_result=$(printf "%s\n" "''${apps[@]}" | awk -F ';' '{print $1" "$2}' | fzf) + [[ -z $fzf_result ]] && exit 0 + fzf_result=''${fzf_result/ /;} + line=$(printf "%s\n" "''${apps[@]}" | grep "$fzf_result") + command=$(echo "$line" | sed 's/^[^;]*;//;s/^[^;]*;//') + + exec "$command" + exit $? + } + + [[ $1 == "" ]] && ui + + if [[ $1 == "rebuild" ]];then + cd ${configDirectory} && git add . && sudo nixos-rebuild switch --flake . $EXTRA_ARGS + elif [[ $1 == "test" ]];then + cd ${configDirectory} && git add . && sudo nixos-rebuild test --flake . $EXTRA_ARGS + elif [[ $1 == "update" ]];then + cd ${configDirectory} && nix flake update $EXTRA_ARGS + elif [[ $1 == "gc" ]];then + echo "Starting Nix garbage collection..." + cd ${configDirectory} && \ + echo "Cleaning up system garbage..." && \ + sudo nix-collect-garbage -d && \ + echo "Cleaning up user garbage..." && \ + nix-collect-garbage -d && \ + echo "Collecting garbage from Nix store..." && \ + nix-store --gc && \ + echo "Optimizing Nix store..." && \ + nix-store --optimise + echo "Nix garbage collection complete." + elif [[ $1 == "cb" ]];then + sudo /run/current-system/bin/switch-to-configuration boot + elif [[ $1 == "listgen" ]];then + sudo nix-env -p /nix/var/nix/profiles/system --list-generations + else + echo "Unknown argument" + fi +'' diff --git a/home/programs/nvf/default.nix b/home/programs/nvf/default.nix new file mode 100644 index 0000000..e400962 --- /dev/null +++ b/home/programs/nvf/default.nix @@ -0,0 +1,33 @@ +{ + inputs, + pkgs, + config, + ... +}: let + c = config.lib.stylix.colors; +in { + imports = [inputs.nvf.homeManagerModules.default]; + programs.nvf = { + enable = true; + settings = { + vim.luaConfigRC.hl-overrides = '' + local function apply_hl() + vim.api.nvim_set_hl(0, "MiniStarterHeader", { fg = "#${c.base0D}", bold = true }) + vim.api.nvim_set_hl(0, "SnacksPickerBorder", { fg = "#${c.base0D}" }) + vim.api.nvim_set_hl(0, "SnacksPickerTitle", { fg = "#${c.base0D}", bold = true }) + end + apply_hl() + vim.api.nvim_create_autocmd("ColorScheme", { pattern = "*", callback = apply_hl }) + ''; + imports = [ + ./options.nix + ./languages.nix + ./picker.nix + ./snacks.nix + ./keymaps.nix + ./utils.nix + ./mini.nix + ]; + }; + }; +} diff --git a/home/programs/nvf/flake.nix b/home/programs/nvf/flake.nix new file mode 100644 index 0000000..b9fdd4f --- /dev/null +++ b/home/programs/nvf/flake.nix @@ -0,0 +1,37 @@ +{ + inputs, + pkgs, + system, + ... +}: let + nvimConfig = inputs.nvf.lib.neovimConfiguration { + inherit pkgs; + modules = [ + ./options.nix + ./languages.nix + ./picker.nix + ./snacks.nix + ./keymaps.nix + ./utils.nix + ./mini.nix + ]; + }; +in { + packages.${system}.nvim = nvimConfig.neovim; + + apps.${system}.nvim = { + type = "app"; + program = "${nvimConfig.neovim}/bin/nvim"; + }; + defaultApp.${system} = { + type = "app"; + program = "${nvimConfig.neovim}/bin/nvim"; + }; + + homeManagerModules.nvim = { + imports = [ + inputs.nvf.homeManagerModules.default + ./default.nix + ]; + }; +} diff --git a/home/programs/nvf/keymaps.nix b/home/programs/nvf/keymaps.nix new file mode 100644 index 0000000..b708c1b --- /dev/null +++ b/home/programs/nvf/keymaps.nix @@ -0,0 +1,327 @@ +{ + vim = { + globals.mapleader = " "; + + keymaps = [ + { + key = "s"; + mode = "n"; + silent = true; + action = "lua MiniJump2d.start(MiniJump2d.builtin_opts.single_character)"; + desc = "Jump2d"; + } + { + key = "K"; + mode = "n"; + silent = true; + action = "lua vim.lsp.buf.hover()"; + desc = "LSP Hover"; + } + { + key = ""; + mode = "n"; + silent = true; + action = "bnext"; + desc = "Next Buffer"; + } + + # Format + { + key = "lf"; + mode = "n"; + silent = true; + action = "lua require('conform').format({ async = true, lsp_format = 'fallback' })"; + desc = "Format file"; + } + + # Terminal + { + key = "tt"; + mode = "n"; + silent = true; + action = "lua Snacks.terminal.toggle()"; + desc = "Toggle terminal"; + } + { + key = "tf"; + mode = "n"; + silent = true; + action = "lua Snacks.terminal.toggle(nil, { style = 'float' })"; + desc = "Toggle terminal (float)"; + } + { + key = "tg"; + mode = "n"; + silent = true; + action = "lua Snacks.lazygit()"; + desc = "Lazygit"; + } + { + key = "ts"; + mode = "v"; + silent = true; + action = ":SttrTransform"; + desc = "String Transform"; + } + { + key = "tj"; + mode = "n"; + silent = true; + action = ":JwtTui"; + desc = "JWT TUI"; + } + { + key = "tj"; + mode = "v"; + silent = true; + action = ":JwtTuiOpen"; + desc = "JWT TUI"; + } + + # UI + { + key = "uw"; + mode = "n"; + silent = true; + action = "set wrap!"; + desc = "Toggle word wrapping"; + } + { + key = "ul"; + mode = "n"; + silent = true; + action = "set linebreak!"; + desc = "Toggle linebreak"; + } + { + key = "us"; + mode = "n"; + silent = true; + action = "set spell!"; + desc = "Toggle spellLazyGitcheck"; + } + { + key = "uc"; + mode = "n"; + silent = true; + action = "set cursorline!"; + desc = "Toggle cursorline"; + } + { + key = "un"; + mode = "n"; + silent = true; + action = "set number!"; + desc = "Toggle line numbers"; + } + { + key = "ur"; + mode = "n"; + silent = true; + action = "set relativenumber!"; + desc = "Toggle relative line numbers"; + } + { + key = "ut"; + mode = "n"; + silent = true; + action = "set showtabline=2"; + desc = "Show tabline"; + } + { + key = "uT"; + mode = "n"; + silent = true; + action = "set showtabline=0"; + desc = "Hide tabline"; + } + + # Todos + { + key = "xt"; + mode = "n"; + silent = true; + action = "TodoTrouble"; + desc = "Todo (Trouble)"; + } + + # Shell + { + key = "!"; + mode = "n"; + silent = true; + lua = true; + desc = "Insert command output"; + action = '' + function() + local cmd = vim.fn.input("Command: ") + if cmd == "" then return end + local lines = vim.fn.systemlist(cmd) + while #lines > 0 and lines[#lines] == "" do + table.remove(lines) + end + if #lines == 0 then return end + vim.api.nvim_put(lines, "l", true, true) + end + ''; + } + { + key = "!"; + mode = "v"; + silent = true; + lua = true; + desc = "Run command with selection"; + action = '' + function() + local start_line = vim.fn.line("'<") + local end_line = vim.fn.line("'>") + local lines = vim.api.nvim_buf_get_lines(0, start_line - 1, end_line, false) + local input_text = table.concat(lines, "\n") + + local cmd = vim.fn.input("$ ") + if cmd == "" then return end + + local result = vim.fn.system({"bash", "-c", cmd}, input_text) + local output = vim.split(result, "\n", { plain = true }) + if output[#output] == "" then table.remove(output) end + if #output == 0 then return end + + vim.api.nvim_buf_set_lines(0, start_line - 1, end_line, false, output) + end + ''; + } + + # QOL + { + key = ">"; + mode = "v"; + silent = true; + action = ">gv"; + desc = "Indent and keep selection"; + } + { + key = "<"; + mode = "v"; + silent = true; + action = "tdq") + vim.keymap.del("n", "tdt") + ''; + undoFile.enable = true; + utility.yazi-nvim = { + enable = true; + mappings.openYazi = "e"; + }; + notes.todo-comments.enable = true; + assistant.copilot = { + enable = true; + cmp.enable = true; + }; + + autocomplete = { + nvim-cmp = { + enable = true; + sources = { + buffer = "[Buffer]"; + path = "[Path]"; + }; + sourcePlugins = [ + pkgs.vimPlugins.cmp-cmdline + ]; + }; + }; + + snippets.luasnip.enable = true; + ui = { + noice.enable = true; + colorizer.enable = true; + }; + + visuals = { + rainbow-delimiters.enable = true; + }; + + extraPlugins = { + sttr-nvim = { + package = pkgs.vimUtils.buildVimPlugin { + name = "sttr-nvim"; + src = pkgs.fetchFromGitHub { + owner = "anotherhadi"; + repo = "sttr.nvim"; + rev = "b41f2f51372222e23efbe5df9d72391cd933d4d1"; + hash = "sha256-JPv0NNNUUNPNJM5LHYjcmTvilbOKB3OxI2Q6wxVbTks="; + }; + }; + setup = '' + require("sttr").setup() + ''; + }; + jwt-tui-nvim = { + package = pkgs.vimUtils.buildVimPlugin { + name = "jwt-tui-nvim"; + src = pkgs.fetchFromGitHub { + owner = "anotherhadi"; + repo = "jwt-tui.nvim"; + rev = "c5100cb2cdfaf333014076a1a5c4c6a778bf3983"; + hash = "sha256-qnQYZuQwyWkezhuyOorM67KBtatUboubofuT9A6McJI="; + }; + }; + setup = '' + require("jwt-tui").setup() + ''; + }; + }; + }; +} diff --git a/home/programs/proton/auto-start-vpn.nix b/home/programs/proton/auto-start-vpn.nix new file mode 100644 index 0000000..6222d7f --- /dev/null +++ b/home/programs/proton/auto-start-vpn.nix @@ -0,0 +1,5 @@ +{ + wayland.windowManager.hyprland.settings.exec-once = [ + "protonvpn-app --start-minimized &" + ]; +} diff --git a/home/programs/proton/default.nix b/home/programs/proton/default.nix new file mode 100644 index 0000000..2473a57 --- /dev/null +++ b/home/programs/proton/default.nix @@ -0,0 +1,39 @@ +{ + pkgs, + config, + ... +}: { + home.packages = with pkgs; [ + proton-vpn + proton-pass + proton-authenticator + ]; + + # Fix Proton Authenticator desktop entry + xdg.desktopEntries = { + "Proton Authenticator" = { + name = "Proton Authenticator"; + exec = "env WEBKIT_DISABLE_COMPOSITING_MODE=1 ${pkgs.proton-authenticator}/bin/proton-authenticator"; + icon = "proton-authenticator"; + type = "Application"; + categories = ["Utility"]; + terminal = false; + }; + "Proton Calendar" = { + name = "Proton Calendar"; + exec = ''${config.programs.helium.package}/bin/helium "https://calendar.proton.me"''; + icon = "proton-calendar"; + type = "Application"; + categories = ["Utility"]; + terminal = false; + }; + "Proton Mail" = { + name = "Proton Mail"; + exec = ''${config.programs.helium.package}/bin/helium "https://mail.proton.me/"''; + icon = "proton-mail"; + type = "Application"; + categories = ["Utility"]; + terminal = false; + }; + }; +} diff --git a/home/programs/shell/default.nix b/home/programs/shell/default.nix new file mode 100644 index 0000000..a960cd7 --- /dev/null +++ b/home/programs/shell/default.nix @@ -0,0 +1,11 @@ +# Import all shell configurations +{ + imports = [ + ./fzf.nix + ./zsh.nix + ./starship.nix + ./zoxide.nix + ./eza.nix + ./direnv.nix + ]; +} diff --git a/home/programs/shell/direnv.nix b/home/programs/shell/direnv.nix new file mode 100644 index 0000000..2b51c9d --- /dev/null +++ b/home/programs/shell/direnv.nix @@ -0,0 +1,6 @@ +{ + programs.direnv = { + enable = true; + nix-direnv.enable = true; + }; +} diff --git a/home/programs/shell/eza.nix b/home/programs/shell/eza.nix new file mode 100644 index 0000000..dbf4c51 --- /dev/null +++ b/home/programs/shell/eza.nix @@ -0,0 +1,13 @@ +# Eza is a ls replacement +{ + programs.eza = { + enable = true; + icons = "auto"; + + extraOptions = [ + "--group-directories-first" + "--no-quotes" + "--icons=always" + ]; + }; +} diff --git a/home/programs/shell/fzf.nix b/home/programs/shell/fzf.nix new file mode 100644 index 0000000..9ad8965 --- /dev/null +++ b/home/programs/shell/fzf.nix @@ -0,0 +1,33 @@ +# Fzf is a general-purpose command-line fuzzy finder. +{ + config, + lib, + ... +}: let + accent = "#" + config.lib.stylix.colors.base0D; + foreground = "#" + config.lib.stylix.colors.base05; + muted = "#" + config.lib.stylix.colors.base03; +in { + programs.fzf = { + enable = true; + enableZshIntegration = true; + colors = lib.mkForce { + "fg+" = accent; + "bg+" = "-1"; + "fg" = foreground; + "bg" = "-1"; + "prompt" = muted; + "pointer" = accent; + }; + defaultOptions = [ + "--margin=1" + "--layout=reverse" + "--border=none" + "--info='hidden'" + "--header=''" + "--prompt='/ '" + "-i" + "--no-bold" + ]; + }; +} diff --git a/home/programs/shell/starship.nix b/home/programs/shell/starship.nix new file mode 100644 index 0000000..bffc163 --- /dev/null +++ b/home/programs/shell/starship.nix @@ -0,0 +1,60 @@ +# starship is a minimal, fast, and extremely customizable prompt for any shell! +{ + config, + lib, + ... +}: let + accent = "#${config.lib.stylix.colors.base0D}"; + background-alt = "#${config.lib.stylix.colors.base01}"; +in { + programs.starship = { + enable = true; + settings = { + add_newline = true; + format = lib.concatStrings [ + "$nix_shell" + "$hostname" + "$directory" + "$git_branch" + "$git_state" + "$git_status" + "$character" + ]; + directory = { + style = accent; + }; + + character = { + success_symbol = "[❯](${accent})"; + error_symbol = "[❯](red)"; + vimcmd_symbol = "[❮](cyan)"; + }; + + nix_shell = { + format = "[$symbol]($style) "; + symbol = "🐚"; + style = ""; + }; + + git_branch = { + symbol = "[](${background-alt}) "; + style = "fg:${accent} bg:${background-alt}"; + format = "on [$symbol$branch]($style)[](${background-alt}) "; + }; + + git_status = { + format = "[[(*$conflicted$untracked$modified$staged$renamed$deleted)](218)($ahead_behind$stashed)]($style)"; + style = "cyan"; + conflicted = ""; + renamed = ""; + deleted = ""; + stashed = "≡"; + }; + + git_state = { + format = "([$state( $progress_current/$progress_total)]($style)) "; + style = "bright-black"; + }; + }; + }; +} diff --git a/home/programs/shell/zoxide.nix b/home/programs/shell/zoxide.nix new file mode 100644 index 0000000..4bf8749 --- /dev/null +++ b/home/programs/shell/zoxide.nix @@ -0,0 +1,7 @@ +# Zoxide is a cd replacement +{ + programs.zoxide = { + enable = true; + enableZshIntegration = true; + }; +} diff --git a/home/programs/shell/zsh.nix b/home/programs/shell/zsh.nix new file mode 100644 index 0000000..f7055be --- /dev/null +++ b/home/programs/shell/zsh.nix @@ -0,0 +1,196 @@ +# My shell configuration +{ + pkgs, + lib, + config, + ... +}: { + home.packages = with pkgs; [ + bat + ripgrep + ]; + + # Add go binaries to the PATH + home.sessionPath = ["$HOME/go/bin"]; + + home.sessionVariables = { + COLORTERM = "truecolor"; + }; + + programs.zsh = { + enable = true; + enableCompletion = true; + autosuggestion.enable = true; + syntaxHighlighting = { + enable = true; + highlighters = [ + "main" + "brackets" + "pattern" + "regexp" + "root" + "line" + ]; + }; + historySubstringSearch.enable = true; + + history = { + ignoreDups = true; + save = 10000; + size = 10000; + }; + + profileExtra = lib.optionalString (config.home.sessionPath != []) '' + export PATH="$PATH''${PATH:+:}${lib.concatStringsSep ":" config.home.sessionPath}" + ''; + + shellAliases = { + # Change default + vim = "nvim"; + vi = "nvim"; + cd = "z"; + ls = "eza --icons=always --no-quotes"; + tree = "eza --icons=always --tree --no-quotes"; + cat = "bat --theme=base16 --color=always --paging=never --tabs=2 --wrap=never --plain"; + mkdir = "mkdir -p"; + + # Shortcuts + spt = "spotatui"; + v = "nvim"; + c = "clear"; + e = "exit"; + open = "${pkgs.xdg-utils}/bin/xdg-open"; + + notes = "nvim ~/notes/index.md --cmd 'cd ~/notes' -c ':lua Snacks.picker.smart()'"; + nix-shell = "nix-shell --command zsh"; + + # git + g = "lazygit"; + ga = "git add"; + gc = "git commit"; + gcu = "git add . && git commit -m 'Update'"; + gp = "git push"; + gpl = "git pull"; + gs = "git status"; + gd = "git diff"; + gco = "git checkout"; + gcb = "git checkout -b"; + gbr = "git branch"; + grs = "git reset HEAD~1"; + grh = "git reset --hard HEAD~1"; + gaa = "git add ."; + gcm = "git commit -m"; + + # Typo + clera = "clear"; + celar = "clear"; + claer = "clear"; + sl = "ls"; + }; + + initContent = + # bash + '' + bindkey -e + + # Open command in VIM + autoload -Uz edit-command-line + zle -N edit-command-line + bindkey '^X' edit-command-line + + # Suffix Aliases + alias -s {nix,md,txt,json,yml,yaml,go}=nvim + alias -s {png,jpg,jpeg,gif,pdf}=xdg-open + + # 3. Global Aliases (Remplacés n'importe où dans la commande, pas seulement au début) + alias -g G="| grep" + alias -g L="| less" + alias -g V="| nvim" + alias -g H="| head" + alias -g T="| tail" + alias -g JQ="| jq" + alias -g C="| wl-copy" + alias -g NE="2>/dev/null" + alias -g ND=">/dev/null" + alias -g NUL=">/dev/null 2>1" + + # search history based on what's typed in the prompt + autoload -U history-search-end + zle -N history-beginning-search-backward-end history-search-end + zle -N history-beginning-search-forward-end history-search-end + bindkey "^[OA" history-beginning-search-backward-end + bindkey "^[OB" history-beginning-search-forward-end + + # General completion behavior + zstyle ':completion:*' completer _extensions _complete _approximate + + # Use cache + zstyle ':completion:*' use-cache on + zstyle ':completion:*' cache-path "$XDG_CACHE_HOME/zsh/.zcompcache" + + # Complete the alias + zstyle ':completion:*' complete true + + # Autocomplete options + zstyle ':completion:*' complete-options true + + # Completion matching control + zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' 'r:|[._-]=* r:|=*' 'l:|=* r:|=*' + zstyle ':completion:*' keep-prefix true + + # Group matches and describe + zstyle ':completion:*' menu select + zstyle ':completion:*' list-grouped false + zstyle ':completion:*' list-separator ''' + zstyle ':completion:*' group-name ''' + zstyle ':completion:*' verbose yes + zstyle ':completion:*:matches' group 'yes' + zstyle ':completion:*:warnings' format '%F{red}%B-- No match for: %d --%b%f' + zstyle ':completion:*:messages' format '%d' + zstyle ':completion:*:corrections' format '%B%d (errors: %e)%b' + zstyle ':completion:*:descriptions' format '[%d]' + + # Colors + zstyle ':completion:*' list-colors ''${(s.:.)LS_COLORS} + + # Case insensitive tab completion + zstyle ':completion:*:*:cd:*' tag-order local-directories directory-stack path-directories + zstyle ':completion:*:*:cd:*:directory-stack' menu yes select + zstyle ':completion:*:-tilde-:*' group-order 'named-directories' 'path-directories' 'users' 'expand' + zstyle ':completion:*:*:-command-:*:*' group-order aliases builtins functions commands + zstyle ':completion:*' special-dirs true + zstyle ':completion:*' squeeze-slashes true + + # Sort + zstyle ':completion:*' sort false + zstyle ":completion:*:git-checkout:*" sort false + zstyle ':completion:*' file-sort modification + zstyle ':completion:*:eza' sort false + zstyle ':completion:complete:*:options' sort false + zstyle ':completion:files' sort false + + autoload zmv + + hash -d dl=~/Downloads + hash -d ni=~/.config/nixos + hash -d de=~/dev + hash -d cy=~/Cyber + + ${lib.optionalString config.services.gpg-agent.enable '' + gnupg_path=$(ls $XDG_RUNTIME_DIR/gnupg) + export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/gnupg/$gnupg_path/S.gpg-agent.ssh" + ''} + + # Allow foot to pipe command output + function precmd { + if ! builtin zle; then + print -n "\e]133;D\e\\" + fi + } + function preexec { + print -n "\e]133;C\e\\" + } + + ''; + }; +} diff --git a/home/programs/spotatui/default.nix b/home/programs/spotatui/default.nix new file mode 100644 index 0000000..70c61ab --- /dev/null +++ b/home/programs/spotatui/default.nix @@ -0,0 +1,104 @@ +# Spotatui is a terminal user interface for Spotify, written in Rust. It allows you to control your Spotify playback and manage your playlists directly from the terminal. +{ + config, + pkgs, + ... +}: let + c = config.lib.stylix.colors; + rgb = base: "${c."${base}-rgb-r"}, ${c."${base}-rgb-g"}, ${c."${base}-rgb-b"}"; +in { + home.packages = with pkgs; [ + spotatui + ]; + + home.file.".config/spotatui/config.yml".text = '' + keybindings: + back: q + next_page: ctrl-d + previous_page: ctrl-u + jump_to_start: ctrl-a + jump_to_end: ctrl-e + jump_to_album: a + jump_to_artist_album: A + jump_to_context: o + manage_devices: d + decrease_volume: '-' + increase_volume: + + toggle_playback: space + seek_backwards: < + seek_forwards: '>' + next_track: n + previous_track: p + force_previous_track: P + help: '?' + shuffle: ctrl-s + repeat: ctrl-r + search: / + submit: enter + copy_song_url: c + copy_album_url: C + audio_analysis: v + lyrics_view: B + cover_art_view: G + add_item_to_queue: z + show_queue: Q + open_settings: alt-, + save_settings: alt-s + listening_party: ctrl-p + like_track: F + behavior: + seek_milliseconds: 5000 + volume_increment: 10 + volume_percent: 100 + tick_rate_milliseconds: 16 + enable_text_emphasis: true + show_loading_indicator: true + enforce_wide_search_bar: true + enable_global_song_count: false + disable_mouse_inputs: false + enable_discord_rpc: false + discord_rpc_client_id: null + enable_announcements: false + announcement_feed_url: null + seen_announcement_ids: + - 2026-05-19-sonos-help-wanted + - 2026-02-27-major-refactor-complete + shuffle_enabled: false + liked_icon: ♥ + shuffle_icon: 🔀 + repeat_track_icon: 🔂 + repeat_context_icon: 🔁 + playing_icon: ▶ + paused_icon: ⏸ + set_window_title: true + visualizer_style: Equalizer + dismissed_announcements: [] + relay_server_url: wss://spotatui-party.spotatui.workers.dev/ws + stop_after_current_track: false + sidebar_width_percent: 20 + playbar_height_rows: 6 + library_height_percent: 30 + startup_behavior: continue + disable_auto_update: true + auto_update_delay: '0' + keepawake_enabled: true + theme: + preset: Custom + active: ${rgb "base0D"} + banner: ${rgb "base0C"} + error_border: ${rgb "base08"} + error_text: ${rgb "base08"} + hint: ${rgb "base0A"} + hovered: ${rgb "base0E"} + inactive: ${rgb "base03"} + playbar_background: Reset + playbar_progress: ${rgb "base0D"} + playbar_progress_text: ${rgb "base05"} + playbar_text: Reset + selected: ${rgb "base0D"} + text: Reset + background: Reset + header: Reset + highlighted_lyrics: ${rgb "base0B"} + ''; +} diff --git a/home/programs/thunar/default.nix b/home/programs/thunar/default.nix new file mode 100644 index 0000000..b977f6b --- /dev/null +++ b/home/programs/thunar/default.nix @@ -0,0 +1,176 @@ +# Thunar is a file explorer +{ + pkgs, + pkgs-stable, + config, + lib, + ... +}: let + user = config.var.username; +in { + # ctrl + m to toggle the menubar + home.packages = + (with pkgs-stable; [ + xfce.thunar + xfce.xfconf + xfce.tumbler + xfce.thunar-archive-plugin + xfce.thunar-volman + xfce.thunar-media-tags-plugin + p7zip + xarchiver + ]) + ++ (with pkgs; [ + # Icon themes: keep on global pkgs to avoid conflicts with other modules + papirus-icon-theme + material-icons + material-design-icons + material-symbols + ]); + + gtk = { + enable = true; + iconTheme = { + name = "Papirus-Dark"; + package = pkgs.papirus-icon-theme; + }; + + # bookmarks for the side pane + gtk3.bookmarks = [ + "file:///home/${user}/Downloads Downloads" + "file:///home/${user}/Pictures Pictures" + "file:///home/${user}/.config/nixos NixOS" + "file:///home/${user}/dev Development" + ]; + }; + + qt.enable = true; + + home.sessionVariables = { + XDG_ICON_DIR = "${pkgs.papirus-icon-theme}/share/icons/Papirus"; + QS_ICON_THEME = "Papirus"; + QT_STYLE_OVERRIDE = lib.mkForce "Fusion"; + }; + + home.file.".config/xarchiver/xarchiverrc".text = '' + [xarchiver] + preferred_format=0 + prefer_unzip=true + confirm_deletion=true + sort_filename_content=false + advanced_isearch=true + auto_expand=true + store_output=false + icon_size=2 + show_archive_comment=false + show_sidebar=true + show_location_bar=true + show_toolbar=true + preferred_custom_cmd= + preferred_temp_dir=/tmp + preferred_extract_dir=./ + allow_sub_dir=0 + ensure_directory=true + overwrite=false + full_path=2 + touch=false + fresh=false + update=false + store_path=false + updadd=true + freshen=false + recurse=true + solid_archive=false + remove_files=false + ''; + + home.file.".config/xfce4/xfconf/xfce-perchannel-xml/thunar.xml" = { + text = '' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ''; + force = true; + }; + + xdg.configFile."Thunar/uca.xml".text = '' + + + + utilities-terminal + Open Terminal Here + 1700000000000001 + ghostty -d %f + Opens terminal in the selected folder + * + + + + + + Extract here + + 1689618425925956-3 + xarchiver -x . %f + Extracts the archive into the directory it is located in. + * + *.tar.bz2;*.tar.gz;*.tar.xz;*.tar.Z;*.tar;*.taz;*.tb2;*.tbz;*.tbz2;*.tgz;*.txz;*.zip;*.bz2;*.docx;*.apk;*.gz;*.odt; + + + + package-x-generic + Compress here (tar.gz) + + 1700000000000003 + tar -czvf %n.tar.gz %N + Creates a compressed archive (.tar.gz) of selected files/folders. + * + * + + + + + ''; +} diff --git a/home/programs/yazi/default.nix b/home/programs/yazi/default.nix new file mode 100644 index 0000000..1c72124 --- /dev/null +++ b/home/programs/yazi/default.nix @@ -0,0 +1,129 @@ +{pkgs, ...}: { + programs.yazi = { + enable = true; + shellWrapperName = "y"; + + plugins = { + git = { + package = pkgs.yaziPlugins.git; + setup = true; + }; + ouch = pkgs.yaziPlugins.ouch; + piper = pkgs.yaziPlugins.piper; + convert = pkgs.yaziPlugins.convert; + "jump-to-char" = pkgs.yaziPlugins."jump-to-char"; + "wl-clipboard" = pkgs.yaziPlugins."wl-clipboard"; + "batch-rename-gui" = pkgs.yaziPlugins.mkYaziPlugin { + pname = "batch-rename-gui.yazi"; + version = "0-unstable-2025-07-08"; + src = pkgs.fetchFromGitHub { + owner = "pakhromov"; + repo = "batch-rename-gui.yazi"; + rev = "5c2d5aa349948b6ab405a171541faab44751f6a5"; + hash = "sha256-3RviPY3WOyYi5GWXWRYMWp6VLxCe5cuJX7Kb7AyWxLE="; + }; + }; + }; + + settings.mgr.ratio = [0 4 3]; + + settings.plugin = { + prepend_fetchers = [ + { + url = "*"; + run = "git"; + group = "git"; + } + { + url = "*/"; + run = "git"; + group = "git"; + } + ]; + prepend_previewers = [ + { + url = "*.md"; + run = ''piper -- CLICOLOR_FORCE=1 glow -w=$w -s=dark "$1"''; + } + ]; + prepend_openers = [ + { + url = "*.{zip,tar,gz,bz2,xz,7z,rar}"; + run = "ouch"; + } + ]; + }; + + keymap.mgr.prepend_keymap = [ + { + on = ["C"]; + run = "plugin ouch"; + desc = "Compress"; + } + { + on = ["X"]; + run = "plugin ouch --args=extract"; + desc = "Extract"; + } + { + on = ["c" "p"]; + run = "plugin convert -- --extension='png'"; + desc = "Convert to PNG"; + } + { + on = ["c" "j"]; + run = "plugin convert -- --extension='jpg'"; + desc = "Convert to JPG"; + } + { + on = ["c" "w"]; + run = "plugin convert -- --extension='webp'"; + desc = "Convert to WebP"; + } + { + on = ["M"]; + run = ''shell 'exiftool "$@" | less' --block''; + desc = "Show metadata"; + } + { + on = ["T"]; + run = "plugin toggle-parent"; + desc = "Toggle parent pane"; + } + { + on = ["F"]; + run = "plugin jump-to-char"; + desc = "Jump to char"; + } + { + on = ["Y"]; + run = "plugin wl-clipboard"; + desc = "Copy to clipboard (Wayland)"; + } + { + on = ["B"]; + run = "plugin batch-rename-gui"; + desc = "Batch rename"; + } + ]; + }; + + home.packages = with pkgs; [glow ouch hexyl exiftool fzf wl-clipboard]; + + xdg.configFile."yazi/plugins/toggle-parent.yazi/main.lua".text = '' + --- @sync entry + local RESTORE_WIDTH = 1 + return { + entry = function(st, job) + local r = rt.mgr.ratio + if r.parent == 0 then + rt.mgr.ratio = { st.width or RESTORE_WIDTH, r.current, r.preview } + else + st.width = r.parent + rt.mgr.ratio = { 0, r.current, r.preview } + end + ya.emit("app:resize", {}) + end + } + ''; +} diff --git a/home/system/caelestia-shell/appearance.nix b/home/system/caelestia-shell/appearance.nix new file mode 100644 index 0000000..f80a0c9 --- /dev/null +++ b/home/system/caelestia-shell/appearance.nix @@ -0,0 +1,50 @@ +{ + pkgs, + config, + ... +}: let + inherit (config.theme) bar-rounding bar-thickness; + inherit (config.stylix) fonts; +in { + home.packages = with pkgs; [ + papirus-icon-theme + ]; + + programs.caelestia.settings = { + paths.sessionGif = ./session-gif-hacker-cat.gif; + background.enabled = false; + appearance = { + transparency = { + enabled = true; + base = config.theme.active-opacity; + layers = config.theme.inactive-opacity; + }; + font.family = { + material = "Material Symbols Rounded"; + mono = fonts.monospace.name; + sans = fonts.sansSerif.name; + }; + }; + utilities = { + enabled = true; + maxToasts = 4; + toasts = { + audioInputChanged = false; + audioOutputChanged = false; + capsLockChanged = false; + chargingChanged = true; + configLoaded = false; + dndChanged = true; + gameModeChanged = true; + numLockChanged = false; + nowPlaying = false; + kbLayoutChanged = false; + }; + }; + dashboard.showOnHover = false; + border = { + rounding = bar-rounding; + thickness = bar-thickness; + }; + }; +} diff --git a/home/system/caelestia-shell/bar.nix b/home/system/caelestia-shell/bar.nix new file mode 100644 index 0000000..532c4f4 --- /dev/null +++ b/home/system/caelestia-shell/bar.nix @@ -0,0 +1,68 @@ +{ + programs.caelestia.settings.bar = { + clock.showIcon = false; + popouts.activeWindow = false; + persistent = true; + status = { + showBattery = true; + showMicrophone = false; + showLockStatus = false; + showBluetooth = true; + showAudio = true; + showKbLayout = false; + showNetwork = true; + }; + workspaces = { + activeIndicator = true; + activeLabel = "󰪥 "; + activeTrail = false; + label = " "; + occupiedBg = true; + occupiedLabel = "󰪥 "; + showWindows = false; + shown = 5; + }; + entries = [ + { + id = "logo"; + enabled = true; + } + { + id = "workspaces"; + enabled = true; + } + { + id = "spacer"; + enabled = true; + } + { + id = "activeWindow"; + enabled = true; + } + { + id = "spacer"; + enabled = true; + } + { + id = "tray"; + enabled = true; + } + { + id = "clock"; + enabled = true; + } + { + id = "statusIcons"; + enabled = true; + } + { + id = "power"; + enabled = true; + } + ]; + tray = { + background = false; + recolour = false; + }; + }; +} diff --git a/home/system/caelestia-shell/default.nix b/home/system/caelestia-shell/default.nix new file mode 100644 index 0000000..b7c4e94 --- /dev/null +++ b/home/system/caelestia-shell/default.nix @@ -0,0 +1,80 @@ +# Caelestia Shell Home Manager Configuration +# See https://github.com/caelestia-dots/shell +{ + pkgs, + inputs, + lib, + ... +}: { + imports = [ + inputs.caelestia-shell.homeManagerModules.default + ./bar.nix + ./launcher.nix + ./appearance.nix + ./scheme.nix + ./swappy.nix + ]; + + programs.caelestia = { + enable = true; + systemd.enable = false; + settings = { + services.weatherLocation = "Paris"; + general = { + apps = { + terminal = ["ghostty"]; + audio = ["pavucontrol"]; + explorer = ["thunar"]; + }; + idle = { + timeouts = []; + }; + }; + }; + cli = { + enable = true; + settings.theme = { + enableTerm = false; + enableDiscord = false; + enableSpicetify = false; + enableBtop = false; + enableCava = false; + enableHypr = false; + enableGtk = false; + enableQt = false; + }; + }; + }; + + home.packages = with pkgs; [ + gpu-screen-recorder + ]; + + wayland.windowManager.hyprland.settings.exec-once = [ + "uwsm app -- caelestia resizer -d" + "uwsm app -- caelestia shell -d" + "caelestia scheme set -n onedark" + "caelestia scheme set -n custom" + ]; + + # shell.json is managed by home-manager (read-only symlink) but caelestia + # needs to write to it at runtime: replace the symlink with a mutable copy. + # The stale .hm-backup must be removed before linkGeneration so HM can + # back up the runtime-modified shell.json without hitting a conflict. + home.activation.caelestiaCleanBackup = lib.hm.dag.entryBefore ["linkGeneration"] '' + $DRY_RUN_CMD rm -f "$HOME/.config/caelestia/shell.json.hm-backup" + ''; + + home.activation.caelestiaWritableShellConfig = lib.hm.dag.entryAfter ["linkGeneration"] '' + if [ -L "$HOME/.config/caelestia/shell.json" ]; then + $DRY_RUN_CMD cp --remove-destination \ + "$(readlink -f "$HOME/.config/caelestia/shell.json")" \ + "$HOME/.config/caelestia/shell.json" + fi + ''; + + services.cliphist = { + enable = true; + allowImages = true; + }; +} diff --git a/home/system/caelestia-shell/launcher.nix b/home/system/caelestia-shell/launcher.nix new file mode 100644 index 0000000..cf90a48 --- /dev/null +++ b/home/system/caelestia-shell/launcher.nix @@ -0,0 +1,188 @@ +{ + programs.caelestia.settings = { + session.commands = { + shutdown = [ + "systemctl" + "poweroff" + ]; + logout = [ + "loginctl" + "lock-session" + ]; + hibernate = [ + "systemctl" + "hibernate" + ]; + reboot = [ + "systemctl" + "reboot" + ]; + }; + launcher = { + actionPrefix = "/"; + actions = [ + { + name = "Calculator"; + icon = "calculate"; + description = "Do simple math equations (powered by Qalc)"; + command = [ + "autocomplete" + "calc" + ]; + enabled = true; + dangerous = false; + } + { + name = "Shutdown"; + icon = "power_settings_new"; + description = "Shutdown the system"; + command = [ + "systemctl" + "poweroff" + ]; + enabled = true; + dangerous = true; + } + { + name = "Reboot"; + icon = "cached"; + description = "Reboot the system"; + command = [ + "systemctl" + "reboot" + ]; + enabled = true; + dangerous = true; + } + { + name = "Logout"; + icon = "exit_to_app"; + description = "Log out of the current session"; + command = [ + "loginctl" + "terminate-user" + "" + ]; + enabled = true; + dangerous = true; + } + { + name = "Lock"; + icon = "lock"; + description = "Lock the current session"; + command = [ + "loginctl" + "lock-session" + ]; + enabled = true; + dangerous = false; + } + { + name = "Sleep"; + icon = "bedtime"; + description = "Suspend then hibernate"; + command = [ + "systemctl" + "suspend-then-hibernate" + ]; + enabled = true; + dangerous = false; + } + { + name = "Restart caelestia"; + icon = "cached"; + description = "Restart caelestia"; + command = [ + "hyprctl" + "dispatch" + "exec" + "caelestia-shell kill | sleep 1 | caelestia-shell" + ]; + enabled = true; + dangerous = false; + } + { + name = "Emoji Picker"; + icon = "mood"; + description = "Toggle the emoji picker"; + command = [ + "caelestia" + "emoji" + "-p" + ]; + enabled = true; + dangerous = false; + } + { + name = "Clipboard History"; + icon = "content_paste"; + description = "Toggle the clipboard history"; + command = [ + "caelestia" + "clipboard" + ]; + enabled = true; + dangerous = false; + } + { + name = "Delete from Clipboard History"; + icon = "content_paste_off"; + description = "Delete a line from the clipboard history"; + command = [ + "caelestia" + "clipboard" + ]; + enabled = true; + dangerous = false; + } + { + name = "Night Shift"; + icon = "moon_stars"; + description = "Toggle Night Shift, the blue light filter"; + command = ["nightshift-toggle"]; + enabled = true; + dangerous = false; + } + { + name = "Hyprpicker"; + icon = "colorize"; + description = "Pick an hex color"; + command = [ + "hyprpicker" + "-a" + ]; + enabled = true; + dangerous = false; + } + { + name = "Run in background"; + icon = "play_circle"; + description = "Type and run any shell command in the background"; + command = [ + "ghostty" + "--title=run-bg" + "-e" + "bash" + "-c" + "printf 'Run: '; read -r cmd; [ -n \"$cmd\" ] && hyprctl dispatch exec \"$cmd\"" + ]; + enabled = true; + dangerous = false; + } + ]; + dragThreshold = 50; + enableDangerousActions = false; + maxShown = 7; + specialPrefix = "@"; + useFuzzy = { + apps = false; + actions = false; + schemes = false; + variants = false; + wallpapers = false; + }; + showOnHover = false; + hiddenApps = []; + }; + }; +} diff --git a/home/system/caelestia-shell/scheme.nix b/home/system/caelestia-shell/scheme.nix new file mode 100644 index 0000000..e8c6e5b --- /dev/null +++ b/home/system/caelestia-shell/scheme.nix @@ -0,0 +1,137 @@ +# This Nix module customizes the color scheme of the Caelestia CLI application using the Stylix base16 color palette. +{ + pkgs, + inputs, + config, + ... +}: let + colors = config.lib.stylix.colors; + + customSchemeFile = pkgs.writeText "custom-dark.txt" '' + primary_paletteKeyColor ${colors.base0D} + secondary_paletteKeyColor ${colors.base04} + tertiary_paletteKeyColor ${colors.base08} + neutral_paletteKeyColor ${colors.base03} + neutral_variant_paletteKeyColor ${colors.base03} + background ${colors.base00} + onBackground ${colors.base05} + surface ${colors.base00} + surfaceDim ${colors.base00} + surfaceBright ${colors.base02} + surfaceContainerLowest ${colors.base01} + surfaceContainerLow ${colors.base01} + surfaceContainer ${colors.base01} + surfaceContainerHigh ${colors.base02} + surfaceContainerHighest ${colors.base02} + onSurface ${colors.base05} + surfaceVariant ${colors.base02} + onSurfaceVariant ${colors.base04} + inverseSurface ${colors.base05} + inverseOnSurface ${colors.base00} + outline ${colors.base03} + outlineVariant ${colors.base02} + shadow ${colors.base00} + scrim ${colors.base00} + surfaceTint ${colors.base0D} + primary ${colors.base0D} + onPrimary ${colors.base00} + primaryContainer ${colors.base0D} + onPrimaryContainer ${colors.base05} + inversePrimary ${colors.base0D} + secondary ${colors.base0C} + onSecondary ${colors.base00} + secondaryContainer ${colors.base02} + onSecondaryContainer ${colors.base0C} + tertiary ${colors.base08} + onTertiary ${colors.base00} + tertiaryContainer ${colors.base08} + onTertiaryContainer ${colors.base00} + error ${colors.base08} + onError ${colors.base00} + errorContainer ${colors.base08} + onErrorContainer ${colors.base05} + primaryFixed ${colors.base0D} + primaryFixedDim ${colors.base0D} + onPrimaryFixed ${colors.base00} + onPrimaryFixedVariant ${colors.base00} + secondaryFixed ${colors.base0C} + secondaryFixedDim ${colors.base0C} + onSecondaryFixed ${colors.base00} + onSecondaryFixedVariant ${colors.base02} + tertiaryFixed ${colors.base08} + tertiaryFixedDim ${colors.base08} + onTertiaryFixed ${colors.base00} + onTertiaryFixedVariant ${colors.base00} + term0 ${colors.base00} + term1 ${colors.base08} + term2 ${colors.base0B} + term3 ${colors.base0A} + term4 ${colors.base0D} + term5 ${colors.base0E} + term6 ${colors.base0C} + term7 ${colors.base05} + term8 ${colors.base03} + term9 ${colors.base08} + term10 ${colors.base0B} + term11 ${colors.base0A} + term12 ${colors.base0D} + term13 ${colors.base0E} + term14 ${colors.base0C} + term15 ${colors.base07} + rosewater ${colors.base06} + flamingo ${colors.base0F} + pink ${colors.base0E} + mauve ${colors.base0D} + red ${colors.base08} + maroon ${colors.base08} + peach ${colors.base09} + yellow ${colors.base0A} + green ${colors.base0B} + teal ${colors.base0C} + sky ${colors.base0C} + sapphire ${colors.base0C} + blue ${colors.base0D} + lavender ${colors.base0D} + klink ${colors.base0D} + klinkSelection ${colors.base0D} + kvisited ${colors.base0E} + kvisitedSelection ${colors.base0E} + knegative ${colors.base08} + knegativeSelection ${colors.base08} + kneutral ${colors.base0A} + kneutralSelection ${colors.base0A} + kpositive ${colors.base0B} + kpositiveSelection ${colors.base0B} + text ${colors.base05} + subtext1 ${colors.base04} + subtext0 ${colors.base03} + overlay2 ${colors.base03} + overlay1 ${colors.base03} + overlay0 ${colors.base02} + surface2 ${colors.base02} + surface1 ${colors.base01} + surface0 ${colors.base01} + base ${colors.base00} + mantle ${colors.base00} + crust ${colors.base00} + success ${colors.base0B} + onSuccess ${colors.base00} + successContainer ${colors.base0B} + onSuccessContainer ${colors.base05} + ''; + + colorsHash = builtins.hashString "sha256" (builtins.toJSON colors); + + customCli = + inputs.caelestia-cli.packages.${pkgs.stdenv.hostPlatform.system}.default.overrideAttrs + (oldAttrs: { + name = "${oldAttrs.name or "caelestia-cli"}-themed-${colorsHash}"; + postUnpack = '' + mkdir -p $sourceRoot/src/caelestia/data/schemes/custom/main + cp ${customSchemeFile} $sourceRoot/src/caelestia/data/schemes/custom/main/dark.txt + echo "Custom scheme added to source" + ''; + }); +in { + programs.caelestia.cli.package = customCli; +} diff --git a/home/system/caelestia-shell/session-gif-hacker-cat.gif b/home/system/caelestia-shell/session-gif-hacker-cat.gif new file mode 100644 index 0000000..4cc58d5 Binary files /dev/null and b/home/system/caelestia-shell/session-gif-hacker-cat.gif differ diff --git a/home/system/caelestia-shell/swappy.nix b/home/system/caelestia-shell/swappy.nix new file mode 100644 index 0000000..8a25049 --- /dev/null +++ b/home/system/caelestia-shell/swappy.nix @@ -0,0 +1,11 @@ +{ + xdg.configFile."swappy/config".text = '' + [Default] + save_dir=~/Pictures/Screenshots + save_filename_format=screenshot-%Y%m%d-%H%M%S.png + show_panel=false + line_size=5 + text_size=20 + text_font=sans-serif + ''; +} diff --git a/home/system/hyprland/animations.nix b/home/system/hyprland/animations.nix new file mode 100644 index 0000000..a0a3952 --- /dev/null +++ b/home/system/hyprland/animations.nix @@ -0,0 +1,52 @@ +{config, ...}: let + animationSpeed = config.theme.animation-speed; + + animationDuration = + if animationSpeed == "slow" + then "4" + else if animationSpeed == "medium" + then "2.5" + else "1.5"; + borderDuration = + if animationSpeed == "slow" + then "10" + else if animationSpeed == "medium" + then "6" + else "3"; +in { + wayland.windowManager.hyprland.settings = { + animations = { + enabled = true; + bezier = [ + "linear, 0, 0, 1, 1" + "md3_standard, 0.2, 0, 0, 1" + "md3_decel, 0.05, 0.7, 0.1, 1" + "md3_accel, 0.3, 0, 0.8, 0.15" + "overshot, 0.05, 0.9, 0.1, 1.1" + "crazyshot, 0.1, 1.5, 0.76, 0.92" + "hyprnostretch, 0.05, 0.9, 0.1, 1.0" + "menu_decel, 0.1, 1, 0, 1" + "menu_accel, 0.38, 0.04, 1, 0.07" + "easeInOutCirc, 0.85, 0, 0.15, 1" + "easeOutCirc, 0, 0.55, 0.45, 1" + "easeOutExpo, 0.16, 1, 0.3, 1" + "softAcDecel, 0.26, 0.26, 0.15, 1" + "md2, 0.4, 0, 0.2, 1" + ]; + + animation = [ + "windows, 1, ${animationDuration}, md3_decel, popin 60%" + "windowsIn, 1, ${animationDuration}, md3_decel, popin 60%" + "windowsOut, 1, ${animationDuration}, md3_accel, popin 60%" + "border, 1, ${borderDuration}, default" + "fade, 1, ${animationDuration}, md3_decel" + "layersIn, 1, ${animationDuration}, menu_decel, slide" + "layersOut, 1, ${animationDuration}, menu_accel" + "fadeLayersIn, 1, ${animationDuration}, menu_decel" + "fadeLayersOut, 1, ${animationDuration}, menu_accel" + "workspaces, 1, ${animationDuration}, menu_decel, slide" + "specialWorkspace, 1, ${animationDuration}, md3_decel, slidevert" + ]; + }; + }; +} diff --git a/home/system/hyprland/bindings.nix b/home/system/hyprland/bindings.nix new file mode 100644 index 0000000..2da3577 --- /dev/null +++ b/home/system/hyprland/bindings.nix @@ -0,0 +1,207 @@ +{ + pkgs, + lib, + config, + ... +}: let + colors = config.lib.stylix.colors; + + mkMenu = menu: let + configFile = pkgs.writeText "config.yaml" ( + lib.generators.toYAML {} { + anchor = "bottom-right"; + border = "#${colors.base0D}80"; + background = "#${colors.base01}EE"; + color = "#${colors.base05}"; + margin_right = 15; + margin_bottom = 15; + rows_per_column = 5; + + inherit menu; + } + ); + in + pkgs.writeShellScriptBin "menu" '' + exec ${lib.getExe pkgs.wlr-which-key} ${configFile} + ''; +in { + wayland.windowManager.hyprland.settings = { + "$mod" = "SUPER"; + "$shiftMod" = "SUPER_SHIFT"; + + bind = + [ + # Applications + ( + "$shiftMod, A, exec, " + + lib.getExe (mkMenu [ + { + key = "a"; + desc = "Proton Authenticator"; + cmd = "env WEBKIT_DISABLE_COMPOSITING_MODE=1 ${pkgs.proton-authenticator}/bin/proton-authenticator"; + } + { + key = "p"; + desc = "Proton Pass"; + cmd = "${pkgs.proton-pass}/bin/proton-pass"; + } + { + key = "v"; + desc = "Proton VPN"; + cmd = "${pkgs.proton-vpn}/bin/protonvpn-app"; + } + { + key = "c"; + desc = "Proton Calendar"; + cmd = "${config.programs.helium.package}/bin/helium 'https://calendar.proton.me/'"; + } + { + key = "m"; + desc = "Proton Mail"; + cmd = "${config.programs.helium.package}/bin/helium 'https://mail.proton.me/'"; + } + { + key = "o"; + desc = "Obsidian"; + cmd = "${pkgs.obsidian}/bin/obsidian"; + } + { + key = "s"; + desc = "Signal"; + cmd = "${pkgs.signal-desktop}/bin/signal-desktop"; + } + { + key = "t"; + desc = "TickTick"; + cmd = "${pkgs.ticktick}/bin/ticktick"; + } + { + key = "b"; + desc = "Helium"; + cmd = "${config.programs.helium.package}/bin/helium"; + } + { + key = "i"; + desc = "Helium (Incognito)"; + cmd = "${config.programs.helium.package}/bin/helium --incognito"; + } + ]) + ) + + "$mod,B, exec, uwsm app -- ${config.programs.helium.package}/bin/helium" # Browser + + # Power + "$mod, X, global, caelestia:session" # Powermenu + ( + "$shiftMod, X, exec, " + + lib.getExe (mkMenu [ + { + key = "l"; + desc = "Lock"; + cmd = "hyprctl dispatch global caelestia:lock"; + } + { + key = "s"; + desc = "Suspend"; + cmd = "systemctl suspend"; + } + { + key = "r"; + desc = "Reboot"; + cmd = "systemctl reboot"; + } + { + key = "p"; + desc = "Power Off"; + cmd = "systemctl poweroff"; + } + { + key = "n"; + desc = "Nightshift"; + cmd = "nightshift-toggle"; + } + { + key = "c"; + desc = "Restart caelestia"; + cmd = "hyprctl dispatch exec 'caelestia-shell kill | sleep 1 | caelestia-shell'"; + } + ]) + ) + + # Quick launch + "$mod,RETURN, exec, uwsm app -- ${pkgs.ghostty}/bin/ghostty" # Ghostty (terminal) + "$mod,E, exec, uwsm app -- ${pkgs.thunar}/bin/thunar" # Thunar + "$shiftMod, E, exec, pkill fuzzel || caelestia emoji -p" # Emoji picker + "$mod, SPACE, global, caelestia:launcher" # Launcher + "$mod, N, exec, caelestia shell drawers toggle sidebar" # Sidebar (Notifications, quick actions) + "$mod, D, exec, caelestia shell drawers toggle dashboard" # Dashboard + + # Windows + "$mod,Q, killactive," # Close window + "$mod,F, fullscreen" # Toggle Fullscreen + "$shiftMod,F, togglefloating," # Toggle Floating + + # Focus Windows + "$mod,H, movefocus, l" # Move focus left + "$mod,J, movefocus, d" # Move focus Down + "$mod,K, movefocus, u" # Move focus Up + "$mod,L, movefocus, r" # Move focus Right + "$shiftMod,H, focusmonitor, -1" # Focus previous monitor + "$shiftMod,J, layoutmsg, removemaster" # Remove from master + "$shiftMod,K, layoutmsg, addmaster" # Add to master + "$shiftMod,L, focusmonitor, 1" # Focus next monitor + + # Utilities + "$shiftMod, SPACE, exec, caelestia shell gameMode toggle" # Toggle Focus/Game mode + "$shiftMod, S, global, caelestia:screenshotFreeze" # Capture region (freeze) + ", Print, global, caelestia:screenshotFreeze" # Capture region (freeze) + "$shiftMod+Alt, S, global, caelestia:screenshot" # Capture region + ] + ++ (builtins.concatLists ( + builtins.genList ( + i: let + ws = i + 1; + in [ + "$mod,code:1${toString i}, workspace, ${toString ws}" + "$mod SHIFT,code:1${toString i}, movetoworkspace, ${toString ws}" + ] + ) + 9 + )); + + bindm = [ + "$mod,mouse:272, movewindow" # Move Window (mouse) + "$mod,R, resizewindow" # Resize Window (mouse) + ]; + + bindl = [ + # Brightness + ", XF86MonBrightnessUp, global, caelestia:brightnessUp" + ", XF86MonBrightnessDown, global, caelestia:brightnessDown" + + # Media + ", XF86AudioPlay, global, caelestia:mediaToggle" + ", XF86AudioPause, global, caelestia:mediaToggle" + ", XF86AudioNext, global, caelestia:mediaNext" + ", XF86AudioPrev, global, caelestia:mediaPrev" + ", XF86AudioStop, global, caelestia:mediaStop" + + # Sound + ", XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle" + ", XF86AudioRaiseVolume, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ 0; wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+" + ", XF86AudioLowerVolume, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ 0; wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-" + ]; + + bindin = [ + # Launcher + "$mod, mouse:272, global, caelestia:launcherInterrupt" + "$mod, mouse:273, global, caelestia:launcherInterrupt" + "$mod, mouse:274, global, caelestia:launcherInterrupt" + "$mod, mouse:275, global, caelestia:launcherInterrupt" + "$mod, mouse:276, global, caelestia:launcherInterrupt" + "$mod, mouse:277, global, caelestia:launcherInterrupt" + "$mod, mouse_up, global, caelestia:launcherInterrupt" + "$mod, mouse_down, global, caelestia:launcherInterrupt" + ]; + }; +} diff --git a/home/system/hyprland/default.nix b/home/system/hyprland/default.nix new file mode 100644 index 0000000..aa158bb --- /dev/null +++ b/home/system/hyprland/default.nix @@ -0,0 +1,171 @@ +# Hyprland is a dynamic tiling Wayland compositor that is highly customizable and performant. +{ + pkgs, + config, + lib, + ... +}: let + border-size = config.theme.border-size; + gaps-in = config.theme.gaps-in; + gaps-out = config.theme.gaps-out; + active-opacity = config.theme.active-opacity; + inactive-opacity = config.theme.inactive-opacity; + rounding = config.theme.rounding; + blur = config.theme.blur; + keyboardLayout = config.var.keyboardLayout; + background = "rgba(" + config.lib.stylix.colors.base00 + "EE)"; +in { + imports = [ + ./animations.nix + ./bindings.nix + ./polkitagent.nix + ./keyboard-backlight.nix # CHANGEME: This is for omen laptop only + ]; + + home.packages = with pkgs; [ + qt5.qtwayland + qt6.qtwayland + libsForQt5.qt5ct + qt6Packages.qt6ct + xcb-util-cursor + libxcb + hyprland-qtutils + adw-gtk3 + hyprshot + hyprpicker + swappy + imv + wf-recorder + wlr-randr + brightnessctl + gnome-themes-extra + dconf + wayland-utils + wayland-protocols + ]; + + wayland.windowManager.hyprland = { + enable = true; + configType = "hyprlang"; + xwayland.enable = true; + systemd = { + enable = false; + variables = [ + "--all" + ]; # https://wiki.hyprland.org/Nix/Hyprland-on-Home-Manager/#programs-dont-work-in-systemd-services-but-do-on-the-terminal + }; + package = null; + portalPackage = null; + + settings = { + exec-once = [ + "dbus-update-activation-environment --systemd --all &" + ]; + + monitor = [ + ",prefered,auto,1" # default + ]; + + env = [ + "XDG_CURRENT_DESKTOP,Hyprland" + "XDG_SESSION_TYPE,wayland" + "XDG_SESSION_DESKTOP,Hyprland" + "ANKI_WAYLAND,1" + "DISABLE_QT5_COMPAT,0" + "QT_AUTO_SCREEN_SCALE_FACTOR,1" + "QT_QPA_PLATFORM,wayland;xcb" + "QT_QPA_PLATFORMTHEME,gtk3" + "QT_WAYLAND_DISABLE_WINDOWDECORATION,1" + "ELECTRON_OZONE_PLATFORM_HINT,auto" + "DIRENV_LOG_FORMAT," + "SDL_VIDEODRIVER,wayland" + "CLUTTER_BACKEND,wayland" + ]; + + cursor = { + no_hardware_cursors = true; + default_monitor = "eDP-2"; + }; + + general = { + resize_on_border = true; + gaps_in = gaps-in; + gaps_out = gaps-out; + border_size = border-size; + layout = "master"; + "col.inactive_border" = lib.mkForce background; + }; + + decoration = { + active_opacity = active-opacity; + inactive_opacity = inactive-opacity; + rounding = rounding; + shadow = { + enabled = true; + range = 20; + render_power = 3; + }; + blur = { + enabled = + if blur + then "true" + else "false"; + size = 18; + }; + }; + + master = { + new_status = "slave"; + allow_small_split = true; + mfact = 0.5; + }; + + gesture = "3, horizontal, workspace"; + + windowrule = [ + "match:class .*, suppress_event maximize" + "match:class helium, suppress_event fullscreen" + "match:class helium, sync_fullscreen false" + + "match:class proton-authenticator, float on" + "match:class proton-authenticator, center on" + "match:class proton-authenticator, size 500 400" + + "match:class protonvpn-app, float on" + "match:class protonvpn-app, center on" + "match:class protonvpn-app, size 500 400" + + "match:title run-bg, float on" + "match:title run-bg, center on" + "match:title run-bg, size 700 80" + ]; + + misc = { + disable_hyprland_logo = true; + disable_splash_rendering = true; + disable_autoreload = true; + focus_on_activate = true; + }; + + input = { + kb_layout = keyboardLayout; + + kb_options = "caps:escape"; + follow_mouse = 1; + sensitivity = 0.5; + repeat_delay = 300; + repeat_rate = 50; + numlock_by_default = true; + + touchpad = { + natural_scroll = true; + clickfinger_behavior = true; + }; + }; + + ecosystem = { + no_update_news = true; + }; + }; + }; +} diff --git a/home/system/hyprland/keyboard-backlight.nix b/home/system/hyprland/keyboard-backlight.nix new file mode 100644 index 0000000..53b72ca --- /dev/null +++ b/home/system/hyprland/keyboard-backlight.nix @@ -0,0 +1,44 @@ +# Turn the keyboard red/off when the battery is low +# Include this one only if you have a omen laptop with RGB keyboard +{ + pkgs, + config, + ... +}: let + alert-when-low-battery = false; + keyboard-backlight = pkgs.writeShellScriptBin "keyboard-backlight" '' + function set_keyboard_backlight { + local color=$1 + echo $color > /sys/devices/platform/hp-wmi/rgb_zones/zone00 + echo $color > /sys/devices/platform/hp-wmi/rgb_zones/zone01 + echo $color > /sys/devices/platform/hp-wmi/rgb_zones/zone02 + echo $color > /sys/devices/platform/hp-wmi/rgb_zones/zone03 + } + state="white" + set_keyboard_backlight ${config.lib.stylix.colors.base0D} + if [ "${toString alert-when-low-battery}" = "false" ]; then + exit 0 + fi + while true; do + BATTERY_LEVEL=$(cat /sys/class/power_supply/BAT*/capacity) + IS_CHARGING=$(cat /sys/class/power_supply/BAT*/status) + if [[ $BATTERY_LEVEL -le 10 && $IS_CHARGING != "Charging" ]]; then + if [[ $state == "red" ]];then + state="white" + set_keyboard_backlight "000000" + else + state="red" + set_keyboard_backlight "FF0000" + fi + else + state="white" + set_keyboard_backlight ${config.lib.stylix.colors.base0D} + fi + sleep 2 + done + ''; + + command = "bash ${keyboard-backlight}/bin/keyboard-backlight &"; +in { + wayland.windowManager.hyprland.settings.exec-once = [command]; +} diff --git a/home/system/hyprland/polkitagent.nix b/home/system/hyprland/polkitagent.nix new file mode 100644 index 0000000..221d359 --- /dev/null +++ b/home/system/hyprland/polkitagent.nix @@ -0,0 +1,6 @@ +# HyprPolkitAgent is a simple polkit agent for wayland compositors +{pkgs, ...}: { + home.packages = with pkgs; [hyprpolkitagent]; + + wayland.windowManager.hyprland.settings.exec-once = ["systemctl --user start hyprpolkitagent"]; +} diff --git a/home/system/hyprpaper/default.nix b/home/system/hyprpaper/default.nix new file mode 100644 index 0000000..be04dbd --- /dev/null +++ b/home/system/hyprpaper/default.nix @@ -0,0 +1,16 @@ +# Hyprpaper is used to set the wallpaper on the system +{lib, ...}: { + # The wallpaper is set by stylix + services.hyprpaper = { + enable = true; + settings = { + ipc = "on"; + splash = false; + }; + }; + systemd.user.services.hyprpaper.Unit.After = lib.mkForce "graphical-session.target"; + + wayland.windowManager.hyprland.settings.exec-once = [ + "systemctl --user enable --now hyprpaper.service" + ]; +} diff --git a/home/system/mime/default.nix b/home/system/mime/default.nix new file mode 100644 index 0000000..c94805d --- /dev/null +++ b/home/system/mime/default.nix @@ -0,0 +1,150 @@ +# Mime type associations for the system. +{ + lib, + pkgs, + ... +}: +with lib; let + defaultApps = { + # check desktop files here: `ls $(echo $XDG_DATA_DIRS| sed "s/:/ /g")` + text = [ + # "org.gnome.TextEditor.desktop" + "nvim-ghostty.desktop" + ]; + code = ["nvim-ghostty.desktop"]; + image = ["imv-dir.desktop"]; + audio = ["mpv.desktop"]; + video = ["mpv.desktop"]; + directory = ["thunar.desktop"]; + office = ["libreoffice.desktop"]; + pdf = ["zathura.desktop"]; + terminal = ["ghostty.desktop"]; + archive = ["xarchiver.desktop"]; + browser = ["helium.desktop"]; + }; + + mimeMap = { + text = ["text/plain"]; + code = [ + "text/x-csrc" + "text/x-chdr" + "text/x-c++src" + "text/x-c++hdr" + "text/x-rust" + "text/x-go" + "text/x-java" + "text/x-csharp" + + "text/x-python" + "application/x-shellscript" + "text/javascript" + "application/javascript" + "text/css" + "text/x-php" + "text/x-ruby" + + "application/json" + "application/xml" + "text/xml" + "text/x-yaml" + "application/x-yaml" + "application/toml" + "text/x-nix" + "text/markdown" + + "text/x-dockerfile" + "application/x-yaml" + "text/x-terraform" + + "application/x-perl" + "text/x-lua" + "text/x-haskell" + ]; + image = [ + "image/bmp" + "image/gif" + "image/jpeg" + "image/jpg" + "image/png" + "image/svg+xml" + "image/tiff" + "image/vnd.microsoft.icon" + "image/webp" + ]; + audio = [ + "audio/aac" + "audio/mpeg" + "audio/ogg" + "audio/opus" + "audio/wav" + "audio/webm" + "audio/x-matroska" + ]; + video = [ + "video/mp2t" + "video/mp4" + "video/mpeg" + "video/ogg" + "video/webm" + "video/x-flv" + "video/x-matroska" + "video/x-msvideo" + ]; + directory = ["inode/directory"]; + office = [ + "application/vnd.oasis.opendocument.text" + "application/vnd.oasis.opendocument.spreadsheet" + "application/vnd.oasis.opendocument.presentation" + "application/vnd.openxmlformats-officedocument.wordprocessingml.document" + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" + "application/vnd.openxmlformats-officedocument.presentationml.presentation" + "application/msword" + "application/vnd.ms-excel" + "application/vnd.ms-powerpoint" + "application/rtf" + ]; + pdf = ["application/pdf"]; + terminal = ["terminal"]; + archive = [ + "application/zip" + "application/rar" + "application/7z" + "application/*tar" + ]; + browser = [ + "text/html" + "application/xhtml+xml" + "x-scheme-handler/http" + "x-scheme-handler/https" + "x-scheme-handler/ftp" + ]; + }; + + nvim-ghostty = pkgs.makeDesktopItem { + name = "nvim-ghostty"; + desktopName = "Neovim (Ghostty)"; + exec = ''ghostty --title="Neovim Editor" -e nvim %F''; + terminal = false; + categories = [ + "Development" + "TextEditor" + ]; + mimeTypes = mimeMap.code ++ mimeMap.text; + }; + + associations = with lists; + listToAttrs ( + flatten (mapAttrsToList (key: map (type: attrsets.nameValuePair type defaultApps."${key}")) mimeMap) + ); +in { + home.packages = [nvim-ghostty]; + + xdg = { + configFile."mimeapps.list".force = true; + mimeApps = { + enable = true; + associations.added = associations; + defaultApplications = associations; + }; + }; +} diff --git a/home/system/udiskie/default.nix b/home/system/udiskie/default.nix new file mode 100644 index 0000000..f87dc5b --- /dev/null +++ b/home/system/udiskie/default.nix @@ -0,0 +1,8 @@ +# Udiskie is a simple daemon that uses udisks to automatically mount removable storage devices. +{ + services.udiskie = { + enable = true; + notify = true; + automount = true; + }; +} diff --git a/hosts/laptop/configuration.nix b/hosts/laptop/configuration.nix new file mode 100644 index 0000000..f333438 --- /dev/null +++ b/hosts/laptop/configuration.nix @@ -0,0 +1,58 @@ +{config, ...}: { + imports = [ + # Mostly system related configuration + ../../nixos/nvidia.nix # CHANGEME: Remove this line if you don't have an Nvidia GPU + ../../nixos/audio.nix + ../../nixos/bluetooth.nix + ../../nixos/fonts.nix + ../../nixos/home-manager.nix + ../../nixos/nix.nix + ../../nixos/systemd-boot.nix + ../../nixos/tuigreet.nix + ../../nixos/users.nix + ../../nixos/utils.nix + ../../nixos/hyprland.nix + ../../nixos/usbguard.nix + ../../home/programs/helium/system.nix # I hate browser's configuration.. + + ../../nixos/omen.nix # CHANGEME: For my laptop only, remove this (OMEN 16) + + # You should let those lines as is + ./hardware-configuration.nix + ./variables.nix + ]; + + # USBGuard: + # Allow all USB devices until a proper policy is configured. + # Run `sudo usbguard generate-policy` with your devices plugged in, + # then set rules = "" and switch implicitPolicyTarget to "block". + # services.usbguard.implicitPolicyTarget = lib.mkForce "allow"; + + services.usbguard.rules = '' + allow id 1d6b:0002 serial "0000:05:00.3" name "xHCI Host Controller" hash "4a4NgfdUaJO43rkCzmWRSeHHR/uUh5+SNsXnhosm9qs=" parent-hash "ldMchY4Tt4GPUYo30eNGvai+Fs/EdnVY3vMyxJUq4Nk=" with-interface 09:00:00 with-connect-type "" + allow id 1d6b:0003 serial "0000:05:00.3" name "xHCI Host Controller" hash "d+DNGWARDtv9nEK2ZvnNOCtFernuMu5/e/oZ7kCppqQ=" parent-hash "ldMchY4Tt4GPUYo30eNGvai+Fs/EdnVY3vMyxJUq4Nk=" with-interface 09:00:00 with-connect-type "" + allow id 1d6b:0002 serial "0000:05:00.4" name "xHCI Host Controller" hash "icotY3rI59mWiKsGxc59BGZZeBjfbuH0b4NUByj3cbQ=" parent-hash "tHvBfznK5rpQn+oa0PEEjHa29EAEvGyCcZixsfwA6W0=" with-interface 09:00:00 with-connect-type "" + allow id 1d6b:0003 serial "0000:05:00.4" name "xHCI Host Controller" hash "UbEoCZW8HT2ldc3qDeiK+IiQlGeaBC7F63681OwmKhI=" parent-hash "tHvBfznK5rpQn+oa0PEEjHa29EAEvGyCcZixsfwA6W0=" with-interface 09:00:00 with-connect-type "" + allow id 1d6b:0002 serial "0000:07:00.3" name "xHCI Host Controller" hash "pz29Oo0RhQ+5+7LgOZR4v3OlcsVv3m9kCgGsGUnoUjI=" parent-hash "DRyV2/31MYHdzkIEfbPQeb/1w4/PjOW6GqWrXkftf2I=" with-interface 09:00:00 with-connect-type "" + allow id 1d6b:0003 serial "0000:07:00.3" name "xHCI Host Controller" hash "O6iOpcl9StImWT62SrbeXacqbG6N/mTIipTRc0ipCGM=" parent-hash "DRyV2/31MYHdzkIEfbPQeb/1w4/PjOW6GqWrXkftf2I=" with-interface 09:00:00 with-connect-type "" + allow id 1d6b:0002 serial "0000:07:00.4" name "xHCI Host Controller" hash "Hp8B0Enf+ACRT2tyy0EqXj7eNsFDAnTRZadzuh/Iqd4=" parent-hash "l2vhvC+VGVKlkBUUK/usFu8jHJ/5bWOnJG6WzRexpt4=" with-interface 09:00:00 with-connect-type "" + allow id 1d6b:0003 serial "0000:07:00.4" name "xHCI Host Controller" hash "rJ3LKdvkCK3SUrCU3lV8qVbmPjA+r9Fe5106x2HlgK4=" parent-hash "l2vhvC+VGVKlkBUUK/usFu8jHJ/5bWOnJG6WzRexpt4=" with-interface 09:00:00 with-connect-type "" + allow id 0bda:c85c serial "00e04c000001" name "Bluetooth Radio" hash "Q/wlToV8WQgEYHBW/UIhnSwCCusCGqAR2D5gspSCImQ=" parent-hash "4a4NgfdUaJO43rkCzmWRSeHHR/uUh5+SNsXnhosm9qs=" with-interface { e0:01:01 e0:01:01 e0:01:01 e0:01:01 e0:01:01 e0:01:01 e0:01:01 e0:01:01 } with-connect-type "hardwired" + allow id 30c9:009f serial "01.00.00" name "HP True Vision FHD Camera" hash "eYW5fqReJd29tfHXkEktKC63dGfDpmlRMo5uMGUWwME=" parent-hash "icotY3rI59mWiKsGxc59BGZZeBjfbuH0b4NUByj3cbQ=" with-interface { 0e:01:01 0e:02:01 0e:02:01 0e:02:01 0e:02:01 0e:02:01 0e:02:01 0e:02:01 0e:02:01 0e:02:01 0e:02:01 0e:02:01 0e:02:01 fe:01:01 } with-connect-type "hardwired" + allow id 03f0:036b serial "" name "HP USB-C Dock G5" hash "iPFGrgGz0sWgKQjWD/F8eNOhkeR728dTG8JJtkUSvuM=" parent-hash "Hp8B0Enf+ACRT2tyy0EqXj7eNsFDAnTRZadzuh/Iqd4=" via-port "7-1" with-interface { 09:00:01 09:00:02 } with-connect-type "hotplug" + allow id 03f0:066b serial "" name "HP USB-C Dock G5" hash "JHDjLFApQNqijjmuKdJSWH5+1oLL7S6LQ9QHTAk5fTk=" parent-hash "rJ3LKdvkCK3SUrCU3lV8qVbmPjA+r9Fe5106x2HlgK4=" via-port "8-1" with-interface 09:00:00 with-connect-type "hotplug" + allow id 03f0:056b serial "201604140001" name "USB Audio" hash "OxQ8HQenW3/4HSGEBOSYFS15rXDTOaNDnjMbICweHgw=" parent-hash "iPFGrgGz0sWgKQjWD/F8eNOhkeR728dTG8JJtkUSvuM=" with-interface { 01:01:00 01:02:00 01:02:00 01:02:00 01:02:00 03:00:00 } with-connect-type "unknown" + allow id 03f0:086b serial "" name "USB2734" hash "MSXcPAlZqkpTyZQylOhSIB8eMfST2AzVHV9EbrBGTWc=" parent-hash "iPFGrgGz0sWgKQjWD/F8eNOhkeR728dTG8JJtkUSvuM=" via-port "7-1.3" with-interface { 09:00:01 09:00:02 } with-connect-type "unknown" + allow id 03f0:046b serial "11AD1D0A89EA2D08310E0B00" name "HP USB-C Dock G5" hash "DEGeuj1u4lwqrzp0UksFX7mSEY9JnGLxg7yxGbglAKE=" parent-hash "iPFGrgGz0sWgKQjWD/F8eNOhkeR728dTG8JJtkUSvuM=" with-interface { 11:00:00 ff:03:00 03:00:00 } with-connect-type "unknown" + allow id 03f0:076b serial "" name "USB5734" hash "BshoqybYo0IKgoDORYPRtbhhlmQrYAxPQb2EAm1JsWA=" parent-hash "JHDjLFApQNqijjmuKdJSWH5+1oLL7S6LQ9QHTAk5fTk=" via-port "8-1.3" with-interface 09:00:00 with-connect-type "unknown" + allow id 0bda:8153 serial "000001000000" name "USB 10/100/1000 LAN" hash "utEnXKJ57kRUbPcGUaNWhEyoOEbLOYAFxvlsyC0PZkk=" parent-hash "JHDjLFApQNqijjmuKdJSWH5+1oLL7S6LQ9QHTAk5fTk=" with-interface { ff:ff:00 02:06:00 0a:00:00 0a:00:00 } with-connect-type "unknown" + allow id 046d:0ab7 serial "2046BAB04T68" name "Blue Microphones" hash "cC6AQ2e1Q/BeFeostpbf1mH2WpoUmt6bhau4NlA3niU=" parent-hash "MSXcPAlZqkpTyZQylOhSIB8eMfST2AzVHV9EbrBGTWc=" with-interface { 01:01:00 01:02:00 01:02:00 01:02:00 01:02:00 01:02:00 01:02:00 03:00:00 } with-connect-type "unknown" + allow id 1532:02a1 serial "" name "Razer Ornata V3" hash "wfuIjBhhGuge8gflyA526SKqKoy8rHJZQZ+2o6usMiE=" parent-hash "MSXcPAlZqkpTyZQylOhSIB8eMfST2AzVHV9EbrBGTWc=" via-port "7-1.3.3" with-interface { 03:01:01 03:00:01 03:00:02 } with-connect-type "unknown" + allow id 13fd:5900 serial "50026B76861EE752 " name "External" hash "l/QvVV5hzZj1z6OUwB/kWl+WnH/7awrdMBoiNVx660M=" parent-hash "MSXcPAlZqkpTyZQylOhSIB8eMfST2AzVHV9EbrBGTWc=" with-interface { 08:06:50 08:06:62 } with-connect-type "unknown" + ''; + + home-manager.users."${config.var.username}" = import ./home.nix; + + # Don't touch this + system.stateVersion = "24.05"; +} diff --git a/hosts/laptop/flake.nix b/hosts/laptop/flake.nix new file mode 100644 index 0000000..916c6e7 --- /dev/null +++ b/hosts/laptop/flake.nix @@ -0,0 +1,20 @@ +{ + inputs, + nixpkgs, + ... +}: +nixpkgs.lib.nixosSystem { + modules = [ + { + nixpkgs.overlays = [ + ]; + _module.args = {inherit inputs;}; + } + inputs.nixos-hardware.nixosModules.omen-16-n0005ne + inputs.home-manager.nixosModules.home-manager + inputs.stylix.nixosModules.stylix + inputs.nix-index-database.nixosModules.default + inputs.helium-browser.nixosModules.default + ./configuration.nix + ]; +} diff --git a/hosts/laptop/hardware-configuration.nix b/hosts/laptop/hardware-configuration.nix new file mode 100644 index 0000000..e2b649e --- /dev/null +++ b/hosts/laptop/hardware-configuration.nix @@ -0,0 +1,52 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ + config, + lib, + modulesPath, + ... +}: { + imports = [ + (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot.initrd.availableKernelModules = [ + "nvme" + "xhci_pci" + "uas" + "usbhid" + "sd_mod" + ]; + boot.initrd.kernelModules = []; + boot.kernelModules = ["kvm-amd"]; + boot.extraModulePackages = []; + + fileSystems."/" = { + device = "/dev/disk/by-uuid/6320d3c6-0231-45ec-817a-c6f0e39aab73"; + fsType = "ext4"; + }; + + fileSystems."/boot" = { + device = "/dev/disk/by-uuid/5251-9B85"; + fsType = "vfat"; + options = [ + "fmask=0077" + "dmask=0077" + ]; + }; + + swapDevices = []; + + # Enables DHCP on each ethernet and wireless interface. In case of scripted networking + # (the default) this is the recommended approach. When using systemd-networkd it's + # still possible to use this option, but it's recommended to use it in conjunction + # with explicit per-interface declarations with `networking.interfaces..useDHCP`. + networking.useDHCP = lib.mkDefault true; + # networking.interfaces.eno1.useDHCP = lib.mkDefault true; + # networking.interfaces.enp7s0f4u1u4.useDHCP = lib.mkDefault true; + # networking.interfaces.wlo1.useDHCP = lib.mkDefault true; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} diff --git a/hosts/laptop/home.nix b/hosts/laptop/home.nix new file mode 100644 index 0000000..4ed5f33 --- /dev/null +++ b/hosts/laptop/home.nix @@ -0,0 +1,63 @@ +{config, ...}: { + imports = [ + # Programs + ../../home/programs/helium + ../../home/programs/proton + ../../home/programs/proton/auto-start-vpn.nix + ../../home/programs/ghostty + ../../home/programs/nvf + ../../home/programs/shell + ../../home/programs/git + ../../home/programs/git/lazygit.nix + ../../home/programs/git/signing.nix # CHANGEME: Change the key or remove this file + ../../home/programs/thunar + ../../home/programs/nixy + ../../home/programs/nightshift + ../../home/programs/nix-utils + ../../home/programs/spotatui + ../../home/programs/yazi + + ../../home/programs/group/basic-apps.nix + ../../home/programs/group/cybersecurity.nix + ../../home/programs/group/dev.nix + ../../home/programs/group/misc.nix + + # System (Desktop environment like stuff) + ../../home/system/hyprland + ../../home/system/caelestia-shell + ../../home/system/hyprpaper + ../../home/system/mime + ../../home/system/udiskie + + ./variables.nix # Mostly user-specific configuration + ./secrets # CHANGEME: You should probably remove this line, this is where I store my secrets + ]; + + home = { + inherit (config.var) username; + homeDirectory = "/home/" + config.var.username; + file.".face" = { + source = ./profile_picture.png; + }; + + sessionVariables = { + AQ_DRM_DEVICES = "/dev/dri/card2:/dev/dri/card1"; # CHANGEME: Related to the GPU + }; + + # Don't touch this + stateVersion = "24.05"; + }; + + wayland.windowManager.hyprland.settings.monitor = [ + "eDP-2,highres,0x0,1" # My internal laptop screen + "desc:AOC U34G2G1 0x00000E06,3440x1440@99.98,auto,1" # My external monitor + ]; + + programs = { + home-manager.enable = true; + nixy = { + enable = true; + configDirectory = config.var.configDirectory; + }; + }; +} diff --git a/hosts/laptop/profile_picture.png b/hosts/laptop/profile_picture.png new file mode 100644 index 0000000..71c63c9 Binary files /dev/null and b/hosts/laptop/profile_picture.png differ diff --git a/hosts/laptop/secrets/default.nix b/hosts/laptop/secrets/default.nix new file mode 100644 index 0000000..eac568f --- /dev/null +++ b/hosts/laptop/secrets/default.nix @@ -0,0 +1,61 @@ +# Those are my secrets, encrypted with sops +# You shouldn't import this file, unless you edit it +{ + inputs, + pkgs, + config, + ... +}: let + home = config.home.homeDirectory; +in { + imports = [inputs.sops-nix.homeManagerModules.sops]; + + sops = { + age.keyFile = "${home}/.config/sops/age/keys.txt"; + defaultSopsFile = ./secrets.yaml; + secrets = { + ssh-config = { + path = "${home}/.ssh/config"; + }; + github-key = { + path = "${home}/.ssh/github"; + }; + jack-key = { + path = "${home}/.ssh/jack"; + }; + signing-key = { + path = "${home}/.ssh/key"; + }; + signing-pub-key = { + path = "${home}/.ssh/key.pub"; + }; + }; + }; + + home.file.".config/nixos/.sops.yaml".text = '' + keys: + - &primary age12yvtj49pfh3fqzqflscm0ek4yzrjhr6cqhn7x89gdxnlykq0xudq5c7334 + - &work age1c8pawdsxptfslgrz2c56s39mrtnjzc5mm3hfzgr2wdwu2v6vfsdsupjsq6 + creation_rules: + - path_regex: hosts/laptop/secrets/secrets.yaml$ + key_groups: + - age: + - *primary + - path_regex: hosts/server/secrets/secrets.yaml$ + key_groups: + - age: + - *primary + - path_regex: hosts/work/secrets/secrets.yaml$ + key_groups: + - age: + - *work + ''; + + systemd.user.services.mbsync.Unit.After = ["sops-nix.service"]; + home.packages = with pkgs; [ + sops + age + ]; + + wayland.windowManager.hyprland.settings.exec-once = ["systemctl --user start sops-nix"]; +} diff --git a/hosts/laptop/secrets/secrets.yaml b/hosts/laptop/secrets/secrets.yaml new file mode 100644 index 0000000..49bcc0f --- /dev/null +++ b/hosts/laptop/secrets/secrets.yaml @@ -0,0 +1,20 @@ +ssh-config: ENC[AES256_GCM,data:/TWslzoF2wtZ9T41H1y0wLNEx+Xzff8pQGr6AfEcACExRCv4rd5hD9pNAlmlcTtISJJBPEWY45WsLfSKuD4r3715IENM2biQUvlq47THfkGviQuQ6KAXiJxBQ/7qRNqGGt7WFRlWFRGYCiyjw9h4pOhovGgw8TU6tIgIsXjo0psclHoJoE4B3cSOby7DbN8jVI9NjpBGiQMXmUB3JVz7muC9F5EAs+XZUIl7TjQMxob3PiF5LqTJITODSxboAAk901rjS5gjQKpQKfj28TpUs5yCIo9RzSBO3z5orJy+ylupocRuqtC8ujAMqNb828G+0nRx18tpiGqXxRWUBZRNbM+vQHWzb5JWQpEBsu1twsOownVVrkyPkbLpYX4YSSnRdnL8VHmlZfLk1ZFURbsdDSRf57F+Bxo5Yn8XAkFaM5HYgUo4VBabGzVVAHOBWJWi3lRrlAqYdMBbSvDl1t6eQ0xp990RGh7wZvwnaTDqtkOJnLoAknTFi4yjMzSyk5UV,iv:1UJQU4eBZE1BMVnJY2CQTDH8jXSMlrv3gGU3cKTOvdU=,tag:OzLQRkTAKG2KQXv+Vh7Msw==,type:str] +github-key: ENC[AES256_GCM,data:xUgFMlBo8e+3eXqNscxbby1dWug3SgUagDiNUe/IGVbU6cczkaJ3uOaB0OuRBQ8AYhOLkzXj0pIKjUrElHwmYrhURtS1aF4SFEGJsjhhobNA//j3E2/5/nLVjfco+lRzyHdwmsNhEUCqEhsXrrodJMb39H4b5oip3z0rjc729YveiWUKQxXVZVPurp3nq9yNnix9R4CA6XYFRW6T6MNqgPD5qhbcDlhxLb/SN+uI5h+5eZIS24VDWlKaTaCLL5KLhZmfuA37SquOQ+edi9Yg8MnfrZkMrp/3qmAjP2rSQLMOc4QdQCLQBQSf0/snpydgLwY+FoJmMSztwtkqUdIZWOfDUJbJxegEOrAR68jLTNbp+GYiDn3thtOZDiK5p/M1amjCT+A9qeFMed5WS+aZHNTRbR9UcfiP6+48MGZFt1mr7q+/CoL04/DTp0w6tUf6/SZD31NvTJDqngkhpc0ZH9Dh5+2JcnBWpq25AM36kZTn1hIQCLNTr/oGWZXSLA2tksAhQCaUcFj4IIh6Bl96,iv:GEJsAs5NriwENYTV/VShgJF6iMmrtTwNiXOvfXyEP8E=,tag:nfZgsFqaet075GjQAoVZxQ==,type:str] +jack-key: ENC[AES256_GCM,data:VfCl3wH0MMBc8QDyjLDFeSvzSEsf7uGpfJvRjFrmjW+bPRUXBpZhJV8a9VQIAz7z7zZXvzARMfCeI0ydyC57CW81GH5/H5pneJ4b+xreINjVfdLbL1nC1thelo/O64jda/L+xVKhgE+QQi8/zt4JmXGghkP+74nYcTTaMpmcbgWw354J1ybXqyCEY+88nsJ1d2s+M7M2bplx4fGb7sLUs6sqdsad3sENzhH/0HQCFXreHTtgsLbIs8ccmdRgFNKM8/wD0OoW76rOQsJoA9JY4yOTQNVoX5M8+Olj6+wVlt6QBrWrYRuEztGnHrHvzxiHXtmEkMwVNfoPpEflQyRYRa0rVp/66REOkMckGx6/LbxKFgrxnifRlsK3kWd28v2bRGVQOghUluYUtVkaJ+eh6o6ik0NQKx8/H6BznBSDE6MjDwbLv434LHBfDtAqhWN1eMbOlunFivsl5Hb/6rl9kydHlcCS6FY8cUHoKQ90gDaUuDrvUifwmdO5hU0GH5tgvGi1ReK9ndcpQsrHptG6,iv:oC1xU5Tu3The105VYRmxIw4kEwDoqe8T/EH6mmqpqwQ=,tag:Pu8c536u6W7ALrqjRsvXDw==,type:str] +signing-key: ENC[AES256_GCM,data:NvLqmt7NzrWkbQQqFfosmSMvEv8C8+MDDpxSoDo3zZ3MR6WXr9B+6CnUc6rtevM230wgE17VC9XlmcQxX+PjJsWq6gZteK5THTIcrR5zPJVNlVCEyeLKoFj/6m7qBgyyoN3OjCNjgMkhsm009jwBgNk0qJMAYebOGo8eoP/al+4ytm7dhna+iX5WZabAg0J4z4JMDQonqQl3SaDnCEdHvk9m7ZEP2vUFscPkbLj4ewgFq+bUCHOOQb2uqRJoEgcR/NetRFcQfzcU6lp7JxobaICaO3zdmomUm7oabIUTrc3Kom3Wjw8ryqfqC1/SC0SHr5XGk2ygk0WnlQ4kNshqriL2dwbWAzy1Z/cTX9+aB/KNtC0U6zWG1bpnL3dgSgvhRiocIis/eNg1HWsLWVicmdebL/lXHztxFMdTuX/gWgQBotggTmx+OFGZfP9ZGlF3635mDxM/fEOCtTyA195dMicCUsjEpBegNtXsp+oOtxyRI0jSW47MBcXFP09f5ywELTPyz4eOUHO8sQ6UfJ6X,iv:KNQUlMPaiR4x1Fw+HZe/EOmh/gfsrqlefpq23uflz/8=,tag:illu42HKunQXnijjsUIvnQ==,type:str] +signing-pub-key: ENC[AES256_GCM,data:XuokZmCsnaNQ0rvVa3k81T4vtxw//r63xp1yHDLaNAMwA2r2bh6addl9WoAmm76g1rweqZrAAIw1PXDb90ubPaBP1iEHSkGZpwUpy/tOTePRdHMW2WtVvidpHQ==,iv:auB/bA89cJK6DnQi1BK2uldXRPyJfo+r7nl5qOLefUk=,tag:/I3kB6El1yesBMGOjJ+oHA==,type:str] +sops: + age: + - recipient: age12yvtj49pfh3fqzqflscm0ek4yzrjhr6cqhn7x89gdxnlykq0xudq5c7334 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBHVWN4YjZqczB3Q21WL1lz + ckROWkhRditHblVHVEpOS0E0aGVqdW14M0ZvCkNzRXlCOWFBWmQwTGpTYVdFRlpq + bFdOR2pSTEZpUVpvUHo2NklrQm5EU1kKLS0tIFZ5ZWhYcHg1Z0hTOTZIdHR1QUxv + cmVxVC8rVDlWMUdZaGw3bmdOaWZGS1EKYahBlc8XpB5UdKZQkvxbLcKQ/xkFJjWo + FSfQWnjhe/a7BJtJEcKZkjOQU0mYqlSu+uT2RA9diCQeRUJPRF+nAw== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2026-04-25T11:23:30Z" + mac: ENC[AES256_GCM,data:ZnLSwtyhaiMIcXxzlwhtk0dWVnOkn0avfeRezPPNBUXd0oyJY+krBsLXJdSNPHV/X/L58476okYjUzfIQzEAkrL9Fb7v/Jt0aw4SDrxbF+qbcfdvsWPUjFDJIPovuf3ee3o7iXGU2ItGTaJa2eFACoyd37KVc7jZd6gvYYAyULA=,iv:7IKqe0c5CTgJrS7OgCQWhtxaCVKo+UWEibttFUVCWGM=,tag:OfCrKPzrPBZThCR1j7IB7A==,type:str] + unencrypted_suffix: _unencrypted + version: 3.12.2 diff --git a/hosts/laptop/variables.nix b/hosts/laptop/variables.nix new file mode 100644 index 0000000..c703f53 --- /dev/null +++ b/hosts/laptop/variables.nix @@ -0,0 +1,38 @@ +{ + config, + lib, + ... +}: { + imports = [ + # Choose your theme here: + ../../themes/nixy.nix + ]; + + config.var = { + hostname = "h-laptop"; + username = "hadi"; + configDirectory = "/home/" + config.var.username + "/.config/nixos"; # The path of the nixos configuration directory + + keyboardLayout = "fr"; + + timeZone = "Europe/Paris"; + defaultLocale = "en_US.UTF-8"; + extraLocale = "fr_FR.UTF-8"; + + git = { + username = "Hadi"; + email = "112569860+anotherhadi@users.noreply.github.com"; + }; + + autoUpgrade = false; + autoGarbageCollector = true; + }; + + # DON'T TOUCH THIS + options = { + var = lib.mkOption { + type = lib.types.attrs; + default = {}; + }; + }; +} diff --git a/hosts/server/configuration.nix b/hosts/server/configuration.nix new file mode 100644 index 0000000..4f2be5c --- /dev/null +++ b/hosts/server/configuration.nix @@ -0,0 +1,42 @@ +{config, ...}: { + imports = [ + # NixOS module + ../../nixos/home-manager.nix + ../../nixos/nix.nix + ../../nixos/systemd-boot.nix + ../../nixos/users.nix + ../../nixos/utils.nix + ../../nixos/amd-graphics.nix + + # NixOS server modules + ../../server-modules/ssh.nix + ../../server-modules/firewall.nix + ../../server-modules/cloudflared.nix + ../../server-modules/glance + ../../server-modules/adguardhome.nix + ../../server-modules/arr.nix + ../../server-modules/blog.nix + ../../server-modules/awesome-wallpapers.nix + ../../server-modules/iknowyou.nix + ../../server-modules/stirling-pdf.nix + ../../server-modules/cyberchef.nix + ../../server-modules/mazanoke.nix + ../../server-modules/kernel-hardening.nix + ../../server-modules/fail2ban.nix + ../../server-modules/default-creds.nix + ../../server-modules/umami.nix + ../../server-modules/gitea.nix + ../../server-modules/mealie.nix + + # You should let those lines as is + ./hardware-configuration.nix + ./variables.nix + + ./secrets + ]; + + home-manager.users."${config.var.username}" = import ./home.nix; + + # Don't touch this + system.stateVersion = "24.05"; +} diff --git a/hosts/server/flake.nix b/hosts/server/flake.nix new file mode 100644 index 0000000..f4a3df3 --- /dev/null +++ b/hosts/server/flake.nix @@ -0,0 +1,17 @@ +{ + inputs, + nixpkgs, + ... +}: +nixpkgs.lib.nixosSystem { + modules = [ + {_module.args = {inherit inputs;};} + inputs.home-manager.nixosModules.home-manager + inputs.stylix.nixosModules.stylix + inputs.sops-nix.nixosModules.sops + inputs.nixarr.nixosModules.default + inputs.nix-index-database.nixosModules.default + inputs.default-creds.nixosModules.default + ./configuration.nix + ]; +} diff --git a/hosts/server/hardware-configuration.nix b/hosts/server/hardware-configuration.nix new file mode 100644 index 0000000..c7bbfe2 --- /dev/null +++ b/hosts/server/hardware-configuration.nix @@ -0,0 +1,52 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ + config, + lib, + pkgs, + modulesPath, + ... +}: { + imports = [(modulesPath + "/installer/scan/not-detected.nix")]; + boot.initrd.availableKernelModules = [ + "xhci_pci" + "ahci" + "nvme" + "usbhid" + "usb_storage" + "sd_mod" + ]; + boot.initrd.kernelModules = ["dm-snapshot"]; + boot.kernelModules = ["kvm-amd"]; + boot.extraModulePackages = []; + fileSystems."/" = { + device = "/dev/disk/by-uuid/350cf109-5380-4982-8a9e-279a9275ee18"; + fsType = "ext4"; + }; + fileSystems."/boot" = { + device = "/dev/disk/by-uuid/DD15-1125"; + fsType = "vfat"; + options = [ + "fmask=0077" + "dmask=0077" + ]; + }; + fileSystems."/mnt/data" = { + device = "/dev/disk/by-uuid/0b055155-0134-448c-b1ca-e81030ff064e"; + fsType = "btrfs"; + options = [ + "subvol=/" + "compress=zstd" + ]; # adapte selon si t'as des subvolumes + }; + swapDevices = []; + # Enables DHCP on each ethernet and wireless interface. In case of scripted networking + # (the default) this is the recommended approach. When using systemd-networkd it's + # still possible to use this option, but it's recommended to use it in conjunction + # with explicit per-interface declarations with `networking.interfaces..useDHCP`. + networking.useDHCP = lib.mkDefault true; + # networking.interfaces.enp3s0.useDHCP = lib.mkDefault true; + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} diff --git a/hosts/server/home.nix b/hosts/server/home.nix new file mode 100644 index 0000000..5eafaa1 --- /dev/null +++ b/hosts/server/home.nix @@ -0,0 +1,32 @@ +{config, ...}: { + imports = [ + # Mostly user-specific configuration + ./variables.nix + + # Programs + ../../home/programs/nvf + ../../home/programs/shell + ../../home/programs/git + ../../home/programs/git/lazygit.nix + ../../home/programs/nixy + ../../home/programs/nix-utils + ../../home/programs/yazi + + ../../home/programs/group/dev.nix + ]; + + home = { + inherit (config.var) username; + homeDirectory = "/home/" + config.var.username; + + # Don't touch this + stateVersion = "24.05"; + }; + + programs.home-manager.enable = true; + + programs.nixy = { + enable = true; + configDirectory = config.var.configDirectory; + }; +} diff --git a/hosts/server/secrets/default.nix b/hosts/server/secrets/default.nix new file mode 100644 index 0000000..19b2321 --- /dev/null +++ b/hosts/server/secrets/default.nix @@ -0,0 +1,33 @@ +{pkgs, ...}: { + sops = { + age.keyFile = "/home/hadi/.config/sops/age/keys.txt"; + defaultSopsFile = ./secrets.yaml; + secrets = { + sshconfig = { + owner = "hadi"; + path = "/home/hadi/.ssh/config"; + mode = "0600"; + }; + github-key = { + owner = "hadi"; + path = "/home/hadi/.ssh/github"; + mode = "0600"; + }; + signing-key = { + owner = "hadi"; + path = "/home/hadi/.ssh/key"; + mode = "0600"; + }; + signing-pub-key = { + owner = "hadi"; + path = "/home/hadi/.ssh/key.pub"; + mode = "0600"; + }; + }; + }; + + environment.systemPackages = with pkgs; [ + sops + age + ]; +} diff --git a/hosts/server/secrets/secrets.yaml b/hosts/server/secrets/secrets.yaml new file mode 100644 index 0000000..7748f5d --- /dev/null +++ b/hosts/server/secrets/secrets.yaml @@ -0,0 +1,24 @@ +umami-secret: ENC[AES256_GCM,data:tImpd4sD92Omf/YFB8YE4gxAu+g801wQNR+k5rhY6AbzIIYOzpVmQL4XGjfp9Teky3olii4s3XTcmTyuMoxMWg==,iv:QFAEzYnAnxOOtrHWiM2IkvSs0Aqk3s1T5X7j5WC+tO8=,tag:FIbgHLfRVMJ2qZ6dOJ8zLw==,type:str] +sshconfig: ENC[AES256_GCM,data:R54HVxqAyj9yGO/AYL8p6cnXgYxkQKW9XveHlBMTnDXBJ7r/4HgnefdymprnXmdlbNWcWrRqmaLEuzJs/0BfixXfMvmGTUrmJ0ASVuDrz9k6rOLADAKFikQh0dib7NU4JmPgmUzMncXc2WuCd3BCG3kwBQ==,iv:Ro9FA+MzTAp+ERQMT88z8ioCox/dTj2vWcqCDOSLag4=,tag:5XiXIyz5/pjGFOB5ZjdOVg==,type:str] +github-key: ENC[AES256_GCM,data:NRYhcBIwGJEV13+YECLR+2IErsn/7clbnkx0Mltr7dQajSb5WHZ3QDH0KQPylEHhplE5IVS0h4I0z+Pb1B0UteCxFmJ5wZq+2BKZkvE7G3dojqBpgHcVqJV2GLEJkRjlHfRgsbq/OBe8xcsPh20P1KUyP0WIwVbpt+9dFWGxEGYkp2uSyuBIJ98kElt0zuVgl7WcYoDO7v5WmGzZfla+yZwURvMk8zcM3gopo+4KL6YnYUs+UA3VlBBn6VK4Nvbqy6X0R0+ZA5HHAXg+OFgGmfWnENZmsyQJHXEchGGgEldzThkQ4r8yMkgN/ax+AGouLyzbITapGE4sE11FFgL6Hmp4pSXxl3UAGF+cvV5pIujbb28CXmSPRMyYpoNxI93PSYz/txAzE6Cr2dgwxR4zpMelv4i6IaGnY8NgpY8jp2Y6C0uuJxJCN0RtnjQw1rM2uRnm7vMGyU7XXz9DEVfGnYpTWnykXsEjHE5DVGy80ejYQlc6dtmf3vdTWpt+YYdCPw8/cd0PIx2D6geh1c28,iv:wl+RG24mXYMklD8CBGXVD36DMhlWT/7zh8ZMvr7vgOk=,tag:OJhqF8PoXotr7IsyFW6q1g==,type:str] +adguard-pwd: ENC[AES256_GCM,data:CAmZFpKN6FFRlCk=,iv:cz45T/z2ZYHNC46FNVp2YHmdhXD4ERhM31+Jo+9PkSk=,tag:GTUvzkYSP4flXs/HUNGYhw==,type:str] +recyclarr: ENC[AES256_GCM,data:eJNbGHb4SZvbF7FAHMrpRynmpVyPiTpyZqNx40Fo+lanqdm7d7oRhkLD2PfqxpTcIyV6BxJk12wGUC0uWVuAihmToL/Ih2FJWIQFUOdbaov/xNWHE9mtoRX/A3gIwD8e3DoFMK/dAk2/TyvvAfxi2eYTDJvxecEttHQGxafq1jveHFDcC9e1aFk3M8O8YlX5yF3zl90mugsUVP+iaSURnY/nglZuEDzfJ6Edge7r5OSL6WYh3OUIu1yzuuKXRZ47B/gpXO/cP89JMmxdPj3FUJkk7Htf0s9ALzpVE9fRohDGcpPIkR6COCLTL+mqvVmyopA1zPoX8/X8eiuocpaT3vqJit7Bc6InzflY/5rlg1x0SyoXWQfEsperfNBeiZGngp382I7rrZ8QSwF4AIsmngNeyDRAnfasAU5OVwK+yPIVhRueEFLNrJPG3j2hpArlzpvY2EPBVJDrYwFslis8CASoUdvu6C7VxtJXFcOZR8QemwJarJFU7v1bVhQoIkarn3V7FfAXg/8RfYrn9HAIq5AiFFbQRNHWXzIceIgNKQFb5yfagtMtMq6XKhjsV07jeYt9X/YU80XRfkPm05yiLdLQHcDNmlB3R+SFPD7qjTE7LuSH1Kdc3DvxwrKfHJLsJ+nSIL1po8gDMW8BPc0g4n4dpQ6CFK5BaDFK4eovNpgAXoRC9orkGw/16YmMozp6J78VJLzu3jcYMFbySFznDUuWcFf/7dVV+7pLAj2ffWXzScLISRBhZ9RNUMaZAKAk7WTmxBhw0yzNiih8OFUkbpp1FFLuU0bnBY0iEz+8/OSwv8H7t0HYe29HO61p1huH34B/ZkPA5VLKivFh2mOPNzbvMqtIAkq1ro82Psvc6t88gVIc+VAOZ9zDLohp0FXrNVXwnrs7fxevQa0pUClDivO1ib5G4Znor7q+13jZglmh3G7nHiniO607dRoxszzVEQdTn8ku3XAfIPStsSfQwH46nXhr2kDkspcA7BqwJph0dsKKlfzf22C0OJkDY0L1DgKFvJRmmKAhOdB6XxXYwS+BcDT+8ugejTKpulyPSsbdb0m9p9lVAVu0GMxFEbUsuE+QHiAAP5Vle7swpl4h3i8uHSfKFra3qEswwRnPAHhPSdLSaSU6O6T5gN/b0hhO6dAiNR0UOkOG59fPasL0MRpeb3SkM4Nd6g5b/hY8dXaXR7pQHvh+4GmfJFWYaWm/cZ8k9JAYAw9Sn/spWnjRmpv9bnSxADGbkdV8NDHquDDDFVIIoDnWhQJpqrL61KZITx2Ete1SYdNiy++p3mOYisJgHDsRR1RNQNxhRW4EY8c5nCzgc8x+rU432pCOfMbAuGEfQXMwMGFGeoUg6EL5xEyUEJ/aqymxI+Vjk8h7KfDnOyyL/+1BKEd/GccrjeQfeZGRLI0Tu5gVgL6twc+u4av6inNMMhPFzZuVrfeo6bip5C8R0dK6Pbdz2L/fsgn3E4NNi14NM/DgLLhJRLvKQdCQx+BT+3soNRw5htTzuNS48MD2YDwZYvNfu6mo0r4j4I7Tj8zuCjddbGVa2/5XnhcfdUBx1VOd90H1RKkk8kgSoR0bgo7mLls=,iv:HT3a2YnFy0cF9qUO671kwqxuzFfNnfqynCUVGHf+3dM=,tag:nrA++7fsnc4Cx0OPSDKaRw==,type:str] +wireguard-pia: ENC[AES256_GCM,data:2IvJARGhesMuH9RdWzsyrwA7eqrhLyacQqZ1RNEkGOPUkQGX4uimKBSzkxXRy/haZ4V2k73JdLSaB9rAuI0n65GmWHmarwZekOyhRZSNb+zvFgw5BPZmywG1wR2HiTGR/qILovAaz47q/VnohUnjbbMCUvarC4PytWGxMUH96GIgZar8HjHFtK8grCSxlvpHKiDeKx8VSXnY/Pxj1EplBtIqwmtAeZdf/VjtwOL0nY54doPwHdIAvJ0B8Cu0a1zJIGEbV1NlKIHEJ1YA7rmv1ODkBnbXbIHMxAR3jeqR/UDqhDmXe41KujhiJI7nNeO7FKo2v92jK3fSbxYKatLrzXktHpE9JsMYVBXzTK7yAXPgoDdgLXzWH0OrJGBSisPrvqmxUko7MPreuwVYfFlKpll6JLifk8sML4A+94UPR8b89guXn7kBkLg1Y1oIAyguCdKpNOD31nXBMFF0nTcmCwyshDySaGTfJDgox65/77AiN1wH,iv:cdu6lBjLnEEfSFmWMC4Vn2sLKsvpCaatzXlgRNkEMeA=,tag:y1rAeNPB+DNGTpnP94iQrA==,type:str] +signing-key: ENC[AES256_GCM,data:FrJzuTgH/ooZkcnYL55uQcc4u+QzNnFvNVs2wDSE4nnwku+EuCJBlb8pd/6W0KPwIXzcki/8CY0YfRcRrzjExMgMa4hwxrlxS9bk3LNPzJsrRK5RJgPg3iA8L791f1zcDxNf8RuWatIqm1TCK+Vhdk/p+221zy1Gcq1dW8X+o4XzbPBzHdLagcIdB0wpjYTtIoGP2X8GoL/NJpuzIiQBK1HdGNKvUI2+ztqCQZOsxm+Fki57NteX3/Llw8AwABjdZvviOBZ62OvJ/SsOQ9NYAvKfAkog5zCn8DLvaqAPGSxRBQEYWM8GyL2imgs54YfEsOpGa4DzMiv4Sc5m398E/asaPq357eksUqh3EYpzoKZ5bIbd5+Vs3KBWKHltUCzXLHaLrIX0CuJFQFi7DCxEbYqlb04x5t3jc/c+/7uwqBHv1Y5gwAjd8JswDWmE7Q3xSk96Za57SCxWPYTo2ErsA2XdL+yxXdhmqkhDZKtUzrcHExhnYe7YLpSlBEclJ/G2BeTOFIWoAmN+1y4rh21R,iv:VaZrv5/41ZyIax702Yae4QmFKpcEaWwPmTo2Mxao3bU=,tag:HC0eqDNit7jQKeeDAKWXKg==,type:str] +signing-pub-key: ENC[AES256_GCM,data:CB7uU2Q4oTEKihpTIXGLaV0fJ1cv/p4oJJ5kjaU6BZiKhsiMA1JILUw2oVIDTDb+80WPzolDzZwWM8v31d5QIrZpHcPrdRLyV0X2USfG9U4aQ/ls79QAyOOJXA==,iv:/Eb5/+p86tw3tqNiDVHGu7HS1KBtFiYIgasRYJsAiEo=,tag:dGdJlcrnuU73s+IMQ3w3hA==,type:str] +cloudflared-token: ENC[AES256_GCM,data:7DwWFL6JbJXuc6fSyrZkMt/+DAcqDYBQOzJ1QhBL4yfCpQ57mjDV2beRZ8H7SuyoKY3caifHfAVVPDGG1YnffZ9anLRyDW383aHKmgaeztOXj44eVQcHi3evnSiH6h0HasiyO8pNzhnKpYew8CwHSvYZMraX3ITz8UKOTtsanO9/8ZD6Y9gyxfLoySqbeBy2x/0Ql5hrDfrX854C+vYuXM9VJbtQqMBa7+IBydUvddk=,iv:jZTk5ptuwc+1aP2rimqGnyCHR4/J+W4Kyn3LKXXkv/I=,tag:xr/LhoNH5aWdIJr0Py6nAg==,type:str] +sops: + age: + - recipient: age12yvtj49pfh3fqzqflscm0ek4yzrjhr6cqhn7x89gdxnlykq0xudq5c7334 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB5Z3MzZmoyVDRtRmd3amFJ + MWVvWlA1c3RFeVMrbHJQQmNTcG9ZN2tXSWxjClJ0L1psd1RFM1EreG1yNHdOYzZF + aXphL0lvcGNFTFFMbkNocGNXY00xdW8KLS0tIFh2YjN0aTlRazBXSktnQWx0L3BY + TEc5d01RaVFGNXc3dlljM0FTTHpENjQKOqwI+pl8UxVIVl43glnOYvW660/PsDGY + yefODJGVtHrOm3yeXC2xlTi3sFW+c5wUl2yPqddbvcBt5Ud/yd4iXQ== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2026-04-12T18:24:10Z" + mac: ENC[AES256_GCM,data:D7gWC1fxZkpG8dCr7aWhcyLT92NK1OefS4SIAq5ZImMYRJzzvhXtyJM9tzUYVWPU0ojhgOJyawlWEFk1P/DWjOrafBsBHdxUl5FtZrRb4Z/rquODhR8OT8UYFVKyAmjSfomUEDzYetJdXdAxhX3eNlT+eKI51IjqD9y1dYqcjMw=,iv:ZPIkMf/fUETeUYQdqu4TpS/ZE752079jIW9BlehhWlw=,tag:Z3i/Zc0zkEF5rsNnkmUB9A==,type:str] + unencrypted_suffix: _unencrypted + version: 3.12.2 diff --git a/hosts/server/variables.nix b/hosts/server/variables.nix new file mode 100644 index 0000000..f12b7e2 --- /dev/null +++ b/hosts/server/variables.nix @@ -0,0 +1,42 @@ +{ + config, + lib, + ... +}: { + imports = [ + # Choose your theme here: + ../../themes/nixy.nix + ]; + + config.var = { + hostname = "jack"; + username = "hadi"; + configDirectory = "/home/" + config.var.username + "/.config/nixos"; # The path of the nixos configuration directory + + keyboardLayout = "fr"; + + timeZone = "Europe/Paris"; + defaultLocale = "en_US.UTF-8"; + extraLocale = "fr_FR.UTF-8"; + + git = { + username = "Hadi"; + email = "112569860+anotherhadi@users.noreply.github.com"; + }; + + autoUpgrade = false; + autoGarbageCollector = true; + + domain = "hadi.icu"; + tunnelId = "a1dfa315-7fc3-4a65-8c02-8387932c35c3"; + networkInterface = "enp3s0"; + }; + + # Let this here + options = { + var = lib.mkOption { + type = lib.types.attrs; + default = {}; + }; + }; +} diff --git a/hosts/work/configuration.nix b/hosts/work/configuration.nix new file mode 100644 index 0000000..92c3c91 --- /dev/null +++ b/hosts/work/configuration.nix @@ -0,0 +1,41 @@ +{config, ...}: { + imports = [ + # Mostly system related configuration + ../../nixos/audio.nix + ../../nixos/bluetooth.nix + ../../nixos/fonts.nix + ../../nixos/home-manager.nix + ../../nixos/nix.nix + ../../nixos/systemd-boot.nix + ../../nixos/tuigreet.nix + ../../nixos/usbguard.nix + ../../nixos/users.nix + ../../nixos/utils.nix + ../../nixos/hyprland.nix + ../../home/programs/helium/system.nix # I hate browser's configuration.. + + # You should let those lines as is + ./hardware-configuration.nix + ./variables.nix + ]; + + home-manager.users."${config.var.username}" = import ./home.nix; + + # USBGuard: + # Allow all USB devices until a proper policy is configured. + # Run `sudo usbguard generate-policy` with your devices plugged in, + # then set rules = "" and switch implicitPolicyTarget to "block". + # services.usbguard.implicitPolicyTarget = lib.mkForce "allow"; + services.usbguard.rules = '' + allow id 1d6b:0002 serial "0000:00:14.0" name "xHCI Host Controller" hash "jEP/6WzviqdJ5VSeTUY8PatCNBKeaREvo2OqdplND/o=" parent-hash "rV9bfLq7c2eA4tYjVjwO4bxhm+y6GgZpl9J60L0fBkY=" with-interface 09:00:00 with-connect-type "" + allow id 1d6b:0003 serial "0000:00:14.0" name "xHCI Host Controller" hash "prM+Jby/bFHCn2lNjQdAMbgc6tse3xVx+hZwjOPHSdQ=" parent-hash "rV9bfLq7c2eA4tYjVjwO4bxhm+y6GgZpl9J60L0fBkY=" with-interface 09:00:00 with-connect-type "" + allow id 17ef:608d serial "" name "Lenovo USB Optical Mouse" hash "klpDZuv1jhWGNqZLOl+KXF+75Ir3PfBm6D6ncjoLRBU=" parent-hash "jEP/6WzviqdJ5VSeTUY8PatCNBKeaREvo2OqdplND/o=" via-port "1-7" with-interface 03:01:02 with-connect-type "hotplug" + allow id 17ef:6190 serial "" name "Lenovo Calliope USB Keyboard G2" hash "CfZ9R/aoXGm7BN/ojVEzKQwVoxCUtRWMuACrE7BL/5Y=" parent-hash "jEP/6WzviqdJ5VSeTUY8PatCNBKeaREvo2OqdplND/o=" via-port "1-10" with-interface { 03:01:01 03:00:00 } with-connect-type "hotplug" + allow id 0781:5581 name " SanDisk 3.2Gen1" + ''; + + networking.firewall.allowedTCPPorts = [9001]; + + # Don't touch this + system.stateVersion = "24.05"; +} diff --git a/hosts/work/flake.nix b/hosts/work/flake.nix new file mode 100644 index 0000000..963a5c2 --- /dev/null +++ b/hosts/work/flake.nix @@ -0,0 +1,18 @@ +{ + inputs, + nixpkgs, + ... +}: +nixpkgs.lib.nixosSystem { + modules = [ + { + nixpkgs.overlays = []; + _module.args = {inherit inputs;}; + } + inputs.home-manager.nixosModules.home-manager + inputs.stylix.nixosModules.stylix + inputs.nix-index-database.nixosModules.default + inputs.helium-browser.nixosModules.default + ./configuration.nix + ]; +} diff --git a/hosts/work/hardware-configuration.nix b/hosts/work/hardware-configuration.nix new file mode 100644 index 0000000..5357795 --- /dev/null +++ b/hosts/work/hardware-configuration.nix @@ -0,0 +1,45 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ + config, + lib, + pkgs, + modulesPath, + ... +}: { + imports = [ + (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot.initrd.availableKernelModules = [ + "xhci_pci" + "ahci" + "nvme" + "usb_storage" + "usbhid" + "sd_mod" + ]; + boot.initrd.kernelModules = []; + boot.kernelModules = ["kvm-intel"]; + boot.extraModulePackages = []; + + fileSystems."/" = { + device = "/dev/disk/by-uuid/5dbf85d3-d236-4af8-b489-d6066bfe1eb7"; + fsType = "ext4"; + }; + + fileSystems."/boot" = { + device = "/dev/disk/by-uuid/043E-1755"; + fsType = "vfat"; + options = [ + "fmask=0077" + "dmask=0077" + ]; + }; + + swapDevices = []; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} diff --git a/hosts/work/home.nix b/hosts/work/home.nix new file mode 100644 index 0000000..860dee8 --- /dev/null +++ b/hosts/work/home.nix @@ -0,0 +1,53 @@ +{config, ...}: { + imports = [ + # Programs + ../../home/programs/proton + ../../home/programs/helium + ../../home/programs/ghostty + ../../home/programs/nvf + ../../home/programs/shell + ../../home/programs/git + ../../home/programs/git/lazygit.nix + ../../home/programs/thunar + ../../home/programs/nixy + ../../home/programs/nightshift + ../../home/programs/nix-utils + ../../home/programs/spotatui + ../../home/programs/yazi + + ../../home/programs/group/basic-apps.nix + ../../home/programs/group/cybersecurity.nix + ../../home/programs/group/dev.nix + ../../home/programs/group/misc.nix + + # System (Desktop environment like stuff) + ../../home/system/hyprland + ../../home/system/caelestia-shell + ../../home/system/hyprpaper + ../../home/system/mime + ../../home/system/udiskie + + ./variables.nix # Mostly user-specific configuration + ./secrets # CHANGEME: You should probably remove this line, this is where I store my secrets + ]; + + home = { + inherit (config.var) username; + homeDirectory = "/home/" + config.var.username; + + # Don't touch this + stateVersion = "24.05"; + }; + + wayland.windowManager.hyprland.settings.monitor = [ + "desc:Philips Consumer Electronics Company PHL 221B8L ZV02144013987,highres,0x0,1" + ]; + + programs = { + home-manager.enable = true; + nixy = { + enable = true; + configDirectory = config.var.configDirectory; + }; + }; +} diff --git a/hosts/work/secrets/default.nix b/hosts/work/secrets/default.nix new file mode 100644 index 0000000..093d5f0 --- /dev/null +++ b/hosts/work/secrets/default.nix @@ -0,0 +1,58 @@ +# Those are my secrets, encrypted with sops +# You shouldn't import this file, unless you edit it +{ + inputs, + pkgs, + config, + ... +}: let + home = config.home.homeDirectory; +in { + imports = [inputs.sops-nix.homeManagerModules.sops]; + + sops = { + age.keyFile = "${home}/.config/sops/age/keys.txt"; + defaultSopsFile = ./secrets.yaml; + secrets = { + ssh-config = { + path = "${home}/.ssh/config"; + }; + netrc = { + path = "${home}/.netrc"; + }; + github-key = { + path = "${home}/.ssh/github"; + }; + gitlab-key = { + path = "${home}/.ssh/gitlab"; + }; + }; + }; + + home.file.".config/nixos/.sops.yaml".text = '' + keys: + - &primary age12yvtj49pfh3fqzqflscm0ek4yzrjhr6cqhn7x89gdxnlykq0xudq5c7334 + - &work age1c8pawdsxptfslgrz2c56s39mrtnjzc5mm3hfzgr2wdwu2v6vfsdsupjsq6 + creation_rules: + - path_regex: hosts/laptop/secrets/secrets.yaml$ + key_groups: + - age: + - *primary + - path_regex: hosts/server/secrets/secrets.yaml$ + key_groups: + - age: + - *primary + - path_regex: hosts/work/secrets/secrets.yaml$ + key_groups: + - age: + - *work + ''; + + systemd.user.services.mbsync.Unit.After = ["sops-nix.service"]; + home.packages = with pkgs; [ + sops + age + ]; + + wayland.windowManager.hyprland.settings.exec-once = ["systemctl --user start sops-nix"]; +} diff --git a/hosts/work/secrets/secrets.yaml b/hosts/work/secrets/secrets.yaml new file mode 100644 index 0000000..ae328cb --- /dev/null +++ b/hosts/work/secrets/secrets.yaml @@ -0,0 +1,19 @@ +ssh-config: ENC[AES256_GCM,data:npBcAOSwHpApUASlZmRo4stwMrOjdrdmhfYwumjbTpcq8aQ2ybV8le7cjNdVqIyxgwxUFV4/tGfmsq4nlrWIO/85spwfC5DyPGaZ848NI3UZJj8k2GKuw5qk/xGsTveNhq+vNZQcHeL4aeXF2TRmFLDHYGTku9anFL7FWkQ75MmGW78XfPUEyZJ52ylXq3gkYeVSrl6cXuwJw/QBlu+XTgFk4MM+E5BTXBFFNJOYkIt4GwWX7wdI+QqPEof8J0ENYdxUAMKMueL4pLNclWP0fu7QC7gwwRJWjauCNElJiDhpVFa6WukJV/Ut+I30FH9cJtj0rSodeu0hq2fWaiQ0wVbQudxi0JcnxJQs+B9nb6kpF+TN0MiD,iv:c7DMZSmlgMMnNlR0/kNRKPYjCzvNQJ46mZzojHppSg8=,tag:ausjsFk0H9nOiiMebHXSUg==,type:str] +netrc: ENC[AES256_GCM,data:EOpuZhDVXe7Q4P/98C3gtEvkdawI26d4oX/wRNytyp/mAdkHytXiLpFdsuO/3DADOG8h1CCo1UTs9ex+bqoD/LdChdp7INfNDSQ+aDxTiG0rLBgjvy8TIj8=,iv:tc/RbN1Upbjv+3rU5zUR3P//a1Hj1xODInLMShg4i1Y=,tag:7E9G2g4g+eMeJrwI20R/1g==,type:str] +github-key: ENC[AES256_GCM,data:LRgJxUcKvLiqVJ3acz88oGp5qmvbo7QiyTbcft3YwZr+84CLbty9GCMrryJ8DFnP8GCGh+cCQxyvk/n/hA71qz7WZ6vIWbTN2byP0LHwDtQpugYOQi9z1Q04hQU3DYnsqKS8hu6bnUV/SzrDpAOXugyMGZL5dITitidgEsVG5PxB+bzTZGhg7EOcZISz955AEtD+bGedvxaryEcMYPTZwRHYPl2+wvKKIbeZMiup6i0BCCYktUUIb3qSBawbknZ9nfbQFODkZbNuEEhyU2MITz2ajQEx8AjE4eUutjBBQpJsesIhiAyq5H1AmJDzesC4iccFUpTVHFWf20clPX9QTH5njqbJ+aw1hIzU2ljK3vou1eZfoZ5HCdV3+tuQTJGYcfFY29/PaN4sENPhgbYm0p9Ui4UlMbte3FfmhSqdMzIc8jIB8dPMtoUM/NTjxof/dVu/TPMBTqnJplzNgvH1r2UcPToiAVfWj96tXsr2ESZfE9q9oQh9EGMcyGpXxq06Gni4tOnXDaF3oHyWAiJ6jP/wrYag5/67m4DwpFEymg+/ROKcy2ou3MYA+748ocKYFRoOVfY+SwcM4bxl6smstsRZW8SoDo6O9ikZII51LIN7X/6sQ0L+dgsBTT75zm8DOAFx2tnVgSPN8HYsd2tyHA3L6pYxAAGmY6lSGJfgmYP8hForSuZgCSxWhlwPHLLrU14A2wOFw+X5b4Zgy2ZdsTv3pHDn35a8lNwANKiWhXSc/irie0enmNjKyKTQDcVxq65mho2D+q7XANjDYtqQ8VX93HD2mLNljuA5GjJxtlTrw6V80AI9OiKjMlbEIG5BHIwOcDj5z53kZ2hPHIlSMCXVBXgBwZgPzw2GXDnIgsLFtGirVj/H+N8IWUioUgyimLjygPJwk8lcIrRCA279O7PnFAQKW3gchs4BN76vF41dR5AVJrDeWmSRonMHZEmGaHONEy+8pxFYf+u7hI6dC6YwrhNYHFgKymtKoYCGS1VTi3MXVPxzL4KxnS+StgfDqzf/FypqGD+c9Qkz3THw01J5SyQO4r7Y7cJFhpRvF09uDvT55BtUVuxexOUxANsmbzJCSKG0GLEWa6e+8owLHRbUh5fQQHN4WVMOCb2XLJkHM6YkZv+Sl3sjwUOtZS1+hRAz4I5BsxxNYK3OySwlzb5yBF2axC6z0DTpXNhyMUSEm2yI4gGroW+x0q8AK4dYelhcBC2QYYp8a2QkQu7vphg05QusuebZpjhRsFVphkjNmpEmAxAGRK/AaRr6YZtfVe/IsZgXso9xr75TBl/wee3jl5kLfBxs0q4lUCmfAcdfkT9EUWp6IOX6E+l7rgObuPLU5q64QtPzu5WDG2zM8cQWMbGt34EnKqSqwUPP3cmEVNuPSWh4bubLFKh+wcREMaMQ5j9GA9AXHDQnFsp3M9L3+0CBJIdBGnZetkjpg3l8INkqXzI35rNmJ6DkfmAE1a/SLLu9qkYK8HWi+1hsqKpNqv6bAp9iKSCb/tFc88wgNVh2n9UVZXBuWXCmtwc2BUfaN9/rw6L/+iqrTu9vrq0LTDSy8A1RuKr3aY+EyCN9gd+BVjEjpszFD8Jnrgj4qz5jihEgo8/AdGAS5/8QiMhdr18LQ5JaNC2EAsSswHx4MpOtFyyt84qJV0Ip4zegDJ0wMukjBJuRsZ6yR6ThgB0357pdmJsSXvj4XgevTwewWMmyX18kleac/i7oifv1xvp1gQrgigdp7s3tY91zH2o1LG/DqTbife7lgt9P6kR/LsHevJaVOytLv8DTO1ggTZjHDMT+A9DiUVot/gmhPcf5JwMnhV6PII5XtR4dy+lIs876JQFDm2YUgWNTPO+EJS/G63TgHxyJxBhumPCODzbYY58x+RFzykPvBuf+d6MpP2A2Pc2KPgW/SWc4XqTUVj6FIgwS58NJm06uLdh3vrEEUqO+fL6KOzmLYAa5TabqOv9oFGXYpOJ8sJtfGXIj6i+/aG4LrNZGeTzBzvz+W2jOcAH27qciC4YopLcP4NR6aXA3jYLVOLCnh54IfPVgMFFg0ZoqeaHEZN9jJIMsXNGbGsfT+f9FxN8JxAOM/iqqAVeCguXxNiKGJuCl+uQU2QdqyJVSgyq1xtXibRqGfJCDc+oGnXy5/jxjb0uDzhdYH94kfR4cj01MTDqt3kfFNjJtjl0KBR0oXj/E//PJwRgKJ3i0o5jYjRyLSqUfUJvEyiPrOmzAZrXQT8aYeOyB5MO4t0pdcMGBwcrWPkmxRiu3dERJHJttpFD03Iv5qFRZdNAsrfzu0dW59nO9x//Czxs3mcJfRyj2moAjMiyYC6vg5hPZso3lyDyJgvEySZ70GhJAfkb6peossSco7cdEw6lVisXDk9BuPArDn/kua94eUiajB1v3dwwvWNc535HQIQIbTd5478JESiFmB7mt5EXFXWVZWDhPRxkK8Px3KErl+4WBZec+glBSnrY1VqXDdBRG63etA/Ev2P4ih0MTEiv7/Bcbw9uzVsIIwhyopY3JtkJP/YqZpS9HSDzSTnkCcetO9YC6K1aqRjdxzDwfOqadu98gzXxZZOsGMFaBgptFqBwfrP5Z8+CWWebMIL2HzZCEhMZhHRFcfi5dI7t6R2AS6cqRFXQlaB75lYhOvFLmeuMtspjTUL2SQa1J17bZn9JYVNvBfL4twfZdp4zjo5DgFF5LiHC6uQa4LW3aWN8ujQ2CGRP67iRsIgedfrNZG6vdkwDMpzhyFFZXXrs507RTimTJGngX1kBWNb+j+b/RmjLsdONPPgCgE1o9fxJCfHM53zDHSlVcO8rsLideXY6HIUKgZC0khgpif5YBG+iHeqfT3ZBLwhLjK0GH6oP3TKw0xmHWq4Nb6C6OqdEIGQ7Rxt+rWOOPKhUMyzdhwz1YpeZA0zobRdR7isvmWGTMwxS56r+NuI6dOQL6xs+MlVFOPtyYNJAF2qWDHt0XOa/7Kv4XDRF7zDA19ZhqG8xDU9NtDwUDFrPBV5kO0TDSHuh7WShkzyXJYfc62WEIxIfbdMVX1m+mG20/f6Tk2r9wRxtAdxU4WqhK+YaZf8ZE6LfsNwJVyWI+o0VeK2v/2GkdUVeuDvq9aju+BipuUUHs9K09a4EyZOMNJtYUPj53W76rVP3rwAXr2jj+sWeDFCibsNTkv2KuyOzOM1cJCbONXNfqPAo5yx3cAwXp/ikz9kPMwmVqgIHGAd6QsTmaBXe4ex5C+GA1OBCMvk6ZAoSwRsAmoOZdharD+6dEEFL4HeqQx3XT+ddTRcGiQxgxuwPDAxcuCBkvqZSuVt1jb2c4WpL9id1S0TEsfzRtDj6VGM318jV3pj3pZvLXwVMJc7J4o6f0MNhjtgOZdcc302sh6HrusTn/zrRPpQVUPHkmmvmB4eP6IVT6aeKQS8Vt10PNtXbJKLYqFGnlTrrlHxBrGDMfz/j5ycai16VKeaKS1SnR1TQAReOaOksMc17xDVo9hnocOMs89tzCkDQ3e14lKngxWzmcxZAS6NGA5u/Y6x48b8OCiVbsbOxoeI5ouKd37TVPJEHo1VRPOhruVU50xv+eZtCbSkpTWPMq3r4AXZJjTKXn3aYTMQNMisR0yhto4dkdoNQw93ngm+MSduv+Sxt3VG108G6UDVEjE21ylMDueP5rDQ4G2sBPgIT/uSyFWan3tcP2eTFjps4BB0yzx4evjdUqu+Uqkvts7DOPY4MT8/g8YO41PvAW5sFItcwr6gLALyVSK8I3dzePeNELXK6daHLhkcI4EN4Yh3OO+kkT00X29A/V7wqIoV7T06FneC6Hg8rWyPHTFbAO0zqXK58Tp4E0kp0LkZHS+nLbmvuZOKSyQOMNWTvMYcagfRc+VgbAPjnZ9yRCXvWHY6N2z2CTKEioYoqt3Sgs8dgRHVZK/qGoO5lAWfdb6cTUFOZU0FnXYTS2ccQdOf8bJHOmldhavi0Oswe6wWpg3/Rp5Rvm0Y0g3r5CEF6lybkjM4K6eXc3DsFWcV43VPw/1w0sV3ErtuJHVyYxZzyS+iO0FC0Vpvru2emHoylbn0Tw3Cy31onjbnRlJfd9hzEZYiCUDj9l2P5b8Lrmw127NL25pzA+tdnRi55QS+ceUZ6omPqf7YsIO5AygG5+ZDCwFfjBX3tW5dpEFXzsdx1GWLopxT8RkPxjRjm8Z5EJpQtIYmptc3C6nBvPPCx0qVXJKo0LNbm9pZ1QPF0Vi/qS+V8PsL6dwPFH4t5jcKXJUdPNuiVLcqogKVicPSP+NviDn38UjWXixPHhkYk5Rv/2setqUXkKM+vePnOv7fNE3Px8QqJembwYkaj+T5do8st2KbJy08B2/l3gYvKoMZ5A3B3ypz3gghnEYPXb9uK1QyQIUsfV8tPFyFFWLVDQbSBSbqsWDfV1FThAJSi/FhcI4Al2JuqPvESQmjKW3qP6kk2GXQQco+R0lPszTEum1M9YQxq6YnRRy/wAPnHZgSgwNliNzx9d/FQbgo1kNg5LgdFjZh41ooPAubRyxfkHxzsVrnhjEV22wA/7dsAdllnnWRARQjBfn3tzENiG8YV/pWZF78aL8XZwapiPrWI=,iv:2Mvmz1CFO1112RxjIl6sxyNIDqa/cg00um6RcQaHNY8=,tag:+zygdwQdCBeBXVLvAj/jJQ==,type:str] +gitlab-key: ENC[AES256_GCM,data:1iAAh7CEeJGYibM1wcFn9MRK8TtgRFA2dCSVZThiCI53GKkbbf5JZ2cYJm3p/D9loP0/lU7TbNR8IjVyqqGP8MF+u4cm0gFIEL0i9+wBKIJsYXxzXV7XIQNTF1JU26/b+hpfUEcqXANQ88wdaGTrEDYAaMV0kYcBUkpMgUdIU+iCJkr3bPKZRjengA3/Sj6QkRzBTBrWo8ANEAnmi+Nn8NTFdHbwp+uLwelijCOz4iiShMTRjJYtBZ8zlGXf7qv9warXn91oh1p5aPYBRH6CuUwX1lZYDPmFGxOS5usYYippqsRmEEg9Haas0EwxU8CAZgX6cNnfjhq3le86vCapqZnzdNAwR5rvMEQ178Fl89Ri5Ka7n9GU7CFRzzXpykPErKbsG+T3KtfO20Lo2eDWO/gXuQILZcwaFDEbZuXq7qbrtyJ1TmtXQF73paG7yEITwOFLaMeJVRX/WvdXbzFo9X8V7zv7iuyyi4Y/RzkW2g7Ck0x3MIgxyUkDQZnb9XLYm5PzoKZ54uXIC6tqaC7ux7o785VOvaaNJiu1r+mtm7tN3VD3nQGBMGC4BqM4iYEt/KcTC4fn4rSwecfcYTpGQf6LfDOWgZvBz8Fw8AraWIANjHkOMrlWhIJJ8g7N+35rThEfrC1hGAptWsOSVZ0NbZk3UMCzv88KpDJA/9rekLIpAodJaZafM3VhK2ZLU4i6IYprKlsFYB/+WDwvppX+LIofMdhZfGhI+hRyiNF1egh+PBv/UzHIdanNLiITXO6/Kt5kgSujVmr2O6NWOlx+Ve1udxXWzNxp0qrMKa2JVljBS4UFw4HPM0LzQ2KMW3rZ1fWq88/dRtzoBJfouL8smeSrc+VJJACEzHevXq4e8zgjg9+QnK+ZWNwcna1bQgB+lG76hGnfVvIHF4PQM6tGSS6RLQrwsAMI8DMsiRhYUc8Bdrj2+fM8GFTC81pYyRsmha6tJmq+S8oM919iTqFFGFk4NFMy1Mj/95Ckrb0tkCIiJe+Quvu91oLVzLAbkRdDF/H6rudrndhqlAANQs0acPemuD4/rrUfv+jFEiOazjydGrHTae0jnJyS5mR3QZxWst0p7Q+yIlduU+kY9uX+ZuDwjUsOqy56K2mn9+dPVA10D0hqSiWUQQ+TQU5QGaalJRjt4RG2V3fcwCs8nla4XNrxaSty67141CBJHgh4I37qCFcu1f7YqqKJNmVJwBX2/70Rg0nb63FPDh6UWtyaheQD4GL+2ZUJmlh+ZMPzJZEO6fABOQoyyMZhOv2Pem+AQHD97sN32E2WoCiSxMFYFe4Pc9sy5rFkZb7OsdNK3VzoeWVkklhNqpis0sU50Bqt48V+2qXFU12LGUuglzo9dBTJCgaD6xqadEYlh+WH18Q6yQPefcwcWzl0Ql/Y/F0XfSEgaIyd/VZdQ6QP3ZF6q4oEtKOCg+AnkbMVUw5TA+RdW/UnhJlErIs+AQRkKZ8JwpIalTccAEk7VgQQdRiCD1PBhc+0T9gzTbQTqCB8pCqy7M6UEUbumOfyUKOtkosk0Bx8MLtyzX7va+3D0h7Cdze4CFTUT8EZquSWoX5ozwF1DdsBs3wrunIa1FYYaZQDiMiYLZ64TRzVBujeyZxFQLgKPbEBBr1BalgJglGALLZUfkmz01g5stgkZDeXvbTgA0W9PKFhZ+lLfrZ2NQzblZ6DiLeFM5ybxSbCbBSx2gzzBuMgbWOVTFDXLRuGOE0GRWVpzEtcqTncQfbJT+6AicA86e6MuXn12Zq3uyF4HoiybBFEAkYF24qLz2XZ6K9E7aNdWJAY2dcvq+LCoaHKlpekSUO+jrfykEfH5eFhnSj+hrwtSa3+3tLkuNdzjEpTcvq3l0d9dVAcMswv93RrU9PNGs66W7wRKiiOYvC+BqjOIkUvXVxr5Tl/1WDUgah1BTaQO80KEphtmEen4s1gLQEUN6lA0HsBAyDOMHGfkDgcT2pH8A6s5bc8BpXyyGZOLQ89h5vpvCPFFbxHNxffKXgRWLUfoNoXDqBG0kxDm7+CLmkD9jmH1XkRu3a0qr9KgZDUqQoVHCpUMXF8/HN7+1VHIUP5pWO9mupX0jL91ymF16HBCucJQiCWmKr2Cn+huPwtzcRblAoQAZY4da1PbIBwdys8Q77WETrTiK/XrQHiE/ZRiPFZK3B4wPFjMGyp7yhnF23ram76E3ny0xqunfjvyTLcLVmkmdDIz6FpNCa2Qd+oqpkKzFEF3hcmZgue9uqsmjJk4ymAKqTXB2PUdz0GoOe7obg6QyZS0WvgsuCuem5yePjYL43AXiFfyDp4fDRRaB5qpJzXS8HzCh0Whyg3z8UEygVnXMmL1k/84LsfME4/ubMV4cJn5Q9rDFGIwUfk4M98Y1ylPWQfcbwpAxtipBN0uQL6WX6L4dglE4wcf/0d6IGmIxF03E08BvvQvniox7fZEIYY8dP9LlitXZBfKqSDw3jQ5JuLllGI//hbXGu8IxWFnABz5i/NkNGJnSb6b4V5vWXAWSBi918ZZYMmxqH87hypen6ONq2jxPXdgN4lphyQDxL7Sx1oNAUUdm8NqTj47g6Ny0RWHUJPAnKAZNpAljmbCny0fkTzDzg/OhetkUv6+BSRZq800gaGkNz41cmJvTZBe+MOrGEvHwc5C2uFsLJuagJ+vryyN0sdpuSFVF/3Zm8Ch/aFldeS5xjwf7Yfy2Nb2H2WRJbFa01sEbMiMkrhLLpyQdwL9XoFBN/1IKoZyQE0fBLXwU8D9BnL3PCBbSeVDoswRt7hPe40SyBMTu9uhzn9n7DXhWqb+hpbM1ViDlT1wE/P4xx3UcRRb+xx5ANkbuF11Yf16cAa0hwM/2BmRAVInmgeNS4Lp/gre0WBO9x21I3rZ5YaRxRsOUTBlaElYRMcxQQTkw6sc1TM3u7lK+b6Ug8iS8jYP+3m/QGHF4W/3eHVoELfBq8vwYCPa87338sQwlLAmQlf5REYBqDhV0Z075hmwGeOPW/Q+2cKpY8XdlD/eYKhgNuHV1pL1CRAbWCkZg21Lq7zVR+wYuu3tuEqmIT7+P0Yj4EjNiODe523wBNPH2gxLzupPZmT/fR1YoI/ij51qj6QPCQgy1eJB4TTlmNJHDNBKEakVr26wFg4Pd6y+99W1sEPNn6weoezXLk5DWSXln0AdAmYcxa5I8ZWGwDrTMASf6QUNlg0lTXbqw9khZgdk069zrfYzBhtcSyHAqg6DzyHeLzUbPNXmvBS2WGbbJUZX73tqB+cRAD4UUDv02ZQ2YrUT0AQpvc9+dekzWuv/UGnQ1Y085NMSP6s+sGL0WfcOamb39Y7Ov4y6hCikq5M1TiHogndk7Apkm1hQLOiUM3Tb0IXmrBtmX6RxvUgXBLQ+XuZjJ3884soM0swwdt9f2vKljG2lnOnCdHPVSQUO3XQ90itLXQhq21B8SOiFA0DvRWJMEhr4d3LdNOAbj6Iu1yQ0PvdEaD0X+1ND/3Tot6yAlAqzA6+47tnU1Gq0s6Y6uqkW5u2oSSwMoeIoRInBIKLO4tSW/rKICWJznuDivRIm5BHPFajEnahJdzclA7sPsbbKNwXEj7jzJELl+oUympJ/L1dpPfxcM3tSmErgwfwdNWNkf97kml9MZ03F2bUm71Azm1tq26aFUUOGxbsGI2T8NNFJsf25m5CfC06YK3F5Yb8pG08IhKRrkihM356uJcjC0m5V+OUETF2fTQLytWbq1gthXfaG+gE4Gk/MUX1vHfGUprTf3JYgiIZzgIIZeaX5j4XJ7hykwb6ahhIMX/ndB5XYGCER2vkDrDPwspsAL/pXiIOMDFSwJVsvf/9fbLDttYNJCR2B9/Enbjh87abaYlQsgUjsPFPAGH2nw7hX6iuEihrPyLZdUp0xJb2PIq8R4xpiStzomDdVkC018YPRWank9mKXHYf4+1QdQ3AftOs5iDMgf50XASNl/6F4V+NGX2vRiPJ2gxWBvpoPu5csSgKetHiJCqNLbHLggFQEjYJyW3Cepsm87LC1/eEa7AEPdR+eQYsIp4Xr1LMD9cEogHpz+/VOgdtcQmPMrNHsRolTaO5lT1vbrRJE+SM6byoi/ACDKI2pRObI+FPzflmm5X0/Kh+b6InGzCXR+k1CXyUauI6wro82J8T+vHdxPEy59kdXlAicy7q0/+UZ8zF4ApNT7XXV9sgmyhzD3/v1kWwDPnowptr/JJT01TTHTUPtDDqy5X497h56jqwjWex3Lc7cTusrkVrcHg26fIMw/zyTW3pgmrwpGayVC8kg3pNJQw+MX6xYO5Cq/EQv72rOKVw5YY83IWqkh6GHn3bTghvMETiWoCDUPB0JNsPY1i7hrFCYzGJib+p6M53ngNCfjI786qZ78CQVhmIyl8VGGwYrvtHY3UFArXUDK/Y9rc2lvMoCIBCwhq5w/eaJiTN1BhMgFVvgbdI+Y9cj/UgtE3yFjsQp/kI+oEyCDQntuzO1UhZiP2/9nXm4Lyf/ZhUcdEI9I0=,iv:aG4nqGJ/TRiAtiWoPwqej6We+IWEWFibCqL7bGwXbkA=,tag:c5ckW2o4+2rm/5mrGF1tzg==,type:str] +sops: + age: + - recipient: age1c8pawdsxptfslgrz2c56s39mrtnjzc5mm3hfzgr2wdwu2v6vfsdsupjsq6 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBVby9Wa1NUUkpyeDMwU3dM + R0EyeFVtT0tJU0pKaWtXQzRkTDBPY3JjcTFrClNIQnl2WVorS0FZZjhicTQ5V2kx + MUZTZWZtaUk2a1ZhUTBCUnhkWHFIMFUKLS0tIElLcjJLZWNLOUJYN0NNVGFNUEFN + RkMrdTYwNkY1Tlc3M3dxTFdkRXJJZUEKUlYU45jXpS9hJO9Z/uAQ6XMj9QWgMMRI + LbJxvt48+yC+Y0XKOtDE0lHAuGNzUG8R/7FB1tTD8NCamBe46KGCIg== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2026-04-23T07:50:07Z" + mac: ENC[AES256_GCM,data:V3us1oxkQxIg5hn8TMiSHWa0RhNbio2mP8j59lSCKDLjnpTUHUAUZZOan+fkBwPxxtIdZFVZQl/kZuEHcnNwXk8J0DLeT8jrs8pvlDCHMAc+C9uzThNjQ9CrZ2C/dNtoI6uop3a6qo8UMhKhvAus08yR8rLsY7Gqt/In28HKqxU=,iv:g8wmq1thPfkSSfG+mtJS0431wbon/uylDTfH0P31dlw=,tag:5Z6CJMWeGN6frTLJQMxGGw==,type:str] + unencrypted_suffix: _unencrypted + version: 3.12.2 diff --git a/hosts/work/variables.nix b/hosts/work/variables.nix new file mode 100644 index 0000000..9247e0c --- /dev/null +++ b/hosts/work/variables.nix @@ -0,0 +1,38 @@ +{ + config, + lib, + ... +}: { + imports = [ + # Choose your theme here: + ../../themes/nixy.nix + ]; + + config.var = { + hostname = "h-work"; + username = "hadrien"; + configDirectory = "/home/" + config.var.username + "/.config/nixos"; # The path of the nixos configuration directory + + keyboardLayout = "fr"; + + timeZone = "Europe/Paris"; + defaultLocale = "en_US.UTF-8"; + extraLocale = "fr_FR.UTF-8"; + + git = { + username = "Hadi"; + email = "hadi@example.com"; + }; + + autoUpgrade = false; + autoGarbageCollector = true; + }; + + # DON'T TOUCH THIS + options = { + var = lib.mkOption { + type = lib.types.attrs; + default = {}; + }; + }; +} diff --git a/nixos/amd-graphics.nix b/nixos/amd-graphics.nix new file mode 100644 index 0000000..c2886a9 --- /dev/null +++ b/nixos/amd-graphics.nix @@ -0,0 +1,11 @@ +{pkgs, ...}: { + hardware.graphics = { + enable = true; + extraPackages = with pkgs; [ + rocmPackages.clr.icd + # Support VA-API pour AMD + libvdpau-va-gl + libva-vdpau-driver + ]; + }; +} diff --git a/nixos/audio.nix b/nixos/audio.nix new file mode 100644 index 0000000..1fe3078 --- /dev/null +++ b/nixos/audio.nix @@ -0,0 +1,23 @@ +# Audio configuration for NixOS using PipeWire +{ + security.rtkit.enable = true; + services.pulseaudio.enable = false; + + services.pipewire = { + enable = true; + alsa.enable = true; + alsa.support32Bit = true; + pulse.enable = true; + jack.enable = true; + wireplumber = { + enable = true; + extraConfig = { + "10-disable-camera" = { + "wireplumber.profiles" = { + main."monitor.libcamera" = "disabled"; + }; + }; + }; + }; + }; +} diff --git a/nixos/bluetooth.nix b/nixos/bluetooth.nix new file mode 100644 index 0000000..cea59b7 --- /dev/null +++ b/nixos/bluetooth.nix @@ -0,0 +1,7 @@ +# Bluetooth configuration for NixOS +{ + hardware.bluetooth = { + enable = true; + powerOnBoot = true; + }; +} diff --git a/nixos/docker.nix b/nixos/docker.nix new file mode 100644 index 0000000..cf586fd --- /dev/null +++ b/nixos/docker.nix @@ -0,0 +1,5 @@ +{config, pkgs, ...}: { + virtualisation.docker.enable = true; + virtualisation.docker.package = pkgs.docker_29; + users.users."${config.var.username}".extraGroups = ["docker"]; +} diff --git a/nixos/fonts.nix b/nixos/fonts.nix new file mode 100644 index 0000000..4c06f62 --- /dev/null +++ b/nixos/fonts.nix @@ -0,0 +1,26 @@ +# Fonts configuration for NixOS +{pkgs, ...}: { + fonts = { + packages = with pkgs; [ + roboto + work-sans + comic-neue + source-sans + comfortaa + inter + lato + lexend + jost + dejavu_fonts + noto-fonts + noto-fonts-cjk-sans + noto-fonts-color-emoji + nerd-fonts.fira-code + nerd-fonts.meslo-lg + openmoji-color + twemoji-color-font + ]; + + enableDefaultPackages = false; + }; +} diff --git a/nixos/home-manager.nix b/nixos/home-manager.nix new file mode 100644 index 0000000..69369eb --- /dev/null +++ b/nixos/home-manager.nix @@ -0,0 +1,20 @@ +# Home-manager configuration for NixOS +{ + inputs, + pkgs, + ... +}: { + home-manager = { + useGlobalPkgs = true; + useUserPackages = true; + backupFileExtension = "hm-backup"; + extraSpecialArgs = { + inherit inputs; + pkgs-stable = import inputs.nixpkgs-stable { + system = pkgs.stdenv.hostPlatform.system; + config.allowUnfree = true; + }; + pkgs-nur-hadi = inputs.nur-anotherhadi.packages.${pkgs.stdenv.hostPlatform.system}; + }; + }; +} diff --git a/nixos/hyprland.nix b/nixos/hyprland.nix new file mode 100644 index 0000000..0a4943b --- /dev/null +++ b/nixos/hyprland.nix @@ -0,0 +1,14 @@ +# Hyprland is a dynamic tiling Wayland compositor. +{ + inputs, + pkgs, + ... +}: { + programs.hyprland = { + enable = true; + withUWSM = true; + package = inputs.hyprland.packages."${pkgs.stdenv.hostPlatform.system}".hyprland; + portalPackage = + inputs.hyprland.packages.${pkgs.stdenv.hostPlatform.system}.xdg-desktop-portal-hyprland; + }; +} diff --git a/nixos/nix.nix b/nixos/nix.nix new file mode 100644 index 0000000..5ee8294 --- /dev/null +++ b/nixos/nix.nix @@ -0,0 +1,63 @@ +# Nix configuration for NixOS +{ + config, + inputs, + ... +}: let + autoGarbageCollector = config.var.autoGarbageCollector; +in { + # Ask for password once per SSH session (tied to the tty, expires when session closes) + security.sudo.extraConfig = '' + Defaults timestamp_type=tty,timestamp_timeout=-1 + ''; + + security.sudo.extraRules = [ + { + users = [config.var.username]; + commands = [ + { + command = "/run/current-system/sw/bin/nixos-rebuild"; + options = ["NOPASSWD"]; + } + ]; + } + ]; + nixpkgs.config = { + allowUnfree = true; + allowBroken = false; + }; + nix = { + nixPath = ["nixpkgs=${inputs.nixpkgs}"]; + channel.enable = false; + extraOptions = '' + warn-dirty = false + ''; + settings = { + download-buffer-size = 262144000; # 250 MB (250 * 1024 * 1024) + auto-optimise-store = true; + experimental-features = [ + "nix-command" + "flakes" + ]; + substituters = [ + # high priority since it's almost always used + "https://cache.nixos.org?priority=10" + + "https://hyprland.cachix.org" + "https://nix-community.cachix.org" + "https://numtide.cachix.org" + ]; + trusted-public-keys = [ + "hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc=" + "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" + "numtide.cachix.org-1:2ps1kLBUWjxIneOy1Ik6cQjb41X0iXVXeHigGmycPPE=" + ]; + }; + gc = { + automatic = autoGarbageCollector; + persistent = true; + dates = "weekly"; + options = "--delete-older-than 7d"; + }; + }; +} diff --git a/nixos/nvidia.nix b/nixos/nvidia.nix new file mode 100644 index 0000000..2c35464 --- /dev/null +++ b/nixos/nvidia.nix @@ -0,0 +1,102 @@ +# Nvidia configuration for NixOS with Wayland and Hyprland support +# Import this module only if you have an Nvidia GPU +{ + pkgs, + config, + ... +}: let + # Using beta driver for recent GPUs like RTX 4070 + nvidiaDriverChannel = config.boot.kernelPackages.nvidiaPackages.production; +in { + # Video drivers configuration for Xorg and Wayland + services.xserver.videoDrivers = ["nvidia"]; # Simplified - other modules are loaded automatically + + # Kernel parameters for better Wayland and Hyprland integration + boot.kernelParams = [ + "nvidia-drm.modeset=1" # Enable mode setting for Wayland + "nvidia.NVreg_PreserveVideoMemoryAllocations=1" # Improves resume after sleep + ]; + + # Blacklist nouveau to avoid conflicts + boot.blacklistedKernelModules = ["nouveau"]; + + # Environment variables for better compatibility + environment.variables = { + LIBVA_DRIVER_NAME = "nvidia"; # Hardware video acceleration + GBM_BACKEND = "nvidia-drm"; # Graphics backend for Wayland + __GLX_VENDOR_LIBRARY_NAME = "nvidia"; # Use Nvidia driver for GLX + NIXOS_OZONE_WL = "1"; # Wayland support for Electron apps + __GL_GSYNC_ALLOWED = "1"; # Enable G-Sync if available + __GL_VRR_ALLOWED = "1"; # Enable VRR (Variable Refresh Rate) + NVD_BACKEND = "direct"; # Configuration for new driver + MOZ_ENABLE_WAYLAND = "1"; # Wayland support for Firefox + }; + + # Configuration for proprietary packages + nixpkgs.config = { + nvidia.acceptLicense = true; + }; + + # Nvidia configuration + hardware = { + nvidia = { + open = false; # Proprietary driver for better performance + nvidiaSettings = true; # Nvidia settings utility + powerManagement = { + enable = true; # Power management + finegrained = true; # More precise power consumption control + }; + modesetting.enable = true; # Required for Wayland + package = nvidiaDriverChannel; + forceFullCompositionPipeline = true; # Prevents screen tearing + + # Configuration for hybrid AMD+Nvidia laptop + prime = { + # Optimized configuration for switchable graphics laptops + offload = { + enable = true; # Mode optimized for power saving + enableOffloadCmd = true; # Allows running applications with dedicated GPU + }; + # sync.enable disabled as offload is generally better for laptops + sync.enable = false; + # PCI IDs verified for your hardware + amdgpuBusId = "PCI:5:0:0"; # Integrated AMD GPU + nvidiaBusId = "PCI:1:0:0"; # Dedicated Nvidia GPU + }; + }; + + # Enhanced graphics support + graphics = { + enable = true; + enable32Bit = true; + extraPackages = with pkgs; [ + nvidia-vaapi-driver + libva-vdpau-driver + libvdpau-va-gl + mesa + egl-wayland + vulkan-loader + vulkan-validation-layers + libva + ]; + }; + }; + + # Nix cache for CUDA + nix.settings = { + substituters = ["https://cuda-maintainers.cachix.org"]; + trusted-public-keys = [ + "cuda-maintainers.cachix.org-1:0dq3bujKpuEPMCX6U4WylrUDZ9JyUG0VpVZa7CNfq5E=" + ]; + }; + + # Additional useful packages + environment.systemPackages = with pkgs; [ + vulkan-tools + mesa-demos + libva-utils # VA-API debugging tools + ]; + + # Enable Nvidia container toolkit for GPU acceleration in containers (docker) + hardware.nvidia-container-toolkit.enable = false; +} diff --git a/nixos/omen.nix b/nixos/omen.nix new file mode 100644 index 0000000..cc16439 --- /dev/null +++ b/nixos/omen.nix @@ -0,0 +1,64 @@ +# Omen laptop configuration for NixOS +# Import this only if you have an HP Omen laptop +{ + config, + pkgs, + ... +}: let + hp-omen-linux-module = pkgs.callPackage ( + { + kernel ? config.boot.kernelPackages.kernel, + stdenv, + fetchFromGitHub, + }: + stdenv.mkDerivation (finalAttrs: { + pname = "hp-omen-linux-module"; + version = "rebase-6.14"; + src = fetchFromGitHub { + owner = "ranisalt"; + repo = "hp-omen-linux-module"; + rev = finalAttrs.version; + sha256 = "sha256-2zCm29bdboSjRm/caMjBPGNc0tZXPUnIIYlHxxfhAok="; + }; + setSourceRoot = '' + export sourceRoot=$(pwd)/${finalAttrs.src.name}/src + ''; + nativeBuildInputs = kernel.moduleBuildDependencies; + makeFlags = [ + "KERNELDIR=${kernel.dev}/lib/modules/${kernel.modDirVersion}/build" + ]; + installPhase = '' + runHook preInstall + install hp-wmi.ko -Dm444 -t $out/lib/modules/${kernel.modDirVersion}/kernel/drivers/platform/x86/hp/ + runHook postInstall + ''; + }) + ) {kernel = config.boot.kernelPackages.kernel;}; +in { + boot.extraModulePackages = [hp-omen-linux-module]; + boot.kernelModules = ["hp-wmi"]; + boot.kernelParams = ["hp_wmi.force_slow_fan_control=1"]; + + users.groups.omen-rgb = {}; + users.users.${config.var.username}.extraGroups = ["omen-rgb"]; + + systemd.tmpfiles.rules = [ + "w /sys/devices/platform/hp-wmi/rgb_zones/zone00 0660 root omen-rgb -" + "w /sys/devices/platform/hp-wmi/rgb_zones/zone01 0660 root omen-rgb -" + "w /sys/devices/platform/hp-wmi/rgb_zones/zone02 0660 root omen-rgb -" + "w /sys/devices/platform/hp-wmi/rgb_zones/zone03 0660 root omen-rgb -" + ]; + + services.udev.extraRules = '' + SUBSYSTEM=="platform", KERNEL=="hp-wmi", ACTION=="add", \ + RUN+="${pkgs.coreutils-full}/bin/sleep 2", \ + RUN+="${pkgs.coreutils}/bin/chgrp omen-rgb /sys/devices/platform/hp-wmi/rgb_zones/zone00", \ + RUN+="${pkgs.coreutils}/bin/chmod 0660 /sys/devices/platform/hp-wmi/rgb_zones/zone00", \ + RUN+="${pkgs.coreutils}/bin/chgrp omen-rgb /sys/devices/platform/hp-wmi/rgb_zones/zone01", \ + RUN+="${pkgs.coreutils}/bin/chmod 0660 /sys/devices/platform/hp-wmi/rgb_zones/zone01", \ + RUN+="${pkgs.coreutils}/bin/chgrp omen-rgb /sys/devices/platform/hp-wmi/rgb_zones/zone02", \ + RUN+="${pkgs.coreutils}/bin/chmod 0660 /sys/devices/platform/hp-wmi/rgb_zones/zone02", \ + RUN+="${pkgs.coreutils}/bin/chgrp omen-rgb /sys/devices/platform/hp-wmi/rgb_zones/zone03", \ + RUN+="${pkgs.coreutils}/bin/chmod 0660 /sys/devices/platform/hp-wmi/rgb_zones/zone03" + ''; +} diff --git a/nixos/systemd-boot.nix b/nixos/systemd-boot.nix new file mode 100644 index 0000000..1dbd4fa --- /dev/null +++ b/nixos/systemd-boot.nix @@ -0,0 +1,43 @@ +# Systemd-boot configuration for NixOS +{pkgs, ...}: { + boot = { + bootspec.enable = true; + loader = { + efi.canTouchEfiVariables = true; + systemd-boot = { + enable = true; + consoleMode = "auto"; + configurationLimit = 8; + }; + }; + tmp.cleanOnBoot = true; + kernelPackages = pkgs.linuxPackages_latest; # _zen, _hardened, _rt, _rt_latest, etc. + + # Silent boot + kernelParams = [ + "quiet" + "splash" + "rd.systemd.show_status=false" + "rd.udev.log_level=3" + "udev.log_priority=3" + "boot.shell_on_fail" + ]; + consoleLogLevel = 0; + initrd.verbose = false; + + # plymouth = { + # enable = true; + # theme = lib.mkForce "cuts_alt"; + # themePackages = with pkgs; [ + # (adi1090x-plymouth-themes.override { + # selected_themes = ["cuts_alt"]; + # }) + # ]; + # }; + }; + + # To avoid systemd services hanging on shutdown + systemd.settings.Manager = { + DefaultTimeoutStopSec = "10s"; + }; +} diff --git a/nixos/tuigreet.nix b/nixos/tuigreet.nix new file mode 100644 index 0000000..126b02b --- /dev/null +++ b/nixos/tuigreet.nix @@ -0,0 +1,62 @@ +{ + pkgs, + inputs, + config, + lib, + ... +}: let + c = config.lib.stylix.colors; + tuigreet = inputs.notashelf-tuigreet.packages.${pkgs.stdenv.hostPlatform.system}.default; + + theme = lib.concatStringsSep ";" [ + "border=#${c.base0D}" + "text=#${c.base05}" + "prompt=#${c.base0D}" + "action=#${c.base0C}" + "button=#${c.base0D}" + "container=#${c.base00}" + "input=#${c.base02}" + ]; + + tuigreet-launch = pkgs.writeShellScript "tuigreet-launch" '' + exec ${tuigreet}/bin/tuigreet \ + --time \ + --time-format '%H:%M %A %d %B' \ + --sessions /run/current-system/sw/share/wayland-sessions \ + --remember \ + --remember-user-session \ + --asterisks \ + --greeting 'Welcome' \ + --container-padding 2 \ + --theme '${theme}' \ + --power-shutdown 'systemctl poweroff' \ + --power-reboot 'systemctl reboot' + ''; +in { + services.greetd = { + enable = true; + settings = { + default_session = { + command = "${tuigreet-launch}"; + user = "greeter"; + }; + }; + }; + + # this is a life saver. + # literally no documentation about this anywhere. + # might be good to write about this... + # https://www.reddit.com/r/NixOS/comments/u0cdpi/tuigreet_with_xmonad_how/ + systemd.services.greetd.serviceConfig = { + Type = "idle"; + StandardInput = "tty"; + StandardOutput = "tty"; + StandardError = "journal"; # Without this errors will spam on screen + # Without these bootlogs will spam on screen + TTYReset = true; + TTYVHangup = true; + TTYVTDisallocate = true; + }; + + environment.systemPackages = [tuigreet]; +} diff --git a/nixos/usbguard.nix b/nixos/usbguard.nix new file mode 100644 index 0000000..a1567d1 --- /dev/null +++ b/nixos/usbguard.nix @@ -0,0 +1,10 @@ +{config, ...}: { + services.usbguard = { + enable = true; + implicitPolicyTarget = "block"; + IPCAllowedUsers = [ + "root" + config.var.username + ]; + }; +} diff --git a/nixos/users.nix b/nixos/users.nix new file mode 100644 index 0000000..f33b2a1 --- /dev/null +++ b/nixos/users.nix @@ -0,0 +1,22 @@ +# Users configuration for NixOS +{ + config, + pkgs, + ... +}: let + username = config.var.username; +in { + programs.zsh.enable = true; + users = { + defaultUserShell = pkgs.zsh; + + users.${username} = { + isNormalUser = true; + description = "${username} account"; + extraGroups = [ + "networkmanager" + "wheel" + ]; + }; + }; +} diff --git a/nixos/utils.nix b/nixos/utils.nix new file mode 100644 index 0000000..44d6a4c --- /dev/null +++ b/nixos/utils.nix @@ -0,0 +1,151 @@ +# Misc +{ + pkgs, + config, + ... +}: let + hostname = config.var.hostname; + keyboardLayout = config.var.keyboardLayout; + configDir = config.var.configDirectory; + timeZone = config.var.timeZone; + defaultLocale = config.var.defaultLocale; + extraLocale = config.var.extraLocale; + autoUpgrade = config.var.autoUpgrade; +in { + networking.hostName = hostname; + + networking.networkmanager.enable = true; + systemd.services.NetworkManager-wait-online.enable = false; + + system.autoUpgrade = { + enable = autoUpgrade; + dates = "04:00"; + flake = "${configDir}"; + flags = [ + "--update-input" + "nixpkgs" + "--commit-lock-file" + ]; + allowReboot = false; + }; + + time = { + timeZone = timeZone; + }; + i18n.defaultLocale = defaultLocale; + i18n.inputMethod = { + enable = true; + type = "fcitx5"; + fcitx5.addons = with pkgs; [fcitx5-gtk]; + }; + i18n.extraLocaleSettings = { + LC_ADDRESS = extraLocale; + LC_IDENTIFICATION = extraLocale; + LC_MEASUREMENT = extraLocale; + LC_MONETARY = extraLocale; + LC_NAME = extraLocale; + LC_NUMERIC = extraLocale; + LC_PAPER = extraLocale; + LC_TELEPHONE = extraLocale; + LC_TIME = extraLocale; + }; + + services = { + xserver = { + enable = true; + xkb.layout = keyboardLayout; + xkb.variant = ""; + }; + gnome.gnome-keyring.enable = true; + psd = { + enable = true; + resyncTimer = "10m"; + }; + }; + console.keyMap = keyboardLayout; + + environment.variables = { + XDG_DATA_HOME = "$HOME/.local/share"; + PASSWORD_STORE_DIR = "$HOME/.local/share/password-store"; + EDITOR = "nvim"; + }; + + services.libinput.enable = true; + programs.dconf.enable = true; + services = { + dbus = { + enable = true; + implementation = "broker"; + packages = with pkgs; [ + gcr + gnome-settings-daemon + ]; + }; + gvfs.enable = true; + upower.enable = true; + power-profiles-daemon.enable = true; + udisks2.enable = true; + }; + + # enable zsh autocompletion for system packages (systemd, etc) + environment.pathsToLink = ["/share/zsh"]; + + # Faster rebuilding + documentation = { + enable = true; + doc.enable = false; + man.enable = true; + dev.enable = false; + info.enable = false; + nixos.enable = false; + }; + + environment.systemPackages = with pkgs; [ + fd + bc + gcc + file + git-ignore + xdg-utils + wget + curl + gnupg + openssl + vim + go + comma + zip + unzip + optipng + jpegoptim + pfetch + btop + unrar + p7zip + ]; + + xdg.portal = { + enable = true; + xdgOpenUsePortal = true; + config = { + common.default = ["gtk"]; + hyprland.default = [ + "gtk" + "hyprland" + ]; + }; + + extraPortals = [pkgs.xdg-desktop-portal-gtk]; + }; + + security = { + # allow wayland lockers to unlock the screen + pam.services.hyprlock.text = "auth include login"; + + # userland niceness + rtkit.enable = true; + + # don't ask for password for wheel group + sudo.wheelNeedsPassword = false; + }; +} diff --git a/server-modules/adguardhome.nix b/server-modules/adguardhome.nix new file mode 100644 index 0000000..9caa2c2 --- /dev/null +++ b/server-modules/adguardhome.nix @@ -0,0 +1,22 @@ +# Adguard is a network-wide ad blocker +# When installed, open localhost:3000 to setup +{config, ...}: { + services.adguardhome = { + enable = true; + port = 3000; + }; + + networking.firewall = { + allowedTCPPorts = [53]; + allowedUDPPorts = [53]; + # Allow containers to reach adguard UI (for glance dns-stats widget) + extraCommands = '' + iptables -I INPUT 1 -s 10.233.0.0/16 -p tcp --dport 3000 -j ACCEPT + ''; + extraStopCommands = '' + iptables -D INPUT -s 10.233.0.0/16 -p tcp --dport 3000 -j ACCEPT 2>/dev/null || true + ''; + }; + + services.cloudflared.tunnels."${config.var.tunnelId}".ingress."adguard.${config.var.domain}" = "http://localhost:${toString config.services.adguardhome.port}"; +} diff --git a/server-modules/arr.nix b/server-modules/arr.nix new file mode 100644 index 0000000..707543c --- /dev/null +++ b/server-modules/arr.nix @@ -0,0 +1,66 @@ +# *arr is a collection of media management applications. +# See https://github.com/rasmus-kirk/nixarr +# Setup guide: https://nixarr.com/wiki/setup/ +{config, ...}: let + username = config.var.username; +in { + # Add my secrets + sops.secrets = { + recyclarr = { + owner = "recyclarr"; + mode = "0777"; + }; + wireguard-pia = { + group = "media"; + mode = "0600"; + }; + }; + + nixarr = { + enable = true; + + mediaUsers = [username]; + mediaDir = "/mnt/data/media"; + stateDir = "/mnt/data/.state/nixarr"; + + vpn = { + enable = true; + wgConf = config.sops.secrets.wireguard-pia.path; + }; + + jellyfin.enable = true; + jellyseerr.enable = true; + prowlarr.enable = true; + radarr.enable = true; + sonarr.enable = true; + bazarr.enable = true; + transmission = { + enable = true; + extraSettings = { + trash-original-torrent-files = true; + rpc-whitelist-enabled = false; + rpc-host-whitelist-enabled = false; + }; + vpn.enable = true; + }; + recyclarr = { + enable = true; + configFile = config.sops.secrets.recyclarr.path; + }; + }; + + users.users.jellyfin.extraGroups = [ + "video" + "render" + ]; + + services.cloudflared.tunnels."${config.var.tunnelId}".ingress = { + "media.${config.var.domain}" = "http://localhost:8096"; + "demandemedia.${config.var.domain}" = "http://localhost:5055"; + "bazarr.${config.var.domain}" = "http://localhost:6767"; + "prowlarr.${config.var.domain}" = "http://localhost:9696"; + "radarr.${config.var.domain}" = "http://localhost:7878"; + "sonarr.${config.var.domain}" = "http://localhost:8989"; + "transmission.${config.var.domain}" = "http://localhost:9091"; + }; +} diff --git a/server-modules/awesome-wallpapers.nix b/server-modules/awesome-wallpapers.nix new file mode 100644 index 0000000..b3dd75b --- /dev/null +++ b/server-modules/awesome-wallpapers.nix @@ -0,0 +1,41 @@ +{ + config, + inputs, + lib, + ... +}: let + inherit (import ./mk-container.nix {inherit lib config;}) mkContainer; +in { + imports = [ + (mkContainer { + name = "wallpapers"; + hostIp = "10.233.4.1"; + containerIp = "10.233.4.2"; + nixosConfig = {pkgs, ...}: { + services.nginx = { + enable = true; + virtualHosts."wallpapers" = { + root = "${inputs.awesome-wallpapers.packages.${pkgs.stdenv.hostPlatform.system}.default}/share/awesome-wallpapers"; + listen = [ + { + addr = "0.0.0.0"; + port = 8080; + } + ]; + locations."/" = { + tryFiles = "$uri $uri/ /index.html"; + }; + extraConfig = '' + port_in_redirect off; + absolute_redirect off; + ''; + }; + }; + networking.firewall.allowedTCPPorts = [8080]; + system.stateVersion = "24.05"; + }; + }) + ]; + + services.cloudflared.tunnels."${config.var.tunnelId}".ingress."wallpapers.${config.var.domain}" = "http://10.233.4.2:8080"; +} diff --git a/server-modules/blog.nix b/server-modules/blog.nix new file mode 100644 index 0000000..33c9618 --- /dev/null +++ b/server-modules/blog.nix @@ -0,0 +1,67 @@ +{ + config, + inputs, + lib, + ... +}: let + inherit (import ./mk-container.nix {inherit lib config;}) mkContainer; + domain = config.var.domain; +in { + imports = [ + (mkContainer { + name = "blog"; + hostIp = "10.233.3.1"; + containerIp = "10.233.3.2"; + nixosConfig = {pkgs, ...}: { + services.nginx = { + enable = true; + virtualHosts = { + "blog" = { + root = "${inputs.blog.packages.${pkgs.stdenv.hostPlatform.system}.default}/share/blog"; + listen = [ + { + addr = "0.0.0.0"; + port = 8080; + } + ]; + locations."/" = { + tryFiles = "$uri $uri/ =404"; + }; + extraConfig = '' + port_in_redirect off; + absolute_redirect off; + error_page 403 /403.html; + error_page 404 /404.html; + error_page 500 /500.html; + error_page 503 /503.html; + add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' data: https://umami.${domain}; style-src 'self' 'unsafe-inline'; img-src 'self' data: https://git.${domain}; connect-src 'self' https://umami.${domain};" always; + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Content-Type-Options "nosniff" always; + add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always; + ''; + }; + "www-redirect" = { + listen = [ + { + addr = "0.0.0.0"; + port = 8081; + } + ]; + extraConfig = "return 301 https://${domain}$request_uri;"; + }; + }; + }; + networking.firewall.allowedTCPPorts = [ + 8080 + 8081 + ]; + system.stateVersion = "24.05"; + }; + }) + ]; + + services.cloudflared.tunnels."${config.var.tunnelId}".ingress = { + "${config.var.domain}" = "http://10.233.3.2:8080"; + "www.${config.var.domain}" = "http://10.233.3.2:8081"; + }; +} diff --git a/server-modules/cloudflared.nix b/server-modules/cloudflared.nix new file mode 100644 index 0000000..4bccfdb --- /dev/null +++ b/server-modules/cloudflared.nix @@ -0,0 +1,37 @@ +# Cloudflared tunnel configuration for NixOS +# It allows exposing services securely via Cloudflare Tunnel +{ + config, + pkgs, + ... +}: { + sops.secrets.cloudflared-token.mode = "0400"; + + # To setup cloudflared, run: + # - `cloudflared tunnel login` + # - `cloudflared tunnel create YourTunnelName` + # + # This will create a credentials file & give you the tunnel ID to use below. + services.cloudflared = { + enable = true; + tunnels."${config.var.tunnelId}" = { + credentialsFile = config.sops.secrets."cloudflared-token".path; + default = "http_status:404"; + }; + }; + + environment.systemPackages = with pkgs; [ + cloudflared + ]; + + systemd.services."cloudflared-tunnel-${config.var.tunnelId}" = { + wantedBy = ["multi-user.target"]; + after = ["network-online.target"]; + wants = ["network-online.target"]; + }; + + # At the moment (2025), for support of browser rendering of the tunnels, this line is required: + services.openssh.settings.Macs = [ + "hmac-sha2-256" + ]; +} diff --git a/server-modules/cyberchef.nix b/server-modules/cyberchef.nix new file mode 100644 index 0000000..fa22798 --- /dev/null +++ b/server-modules/cyberchef.nix @@ -0,0 +1,33 @@ +{ + config, + lib, + ... +}: let + inherit (import ./mk-container.nix {inherit lib config;}) mkContainer; +in { + imports = [ + (mkContainer { + name = "cyberchef"; + hostIp = "10.233.5.1"; + containerIp = "10.233.5.2"; + nixosConfig = {pkgs, ...}: { + services.nginx = { + enable = true; + virtualHosts."cyberchef" = { + root = "${pkgs.cyberchef}/share/cyberchef"; + listen = [ + { + addr = "0.0.0.0"; + port = 8080; + } + ]; + }; + }; + networking.firewall.allowedTCPPorts = [8080]; + system.stateVersion = "24.05"; + }; + }) + ]; + + services.cloudflared.tunnels."${config.var.tunnelId}".ingress."cyberchef.${config.var.domain}" = "http://10.233.5.2:8080"; +} diff --git a/server-modules/default-creds.nix b/server-modules/default-creds.nix new file mode 100644 index 0000000..297baaf --- /dev/null +++ b/server-modules/default-creds.nix @@ -0,0 +1,36 @@ +{ + config, + inputs, + lib, + ... +}: let + inherit (import ./mk-container.nix {inherit lib config;}) mkContainer; + domain = config.var.domain; +in { + imports = [ + (mkContainer { + name = "def-creds"; + hostIp = "10.233.6.1"; + containerIp = "10.233.6.2"; + nixosConfig = {...}: { + imports = [inputs.default-creds.nixosModules.default]; + services.default-creds = { + enable = true; + port = 8087; + }; + networking.firewall.allowedTCPPorts = [8087]; + systemd.services.default-creds.environment = { + HOST = lib.mkForce "0.0.0.0"; + PUBLIC_UMAMI_URL = "https://umami.${domain}"; + PUBLIC_UMAMI_WEBSITE_ID = "7197484c-01ad-488e-9caa-5ab7b7595f08"; + UMAMI_URL = "https://umami.${domain}"; + UMAMI_WEBSITE_ID = "7197484c-01ad-488e-9caa-5ab7b7595f08"; + }; + system.stateVersion = "24.05"; + }; + }) + ]; + + services.default-creds.enable = lib.mkForce false; + services.cloudflared.tunnels."${config.var.tunnelId}".ingress."default-creds.${config.var.domain}" = "http://10.233.6.2:8087"; +} diff --git a/server-modules/fail2ban.nix b/server-modules/fail2ban.nix new file mode 100644 index 0000000..dd7af51 --- /dev/null +++ b/server-modules/fail2ban.nix @@ -0,0 +1,14 @@ +# Fail2Ban is a log-parsing application that protects Linux servers from brute-force attacks. +{ + services.fail2ban = { + enable = true; + maxretry = 5; + bantime = "24h"; # Ban IPs for one day on the first ban + bantime-increment = { + enable = true; # Enable increment of bantime after each violation + multipliers = "1 2 4 8 16 32 64"; + maxtime = "168h"; # Do not ban for more than 1 week + overalljails = true; # Calculate the bantime based on all the violations + }; + }; +} diff --git a/server-modules/firewall.nix b/server-modules/firewall.nix new file mode 100644 index 0000000..0a45838 --- /dev/null +++ b/server-modules/firewall.nix @@ -0,0 +1,7 @@ +# Firewall configuration for NixOS +{ + networking.firewall = { + enable = true; + allowPing = false; + }; +} diff --git a/server-modules/gitea.nix b/server-modules/gitea.nix new file mode 100644 index 0000000..6426f73 --- /dev/null +++ b/server-modules/gitea.nix @@ -0,0 +1,84 @@ +{ + config, + pkgs, + lib, + ... +}: let + inherit (import ./mk-container.nix {inherit lib config;}) mkContainer; + domain = config.var.domain; + catppuccin-gitea = pkgs.fetchzip { + url = "https://github.com/catppuccin/gitea/releases/download/v1.0.2/catppuccin-gitea.tar.gz"; + sha256 = "sha256-rZHLORwLUfIFcB6K9yhrzr+UwdPNQVSadsw6rg8Q7gs="; + stripRoot = false; + }; +in { + imports = [ + (mkContainer { + name = "gitea"; + hostIp = "10.233.11.1"; + containerIp = "10.233.11.2"; + internet = true; + bindMounts."/var/lib/gitea" = { + hostPath = "/var/lib/gitea"; + isReadOnly = false; + }; + nixosConfig = {lib, ...}: { + users.users.gitea.uid = lib.mkForce 978; + users.groups.gitea.gid = lib.mkForce 968; + + services.postgresql = { + enable = true; + ensureDatabases = ["gitea"]; + ensureUsers = [ + { + name = "gitea"; + ensureDBOwnership = true; + } + ]; + }; + + services.gitea = { + enable = true; + database.type = "postgres"; + settings = { + server = { + HTTP_ADDR = "0.0.0.0"; + HTTP_PORT = 3002; + ROOT_URL = "https://git.${domain}/"; + DOMAIN = "git.${domain}"; + LANDING_PAGE = "/anotherhadi"; + }; + service = { + REGISTER_MANUAL_CONFIRM = true; + DISABLE_REGISTRATION = true; + DEFAULT_KEEP_EMAIL_PRIVATE = true; + SHOW_REGISTRATION_BUTTON = false; + }; + ui = { + DEFAULT_THEME = "catppuccin-mocha-mauve"; + THEMES = "catppuccin-latte-mauve,catppuccin-frappe-mauve,catppuccin-macchiato-mauve,catppuccin-mocha-mauve"; + }; + explore = { + DISABLE_USERS_PAGE = true; + DISABLE_ORGANIZATIONS_PAGE = true; + }; + repository.DISABLE_STARS = true; + mailer.ENABLED = false; + api.ENABLE_SWAGGER = false; + other.SHOW_FOOTER_VERSION = false; + }; + }; + + systemd.services.gitea.preStart = lib.mkAfter '' + mkdir -p /var/lib/gitea/custom/public/assets + ln -sfn ${catppuccin-gitea} /var/lib/gitea/custom/public/assets/css + ''; + + networking.firewall.allowedTCPPorts = [3002]; + system.stateVersion = "24.05"; + }; + }) + ]; + + services.cloudflared.tunnels."${config.var.tunnelId}".ingress."git.${domain}" = "http://10.233.11.2:3002"; +} diff --git a/server-modules/glance/default.nix b/server-modules/glance/default.nix new file mode 100644 index 0000000..4763c64 --- /dev/null +++ b/server-modules/glance/default.nix @@ -0,0 +1,154 @@ +{ + config, + lib, + ... +}: let + inherit (import ../mk-container.nix {inherit lib config;}) mkContainer; + domain = config.var.domain; + hostIp = "10.233.12.1"; + + # Convert 6-char hex color to "H S L" string for glance (integers, no % sign) + hexToGlanceHsl = hex: let + h = lib.toLower hex; + d = c: + if c == "a" + then 10 + else if c == "b" + then 11 + else if c == "c" + then 12 + else if c == "d" + then 13 + else if c == "e" + then 14 + else if c == "f" + then 15 + else lib.toInt c; + byte = pos: d (builtins.substring pos 1 h) * 16 + d (builtins.substring (pos + 1) 1 h); + ri = byte 0; + gi = byte 2; + bi = byte 4; + r = ri * 1.0 / 255.0; + g = gi * 1.0 / 255.0; + b = bi * 1.0 / 255.0; + mx = + if r >= g && r >= b + then "r" + else if g >= b + then "g" + else "b"; + mn = + if r <= g && r <= b + then "r" + else if g <= b + then "g" + else "b"; + cmax = + if mx == "r" + then r + else if mx == "g" + then g + else b; + cmin = + if mn == "r" + then r + else if mn == "g" + then g + else b; + delta = cmax - cmin; + l = (cmax + cmin) / 2.0; + s = + if delta < 0.0001 + then 0.0 + else if l <= 0.5 + then delta / (cmax + cmin) + else delta / (2.0 - cmax - cmin); + hue = + if delta < 0.0001 + then 0.0 + else if mx == "r" + then let + raw = 60.0 * (g - b) / delta; + in + if raw < 0.0 + then raw + 360.0 + else raw + else if mx == "g" + then 60.0 * ((b - r) / delta + 2.0) + else 60.0 * ((r - g) / delta + 4.0); + in "${toString (builtins.floor (hue + 0.5))} ${toString (builtins.floor (s * 100.0 + 0.5))} ${ + toString (builtins.floor (l * 100.0 + 0.5)) + }"; + + c = config.stylix.base16Scheme; +in { + # 0444 so the glance user inside the container can read the bind-mounted file + sops.secrets.adguard-pwd.mode = "0444"; + + imports = [ + (mkContainer { + name = "glance"; + hostIp = hostIp; + containerIp = "10.233.12.2"; + internet = true; + bindMounts."/run/secrets/adguard-pwd" = { + hostPath = config.sops.secrets.adguard-pwd.path; + isReadOnly = true; + }; + nixosConfig = {lib, ...}: { + _module.args.domain = domain; + _module.args.adguardUrl = "http://${hostIp}:3000"; + imports = [ + ./home.nix + ./server.nix + ]; + + services.glance = { + enable = true; + settings = { + server = { + port = 5678; + host = "127.0.0.1"; + }; + theme = { + light = false; + background-color = hexToGlanceHsl c.base00; # background + primary-color = hexToGlanceHsl c.base0D; # accent (iris/purple) + positive-color = hexToGlanceHsl c.base0B; # positive (pine/teal) + negative-color = hexToGlanceHsl c.base08; # negative (love/rose) + }; + }; + }; + + services.nginx = { + enable = true; + appendHttpConfig = '' + proxy_cache_path /var/cache/nginx/glance levels=1:2 keys_zone=glance:1m inactive=30m max_size=100m; + ''; + virtualHosts."glance" = { + listen = [ + { + addr = "0.0.0.0"; + port = 8080; + } + ]; + locations."/" = { + proxyPass = "http://127.0.0.1:5678"; + extraConfig = '' + proxy_cache glance; + proxy_cache_valid 200 30m; + proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504; + add_header X-Cache-Status $upstream_cache_status; + ''; + }; + }; + }; + + networking.firewall.allowedTCPPorts = [8080]; + system.stateVersion = "24.05"; + }; + }) + ]; + + services.cloudflared.tunnels."${config.var.tunnelId}".ingress."home.${domain}" = "http://10.233.12.2:8080"; +} diff --git a/server-modules/glance/home.nix b/server-modules/glance/home.nix new file mode 100644 index 0000000..de5a8a1 --- /dev/null +++ b/server-modules/glance/home.nix @@ -0,0 +1,245 @@ +{domain, ...}: { + services.glance.settings.pages = [ + { + name = "Home"; + hide-desktop-navigation = false; + columns = [ + { + size = "small"; + widgets = [ + { + type = "clock"; + hour-format = "24h"; + } + { + type = "weather"; + location = "Paris, France"; + } + { + type = "markets"; + markets = [ + { + symbol = "BTC-USD"; + name = "Bitcoin"; + chart-link = "https://www.tradingview.com/chart/?symbol=INDEX:BTCUSD"; + } + { + symbol = "SOL-USD"; + name = "Solana"; + chart-link = "https://www.tradingview.com/chart/?symbol=INDEX:SOLUSD"; + } + { + symbol = "ETH-USD"; + name = "Ethereum"; + chart-link = "https://www.tradingview.com/chart/?symbol=INDEX:ETHUSD"; + } + ]; + } + ]; + } + { + size = "full"; + widgets = [ + { + type = "search"; + search-engine = "startpage"; + } + { + type = "group"; + widgets = [ + { + type = "bookmarks"; + title = "Bookmarks"; + groups = [ + { + title = ""; + same-tab = true; + color = "245 50 64"; + links = [ + { + title = "Mail"; + url = "https://mail.proton.me"; + } + { + title = "Drive"; + url = "https://drive.proton.me"; + } + { + title = "Lumo"; + url = "https://lumo.proton.me"; + } + { + title = "Calendar"; + url = "https://calendar.proton.me"; + } + { + title = "Maps"; + url = "https://maps.apple.com"; + } + { + title = "Amazon"; + url = "https://amazon.fr"; + } + ]; + } + { + title = "Tools"; + same-tab = true; + color = "245 50 64"; + links = [ + { + title = "Excalidraw"; + url = "https://excalidraw.com"; + } + { + title = "Cobalt (downloader)"; + url = "https://cobalt.meowing.de"; + } + { + title = "Mazanoke (image downgrading)"; + url = "https://mazanoke.${domain}"; + } + { + title = "Stirling PDF"; + url = "https://pdf.${domain}"; + } + { + title = "Vert (file converter)"; + url = "https://vert.sh"; + } + { + title = "Markdown to pdf"; + url = "https://md2file.com"; + } + { + title = "Image to Vector"; + url = "https://www.vectorcascade.com/"; + } + { + title = "PrivateBin"; + url = "https://privatebin.net"; + } + ]; + } + { + title = "Social"; + same-tab = true; + color = "245 50 64"; + links = [ + { + title = "Bsky"; + url = "https://bsky.app"; + } + { + title = "Reddit"; + url = "https://reddit.com"; + } + { + title = "Youtube"; + url = "https://youtube.com"; + } + { + title = "Instagram"; + url = "https://instagram.com"; + } + { + title = "Github"; + url = "https://github.com"; + } + { + title = "Discord"; + url = "https://discord.com/channels/@me/"; + } + ]; + } + { + title = "Other"; + same-tab = true; + color = "245 50 64"; + links = [ + { + title = "Startpage config"; + url = "https://www.startpage.com/do/mypage.pl?prfe=45d331deb05471d659dba933e7400df51d952bb103da6f6125c0e769a6be1d65610456a479f495ceeee7e97311cf227d7c1bb198de0ceeb193d8cddf9c455c19a409cc35c3e3f542ee27bd7cecd3"; + } + { + title = "Hyprland Wiki"; + url = "https://wiki.hypr.land"; + } + { + title = "Search NixOS"; + url = "https://mynixos.com"; + } + { + title = "Nixpkgs"; + url = "https://github.com/NixOS/nixpkgs"; + } + { + title = "Claude"; + url = "https://claude.ai"; + } + { + title = "Gemini"; + url = "https://gemini.google.com"; + } + { + title = "Medium"; + url = "https://medium.com"; + } + ]; + } + ]; + } + { + type = "bookmarks"; + title = "Infosec"; + groups = [ + { + title = ""; + same-tab = true; + color = "245 50 64"; + links = [ + { + title = "Nix 4 Cyber"; + url = "https://n4c.${domain}"; + } + { + title = "Cyberchef"; + url = "https://cyberchef.${domain}"; + } + { + title = "TryHackMe"; + url = "https://tryhackme.com"; + } + { + title = "Root-Me"; + url = "https://root-me.org"; + } + { + title = "Exploit-DB"; + url = "https://exploit-db.com"; + } + { + title = "Crack Station"; + url = "https://crackstation.net"; + } + { + title = "Osint Tracker"; + url = "https://app.osintracker.com"; + } + ]; + } + ]; + } + ]; + } + { + type = "hacker-news"; + limit = 15; + collapse-after = 5; + } + ]; + } + ]; + } + ]; +} diff --git a/server-modules/glance/server.nix b/server-modules/glance/server.nix new file mode 100644 index 0000000..79584c1 --- /dev/null +++ b/server-modules/glance/server.nix @@ -0,0 +1,179 @@ +{ + domain, + adguardUrl, + ... +}: { + services.glance.settings.pages = [ + { + name = "Server"; + hide-desktop-navigation = false; + columns = [ + { + size = "full"; + widgets = [ + { + type = "server-stats"; + servers = [ + { + type = "local"; + name = "Jack"; + } + ]; + } + { + type = "group"; + widgets = [ + { + type = "monitor"; + title = "Services"; + cache = "1m"; + sites = [ + { + title = "Adguard"; + url = "https://adguard.${domain}"; + icon = "si:adguard"; + } + { + title = "Blog"; + url = "https://${domain}"; + icon = "si:blogger"; + } + { + title = "Gitea"; + url = "https://git.${domain}"; + icon = "si:gitea"; + } + { + title = "Mealie"; + url = "https://mealie.${domain}"; + icon = "si:mealie"; + } + { + title = "Umami"; + url = "https://umami.${domain}"; + icon = "si:umami"; + } + { + title = "Iknowyou"; + url = "https://iknowyou.${domain}"; + icon = "sh:iknowyou"; + } + { + title = "Iknowyou Prod"; + url = "https://iknowyou-prod.${domain}"; + icon = "sh:iknowyou"; + } + { + title = "Wallpapers"; + url = "https://wallpapers.${domain}"; + icon = "si:unsplash"; + } + { + title = "Mazanoke"; + url = "https://mazanoke.${domain}"; + icon = "sh:mazanoke"; + } + { + title = "Stirling PDF"; + url = "https://pdf.${domain}"; + icon = "sh:stirling-pdf"; + } + { + title = "Default-creds"; + url = "https://default-creds.${domain}"; + icon = "si:passbolt"; + } + { + title = "Cyberchef"; + url = "https://cyberchef.${domain}"; + icon = "si:codechef"; + } + ]; + } + { + type = "monitor"; + title = "*arr"; + cache = "1m"; + sites = [ + { + title = "Jellyfin"; + url = "https://media.${domain}"; + icon = "si:jellyfin"; + } + { + title = "Jellyseerr"; + url = "https://demandemedia.${domain}"; + icon = "si:odysee"; + } + { + title = "Radarr"; + url = "https://radarr.${domain}"; + icon = "si:radarr"; + } + { + title = "Sonarr"; + url = "https://sonarr.${domain}"; + icon = "si:sonarr"; + } + { + title = "Bazarr"; + url = "https://bazarr.${domain}"; + icon = "si:subtitleedit"; + } + { + title = "Prowlarr"; + url = "https://prowlarr.${domain}"; + icon = "si:podcastindex"; + } + { + title = "Transmission"; + url = "https://transmission.${domain}"; + icon = "si:transmission"; + } + ]; + } + ]; + } + + { + type = "dns-stats"; + service = "adguard"; + url = adguardUrl; + username = "hadi"; + password = "\${secret:adguard-pwd}"; + } + + { + type = "bookmarks"; + groups = [ + { + title = ""; + same-tab = true; + color = "245 50 64"; + links = [ + { + title = "Router"; + url = "http://192.168.1.254/"; + } + { + title = "Cloudflare"; + url = "https://dash.cloudflare.com/"; + } + { + title = "Cloudflare Zero Trust"; + url = "https://one.dash.cloudflare.com/"; + } + { + title = "Cloudflare Access"; + url = "https://anotherhadi.cloudflareaccess.com"; + } + ]; + } + ]; + } + ]; + } + ]; + } + ]; +} diff --git a/server-modules/iknowyou.nix b/server-modules/iknowyou.nix new file mode 100644 index 0000000..65ddd95 --- /dev/null +++ b/server-modules/iknowyou.nix @@ -0,0 +1,64 @@ +{ + config, + inputs, + lib, + ... +}: let + inherit (import ./mk-container.nix {inherit lib config;}) mkContainer; +in { + imports = [ + (mkContainer { + name = "iky-prod"; + hostIp = "10.233.1.1"; + containerIp = "10.233.1.2"; + internet = true; + bindMounts."/etc/iky/config.yaml" = { + hostPath = "/var/lib/iknowyou-prod/config.yaml"; + isReadOnly = false; + }; + nixosConfig = {...}: { + imports = [inputs.iknowyou.nixosModules.default]; + users.users.iknowyou.uid = 999; + users.groups.iknowyou.gid = 999; + services.iknowyou = { + enable = true; + port = 8080; + openFirewall = true; + }; + system.stateVersion = "24.05"; + }; + }) + + (mkContainer { + name = "iky-demo"; + hostIp = "10.233.2.1"; + containerIp = "10.233.2.2"; + nixosConfig = {...}: { + imports = [inputs.iknowyou.nixosModules.default]; + services.iknowyou = { + enable = true; + port = 8080; + openFirewall = true; + }; + systemd.services.iknowyou.environment.IKY_DEMO = "true"; + system.stateVersion = "24.05"; + }; + }) + ]; + + users.users.iknowyou = { + isSystemUser = true; + group = "iknowyou"; + uid = 999; + }; + users.groups.iknowyou.gid = 999; + + systemd.tmpfiles.rules = [ + "f /var/lib/iknowyou-prod/config.yaml 0600 iknowyou iknowyou -" + ]; + + services.cloudflared.tunnels."${config.var.tunnelId}".ingress = { + "iknowyou-prod.${config.var.domain}" = "http://10.233.1.2:8080"; + "iknowyou.${config.var.domain}" = "http://10.233.2.2:8080"; + }; +} diff --git a/server-modules/kernel-hardening.nix b/server-modules/kernel-hardening.nix new file mode 100644 index 0000000..34b8de5 --- /dev/null +++ b/server-modules/kernel-hardening.nix @@ -0,0 +1,35 @@ +# Kernel hardening for the server +{ + boot.kernel.sysctl = { + # Restrict access to kernel logs and pointers + "kernel.dmesg_restrict" = 1; + "kernel.kptr_restrict" = 2; + + # BPF hardening + "net.core.bpf_jit_harden" = 2; + "kernel.unprivileged_bpf_disabled" = 1; + + # Reverse path filtering (anti-spoofing) + "net.ipv4.conf.all.rp_filter" = 1; + "net.ipv4.conf.default.rp_filter" = 1; + + # SYN flood protection + "net.ipv4.tcp_syncookies" = 1; + + # Disable IP source routing + "net.ipv4.conf.all.accept_source_route" = 0; + "net.ipv4.conf.default.accept_source_route" = 0; + + # Ignore ICMP redirects (prevent MITM) + "net.ipv4.conf.all.accept_redirects" = 0; + "net.ipv4.conf.default.accept_redirects" = 0; + "net.ipv4.conf.all.secure_redirects" = 0; + "net.ipv6.conf.all.accept_redirects" = 0; + + # Don't send ICMP redirects + "net.ipv4.conf.all.send_redirects" = 0; + + # Restrict ptrace to parent processes only + "kernel.yama.ptrace_scope" = 1; + }; +} diff --git a/server-modules/mazanoke.nix b/server-modules/mazanoke.nix new file mode 100644 index 0000000..53f73c2 --- /dev/null +++ b/server-modules/mazanoke.nix @@ -0,0 +1,52 @@ +{ + config, + lib, + ... +}: let + inherit (import ./mk-container.nix {inherit lib config;}) mkContainer; +in { + imports = [ + (mkContainer { + name = "mazanoke"; + hostIp = "10.233.7.1"; + containerIp = "10.233.7.2"; + nixosConfig = {pkgs, ...}: let + version = "1.1.5"; + mazanoke-pkg = pkgs.stdenv.mkDerivation { + inherit version; + pname = "mazanoke"; + src = pkgs.fetchFromGitHub { + owner = "civilblur"; + repo = "mazanoke"; + rev = "v${version}"; + hash = "sha256-B/AF4diMNxN94BzpZP/C+K8kNj9q+4SDKWa/qd4LrVU="; + }; + installPhase = '' + mkdir -p $out/share/mazanoke + cp -r ./index.html ./favicon.ico ./manifest.json ./service-worker.js ./assets $out/share/mazanoke/ + ''; + }; + in { + services.nginx = { + enable = true; + virtualHosts."mazanoke" = { + root = "${mazanoke-pkg}/share/mazanoke"; + listen = [ + { + addr = "0.0.0.0"; + port = 8080; + } + ]; + locations."/" = { + index = "index.html"; + }; + }; + }; + networking.firewall.allowedTCPPorts = [8080]; + system.stateVersion = "24.05"; + }; + }) + ]; + + services.cloudflared.tunnels."${config.var.tunnelId}".ingress."mazanoke.${config.var.domain}" = "http://10.233.7.2:8080"; +} diff --git a/server-modules/mealie.nix b/server-modules/mealie.nix new file mode 100644 index 0000000..6a724de --- /dev/null +++ b/server-modules/mealie.nix @@ -0,0 +1,26 @@ +{ + config, + lib, + ... +}: let + inherit (import ./mk-container.nix {inherit lib config;}) mkContainer; +in { + imports = [ + (mkContainer { + name = "mealie"; + hostIp = "10.233.8.1"; + containerIp = "10.233.8.2"; + internet = true; + nixosConfig = {...}: { + services.mealie = { + enable = true; + port = 8080; + }; + networking.firewall.allowedTCPPorts = [8080]; + system.stateVersion = "24.05"; + }; + }) + ]; + + services.cloudflared.tunnels."${config.var.tunnelId}".ingress."mealie.${config.var.domain}" = "http://10.233.8.2:8080"; +} diff --git a/server-modules/mk-container.nix b/server-modules/mk-container.nix new file mode 100644 index 0000000..308589b --- /dev/null +++ b/server-modules/mk-container.nix @@ -0,0 +1,72 @@ +{ + lib, + config, +}: +# Returns a NixOS module (attrset), to be used in `imports`. +# +# Options: +# internet - allow outbound internet access via NAT (default: false) +# externalInterface - WAN interface for NAT, required when internet = true +# bindMounts - host paths to mount into the container (see containers..bindMounts) +# config - NixOS module for the container +let + nginxHardening = {config, ...}: + lib.mkIf config.services.nginx.enable { + services.nginx.serverTokens = false; + }; +in { + mkContainer = { + name, + hostIp, + containerIp, + internet ? false, + externalInterface ? config.var.networkInterface, + bindMounts ? {}, + nixosConfig, + }: + assert lib.assertMsg (lib.stringLength "ve-${name}" <= 15) + "mkContainer: interface name 've-${name}' is ${toString (lib.stringLength "ve-${name}")} chars, max is 15"; + { + containers.${name} = { + autoStart = true; + privateNetwork = true; + hostAddress = hostIp; + localAddress = containerIp; + inherit bindMounts; + config = {...}: { + imports = [ + nixosConfig + nginxHardening + ]; + networking.nameservers = lib.mkIf internet [ + "1.1.1.1" + "1.0.0.1" + ]; + }; + }; + } + // (lib.optionalAttrs internet { + boot.kernel.sysctl."net.ipv4.ip_forward" = lib.mkDefault true; + networking.nat = { + enable = true; + externalInterface = externalInterface; + internalInterfaces = ["ve-${name}"]; + }; + # CONTAINER-FWD (defined by another module) blocks all forwarding by default. + # Insert rules in FORWARD before it: allow return traffic, block LAN, allow internet. + networking.firewall.extraCommands = '' + iptables -I FORWARD 1 -s ${containerIp} -m conntrack --ctstate NEW -j ACCEPT + iptables -I FORWARD 1 -s ${containerIp} -d 192.168.0.0/16 -j DROP + iptables -I FORWARD 1 -s ${containerIp} -d 172.16.0.0/12 -j DROP + iptables -I FORWARD 1 -s ${containerIp} -d 10.0.0.0/8 -j DROP + iptables -I FORWARD 1 -d ${containerIp} -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT + ''; + networking.firewall.extraStopCommands = '' + iptables -D FORWARD -s ${containerIp} -m conntrack --ctstate NEW -j ACCEPT 2>/dev/null || true + iptables -D FORWARD -s ${containerIp} -d 192.168.0.0/16 -j DROP 2>/dev/null || true + iptables -D FORWARD -s ${containerIp} -d 172.16.0.0/12 -j DROP 2>/dev/null || true + iptables -D FORWARD -s ${containerIp} -d 10.0.0.0/8 -j DROP 2>/dev/null || true + iptables -D FORWARD -d ${containerIp} -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT 2>/dev/null || true + ''; + }); +} diff --git a/server-modules/ssh.nix b/server-modules/ssh.nix new file mode 100644 index 0000000..ae98bfb --- /dev/null +++ b/server-modules/ssh.nix @@ -0,0 +1,37 @@ +# SSH configuration +{config, ...}: let + username = config.var.username; +in { + services.openssh = { + enable = true; + ports = [22]; + openFirewall = true; + settings = { + PermitRootLogin = "no"; + PasswordAuthentication = false; + AllowUsers = [username]; + MaxAuthTries = 3; + LoginGraceTime = 20; + X11Forwarding = false; + AllowAgentForwarding = false; + AllowTcpForwarding = false; + ClientAliveInterval = 300; + ClientAliveCountMax = 2; + KexAlgorithms = [ + "curve25519-sha256" + "curve25519-sha256@libssh.org" + ]; + Ciphers = [ + "chacha20-poly1305@openssh.com" + "aes256-gcm@openssh.com" + ]; + }; + }; + + # Add my public SSH key to my user + users.users."${username}".openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPG9SE80ZyBcXZK/f5ypSKudaM5Jo3XtQikCnGo0jI5E hadi@nixy" + ]; + + services.cloudflared.tunnels."${config.var.tunnelId}".ingress."ssh.${config.var.domain}" = "ssh://localhost:22"; +} diff --git a/server-modules/stirling-pdf.nix b/server-modules/stirling-pdf.nix new file mode 100644 index 0000000..30d10ab --- /dev/null +++ b/server-modules/stirling-pdf.nix @@ -0,0 +1,25 @@ +{ + config, + lib, + ... +}: let + inherit (import ./mk-container.nix {inherit lib config;}) mkContainer; +in { + imports = [ + (mkContainer { + name = "stirling-pdf"; + hostIp = "10.233.9.1"; + containerIp = "10.233.9.2"; + nixosConfig = {...}: { + services.stirling-pdf = { + enable = true; + environment."SERVER_PORT" = "8080"; + }; + networking.firewall.allowedTCPPorts = [8080]; + system.stateVersion = "24.05"; + }; + }) + ]; + + services.cloudflared.tunnels."${config.var.tunnelId}".ingress."pdf.${config.var.domain}" = "http://10.233.9.2:8080"; +} diff --git a/server-modules/umami.nix b/server-modules/umami.nix new file mode 100644 index 0000000..26b0ac0 --- /dev/null +++ b/server-modules/umami.nix @@ -0,0 +1,39 @@ +{ + config, + lib, + ... +}: let + inherit (import ./mk-container.nix {inherit lib config;}) mkContainer; +in { + sops.secrets.umami-secret.mode = "0400"; + + imports = [ + (mkContainer { + name = "umami"; + hostIp = "10.233.10.1"; + containerIp = "10.233.10.2"; + bindMounts."/run/secrets/umami-secret" = { + hostPath = config.sops.secrets.umami-secret.path; + isReadOnly = true; + }; + nixosConfig = {...}: { + services.umami = { + enable = true; + settings = { + PORT = 8080; + HOSTNAME = "0.0.0.0"; + APP_SECRET_FILE = "/run/secrets/umami-secret"; + DISABLE_TELEMETRY = true; + DISABLE_BOT_CHECK = true; + }; + }; + # PrivateUsers breaks systemd-creds inside nspawn containers (nested user namespaces) + systemd.services.umami.serviceConfig.PrivateUsers = lib.mkForce false; + networking.firewall.allowedTCPPorts = [8080]; + system.stateVersion = "24.05"; + }; + }) + ]; + + services.cloudflared.tunnels."${config.var.tunnelId}".ingress."umami.${config.var.domain}" = "http://10.233.10.2:8080"; +} diff --git a/themes/nixy.nix b/themes/nixy.nix new file mode 100644 index 0000000..e1d5b25 --- /dev/null +++ b/themes/nixy.nix @@ -0,0 +1,82 @@ +{ + lib, + pkgs, + config, + ... +}: { + options.theme = lib.mkOption { + type = lib.types.attrs; + default = { + rounding = 20; + bar-rounding = 20 + 10; + bar-thickness = 0; + gaps-in = 8; + gaps-out = 8 * 2; + active-opacity = 0.96; + inactive-opacity = 0.92; + blur = true; + border-size = 2; + animation-speed = "medium"; # "fast" | "medium" | "slow" + fetch = "none"; # "nerdfetch" | "neofetch" | "pfetch" | "none" + }; + description = "Theme configuration options"; + }; + + config.stylix = { + enable = true; + + # See https://tinted-theming.github.io/tinted-gallery/ for more schemes + base16Scheme = { + base00 = "0A0A0C"; # Default Background + base01 = "110F12"; # Lighter Background (Used for status bars, line number and folding marks) + base02 = "2D2A36"; # Selection Background + base03 = "514D63"; # Comments, Invisibles, Line Highlighting + base04 = "8E8AA0"; # Dark Foreground (Used for status bars) + base05 = "C2BED6"; # Default Foreground, Caret, Delimiters, Operators + base06 = "D8D5EA"; # Light Foreground (Not often used) + base07 = "EAE7F7"; # Light Background (Not often used) + base08 = "E07080"; # Variables, XML Tags, Markup Link Text, Markup Lists, Diff Deleted + base09 = "D49070"; # Integers, Boolean, Constants, XML Attributes, Markup Link Url + base0A = "C4B060"; # Classes, Markup Bold, Search Text Background + base0B = "80B880"; # Strings, Inherited Class, Markup Code, Diff Inserted + base0C = "70B8C0"; # Support, Regular Expressions, Escape Characters, Markup Quotes + base0D = "9E97F8"; # Functions, Methods, Attribute IDs, Headings, Accent color + base0E = "C090E8"; # Keywords, Storage, Selector, Markup Italic, Diff Changed + base0F = "D080A0"; # Deprecated, Opening/Closing Embedded Language Tags, e.g. + }; + + cursor = { + name = "BreezeX-RosePine-Linux"; + package = pkgs.rose-pine-cursor; + size = 20; + }; + + fonts = { + monospace = { + package = pkgs.maple-mono.NF; + name = "Maple Mono NF"; + }; + sansSerif = { + package = pkgs.source-sans-pro; + name = "Source Sans Pro"; + }; + serif = config.stylix.fonts.sansSerif; + emoji = { + package = pkgs.noto-fonts-color-emoji; + name = "Noto Color Emoji"; + }; + sizes = { + applications = 13; + desktop = 13; + popups = 13; + terminal = 13; + }; + }; + + polarity = "dark"; + image = pkgs.fetchurl { + url = "https://raw.githubusercontent.com/anotherhadi/awesome-wallpapers/refs/heads/main/app/static/wallpapers/black-moutains-and-a-city.png"; + sha256 = "sha256-RTTA3Lf+hnPpo9hwS075kbnIouz12ul2GKO3EIgP6AU="; + }; + }; +}