From 39e6276c7dc0547b3f5f442f41f0337b4fa2350f Mon Sep 17 00:00:00 2001 From: Miguel Palhas Date: Sat, 27 Jun 2026 18:17:25 +0100 Subject: [PATCH] Session overhaul: dev tooling, cleanup, theming, fixes Tooling: - nh + nvd/nom/statix/deadnix/comma (new programs/nix.nix); GC via nh clean - zoxide (cd), atuin, just, lazydocker, dust, duf, difftastic (git dft) Structure: - rename desktop -> konishi; homeConfigurations -> "user@host" for nh autodetect Removals (heavy/unused): - android-studio, unity/.NET/omnisharp/vscode, kicad, zoom, calibre, google-fonts, nerd-dictation Screen recording: - kooha + vokoscreen-ng + `webcam` corner-cam command/window-rule Fixes: - WEBKIT_DISABLE_DMABUF_RENDERER moved to common (electron/tauri on intel) - kitty pinned to Catppuccin-Mocha; darkman no longer toggles kitty/claude - claude theme dark + statusline locale fix - ssh: migrate to settings API + multiplexing/keepalive/AddKeysToAgent; gpg-agent enableSshSupport - silence hyprland configType / gtk4 / xdg userDirs deprecations Flake hygiene: - follows=nixpkgs for foundry/hardware/rose-pine/zen/spicetify (10->5 nixpkgs) - zoxide _ZO_DOCTOR=0 Co-Authored-By: Claude Opus 4.8 (1M context) --- .claude/settings.local.json | 3 +- flake.lock | 116 +++------ flake.nix | 24 +- home/arrakis/default.nix | 1 - home/common/features/xdg.nix | 2 +- home/common/programs/3d.nix | 1 - home/common/programs/claude/default.nix | 105 ++++---- home/common/programs/claude/settings.json | 7 +- home/common/programs/default.nix | 12 +- home/common/programs/desktop/default.nix | 140 ++++++----- home/common/programs/dev.nix | 1 - home/common/programs/git/default.nix | 181 +++++++------- home/common/programs/hyprland/default.nix | 32 ++- home/common/programs/nerd-dictation.nix | 124 ---------- home/common/programs/opencode/default.nix | 62 ++--- home/common/programs/rust.nix | 48 ++-- home/common/programs/unity.nix | 11 - home/common/programs/zsh.nix | 280 +++++++++++----------- home/konishi/default.nix | 2 - hosts/arrakis/default.nix | 43 +++- hosts/common/features/android-studio.nix | 29 --- hosts/common/features/gpu/nvidia.nix | 26 +- hosts/konishi/default.nix | 1 - 23 files changed, 569 insertions(+), 682 deletions(-) delete mode 100644 home/common/programs/nerd-dictation.nix delete mode 100644 home/common/programs/unity.nix delete mode 100644 hosts/common/features/android-studio.nix diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 505c0ba..2cf2a00 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -40,7 +40,8 @@ "Bash(wpctl status:*)", "WebFetch(domain:bugs.chromium.org)", "WebFetch(domain:gitlab.freedesktop.org)", - "Bash(python3 -c ' *)" + "Bash(python3 -c ' *)", + "Bash(statix check *)" ] }, "sandbox": { diff --git a/flake.lock b/flake.lock index 0ad959b..0e544f6 100644 --- a/flake.lock +++ b/flake.lock @@ -59,11 +59,11 @@ "utils": "utils" }, "locked": { - "lastModified": 1762947022, - "narHash": "sha256-qNRKNLwYCL6lUDiZVmdENHkB2lk/33h6JKrypk3HmsI=", + "lastModified": 1782568637, + "narHash": "sha256-IeegzgsunnrAQbNvdZKccstoKaTyUOj/oLyFY5pOJRA=", "owner": "ethui", "repo": "ethui", - "rev": "ce196167dd3aeba1598accb014bd2397334c6cc5", + "rev": "16a2c401793464ee5dc013e01564039904280e88", "type": "github" }, "original": { @@ -143,7 +143,9 @@ "foundry": { "inputs": { "flake-utils": "flake-utils_2", - "nixpkgs": "nixpkgs_4" + "nixpkgs": [ + "nixpkgs" + ] }, "locked": { "lastModified": 1781514265, @@ -183,7 +185,9 @@ }, "hardware": { "inputs": { - "nixpkgs": "nixpkgs_5" + "nixpkgs": [ + "nixpkgs" + ] }, "locked": { "lastModified": 1781168557, @@ -310,7 +314,7 @@ "hyprutils": "hyprutils", "hyprwayland-scanner": "hyprwayland-scanner", "hyprwire": "hyprwire", - "nixpkgs": "nixpkgs_6", + "nixpkgs": "nixpkgs_4", "pre-commit-hooks": "pre-commit-hooks", "systems": "systems_3", "xdph": "xdph" @@ -620,29 +624,13 @@ "type": "github" } }, - "nixpkgs_10": { - "locked": { - "lastModified": 1781074563, - "narHash": "sha256-md8WlXOlfnIeHeOScMTTHFyf2d6iaTwPl2apR5EQ3P4=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "9ae611a455b90cf061d8f332b977e387bda8e1ca", - "type": "github" - }, - "original": { - "owner": "nixos", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, "nixpkgs_2": { "locked": { - "lastModified": 1752480373, - "narHash": "sha256-JHQbm+OcGp32wAsXTE/FLYGNpb+4GLi5oTvCxwSoBOA=", + "lastModified": 1764517877, + "narHash": "sha256-pp3uT4hHijIC8JUK5MEqeAWmParJrgBVzHLNfJDZxg4=", "owner": "nixos", "repo": "nixpkgs", - "rev": "62e0f05ede1da0d54515d4ea8ce9c733f12d9f08", + "rev": "2d293cbfa5a793b4c50d17c05ef9e385b90edf6c", "type": "github" }, "original": { @@ -669,33 +657,6 @@ } }, "nixpkgs_4": { - "locked": { - "lastModified": 1666753130, - "narHash": "sha256-Wff1dGPFSneXJLI2c0kkdWTgxnQ416KE6X4KnFkgPYQ=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "f540aeda6f677354f1e7144ab04352f61aaa0118", - "type": "github" - }, - "original": { - "id": "nixpkgs", - "type": "indirect" - } - }, - "nixpkgs_5": { - "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_6": { "locked": { "lastModified": 1780749050, "narHash": "sha256-3av0pIjlOWQ6rDbNOmpUSvbNnJkGORQKKjb4LtCZsIY=", @@ -711,7 +672,7 @@ "type": "github" } }, - "nixpkgs_7": { + "nixpkgs_5": { "locked": { "lastModified": 1781074563, "narHash": "sha256-md8WlXOlfnIeHeOScMTTHFyf2d6iaTwPl2apR5EQ3P4=", @@ -727,35 +688,6 @@ "type": "github" } }, - "nixpkgs_8": { - "locked": { - "lastModified": 1710272261, - "narHash": "sha256-g0bDwXFmTE7uGDOs9HcJsfLFhH7fOsASbAuOzDC+fhQ=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "0ad13a6833440b8e238947e47bea7f11071dc2b2", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_9": { - "locked": { - "lastModified": 1781074563, - "narHash": "sha256-d34lhgOet4IqYMnCxbIvwFBMOyTV6PT4TyNEOP0/ZhU=", - "rev": "9ae611a455b90cf061d8f332b977e387bda8e1ca", - "type": "tarball", - "url": "https://releases.nixos.org/nixos/unstable/nixos-26.11pre1014179.9ae611a455b9/nixexprs.tar.xz" - }, - "original": { - "type": "tarball", - "url": "https://channels.nixos.org/nixos-unstable/nixexprs.tar.xz" - } - }, "noctalia": { "inputs": { "nixpkgs": [ @@ -848,7 +780,7 @@ "home-manager": "home-manager", "hyprland": "hyprland", "nix-index-database": "nix-index-database", - "nixpkgs": "nixpkgs_7", + "nixpkgs": "nixpkgs_5", "noctalia": "noctalia", "nvchad-starter": "nvchad-starter", "nvchad4nix": "nvchad4nix", @@ -861,7 +793,9 @@ "rose-pine-hyprcursor": { "inputs": { "hyprlang": "hyprlang_2", - "nixpkgs": "nixpkgs_8", + "nixpkgs": [ + "nixpkgs" + ], "utils": "utils_2" }, "locked": { @@ -883,11 +817,11 @@ "nixpkgs": "nixpkgs_3" }, "locked": { - "lastModified": 1754575663, - "narHash": "sha256-afOx8AG0KYtw7mlt6s6ahBBy7eEHZwws3iCRoiuRQS4=", + "lastModified": 1764729618, + "narHash": "sha256-z4RA80HCWv2los1KD346c+PwNPzMl79qgl7bCVgz8X0=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "6db0fb0e9cec2e9729dc52bf4898e6c135bb8a0f", + "rev": "52764074a85145d5001bf0aa30cb71936e9ad5b8", "type": "github" }, "original": { @@ -898,7 +832,9 @@ }, "spicetify-nix": { "inputs": { - "nixpkgs": "nixpkgs_9", + "nixpkgs": [ + "nixpkgs" + ], "systems": "systems_7" }, "locked": { @@ -1115,7 +1051,9 @@ "zen-browser": { "inputs": { "home-manager": "home-manager_2", - "nixpkgs": "nixpkgs_10" + "nixpkgs": [ + "nixpkgs" + ] }, "locked": { "lastModified": 1781820312, diff --git a/flake.nix b/flake.nix index 2d56315..96f2cec 100644 --- a/flake.nix +++ b/flake.nix @@ -26,11 +26,24 @@ }; foundry = { url = "github:shazow/foundry.nix"; + inputs.nixpkgs.follows = "nixpkgs"; }; - hardware.url = "github:NixOS/nixos-hardware/master"; - rose-pine-hyprcursor.url = "github:ndom91/rose-pine-hyprcursor"; - zen-browser.url = "github:0xc000022070/zen-browser-flake"; + hardware = { + url = "github:NixOS/nixos-hardware/master"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + rose-pine-hyprcursor = { + url = "github:ndom91/rose-pine-hyprcursor"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + zen-browser = { + url = "github:0xc000022070/zen-browser-flake"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + # ethui pins its own nixpkgs (verified rust/tauri build) — do not follow. ethui.url = "github:ethui/ethui/nix"; + # hyprland pins its own nixpkgs to match its cachix cache — do not follow, + # or it compiles from source. hyprland = { type = "git"; url = "https://github.com/hyprwm/Hyprland"; @@ -40,7 +53,10 @@ url = "github:noctalia-dev/noctalia-shell"; inputs.nixpkgs.follows = "nixpkgs"; }; - spicetify-nix.url = "github:Gerg-L/spicetify-nix"; + spicetify-nix = { + url = "github:Gerg-L/spicetify-nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; claude-code.url = "github:sadjow/claude-code-nix"; nix-index-database = { url = "github:nix-community/nix-index-database"; diff --git a/home/arrakis/default.nix b/home/arrakis/default.nix index 99806c1..47433b7 100644 --- a/home/arrakis/default.nix +++ b/home/arrakis/default.nix @@ -8,7 +8,6 @@ ../common/programs/zen-browser.nix ../common/programs/hyprland ../common/programs/kitty - ../common/programs/unity.nix ../common/programs/ethui.nix ../common/programs/gpg.nix ../common/features/xdg.nix diff --git a/home/common/features/xdg.nix b/home/common/features/xdg.nix index ad6a61d..aedf74b 100644 --- a/home/common/features/xdg.nix +++ b/home/common/features/xdg.nix @@ -20,7 +20,7 @@ _: enable = true; defaultApplications = { # web - "text/html" = "google-chrome.desktop"; + "text/html" = "zen-twilight.desktop"; "x-scheme-handler/http" = "zen-twilight.desktop"; "x-scheme-handler/https" = "zen-twilight.desktop"; "x-scheme-handler/avbout" = "zen-twilight.desktop"; diff --git a/home/common/programs/3d.nix b/home/common/programs/3d.nix index fa9df07..905cb08 100644 --- a/home/common/programs/3d.nix +++ b/home/common/programs/3d.nix @@ -6,7 +6,6 @@ home.packages = with pkgs; [ blender prusa-slicer - google-fonts ]; fonts.fontconfig.enable = true; diff --git a/home/common/programs/claude/default.nix b/home/common/programs/claude/default.nix index 74f51c2..2a46a3d 100644 --- a/home/common/programs/claude/default.nix +++ b/home/common/programs/claude/default.nix @@ -1,64 +1,69 @@ { pkgs, inputs, ... }: { - home.file.".default-npm-packages".text = '' - @anthropic-ai/sandbox-runtime - @beads/bd - ''; + home = { + packages = with pkgs; [ + inputs.claude-code.packages.${pkgs.stdenv.hostPlatform.system}.default - home.packages = with pkgs; [ - inputs.claude-code.packages.${pkgs.stdenv.hostPlatform.system}.default + # sandbox + bubblewrap + socat + libseccomp - # sandbox - bubblewrap - socat - libseccomp + # voice + sox - # voice - sox + # beads + dolt + ]; - # beads - dolt - ]; + file = { + ".default-npm-packages".text = '' + @anthropic-ai/sandbox-runtime + @beads/bd + ''; - # Commands - home.file.".claude/commands/merge.md".source = ./commands/merge.md; - home.file.".claude/commands/update.md".source = ./commands/update.md; - home.file.".claude/commands/download-playlist.md".source = ./commands/download-playlist.md; + # Commands + ".claude/commands/merge.md".source = ./commands/merge.md; + ".claude/commands/update.md".source = ./commands/update.md; + ".claude/commands/download-playlist.md".source = ./commands/download-playlist.md; - # Skills: agents - home.file.".claude/skills/designer-bold/SKILL.md".source = ./skills/designer-bold/SKILL.md; - home.file.".claude/skills/designer/SKILL.md".source = ./skills/designer/SKILL.md; - home.file.".claude/skills/frontend-design/SKILL.md".source = ./skills/frontend-design/SKILL.md; - home.file.".claude/skills/analyze-branch/SKILL.md".source = ./skills/analyze-branch/SKILL.md; - home.file.".claude/skills/oracle/SKILL.md".source = ./skills/oracle/SKILL.md; - home.file.".claude/skills/librarian/SKILL.md".source = ./skills/librarian/SKILL.md; + # Skills: agents + ".claude/skills/designer-bold/SKILL.md".source = ./skills/designer-bold/SKILL.md; + ".claude/skills/designer/SKILL.md".source = ./skills/designer/SKILL.md; + ".claude/skills/frontend-design/SKILL.md".source = ./skills/frontend-design/SKILL.md; + ".claude/skills/analyze-branch/SKILL.md".source = ./skills/analyze-branch/SKILL.md; + ".claude/skills/oracle/SKILL.md".source = ./skills/oracle/SKILL.md; + ".claude/skills/librarian/SKILL.md".source = ./skills/librarian/SKILL.md; - # Skills: knowledge - home.file.".claude/skills/git-master/SKILL.md".source = ./skills/git-master/SKILL.md; - home.file.".claude/skills/planning-with-files/SKILL.md".source = - ./skills/planning-with-files/SKILL.md; - home.file.".claude/skills/react-patterns/SKILL.md".source = ./skills/react-patterns/SKILL.md; - home.file.".claude/skills/vercel-react-best-practices/SKILL.md".source = - ./skills/vercel-react-best-practices/SKILL.md; + # Skills: knowledge + ".claude/skills/git-master/SKILL.md".source = ./skills/git-master/SKILL.md; + ".claude/skills/planning-with-files/SKILL.md".source = + ./skills/planning-with-files/SKILL.md; + ".claude/skills/react-patterns/SKILL.md".source = ./skills/react-patterns/SKILL.md; + ".claude/skills/vercel-react-best-practices/SKILL.md".source = + ./skills/vercel-react-best-practices/SKILL.md; - # Skills: workflows - home.file.".claude/skills/smart-debug/SKILL.md".source = ./skills/smart-debug/SKILL.md; - home.file.".claude/skills/tdd-cycle/SKILL.md".source = ./skills/tdd-cycle/SKILL.md; - home.file.".claude/skills/security-scan/SKILL.md".source = ./skills/security-scan/SKILL.md; - home.file.".claude/skills/issue/SKILL.md".source = ./skills/issue/SKILL.md; - home.file.".claude/skills/remove-deadcode/SKILL.md".source = ./skills/remove-deadcode/SKILL.md; - home.file.".claude/skills/worktree-compare/SKILL.md".source = ./skills/worktree-compare/SKILL.md; - home.file.".claude/skills/worktree-list/SKILL.md".source = ./skills/worktree-list/SKILL.md; + # Skills: workflows + ".claude/skills/smart-debug/SKILL.md".source = ./skills/smart-debug/SKILL.md; + ".claude/skills/tdd-cycle/SKILL.md".source = ./skills/tdd-cycle/SKILL.md; + ".claude/skills/security-scan/SKILL.md".source = ./skills/security-scan/SKILL.md; + ".claude/skills/issue/SKILL.md".source = ./skills/issue/SKILL.md; + ".claude/skills/remove-deadcode/SKILL.md".source = ./skills/remove-deadcode/SKILL.md; + ".claude/skills/worktree-compare/SKILL.md".source = ./skills/worktree-compare/SKILL.md; + ".claude/skills/worktree-list/SKILL.md".source = ./skills/worktree-list/SKILL.md; - # Skills: linear workflow - home.file.".claude/skills/linear-common/COMMON.md".source = ./skills/linear-common/COMMON.md; - home.file.".claude/skills/work/SKILL.md".source = ./skills/work/SKILL.md; - home.file.".claude/skills/yolo/SKILL.md".source = ./skills/yolo/SKILL.md; + # Skills: linear workflow + ".claude/skills/linear-common/COMMON.md".source = ./skills/linear-common/COMMON.md; + ".claude/skills/work/SKILL.md".source = ./skills/work/SKILL.md; + ".claude/skills/yolo/SKILL.md".source = ./skills/yolo/SKILL.md; - home.file.".claude/statusline.sh" = { - source = ./statusline.sh; - executable = true; + ".claude/statusline.sh" = { + source = ./statusline.sh; + executable = true; + }; + ".claude/CLAUDE.md".source = ./CLAUDE.md; + }; + + mutableFiles.".claude/settings.json".source = ./settings.json; }; - home.mutableFiles.".claude/settings.json".source = ./settings.json; - home.file.".claude/CLAUDE.md".source = ./CLAUDE.md; } diff --git a/home/common/programs/claude/settings.json b/home/common/programs/claude/settings.json index 1f29404..8215086 100644 --- a/home/common/programs/claude/settings.json +++ b/home/common/programs/claude/settings.json @@ -39,6 +39,9 @@ "type": "command", "command": "~/.claude/statusline.sh" }, + "enabledPlugins": { + "typescript-lsp@claude-plugins-official": true + }, "extraKnownMarketplaces": { "impeccable": { "source": { @@ -77,7 +80,5 @@ "url": "https://ha-mcp.n62.casa/mcp" } }, - "enabledPlugins": { - "typescript-lsp@claude-plugins-official": true - } + "tui": "fullscreen" } diff --git a/home/common/programs/default.nix b/home/common/programs/default.nix index a0a2bf5..5bc95df 100644 --- a/home/common/programs/default.nix +++ b/home/common/programs/default.nix @@ -24,17 +24,17 @@ ./tmux.nix ]; - home.mutableFilesRepoPath = "${config.home.homeDirectory}/projects/nixos-config"; - programs = { home-manager.enable = true; }; - home.packages = with pkgs; [ - impala - ]; - home = { + mutableFilesRepoPath = "${config.home.homeDirectory}/projects/nixos-config"; + + packages = with pkgs; [ + impala + ]; + username = lib.mkDefault "naps62"; homeDirectory = lib.mkDefault "/home/${config.home.username}"; stateVersion = lib.mkDefault "24.05"; diff --git a/home/common/programs/desktop/default.nix b/home/common/programs/desktop/default.nix index 7936152..7288495 100644 --- a/home/common/programs/desktop/default.nix +++ b/home/common/programs/desktop/default.nix @@ -10,48 +10,56 @@ ./spicetify.nix ]; - home.packages = with pkgs; [ - # various - google-chrome - thunar - obsidian - mpv - obs-studio - calibre - gimp - font-manager - imv - pavucontrol - zathura - libsForQt5.qt5ct - kdePackages.qt6ct - nwg-look - xournalpp - jq - ffmpeg - unzip + home = { + packages = with pkgs; [ + # various + google-chrome + thunar + obsidian + mpv + # screen recording — evaluating these + obs-studio + kooha # simple Wayland-native screen+audio recorder + vokoscreen-ng # GUI recorder with webcam overlay + gimp + font-manager + imv + pavucontrol + zathura + libsForQt5.qt5ct + kdePackages.qt6ct + nwg-look + xournalpp + jq + ffmpeg + unzip - # remote desktop - remmina + # remote desktop + remmina - # networking - networkmanagerapplet - mtr - dnsutils + # networking + networkmanagerapplet + mtr + dnsutils - # communication - slack - zoom-us - ferdium - signal-desktop + # communication + slack + ferdium + signal-desktop - # dev tools - yaak - bun + # dev tools + yaak + bun - # themes - tela-icon-theme - ]; + # themes + tela-icon-theme + ]; + + pointerCursor = { + package = pkgs.numix-cursor-theme; + name = "Numix-Cursor-Light"; + }; + }; gtk = { enable = true; @@ -71,31 +79,37 @@ }; }; - home.pointerCursor = { - package = pkgs.numix-cursor-theme; - name = "Numix-Cursor-Light"; + xdg.configFile = { + # zathura: include noctalia-generated theme + "zathura/zathurarc".text = '' + include noctaliarc + ''; + + # gtk: include noctalia-generated css (mkForce to override gtk module) + "gtk-3.0/gtk.css".text = lib.mkForce '' + @import url("noctalia.css"); + ''; + "gtk-4.0/gtk.css".text = lib.mkForce '' + @import url("noctalia.css"); + ''; + + # qt: use noctalia color scheme. Applied via QT_QPA_PLATFORMTHEME=qt6ct, + # set in the Hyprland env block (and imported into the dbus activation + # environment so the xdph screen-share picker inherits it too). + # custom_palette=true is required for qt5ct/qt6ct to actually apply the + # color scheme; Fusion is used because it fully honors a custom palette + # (Breeze/native styles partly ignore it). + "qt5ct/qt5ct.conf".text = '' + [Appearance] + style=Fusion + custom_palette=true + color_scheme_path=${config.home.homeDirectory}/.config/qt5ct/colors/noctalia.conf + ''; + "qt6ct/qt6ct.conf".text = '' + [Appearance] + style=Fusion + custom_palette=true + color_scheme_path=${config.home.homeDirectory}/.config/qt6ct/colors/noctalia.conf + ''; }; - - # zathura: include noctalia-generated theme - xdg.configFile."zathura/zathurarc".text = '' - include noctaliarc - ''; - - # gtk: include noctalia-generated css (mkForce to override gtk module) - xdg.configFile."gtk-3.0/gtk.css".text = lib.mkForce '' - @import url("noctalia.css"); - ''; - xdg.configFile."gtk-4.0/gtk.css".text = lib.mkForce '' - @import url("noctalia.css"); - ''; - - # qt: use noctalia color scheme - xdg.configFile."qt5ct/qt5ct.conf".text = '' - [Appearance] - color_scheme_path=${config.home.homeDirectory}/.config/qt5ct/colors/noctalia.conf - ''; - xdg.configFile."qt6ct/qt6ct.conf".text = '' - [Appearance] - color_scheme_path=${config.home.homeDirectory}/.config/qt6ct/colors/noctalia.conf - ''; } diff --git a/home/common/programs/dev.nix b/home/common/programs/dev.nix index d46bb95..cb701ab 100644 --- a/home/common/programs/dev.nix +++ b/home/common/programs/dev.nix @@ -47,7 +47,6 @@ mkcert nss.tools - kicad tea just # project command runner diff --git a/home/common/programs/git/default.nix b/home/common/programs/git/default.nix index 41584a3..86ee782 100644 --- a/home/common/programs/git/default.nix +++ b/home/common/programs/git/default.nix @@ -1,98 +1,103 @@ { pkgs, ... }: { - xdg.configFile."git/commit-message.txt".source = ./commit-message.txt; - xdg.configFile."git/ignore".source = ./ignore; - - programs.git = { - enable = true; - settings = { - user = { - name = "Miguel Palhas"; - email = "mpalhas@gmail.com"; - }; - alias = { - ls = "log --color --graph --oneline --decorate --topo-order --pretty=format:'%C(yellow)%d%Creset %Cgreen(%cr)%Creset %C(bold blue)[%an]%Creset %s %Cred(%h)%Creset' --abbrev-commit"; - ll = ''log --reverse --pretty=format:"%C(yellow)%h%Cred%d\ %Creset%s%Cblue\ [%an]" --decorate --numstat''; - conf = "diff --name-only --diff-filter=U"; - ba = "branch -a"; - pb = "publish"; - ps = "push -u"; - pr = "pull-request"; - ppr = "push-pr"; - cpr = "close-pr"; - opr = "open-pr"; - f = "fetch"; - c = "commit --verbose"; - d = "diff"; - dc = "diff --cached"; - co = "checkout"; - s = "status -sb"; - b = "better-branch"; - rb = "rebase"; - rbc = "rebase --continue"; - w = "commit -am 'wip'"; - # Structural (AST-aware) diff on demand; `git d`/`diff` stays delta. - # Accepts args, e.g. `git dft HEAD~3`. - dft = "!GIT_EXTERNAL_DIFF=difft git diff"; - }; - init = { - defaultBranch = "main"; - }; - core = { - editor = "nvim"; - pager = "delta"; - askpass = ""; - }; - credential = { - helper = "store"; - }; - "credential \"https://git.naps.pt\"" = { - helper = "!tea login helper"; - }; - merge = { - conflictstyle = "zdiff3"; - }; - commit = { - template = "~/.config/git/commit-message.txt"; - }; - push = { - default = "upstream"; - }; - delta = { - navigate = true; - side-by-side = true; - }; - "diff \"image\"" = { - textconv = "mediainfo"; - }; - "diff \"text\"" = { - textconv = "fold -s -w80"; - }; - }; - }; - - home.packages = with pkgs; [ - delta - difftastic - git-crypt - mediainfo - tea - ]; - home.sessionPath = [ - "$HOME/.config/git/scripts" - ]; xdg.configFile = { + "git/commit-message.txt".source = ./commit-message.txt; + "git/ignore".source = ./ignore; "git/scripts".source = ./scripts; }; - programs.gh = { - enable = true; - settings = { - aliases = { - co = "pr checkout"; - ls = "pr list"; - pv = "pr view"; + programs = { + git = { + enable = true; + settings = { + user = { + name = "Miguel Palhas"; + email = "mpalhas@gmail.com"; + }; + alias = { + ls = "log --color --graph --oneline --decorate --topo-order --pretty=format:'%C(yellow)%d%Creset %Cgreen(%cr)%Creset %C(bold blue)[%an]%Creset %s %Cred(%h)%Creset' --abbrev-commit"; + ll = ''log --reverse --pretty=format:"%C(yellow)%h%Cred%d\ %Creset%s%Cblue\ [%an]" --decorate --numstat''; + conf = "diff --name-only --diff-filter=U"; + ba = "branch -a"; + pb = "publish"; + ps = "push -u"; + pr = "pull-request"; + ppr = "push-pr"; + cpr = "close-pr"; + opr = "open-pr"; + f = "fetch"; + c = "commit --verbose"; + d = "diff"; + dc = "diff --cached"; + co = "checkout"; + s = "status -sb"; + b = "better-branch"; + rb = "rebase"; + rbc = "rebase --continue"; + w = "commit -am 'wip'"; + # Structural (AST-aware) diff on demand; `git d`/`diff` stays delta. + # Accepts args, e.g. `git dft HEAD~3`. + dft = "!GIT_EXTERNAL_DIFF=difft git diff"; + }; + init = { + defaultBranch = "main"; + }; + core = { + editor = "nvim"; + pager = "delta"; + askpass = ""; + }; + credential = { + helper = "store"; + }; + "credential \"https://git.naps.pt\"" = { + helper = "!tea login helper"; + }; + merge = { + conflictstyle = "zdiff3"; + }; + commit = { + template = "~/.config/git/commit-message.txt"; + }; + push = { + default = "upstream"; + }; + delta = { + navigate = true; + side-by-side = true; + }; + "diff \"image\"" = { + textconv = "mediainfo"; + }; + "diff \"text\"" = { + textconv = "fold -s -w80"; + }; + }; + }; + + gh = { + enable = true; + + settings = { + aliases = { + co = "pr checkout"; + ls = "pr list"; + pv = "pr view"; + }; }; }; }; + + home = { + packages = with pkgs; [ + delta + difftastic + git-crypt + mediainfo + tea + ]; + sessionPath = [ + "$HOME/.config/git/scripts" + ]; + }; } diff --git a/home/common/programs/hyprland/default.nix b/home/common/programs/hyprland/default.nix index 1b1d0ab..01925ae 100644 --- a/home/common/programs/hyprland/default.nix +++ b/home/common/programs/hyprland/default.nix @@ -6,6 +6,19 @@ }: let cfg = config.custom.hyprland; + + # Floating webcam preview for the "corner-cam" recording trick: run `webcam`, + # then capture the whole screen with kooha/wf-recorder — the preview is in the + # recording. v4l2 only (won't work with the laptop's IPU6 cam). Optional device + # arg, e.g. `webcam /dev/video2`. + webcam = pkgs.writeShellScriptBin "webcam" '' + dev="''${1:-/dev/video0}" + exec ${pkgs.mpv}/bin/mpv \ + --profile=low-latency --untimed \ + --no-osc --no-input-default-bindings \ + --title=webcam-overlay --border=no --ontop \ + "av://v4l2:$dev" + ''; in { options.custom.hyprland = { @@ -39,6 +52,7 @@ in cliphist wf-recorder slurp + webcam ]; home.sessionVariables = { @@ -129,13 +143,18 @@ in "XCURSOR_SIZE, ${toString cfg.cursorSize}" "HYPRCURSOR_THEME, rose-pine-hyprcursor" "HYPRCURSOR_SIZE, ${toString cfg.cursorSize}" + # Route Qt6 apps (incl. the xdph screen-share picker) through qt6ct so + # the noctalia-generated color scheme actually applies. Without this + # var the qt6ct.conf is never read. + "QT_QPA_PLATFORMTHEME, qt6ct" ]; "exec-once" = [ - "dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP" + # Import the Qt theme var too, so the dbus/systemd-activated + # xdg-desktop-portal-hyprland (and its share-picker) inherit it. + "dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP QT_QPA_PLATFORMTHEME" "hyprctl setcursor Nordzy-cursors ${toString cfg.cursorSize}" "hyprsunset" - "nerd-dictation begin --simulate-input-tool WTYPE --suspend-on-start && touch ~/.cache/nerd-dictation-suspended" "noctalia" ]; @@ -167,6 +186,15 @@ in "size 1920 1080, match:class mpv" "move (cursor_x-(window_w*0.5)) (cursor_y-(window_h*0.5)), match:class mpv" + # webcam overlay (`webcam` command) — small, pinned, bottom-right. + # Title rules come after the mpv class rules so they win. + "float on, match:title webcam-overlay" + "size 360 240, match:title webcam-overlay" + "move 100%-380 100%-260, match:title webcam-overlay" + "pin on, match:title webcam-overlay" + "no_initial_focus on, match:title webcam-overlay" + "border_size 0, match:title webcam-overlay" + # thunar "float on, match:class thunar" diff --git a/home/common/programs/nerd-dictation.nix b/home/common/programs/nerd-dictation.nix deleted file mode 100644 index 823fe0e..0000000 --- a/home/common/programs/nerd-dictation.nix +++ /dev/null @@ -1,124 +0,0 @@ -{ - pkgs, - ... -}: -let - venvDir = "$HOME/.local/share/nerd-dictation/venv"; - - # Create an FHS environment where vosk can be pip-installed - nerd-dictation-env = pkgs.buildFHSEnv { - name = "nerd-dictation-fhs"; - targetPkgs = pkgs: with pkgs; [ - # Python and pip for vosk - python3 - python3Packages.pip - python3Packages.virtualenv - - # Audio recording (pipewire) - pipewire - pulseaudio # for parec - - # Input simulation (wayland-compatible) - ydotool - wtype - xdotool - - # Manylinux compatibility - pythonManylinuxPackages.manylinux2014Package - ]; - runScript = "bash"; - }; - - # Fetch nerd-dictation from GitHub - nerd-dictation-src = pkgs.fetchFromGitHub { - owner = "ideasman42"; - repo = "nerd-dictation"; - rev = "main"; - hash = "sha256-xjaHrlJvk8bNvWp1VE4EAHi2VJlAutBxUgWB++3Qo+s="; - }; - - modelUrl = "https://alphacephei.com/vosk/models/vosk-model-en-us-0.22-lgraph.zip"; - modelName = "vosk-model-en-us-0.22-lgraph"; - modelDir = "$HOME/.config/nerd-dictation"; - - # Wrapper script that handles setup and runs nerd-dictation - nerd-dictation = pkgs.writeShellScriptBin "nerd-dictation" '' - set -e - VENV="${venvDir}" - MODEL_DIR="${modelDir}" - - # Setup venv if needed - if [ ! -d "$VENV" ]; then - echo "[nerd-dictation] Setting up Python venv and installing vosk..." - ${nerd-dictation-env}/bin/nerd-dictation-fhs -c " - set -e - mkdir -p \$(dirname ${venvDir}) - python3 -m venv ${venvDir} - source ${venvDir}/bin/activate - pip install --upgrade pip -q - pip install vosk -q - " - echo "[nerd-dictation] Venv ready." - fi - - # Download model if needed - if [ ! -d "$MODEL_DIR/model" ]; then - echo "[nerd-dictation] Downloading VOSK model (${modelName})..." - mkdir -p "$MODEL_DIR" - cd "$MODEL_DIR" - ${pkgs.curl}/bin/curl -L --progress-bar -o "${modelName}.zip" "${modelUrl}" - echo "[nerd-dictation] Extracting model..." - ${pkgs.unzip}/bin/unzip -q "${modelName}.zip" - mv "${modelName}" model - rm "${modelName}.zip" - echo "[nerd-dictation] Model ready." - fi - - exec ${nerd-dictation-env}/bin/nerd-dictation-fhs -c "source $VENV/bin/activate && python3 ${nerd-dictation-src}/nerd-dictation $*" - ''; - - # Toggle script for hyprland keybind - nerd-dictation-toggle = pkgs.writeShellScriptBin "nerd-dictation-toggle" '' - hyprctl() { - env -u LD_LIBRARY_PATH ${pkgs.hyprland}/bin/hyprctl "$@" - } - - set_border() { - local size=$1 - local color=$2 - # Unset existing rules for single-window workspaces - hyprctl keyword windowrule "unset, match:float 0, match:workspace w[t1]" - hyprctl keyword windowrule "unset, match:float 0, match:workspace w[tg1]" - hyprctl keyword windowrule "unset, match:float 0, match:workspace f[1]" - hyprctl keyword windowrule "unset, match:fullscreen 1" - # Re-add with specified border size - hyprctl keyword windowrule "border_size $size, match:float 0, match:workspace w[t1]" - hyprctl keyword windowrule "rounding 0, match:float 0, match:workspace w[t1]" - hyprctl keyword windowrule "border_size $size, match:float 0, match:workspace w[tg1]" - hyprctl keyword windowrule "rounding 0, match:float 0, match:workspace w[tg1]" - hyprctl keyword windowrule "border_size $size, match:float 0, match:workspace f[1]" - hyprctl keyword windowrule "rounding 0, match:float 0, match:workspace f[1]" - hyprctl keyword windowrule "border_size $size, match:fullscreen 1" - # Set border color - hyprctl keyword general:col.active_border "$color" - } - - # Check if currently suspended (file exists when suspended) - if [ -f "$HOME/.cache/nerd-dictation-suspended" ]; then - nerd-dictation resume - rm -f "$HOME/.cache/nerd-dictation-suspended" - set_border 5 "rgb(ff0000)" - else - nerd-dictation suspend - touch "$HOME/.cache/nerd-dictation-suspended" - set_border 0 "0x99999999" - fi - ''; -in -{ - home.packages = [ - nerd-dictation - nerd-dictation-toggle - pkgs.ydotool - ]; -} diff --git a/home/common/programs/opencode/default.nix b/home/common/programs/opencode/default.nix index 2223e33..cf8bfd0 100644 --- a/home/common/programs/opencode/default.nix +++ b/home/common/programs/opencode/default.nix @@ -1,37 +1,39 @@ _: { - # Global config file - xdg.configFile."opencode/opencode.json".source = ./opencode.json; + xdg.configFile = { + # Global config file + "opencode/opencode.json".source = ./opencode.json; - # Global rules (equivalent to ~/.claude/CLAUDE.md) - xdg.configFile."opencode/AGENTS.md".source = ./AGENTS.md; + # Global rules (equivalent to ~/.claude/CLAUDE.md) + "opencode/AGENTS.md".source = ./AGENTS.md; - # Custom agents - xdg.configFile."opencode/agents/oracle.md".source = ./agents/oracle.md; - xdg.configFile."opencode/agents/explorer.md".source = ./agents/explorer.md; - xdg.configFile."opencode/agents/librarian.md".source = ./agents/librarian.md; - xdg.configFile."opencode/agents/fixer.md".source = ./agents/fixer.md; - xdg.configFile."opencode/agents/designer.md".source = ./agents/designer.md; - xdg.configFile."opencode/agents/designer-bold.md".source = ./agents/designer-bold.md; - xdg.configFile."opencode/agents/analyze-branch.md".source = ./agents/analyze-branch.md; + # Custom agents + "opencode/agents/oracle.md".source = ./agents/oracle.md; + "opencode/agents/explorer.md".source = ./agents/explorer.md; + "opencode/agents/librarian.md".source = ./agents/librarian.md; + "opencode/agents/fixer.md".source = ./agents/fixer.md; + "opencode/agents/designer.md".source = ./agents/designer.md; + "opencode/agents/designer-bold.md".source = ./agents/designer-bold.md; + "opencode/agents/analyze-branch.md".source = ./agents/analyze-branch.md; - # Global commands - xdg.configFile."opencode/commands/work.md".source = ./commands/work.md; - xdg.configFile."opencode/commands/merge.md".source = ./commands/merge.md; - xdg.configFile."opencode/commands/update.md".source = ./commands/update.md; - xdg.configFile."opencode/commands/smart-debug.md".source = ./commands/smart-debug.md; - xdg.configFile."opencode/commands/tdd-cycle.md".source = ./commands/tdd-cycle.md; - xdg.configFile."opencode/commands/security-scan.md".source = ./commands/security-scan.md; - xdg.configFile."opencode/commands/issue.md".source = ./commands/issue.md; - xdg.configFile."opencode/commands/remove-deadcode.md".source = ./commands/remove-deadcode.md; - xdg.configFile."opencode/commands/worktree-compare.md".source = ./commands/worktree-compare.md; - xdg.configFile."opencode/commands/worktree-list.md".source = ./commands/worktree-list.md; + # Global commands + "opencode/commands/work.md".source = ./commands/work.md; + "opencode/commands/merge.md".source = ./commands/merge.md; + "opencode/commands/update.md".source = ./commands/update.md; + "opencode/commands/smart-debug.md".source = ./commands/smart-debug.md; + "opencode/commands/tdd-cycle.md".source = ./commands/tdd-cycle.md; + "opencode/commands/security-scan.md".source = ./commands/security-scan.md; + "opencode/commands/issue.md".source = ./commands/issue.md; + "opencode/commands/remove-deadcode.md".source = ./commands/remove-deadcode.md; + "opencode/commands/worktree-compare.md".source = ./commands/worktree-compare.md; + "opencode/commands/worktree-list.md".source = ./commands/worktree-list.md; - # Skills - xdg.configFile."opencode/skills/git-master/SKILL.md".source = ./skills/git-master/SKILL.md; - xdg.configFile."opencode/skills/planning-with-files/SKILL.md".source = - ./skills/planning-with-files/SKILL.md; - xdg.configFile."opencode/skills/react-patterns/SKILL.md".source = ./skills/react-patterns/SKILL.md; - xdg.configFile."opencode/skills/vercel-react-best-practices/SKILL.md".source = - ./skills/vercel-react-best-practices/SKILL.md; + # Skills + "opencode/skills/git-master/SKILL.md".source = ./skills/git-master/SKILL.md; + "opencode/skills/planning-with-files/SKILL.md".source = + ./skills/planning-with-files/SKILL.md; + "opencode/skills/react-patterns/SKILL.md".source = ./skills/react-patterns/SKILL.md; + "opencode/skills/vercel-react-best-practices/SKILL.md".source = + ./skills/vercel-react-best-practices/SKILL.md; + }; } diff --git a/home/common/programs/rust.nix b/home/common/programs/rust.nix index e663467..9640f94 100644 --- a/home/common/programs/rust.nix +++ b/home/common/programs/rust.nix @@ -1,31 +1,33 @@ { pkgs, ... }: { - home.packages = with pkgs; [ - rustup - bacon - mprocs - pkg-config - openssl.dev - taplo - sccache - mold - clang - ]; + home = { + packages = with pkgs; [ + rustup + bacon + mprocs + pkg-config + openssl.dev + taplo + sccache + mold + clang + ]; - home.sessionPath = [ "\${CARGO_HOME:-$HOME/.cargo}/bin" ]; + sessionPath = [ "\${CARGO_HOME:-$HOME/.cargo}/bin" ]; - home.file.".cargo/config.toml".text = '' - [target.x86_64-unknown-linux-gnu] - linker = "clang" - rustflags = ["-C", "link-arg=-fuse-ld=mold"] + file.".cargo/config.toml".text = '' + [target.x86_64-unknown-linux-gnu] + linker = "clang" + rustflags = ["-C", "link-arg=-fuse-ld=mold"] - [build] - rustflags = ["-Z", "threads=12"] - ''; + [build] + rustflags = ["-Z", "threads=12"] + ''; - home.sessionVariables = { - OPENSSL_DIR = "${pkgs.openssl.dev}"; - OPENSSL_LIB_DIR = "${pkgs.openssl.out}/lib"; - OPENSSL_INCLUDE_DIR = "${pkgs.openssl.dev}/include"; + sessionVariables = { + OPENSSL_DIR = "${pkgs.openssl.dev}"; + OPENSSL_LIB_DIR = "${pkgs.openssl.out}/lib"; + OPENSSL_INCLUDE_DIR = "${pkgs.openssl.dev}/include"; + }; }; } diff --git a/home/common/programs/unity.nix b/home/common/programs/unity.nix deleted file mode 100644 index 757c7a1..0000000 --- a/home/common/programs/unity.nix +++ /dev/null @@ -1,11 +0,0 @@ -{ pkgs, ... }: -{ - home.packages = with pkgs; [ - unityhub - omnisharp-roslyn - vscode - dotnet-sdk - icu - stdenv.cc.cc.lib - ]; -} diff --git a/home/common/programs/zsh.nix b/home/common/programs/zsh.nix index d8a2272..8ba4e5d 100644 --- a/home/common/programs/zsh.nix +++ b/home/common/programs/zsh.nix @@ -4,149 +4,159 @@ ... }: { - programs.zsh = { - enable = true; - enableCompletion = true; - autosuggestion.enable = true; - syntaxHighlighting.enable = true; - completionInit = "autoload -U compinit && compinit -u"; + programs = { + zsh = { + enable = true; + enableCompletion = true; + autosuggestion.enable = true; + syntaxHighlighting.enable = true; + completionInit = "autoload -U compinit && compinit -u"; - shellAliases = { - c = "cargo"; - d = "docker"; - dc = "docker compose"; - g = "git"; - n = "nvim"; - vim = "nvim"; - ls = "eza"; - cat = "bat"; - ps = "procs"; - j = "just"; - lzd = "lazydocker"; - open = "xdg-open"; - o = "xdg-open"; - s = "ssh"; - v = "nohup neovide &; disown"; + shellAliases = { + c = "cargo"; + d = "docker"; + dc = "docker compose"; + g = "git"; + n = "nvim"; + vim = "nvim"; + ls = "eza"; + cat = "bat"; + ps = "procs"; + du = "dust"; + df = "duf"; + j = "just"; + lzd = "lazydocker"; + open = "xdg-open"; + o = "xdg-open"; + s = "ssh"; + v = "nohup neovide &; disown"; - # cd - ".." = "cd .."; - "..2" = "cd ../.."; - "..3" = "cd ../../.."; + # cd + ".." = "cd .."; + "..2" = "cd ../.."; + "..3" = "cd ../../.."; + }; + + history = { + size = 10000; + path = "${config.xdg.dataHome}/zsh/history"; + }; + + plugins = [ + { + name = "fzf-tab"; + src = pkgs.fetchFromGitHub { + owner = "Aloxaf"; + repo = "fzf-tab"; + rev = "v1.1.2"; + hash = "sha256-Qv8zAiMtrr67CbLRrFjGaPzFZcOiMVEFLg1Z+N6VMhg="; + }; + } + { + name = "zsh-autopair"; + src = pkgs.fetchFromGitHub { + owner = "hlissner"; + repo = "zsh-autopair"; + rev = "449a7c3"; + hash = "sha256-3zvOgIi+q7+sTXrT+r/4v98qjeiEL4Wh64rxBYnwJvQ="; + }; + } + ]; + + initContent = '' + [[ -f ~/.secrets.zsh ]] && source ~/.secrets.zsh + # [[ -n "$KITTY_WINDOW_ID" ]] && alias ssh="kitten ssh" + + export PATH="$HOME/.bin:$PATH" + export PATH="''${ASDF_DATA_DIR:-$HOME/.asdf}/shims:$PATH" + export FOUNDRY_DISABLE_NIGHTLY_WARNING=true + export LD_LIBRARY_PATH=${pkgs.zlib}/lib:${pkgs.icu}/lib:${pkgs.stdenv.cc.cc.lib}/lib:$LD_LIBRARY_PATH + + ''; }; - history = { - size = 10000; - path = "${config.xdg.dataHome}/zsh/history"; + fzf = { + enable = true; + enableZshIntegration = true; }; - plugins = [ - { - name = "fzf-tab"; - src = pkgs.fetchFromGitHub { - owner = "Aloxaf"; - repo = "fzf-tab"; - rev = "v1.1.2"; - hash = "sha256-Qv8zAiMtrr67CbLRrFjGaPzFZcOiMVEFLg1Z+N6VMhg="; - }; - } - { - name = "zsh-autopair"; - src = pkgs.fetchFromGitHub { - owner = "hlissner"; - repo = "zsh-autopair"; - rev = "449a7c3"; - hash = "sha256-3zvOgIi+q7+sTXrT+r/4v98qjeiEL4Wh64rxBYnwJvQ="; - }; - } + zoxide = { + enable = true; + enableZshIntegration = true; + # Replace `cd` with zoxide: `cd` = smart jump, `cdi` = interactive picker. + options = [ "--cmd cd" ]; + }; + + atuin = { + enable = true; + enableZshIntegration = true; + # Local-only history (no account/sync). Atuin owns Ctrl-R; leave the + # up-arrow as normal zsh prefix history. + flags = [ "--disable-up-arrow" ]; + settings = { + auto_sync = false; + update_check = false; + }; + }; + + starship = { + enable = true; + settings = { + add_newline = true; + + # Disable language modules to keep prompt short + nodejs.disabled = true; + python.disabled = true; + rust.disabled = true; + golang.disabled = true; + java.disabled = true; + ruby.disabled = true; + php.disabled = true; + elixir.disabled = true; + elm.disabled = true; + haskell.disabled = true; + julia.disabled = true; + kotlin.disabled = true; + lua.disabled = true; + nim.disabled = true; + nix_shell.disabled = true; + ocaml.disabled = true; + perl.disabled = true; + purescript.disabled = true; + scala.disabled = true; + swift.disabled = true; + terraform.disabled = true; + zig.disabled = true; + dotnet.disabled = true; + }; + }; + }; + + home = { + packages = with pkgs; [ + btop + inxi + ripgrep + pass + bat + procs + eza + asdf-vm + fd + tdf ]; - initContent = '' - [[ -f ~/.secrets.zsh ]] && source ~/.secrets.zsh - # [[ -n "$KITTY_WINDOW_ID" ]] && alias ssh="kitten ssh" - - export PATH="$HOME/.bin:$PATH" - export PATH="''${ASDF_DATA_DIR:-$HOME/.asdf}/shims:$PATH" - export FOUNDRY_DISABLE_NIGHTLY_WARNING=true - export LD_LIBRARY_PATH=${pkgs.zlib}/lib:${pkgs.icu}/lib:${pkgs.stdenv.cc.cc.lib}/lib:$LD_LIBRARY_PATH - - ''; - }; - - programs.fzf = { - enable = true; - enableZshIntegration = true; - }; - - programs.zoxide = { - enable = true; - enableZshIntegration = true; - # Replace `cd` with zoxide: `cd` = smart jump, `cdi` = interactive picker. - options = [ "--cmd cd" ]; - }; - - programs.atuin = { - enable = true; - enableZshIntegration = true; - # Local-only history (no account/sync). Atuin owns Ctrl-R; leave the - # up-arrow as normal zsh prefix history. - flags = [ "--disable-up-arrow" ]; - settings = { - auto_sync = false; - update_check = false; + sessionVariables = { + "ASDF_NODEJS_AUTO_ENABLE_COREPACK" = "true"; + # home-manager inits zoxide before atuin/fzf, tripping zoxide's doctor + # warning even though the `cd` override works fine (nothing after + # redefines cd). Silence the nag. + "_ZO_DOCTOR" = "0"; }; + + sessionPath = [ + "./.git/safe/../../node_modules/.bin" + "./.git/safe/../../bin" + ]; }; - - programs.starship = { - enable = true; - settings = { - add_newline = true; - - # Disable language modules to keep prompt short - nodejs.disabled = true; - python.disabled = true; - rust.disabled = true; - golang.disabled = true; - java.disabled = true; - ruby.disabled = true; - php.disabled = true; - elixir.disabled = true; - elm.disabled = true; - haskell.disabled = true; - julia.disabled = true; - kotlin.disabled = true; - lua.disabled = true; - nim.disabled = true; - nix_shell.disabled = true; - ocaml.disabled = true; - perl.disabled = true; - purescript.disabled = true; - scala.disabled = true; - swift.disabled = true; - terraform.disabled = true; - zig.disabled = true; - dotnet.disabled = true; - }; - }; - - home.packages = with pkgs; [ - btop - inxi - ripgrep - pass - bat - procs - eza - asdf-vm - fd - tdf - ]; - - home.sessionVariables = { - "ASDF_NODEJS_AUTO_ENABLE_COREPACK" = "true"; - }; - - home.sessionPath = [ - "./.git/safe/../../node_modules/.bin" - "./.git/safe/../../bin" - ]; } diff --git a/home/konishi/default.nix b/home/konishi/default.nix index 6cdbcea..224e274 100644 --- a/home/konishi/default.nix +++ b/home/konishi/default.nix @@ -8,12 +8,10 @@ ../common/programs/zen-browser.nix ../common/programs/hyprland ../common/programs/kitty - ../common/programs/unity.nix ../common/programs/gpg.nix ../common/programs/ethui.nix ../common/programs/3d.nix ../common/programs/godot.nix - ../common/programs/nerd-dictation.nix ../common/features/xdg.nix ../common/features/downloads-cleanup.nix ./monitors.nix diff --git a/hosts/arrakis/default.nix b/hosts/arrakis/default.nix index 08aed32..710c993 100644 --- a/hosts/arrakis/default.nix +++ b/hosts/arrakis/default.nix @@ -20,7 +20,6 @@ ../common/features/nix-ld.nix ../common/features/bluetooth.nix ../common/features/ledger.nix - ../common/features/android-studio.nix ../common/features/home ]; @@ -33,11 +32,43 @@ users.users.naps62.extraGroups = [ "video" ]; - # IPU6 webcam — kernel/firmware support only - # Camera works via libcamera (cam -l, cam -c 1 --capture) but no - # reliable browser integration yet without always-on LED - hardware.firmware = [ pkgs.ivsc-firmware ]; - environment.systemPackages = [ pkgs.libcamera ]; + # IPU6 webcam (Dell XPS 9320, Alder Lake, ov01a10 sensor). + # Uses Intel's hardware ISP via the official hardware.ipu6 module: the + # proprietary HAL (ipu6-camera-bins/-hal + icamerasrc) feeds v4l2-relayd, + # which exposes a normal /dev/video50 ("Intel MIPI Camera") that works in + # every app (Chrome, Zen, mpv, OBS, ...). The module also hides the 32 raw + # IPU6 nodes from WirePlumber/udev, which is what unbreaks Chrome. + # + # The relay is on-demand (v4l2-relayd opens the sensor only when an app opens + # the loopback device), so the LED should follow usage rather than stay on. + # + # Bare libcamera still works as a fallback (software ISP, poor quality): + # libcamerify mpv av://v4l2:/dev/video0 --profile=low-latency --untimed + hardware.ipu6 = { + enable = true; + platform = "ipu6ep"; # Alder Lake / Raptor Lake + }; + + # v4l2-relayd exits whenever a consumer closes the loopback and relies on + # systemd to restart it for the next session. The default start-limit (5 + # restarts / 10s) permanently kills it under rapid open/close (e.g. an app + # probing the device), leaving the camera dead until a manual restart. + # Disable the limit and throttle restarts so it always self-heals. + systemd.services.v4l2-relayd-ipu6 = { + startLimitIntervalSec = 0; + serviceConfig.RestartSec = "1"; + }; + + # The module's rule to lock the raw IPU6 nodes to root gets clobbered by the + # default "video4linux -> group video" rule, so they stay user-readable and + # Chrome hangs enumerating all 32 of them. Re-assert with ':=' (locks the + # value against later rules), matched on the kernel-set ID_V4L_PRODUCT. + # GROUP/MODE alone isn't enough: logind's uaccess still leaves a stale + # "user::rw" ACL on the nodes, so also drop the uaccess tag and wipe any + # ACL on every event (setfacl -b) to keep the raw nodes truly root-only. + services.udev.extraRules = '' + SUBSYSTEM=="video4linux", ENV{ID_V4L_PRODUCT}=="ipu6", GROUP:="root", MODE:="0600", TAG-="uaccess", RUN+="${pkgs.acl}/bin/setfacl -b %N" + ''; services.fprintd.enable = true; } diff --git a/hosts/common/features/android-studio.nix b/hosts/common/features/android-studio.nix deleted file mode 100644 index 2bd7df5..0000000 --- a/hosts/common/features/android-studio.nix +++ /dev/null @@ -1,29 +0,0 @@ -{ pkgs, ... }: -{ - users.users.naps62.extraGroups = [ - "kvm" - "adbusers" - ]; - - # services.udev.packages = with pkgs; [ - # android-udev-rules - # ]; - - environment.systemPackages = with pkgs; [ - android-studio - steam-run - android-studio-tools - nss - vulkan-loader - libpulseaudio - libx11 - libxext - libxdamage - libxfixes - libxi - libxrandr - libxtst - libxcb - libxcomposite - ]; -} diff --git a/hosts/common/features/gpu/nvidia.nix b/hosts/common/features/gpu/nvidia.nix index bf196e0..e9c9575 100644 --- a/hosts/common/features/gpu/nvidia.nix +++ b/hosts/common/features/gpu/nvidia.nix @@ -1,17 +1,21 @@ { config, pkgs, ... }: { - hardware.graphics.enable = true; - services.xserver.videoDrivers = [ "nvidia" ]; - hardware.nvidia = { - modesetting.enable = true; - open = false; - nvidiaSettings = true; - package = config.boot.kernelPackages.nvidiaPackages.stable; + hardware = { + graphics = { + enable = true; + extraPackages = with pkgs; [ + nvidia-vaapi-driver + ]; + }; + nvidia = { + modesetting.enable = true; + open = false; + nvidiaSettings = true; + package = config.boot.kernelPackages.nvidiaPackages.stable; + }; }; - programs.xwayland.enable = true; + services.xserver.videoDrivers = [ "nvidia" ]; - hardware.graphics.extraPackages = with pkgs; [ - nvidia-vaapi-driver - ]; + programs.xwayland.enable = true; } diff --git a/hosts/konishi/default.nix b/hosts/konishi/default.nix index 527cb47..96364c8 100644 --- a/hosts/konishi/default.nix +++ b/hosts/konishi/default.nix @@ -16,7 +16,6 @@ ../common/features/nix-ld.nix ../common/features/bluetooth.nix ../common/features/ledger.nix - ../common/features/android-studio.nix ../common/features/wine.nix ../common/features/steam.nix ../common/features/appimage.nix