mirror of
https://github.com/moons-14/dotfiles.git
synced 2026-10-07 04:44:09 +09:00
Compare commits
26
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a2ee175609 | ||
|
|
66bf009afd | ||
|
|
33e09f8e93 | ||
|
|
eff32fddcd | ||
|
|
8ce3a6082a | ||
|
|
a8246261ad | ||
|
|
8b51b5c55f | ||
|
|
e24d85da56 | ||
|
|
01ead9a385 | ||
|
|
328f11d0ed | ||
|
|
d877ffc76c | ||
|
|
fe40adaeee | ||
|
|
991dde5305 | ||
|
|
96ce4d768c | ||
|
|
30b1480e50 | ||
|
|
71011d7bd1 | ||
|
|
9cced59e58 | ||
|
|
20a601402e | ||
|
|
1b4a5fa5a2 | ||
|
|
5fb55f2e6a | ||
|
|
2a3f7ee6ff | ||
|
|
247db71f2d | ||
|
|
a44a83a587 | ||
|
|
1f1d46ea2a | ||
|
|
29c4815b88 | ||
|
|
28a46d9990 |
@@ -30,3 +30,4 @@
|
|||||||
!/modules/
|
!/modules/
|
||||||
|
|
||||||
!/tests/
|
!/tests/
|
||||||
|
!/skills/
|
||||||
|
|||||||
@@ -24,6 +24,11 @@ makes any statement here stale, update `AGENTS.md` in the same change.
|
|||||||
| `overlays/` | Package replacements and additions |
|
| `overlays/` | Package replacements and additions |
|
||||||
| `shells/` | Development shells |
|
| `shells/` | Development shells |
|
||||||
| `flake/` | Supporting flake outputs such as formatters, checks, and Git hooks |
|
| `flake/` | Supporting flake outputs such as formatters, checks, and Git hooks |
|
||||||
|
| `skills/` | Repository-specific Codex workflows that enforce this contract for recurring changes |
|
||||||
|
|
||||||
|
Before adding or materially extending an application or service, read and
|
||||||
|
follow `skills/add-application-or-service/SKILL.md`. `AGENTS.md` remains the
|
||||||
|
authoritative contract when the skill and repository ever disagree.
|
||||||
|
|
||||||
Use **unit** as the generic internal term for a Registry-managed component and
|
Use **unit** as the generic internal term for a Registry-managed component and
|
||||||
**profile** for a unit that composes multiple units. Do not introduce a
|
**profile** for a unit that composes multiple units. Do not introduce a
|
||||||
|
|||||||
Generated
+248
-80
@@ -91,6 +91,32 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"bun2nix": {
|
"bun2nix": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-parts": "flake-parts_2",
|
||||||
|
"import-tree": "import-tree",
|
||||||
|
"nixpkgs": [
|
||||||
|
"handy",
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"systems": "systems_4",
|
||||||
|
"treefmt-nix": "treefmt-nix"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1770895533,
|
||||||
|
"narHash": "sha256-v3QaK9ugy9bN9RXDnjw0i2OifKmz2NnKM82agtqm/UY=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "bun2nix",
|
||||||
|
"rev": "c843f477b15f51151f8c6bcc886954699440a6e1",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"ref": "2.0.8",
|
||||||
|
"repo": "bun2nix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"bun2nix_2": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-parts": [
|
"flake-parts": [
|
||||||
"llm-agents",
|
"llm-agents",
|
||||||
@@ -129,11 +155,11 @@
|
|||||||
"nixpkgs": "nixpkgs"
|
"nixpkgs": "nixpkgs"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1785771258,
|
"lastModified": 1785831553,
|
||||||
"narHash": "sha256-4qwZF7xxLBokf6gfIBkymFMQiJ36fbJ9SPkOAp5VI4I=",
|
"narHash": "sha256-9q7WKbhq6bOGUdeo9Q/e3PmapJew0b2LCpaCio1X17k=",
|
||||||
"owner": "ilysenko",
|
"owner": "ilysenko",
|
||||||
"repo": "codex-desktop-linux",
|
"repo": "codex-desktop-linux",
|
||||||
"rev": "ab314923b5bf9b786a16cee67605d9eea2433d84",
|
"rev": "7166d1153fd99647fb080605c8b2a8f22b50b08f",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -292,6 +318,24 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flake-parts_2": {
|
"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": {
|
"inputs": {
|
||||||
"nixpkgs-lib": [
|
"nixpkgs-lib": [
|
||||||
"llm-agents",
|
"llm-agents",
|
||||||
@@ -312,7 +356,7 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flake-parts_3": {
|
"flake-parts_4": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs-lib": [
|
"nixpkgs-lib": [
|
||||||
"nixvim",
|
"nixvim",
|
||||||
@@ -333,7 +377,7 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flake-parts_4": {
|
"flake-parts_5": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs-lib": [
|
"nixpkgs-lib": [
|
||||||
"stylix",
|
"stylix",
|
||||||
@@ -419,11 +463,11 @@
|
|||||||
"zon2nix": "zon2nix"
|
"zon2nix": "zon2nix"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1785770443,
|
"lastModified": 1785853205,
|
||||||
"narHash": "sha256-VZ9UpfgG5+Dy17eTLJ8ryV5e7Ki0/0JTA5MhWnfSriw=",
|
"narHash": "sha256-rHvUeXh4druPSNPg2EMvY9F+av/NSQzjNLsf7s6lNnI=",
|
||||||
"owner": "ghostty-org",
|
"owner": "ghostty-org",
|
||||||
"repo": "ghostty",
|
"repo": "ghostty",
|
||||||
"rev": "863fc9531ae0b8e09b7103a9089dfc00319a7d9c",
|
"rev": "594ee212bc3c048ffa06ba90623eaf207a4d145c",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -470,6 +514,27 @@
|
|||||||
"type": "gitlab"
|
"type": "gitlab"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"handy": {
|
||||||
|
"inputs": {
|
||||||
|
"bun2nix": "bun2nix",
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1785763469,
|
||||||
|
"narHash": "sha256-YHfOchlPBKbBbeoaT1amrjKBHJTYMXmcR1Gm31E7TLE=",
|
||||||
|
"owner": "cjpais",
|
||||||
|
"repo": "Handy",
|
||||||
|
"rev": "b1b2d9f9072e55902a46ca6cc655e5893ed7a91d",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "cjpais",
|
||||||
|
"repo": "Handy",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"home-manager": {
|
"home-manager": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
@@ -533,6 +598,21 @@
|
|||||||
"type": "github"
|
"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"
|
||||||
|
}
|
||||||
|
},
|
||||||
"lanzaboote": {
|
"lanzaboote": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"crane": "crane",
|
"crane": "crane",
|
||||||
@@ -558,18 +638,18 @@
|
|||||||
},
|
},
|
||||||
"llm-agents": {
|
"llm-agents": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"bun2nix": "bun2nix",
|
"bun2nix": "bun2nix_2",
|
||||||
"flake-parts": "flake-parts_2",
|
"flake-parts": "flake-parts_3",
|
||||||
"nixpkgs": "nixpkgs_4",
|
"nixpkgs": "nixpkgs_4",
|
||||||
"systems": "systems_4",
|
"systems": "systems_5",
|
||||||
"treefmt-nix": "treefmt-nix"
|
"treefmt-nix": "treefmt-nix_2"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1785753922,
|
"lastModified": 1785826862,
|
||||||
"narHash": "sha256-cRnp7DSvT4BwRI04YSbA0Ocn1iY6+fN9KTfnsADHm3I=",
|
"narHash": "sha256-UOPf9uQHGoNqEMZ2kii8DqlPBd5dYR6uERzdU8wdroQ=",
|
||||||
"owner": "numtide",
|
"owner": "numtide",
|
||||||
"repo": "llm-agents.nix",
|
"repo": "llm-agents.nix",
|
||||||
"rev": "8a86f04f5cfbffc5b5d0b38ac24795ab4909b46b",
|
"rev": "fd0508ef842609ad0c6f5af46c6f572214efebd9",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -578,11 +658,29 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"nani-translate-linux": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": "nixpkgs_5"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1785857772,
|
||||||
|
"narHash": "sha256-JMEQH9x8Pb9cHW4JbWfFBcqxsh4JkPDR5k8dCnphUTU=",
|
||||||
|
"ref": "refs/heads/main",
|
||||||
|
"rev": "9d6fec627a620841c27c7e67e8e7b5719ce9b465",
|
||||||
|
"revCount": 8,
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/zunoser/nani-translate-linux.git"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/zunoser/nani-translate-linux.git"
|
||||||
|
}
|
||||||
|
},
|
||||||
"niri-flake": {
|
"niri-flake": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"niri-stable": "niri-stable",
|
"niri-stable": "niri-stable",
|
||||||
"niri-unstable": "niri-unstable",
|
"niri-unstable": "niri-unstable",
|
||||||
"nixpkgs": "nixpkgs_5",
|
"nixpkgs": "nixpkgs_6",
|
||||||
"nixpkgs-stable": "nixpkgs-stable",
|
"nixpkgs-stable": "nixpkgs-stable",
|
||||||
"xwayland-satellite-stable": "xwayland-satellite-stable",
|
"xwayland-satellite-stable": "xwayland-satellite-stable",
|
||||||
"xwayland-satellite-unstable": "xwayland-satellite-unstable"
|
"xwayland-satellite-unstable": "xwayland-satellite-unstable"
|
||||||
@@ -698,7 +796,7 @@
|
|||||||
},
|
},
|
||||||
"nixos-hardware": {
|
"nixos-hardware": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": "nixpkgs_6"
|
"nixpkgs": "nixpkgs_7"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1785232496,
|
"lastModified": 1785232496,
|
||||||
@@ -718,7 +816,7 @@
|
|||||||
"nixos-wsl": {
|
"nixos-wsl": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-compat": "flake-compat_4",
|
"flake-compat": "flake-compat_4",
|
||||||
"nixpkgs": "nixpkgs_7"
|
"nixpkgs": "nixpkgs_8"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1784642409,
|
"lastModified": 1784642409,
|
||||||
@@ -765,6 +863,21 @@
|
|||||||
"type": "github"
|
"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-libxml2": {
|
"nixpkgs-libxml2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1751274312,
|
"lastModified": 1751274312,
|
||||||
@@ -814,6 +927,19 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs_10": {
|
"nixpkgs_10": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1785571196,
|
||||||
|
"narHash": "sha256-xwSqxTsama0YTtS78+4YyCm6jJg09v78QWfP1cAyoVA=",
|
||||||
|
"rev": "148bab9c1c3c53136ecb44a6ea356a0ed5b39b06",
|
||||||
|
"type": "tarball",
|
||||||
|
"url": "https://releases.nixos.org/nixos/unstable/nixos-26.11pre1045728.148bab9c1c3c/nixexprs.tar.xz"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"type": "tarball",
|
||||||
|
"url": "https://channels.nixos.org/nixos-unstable/nixexprs.tar.xz"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_11": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1770107345,
|
"lastModified": 1770107345,
|
||||||
"narHash": "sha256-tbS0Ebx2PiA1FRW8mt8oejR0qMXmziJmPaU1d4kYY9g=",
|
"narHash": "sha256-tbS0Ebx2PiA1FRW8mt8oejR0qMXmziJmPaU1d4kYY9g=",
|
||||||
@@ -829,7 +955,7 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs_11": {
|
"nixpkgs_12": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772542754,
|
"lastModified": 1772542754,
|
||||||
"narHash": "sha256-WGV2hy+VIeQsYXpsLjdr4GvHv5eECMISX1zKLTedhdg=",
|
"narHash": "sha256-WGV2hy+VIeQsYXpsLjdr4GvHv5eECMISX1zKLTedhdg=",
|
||||||
@@ -845,7 +971,7 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs_12": {
|
"nixpkgs_13": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1778869304,
|
"lastModified": 1778869304,
|
||||||
"narHash": "sha256-30sZNZoA1cqF5JNO9fVX+wgiQYjB7HJqqJ4ztCDeBZE=",
|
"narHash": "sha256-30sZNZoA1cqF5JNO9fVX+wgiQYjB7HJqqJ4ztCDeBZE=",
|
||||||
@@ -892,11 +1018,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs_4": {
|
"nixpkgs_4": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1785602060,
|
"lastModified": 1785747939,
|
||||||
"narHash": "sha256-z7D96eESRM4CPV/XtwpwFn8IDdfLAmxz6lVWrGYXvR4=",
|
"narHash": "sha256-D740uKsMbgsfK2oaDenJLLPIZfq7W0/g4KN/Fls8eKs=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "a5cbcfe954791221bfffe2307f7d1a1bf61a871e",
|
"rev": "104240a772428cc2e20d8fd86c9ddbb886bbaff2",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -907,6 +1033,22 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs_5": {
|
"nixpkgs_5": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1785454630,
|
||||||
|
"narHash": "sha256-LQy14TZp77TwbQf40gg1V3jo8FwJG0jGDkAH+zRHqg8=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "1559d3daa3ecc813a650b79375ea61b6741b8746",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_6": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1785692966,
|
"lastModified": 1785692966,
|
||||||
"narHash": "sha256-vUfIeBEfpbAfZ5zjgIkYk7eHBeVfCYVjLbWnMkseYnk=",
|
"narHash": "sha256-vUfIeBEfpbAfZ5zjgIkYk7eHBeVfCYVjLbWnMkseYnk=",
|
||||||
@@ -922,7 +1064,7 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs_6": {
|
"nixpkgs_7": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1767892417,
|
"lastModified": 1767892417,
|
||||||
"narHash": "sha256-8bW3q88CEg2u4hSP66Vf4lpbLonHz7hqDNBMcCY7E9U=",
|
"narHash": "sha256-8bW3q88CEg2u4hSP66Vf4lpbLonHz7hqDNBMcCY7E9U=",
|
||||||
@@ -935,7 +1077,7 @@
|
|||||||
"url": "https://channels.nixos.org/nixos-unstable/nixexprs.tar.xz"
|
"url": "https://channels.nixos.org/nixos-unstable/nixexprs.tar.xz"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs_7": {
|
"nixpkgs_8": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1783776592,
|
"lastModified": 1783776592,
|
||||||
"narHash": "sha256-UgCQzxeWI75XM8G+hPrPh+MKzEPjG3SpAj7dtqSbksA=",
|
"narHash": "sha256-UgCQzxeWI75XM8G+hPrPh+MKzEPjG3SpAj7dtqSbksA=",
|
||||||
@@ -951,13 +1093,13 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs_8": {
|
"nixpkgs_9": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1785599192,
|
"lastModified": 1785734586,
|
||||||
"narHash": "sha256-dg4RTtDxnXY13UkJNdhmgTUTl0n/IJBlCigfO7nutZw=",
|
"narHash": "sha256-ODZkEK9Gy50yg6h98u7KkitZ3oc/uuTFK00bh1CRdNA=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "6d65bfc1bcef2ef39a239d38e577e92a89fb0f07",
|
"rev": "531670d871c0e29724a02f3cbcac170adc65b58c",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -967,26 +1109,13 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs_9": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1785571196,
|
|
||||||
"narHash": "sha256-xwSqxTsama0YTtS78+4YyCm6jJg09v78QWfP1cAyoVA=",
|
|
||||||
"rev": "148bab9c1c3c53136ecb44a6ea356a0ed5b39b06",
|
|
||||||
"type": "tarball",
|
|
||||||
"url": "https://releases.nixos.org/nixos/unstable/nixos-26.11pre1045728.148bab9c1c3c/nixexprs.tar.xz"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"type": "tarball",
|
|
||||||
"url": "https://channels.nixos.org/nixos-unstable/nixexprs.tar.xz"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixvim": {
|
"nixvim": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-parts": "flake-parts_3",
|
"flake-parts": "flake-parts_4",
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
"nixpkgs"
|
"nixpkgs"
|
||||||
],
|
],
|
||||||
"systems": "systems_5"
|
"systems": "systems_6"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1782919967,
|
"lastModified": 1782919967,
|
||||||
@@ -1005,14 +1134,14 @@
|
|||||||
},
|
},
|
||||||
"noctalia": {
|
"noctalia": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": "nixpkgs_9"
|
"nixpkgs": "nixpkgs_10"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1785767538,
|
"lastModified": 1785809412,
|
||||||
"narHash": "sha256-9foQ31PSKpIu8UWGalt+4G5o4TU21g4a1qwMwJmeOy4=",
|
"narHash": "sha256-QbFIduUhpNIucJy/WcwRxsvTQocnwIXlSwnYEjmGMSQ=",
|
||||||
"owner": "noctalia-dev",
|
"owner": "noctalia-dev",
|
||||||
"repo": "noctalia",
|
"repo": "noctalia",
|
||||||
"rev": "50f0f095053a4b5c10874c4e7080f55dc15d3b38",
|
"rev": "e41c99439605df6d2fa62409139f96ded6ac7345",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -1077,24 +1206,26 @@
|
|||||||
"flake-parts": "flake-parts",
|
"flake-parts": "flake-parts",
|
||||||
"ghostty": "ghostty",
|
"ghostty": "ghostty",
|
||||||
"git-hooks-nix": "git-hooks-nix",
|
"git-hooks-nix": "git-hooks-nix",
|
||||||
|
"handy": "handy",
|
||||||
"home-manager": "home-manager_2",
|
"home-manager": "home-manager_2",
|
||||||
"lanzaboote": "lanzaboote",
|
"lanzaboote": "lanzaboote",
|
||||||
"llm-agents": "llm-agents",
|
"llm-agents": "llm-agents",
|
||||||
|
"nani-translate-linux": "nani-translate-linux",
|
||||||
"niri-flake": "niri-flake",
|
"niri-flake": "niri-flake",
|
||||||
"nix-darwin": "nix-darwin",
|
"nix-darwin": "nix-darwin",
|
||||||
"nix-hazkey": "nix-hazkey",
|
"nix-hazkey": "nix-hazkey",
|
||||||
"nix-index-database": "nix-index-database",
|
"nix-index-database": "nix-index-database",
|
||||||
"nixos-hardware": "nixos-hardware",
|
"nixos-hardware": "nixos-hardware",
|
||||||
"nixos-wsl": "nixos-wsl",
|
"nixos-wsl": "nixos-wsl",
|
||||||
"nixpkgs": "nixpkgs_8",
|
"nixpkgs": "nixpkgs_9",
|
||||||
"nixpkgs-unstable": "nixpkgs-unstable",
|
"nixpkgs-unstable": "nixpkgs-unstable",
|
||||||
"nixvim": "nixvim",
|
"nixvim": "nixvim",
|
||||||
"noctalia": "noctalia",
|
"noctalia": "noctalia",
|
||||||
"services-flake": "services-flake",
|
"services-flake": "services-flake",
|
||||||
"sops-nix": "sops-nix",
|
"sops-nix": "sops-nix",
|
||||||
"stylix": "stylix",
|
"stylix": "stylix",
|
||||||
"systems": "systems_7",
|
"systems": "systems_8",
|
||||||
"treefmt-nix": "treefmt-nix_2",
|
"treefmt-nix": "treefmt-nix_3",
|
||||||
"vicinae": "vicinae",
|
"vicinae": "vicinae",
|
||||||
"vicinae-extensions": "vicinae-extensions"
|
"vicinae-extensions": "vicinae-extensions"
|
||||||
}
|
}
|
||||||
@@ -1157,7 +1288,7 @@
|
|||||||
},
|
},
|
||||||
"soulver-cpp": {
|
"soulver-cpp": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": "nixpkgs_12",
|
"nixpkgs": "nixpkgs_13",
|
||||||
"nixpkgs-libxml2": "nixpkgs-libxml2"
|
"nixpkgs-libxml2": "nixpkgs-libxml2"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
@@ -1181,24 +1312,24 @@
|
|||||||
"base16-helix": "base16-helix",
|
"base16-helix": "base16-helix",
|
||||||
"base16-vim": "base16-vim",
|
"base16-vim": "base16-vim",
|
||||||
"firefox-gnome-theme": "firefox-gnome-theme",
|
"firefox-gnome-theme": "firefox-gnome-theme",
|
||||||
"flake-parts": "flake-parts_4",
|
"flake-parts": "flake-parts_5",
|
||||||
"gnome-shell": "gnome-shell",
|
"gnome-shell": "gnome-shell",
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
"nixpkgs"
|
"nixpkgs"
|
||||||
],
|
],
|
||||||
"nur": "nur",
|
"nur": "nur",
|
||||||
"systems": "systems_6",
|
"systems": "systems_7",
|
||||||
"tinted-kitty": "tinted-kitty",
|
"tinted-kitty": "tinted-kitty",
|
||||||
"tinted-schemes": "tinted-schemes",
|
"tinted-schemes": "tinted-schemes",
|
||||||
"tinted-tmux": "tinted-tmux",
|
"tinted-tmux": "tinted-tmux",
|
||||||
"tinted-zed": "tinted-zed"
|
"tinted-zed": "tinted-zed"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1785680312,
|
"lastModified": 1785794750,
|
||||||
"narHash": "sha256-e26BuraMqnara0VXVk9nsQLgGC+8nvEgYNc6odv5Yi8=",
|
"narHash": "sha256-OqIrGVL7AX462ISyJFAqjbqTc1RZlBkVHCa4dwPEZU4=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "stylix",
|
"repo": "stylix",
|
||||||
"rev": "04b284060ffa638f080ab1b2d05cf1f236217995",
|
"rev": "cb5eb3a7343faba61fd694fac8040a326485a339",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -1222,6 +1353,21 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"systems_10": {
|
||||||
|
"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": {
|
"systems_2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1681028828,
|
"lastModified": 1681028828,
|
||||||
@@ -1284,6 +1430,21 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"systems_6": {
|
"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"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"systems_7": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1774449309,
|
"lastModified": 1774449309,
|
||||||
"narHash": "sha256-brhZ8DmuGtzkCYHJg4HEd602amKm89Y9ytsFZ5uWD1w=",
|
"narHash": "sha256-brhZ8DmuGtzkCYHJg4HEd602amKm89Y9ytsFZ5uWD1w=",
|
||||||
@@ -1299,21 +1460,6 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"systems_7": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1681028828,
|
|
||||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default",
|
|
||||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"systems_8": {
|
"systems_8": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1681028828,
|
"lastModified": 1681028828,
|
||||||
@@ -1409,6 +1555,28 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"treefmt-nix": {
|
"treefmt-nix": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"handy",
|
||||||
|
"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": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
"llm-agents",
|
"llm-agents",
|
||||||
@@ -1429,9 +1597,9 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"treefmt-nix_2": {
|
"treefmt-nix_3": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": "nixpkgs_10"
|
"nixpkgs": "nixpkgs_11"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1785360170,
|
"lastModified": 1785360170,
|
||||||
@@ -1449,16 +1617,16 @@
|
|||||||
},
|
},
|
||||||
"vicinae": {
|
"vicinae": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": "nixpkgs_11",
|
"nixpkgs": "nixpkgs_12",
|
||||||
"soulver-cpp": "soulver-cpp",
|
"soulver-cpp": "soulver-cpp",
|
||||||
"systems": "systems_8"
|
"systems": "systems_9"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1785733880,
|
"lastModified": 1785823793,
|
||||||
"narHash": "sha256-Rv4rVFSvxF7ViOQOrv+N8IEvweS5MCqUM2fnaQVIR+w=",
|
"narHash": "sha256-iGKyp+peQzXI0T9LzYmRHr2tevkbhF5GfzDlVldVm2Q=",
|
||||||
"owner": "vicinaehq",
|
"owner": "vicinaehq",
|
||||||
"repo": "vicinae",
|
"repo": "vicinae",
|
||||||
"rev": "61bd7cd5c9cdd6d8df6e6d34531beb344219ff71",
|
"rev": "b3130be7b480817d2255b4781476a91593267afb",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -1473,7 +1641,7 @@
|
|||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
"nixpkgs"
|
"nixpkgs"
|
||||||
],
|
],
|
||||||
"systems": "systems_9",
|
"systems": "systems_10",
|
||||||
"vicinae": "vicinae_2"
|
"vicinae": "vicinae_2"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
|
|||||||
@@ -38,6 +38,12 @@
|
|||||||
url = "github:ghostty-org/ghostty";
|
url = "github:ghostty-org/ghostty";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Speech to text
|
||||||
|
handy = {
|
||||||
|
url = "github:cjpais/Handy";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
|
||||||
# Shell / Launcher
|
# Shell / Launcher
|
||||||
vicinae.url = "github:vicinaehq/vicinae";
|
vicinae.url = "github:vicinaehq/vicinae";
|
||||||
|
|
||||||
@@ -104,6 +110,9 @@
|
|||||||
url = "github:nix-community/browser-previews";
|
url = "github:nix-community/browser-previews";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
nani-translate-linux.url = "git+https://github.com/zunoser/nani-translate-linux.git";
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs =
|
outputs =
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
homebrew.casks = [ "activitywatch" ];
|
||||||
|
|
||||||
|
launchd.agents.activitywatch = {
|
||||||
|
command = "/usr/bin/open -gja ActivityWatch";
|
||||||
|
serviceConfig.RunAtLoad = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
services.activitywatch = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
watchers.aw-awatcher = {
|
||||||
|
package = pkgs.awatcher;
|
||||||
|
executable = "awatcher";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
description = "ActivityWatch automated time tracker";
|
||||||
|
}
|
||||||
@@ -1,7 +1,12 @@
|
|||||||
{ pkgs, ... }:
|
{ inputs, pkgs, ... }:
|
||||||
{
|
{
|
||||||
|
|
||||||
services.hazkey.enable = true;
|
services.hazkey = {
|
||||||
|
enable = true;
|
||||||
|
server.package =
|
||||||
|
inputs.nix-hazkey.packages.${pkgs.stdenv.hostPlatform.system}.hazkey-server.override
|
||||||
|
{ enableVulkan = true; };
|
||||||
|
};
|
||||||
|
|
||||||
i18n.inputMethod = {
|
i18n.inputMethod = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ _: {
|
|||||||
theme = "dracula";
|
theme = "dracula";
|
||||||
background-blur-radius = 20;
|
background-blur-radius = 20;
|
||||||
background-opacity = 0.9;
|
background-opacity = 0.9;
|
||||||
|
background-opacity-cells = true;
|
||||||
font-family = "BlexMono Nerd Font Mono";
|
font-family = "BlexMono Nerd Font Mono";
|
||||||
mouse-hide-while-typing = true;
|
mouse-hide-while-typing = true;
|
||||||
window-decoration = "auto";
|
window-decoration = "auto";
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
homebrew.casks = [ "handy" ];
|
||||||
|
|
||||||
|
launchd.agents.handy = {
|
||||||
|
command = "/usr/bin/open -gja Handy --args --start-hidden";
|
||||||
|
serviceConfig.RunAtLoad = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
inputs,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
handy = inputs.handy.packages.${pkgs.stdenv.hostPlatform.system}.handy;
|
||||||
|
settingsFile = "${config.xdg.configHome}/com.pais.handy/settings_store.json";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
home.packages = [
|
||||||
|
handy
|
||||||
|
pkgs.wtype
|
||||||
|
];
|
||||||
|
|
||||||
|
# Handy has no disabled-shortcut setting. Empty bindings are rejected before
|
||||||
|
# registration, leaving niri and labwc as the sole owners of Ctrl+Space.
|
||||||
|
home.activation.disableHandyGlobalShortcuts = {
|
||||||
|
after = [ "writeBoundary" ];
|
||||||
|
before = [ ];
|
||||||
|
data = ''
|
||||||
|
settingsFile=${lib.escapeShellArg settingsFile}
|
||||||
|
mkdir -p "$(dirname "$settingsFile")"
|
||||||
|
|
||||||
|
if [ -f "$settingsFile" ]; then
|
||||||
|
${lib.getExe pkgs.jq} \
|
||||||
|
'.settings.bindings.transcribe.current_binding = ""
|
||||||
|
| .settings.bindings.transcribe_with_post_process.current_binding = ""' \
|
||||||
|
"$settingsFile" > "$settingsFile.tmp"
|
||||||
|
else
|
||||||
|
${lib.getExe pkgs.jq} -n '
|
||||||
|
{
|
||||||
|
settings: {
|
||||||
|
bindings: {
|
||||||
|
transcribe: {
|
||||||
|
id: "transcribe",
|
||||||
|
name: "Transcribe",
|
||||||
|
description: "Converts your speech into text.",
|
||||||
|
default_binding: "ctrl+space",
|
||||||
|
current_binding: ""
|
||||||
|
},
|
||||||
|
transcribe_with_post_process: {
|
||||||
|
id: "transcribe_with_post_process",
|
||||||
|
name: "Transcribe with Post-Processing",
|
||||||
|
description: "Converts your speech into text and applies AI post-processing.",
|
||||||
|
default_binding: "ctrl+shift+space",
|
||||||
|
current_binding: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
' > "$settingsFile.tmp"
|
||||||
|
fi
|
||||||
|
|
||||||
|
mv "$settingsFile.tmp" "$settingsFile"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.user.services.handy = {
|
||||||
|
Unit = {
|
||||||
|
Description = "Handy speech-to-text";
|
||||||
|
After = [ "graphical-session.target" ];
|
||||||
|
PartOf = [ "graphical-session.target" ];
|
||||||
|
};
|
||||||
|
Service = {
|
||||||
|
ExecStart = "${lib.getExe handy} --start-hidden";
|
||||||
|
Restart = "on-failure";
|
||||||
|
RestartSec = 5;
|
||||||
|
};
|
||||||
|
Install.WantedBy = [ "graphical-session.target" ];
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
description = "Handy offline speech-to-text";
|
||||||
|
}
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
{ lib, pkgs, ... }:
|
{ lib, pkgs, ... }:
|
||||||
let
|
let
|
||||||
screenshot = import ./screenshot.nix { inherit pkgs; };
|
|
||||||
|
|
||||||
systemctl = lib.getExe' pkgs.systemd "systemctl";
|
systemctl = lib.getExe' pkgs.systemd "systemctl";
|
||||||
|
|
||||||
keybind = key: actionAttrs: {
|
keybind = key: actionAttrs: {
|
||||||
@@ -62,8 +60,6 @@ let
|
|||||||
};
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
home.packages = [ screenshot ];
|
|
||||||
|
|
||||||
wayland.windowManager.labwc = {
|
wayland.windowManager.labwc = {
|
||||||
enable = true;
|
enable = true;
|
||||||
# NixOS owns the package so Home Manager only generates the user config.
|
# NixOS owns the package so Home Manager only generates the user config.
|
||||||
@@ -117,9 +113,9 @@ in
|
|||||||
(snapToEdge "W-C-Up" "up")
|
(snapToEdge "W-C-Up" "up")
|
||||||
(snapToEdge "W-C-Down" "down")
|
(snapToEdge "W-C-Down" "down")
|
||||||
(confirmAction "W-S-e" "Exit labwc?" "Exit")
|
(confirmAction "W-S-e" "Exit labwc?" "Exit")
|
||||||
(execute "Print" "labwc-screenshot region")
|
(execute "Print" "screenshot region")
|
||||||
(execute "C-Print" "labwc-screenshot output")
|
(execute "C-Print" "screenshot output")
|
||||||
(execute "A-Print" "labwc-screenshot all")
|
(execute "A-Print" "screenshot all")
|
||||||
|
|
||||||
# spawn applications (sync with niri modules/applications/niri/home.nix)
|
# spawn applications (sync with niri modules/applications/niri/home.nix)
|
||||||
(execute "W-t" "ghostty")
|
(execute "W-t" "ghostty")
|
||||||
@@ -128,8 +124,13 @@ in
|
|||||||
(execute "W-e" "nautilus --new-window")
|
(execute "W-e" "nautilus --new-window")
|
||||||
(execute "W-l" "loginctl lock-session")
|
(execute "W-l" "loginctl lock-session")
|
||||||
(execute "W-v" "vicinae vicinae://launch/clipboard/history?toggle=true")
|
(execute "W-v" "vicinae vicinae://launch/clipboard/history?toggle=true")
|
||||||
|
(execute "W-j" "nani-translate-primary")
|
||||||
|
(execute "W-S-j" "normcap-translate")
|
||||||
|
(execute "W-C-j" "${lib.getExe' pkgs.xdg-utils "xdg-open"} naniapp://translate")
|
||||||
(execute "W-space" "ghostty +toggle-quick-terminal")
|
(execute "W-space" "ghostty +toggle-quick-terminal")
|
||||||
(execute "W-p" "wdisplays")
|
(execute "W-p" "wdisplays")
|
||||||
|
(execute "W-z" "wl-find-cursor -c 0xCCFF453A -s 160 -d 1200")
|
||||||
|
(execute "C-space" "handy --toggle-transcription")
|
||||||
|
|
||||||
# Function keys (sync with niri modules/applications/niri/home.nix)
|
# Function keys (sync with niri modules/applications/niri/home.nix)
|
||||||
(execute "XF86AudioRaiseVolume" "noctalia msg volume-up")
|
(execute "XF86AudioRaiseVolume" "noctalia msg volume-up")
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
{
|
{
|
||||||
description = "labwc Wayland stacking compositor";
|
description = "labwc Wayland stacking compositor";
|
||||||
|
|
||||||
includes = [ "systems.wayland" ];
|
includes = [
|
||||||
|
"systems.wayland"
|
||||||
|
"applications.screenshot"
|
||||||
|
"applications.wl-find-cursor"
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,36 @@
|
|||||||
{
|
{
|
||||||
|
inputs,
|
||||||
lib,
|
lib,
|
||||||
|
pkgs,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
|
let
|
||||||
|
unstable = inputs.nixpkgs-unstable.legacyPackages.${pkgs.stdenv.hostPlatform.system};
|
||||||
|
labwc = unstable.labwc.overrideAttrs (oldAttrs: {
|
||||||
|
patches = (oldAttrs.patches or [ ]) ++ [
|
||||||
|
./patches/remove-ext-workspace-output-on-destroy.patch
|
||||||
|
];
|
||||||
|
});
|
||||||
|
in
|
||||||
{
|
{
|
||||||
programs.labwc = {
|
programs.labwc = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
package = labwc;
|
||||||
|
};
|
||||||
|
|
||||||
|
xdg.portal.config.labwc.default = [
|
||||||
|
"wlr"
|
||||||
|
"gtk"
|
||||||
|
];
|
||||||
|
|
||||||
|
# xdg-desktop-portal-wlr implements screencasting for wlroots compositors.
|
||||||
|
# Keep it with Labwc: Niri uses xdg-desktop-portal-gnome instead.
|
||||||
|
xdg.portal.wlr = {
|
||||||
|
enable = true;
|
||||||
|
settings.screencast = {
|
||||||
|
chooser_type = "dmenu";
|
||||||
|
chooser_cmd = "${pkgs.fuzzel}/bin/fuzzel --dmenu";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# NixOS decides whether a graphical session manages graphical-session.target
|
# NixOS decides whether a graphical session manages graphical-session.target
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
From: Codex <[email protected]>
|
||||||
|
Subject: [PATCH] output: remove destroyed output from ext-workspace group
|
||||||
|
|
||||||
|
The DRM backend destroys and recreates outputs when a session is paused and
|
||||||
|
resumed. Remove the output from the ext-workspace group before wlroots
|
||||||
|
finishes it, otherwise the group's output_bind listener remains attached and
|
||||||
|
wlr_output_finish() aborts.
|
||||||
|
|
||||||
|
---
|
||||||
|
src/output.c | 3 +++
|
||||||
|
1 file changed, 3 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/output.c b/src/output.c
|
||||||
|
index 2eab8ec..f19c3ff 100644
|
||||||
|
--- a/src/output.c
|
||||||
|
+++ b/src/output.c
|
||||||
|
@@ -277,6 +277,9 @@ handle_output_destroy(struct wl_listener *listener, void *data)
|
||||||
|
struct seat *seat = &server.seat;
|
||||||
|
regions_evacuate_output(output);
|
||||||
|
regions_destroy(seat, &output->regions);
|
||||||
|
+ wlr_ext_workspace_group_handle_v1_output_leave(
|
||||||
|
+ server.workspaces.ext_group, output->wlr_output);
|
||||||
|
+
|
||||||
|
if (seat->overlay.active.output == output) {
|
||||||
|
overlay_finish(seat);
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.51.0
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
{ pkgs }:
|
|
||||||
|
|
||||||
pkgs.writeShellApplication {
|
|
||||||
name = "labwc-screenshot";
|
|
||||||
|
|
||||||
runtimeInputs = with pkgs; [
|
|
||||||
coreutils
|
|
||||||
grim
|
|
||||||
slurp
|
|
||||||
wl-clipboard
|
|
||||||
xdg-user-dirs
|
|
||||||
];
|
|
||||||
|
|
||||||
text = ''
|
|
||||||
mode="''${1:-region}"
|
|
||||||
|
|
||||||
pictures_dir="$(xdg-user-dir PICTURES)"
|
|
||||||
if [[ -z "$pictures_dir" ]]; then
|
|
||||||
pictures_dir="$HOME/Pictures"
|
|
||||||
fi
|
|
||||||
|
|
||||||
output_dir="$pictures_dir/Screenshots"
|
|
||||||
output_file="$output_dir/Screenshot from $(date '+%Y-%m-%d %H-%M-%S').png"
|
|
||||||
|
|
||||||
mkdir -p "$output_dir"
|
|
||||||
|
|
||||||
case "$mode" in
|
|
||||||
region)
|
|
||||||
geometry="$(slurp)" || exit 0
|
|
||||||
grim -g "$geometry" "$output_file"
|
|
||||||
;;
|
|
||||||
|
|
||||||
output)
|
|
||||||
geometry="$(slurp -o)" || exit 0
|
|
||||||
grim -g "$geometry" "$output_file"
|
|
||||||
;;
|
|
||||||
|
|
||||||
all)
|
|
||||||
grim "$output_file"
|
|
||||||
;;
|
|
||||||
|
|
||||||
*)
|
|
||||||
echo "Unknown screenshot mode: $mode" >&2
|
|
||||||
exit 2
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
wl-copy --type image/png < "$output_file"
|
|
||||||
'';
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,167 @@
|
|||||||
|
# shellcheck shell=bash
|
||||||
|
|
||||||
|
set -o errexit -o nounset -o pipefail
|
||||||
|
|
||||||
|
playlist_file="$1"
|
||||||
|
default_id="$2"
|
||||||
|
configuration_id="$3"
|
||||||
|
shift 3
|
||||||
|
|
||||||
|
state_dir="${XDG_RUNTIME_DIR:?}/linux-wallpaperengine"
|
||||||
|
state_file="$state_dir/current"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
printf '%s\n' \
|
||||||
|
'Usage: wallpaperengine-wallpaper COMMAND [ID]' \
|
||||||
|
'' \
|
||||||
|
'Commands:' \
|
||||||
|
' select ID Select a declaratively configured ID for this session' \
|
||||||
|
' next Select the next configured ID' \
|
||||||
|
' previous Select the previous configured ID' \
|
||||||
|
' list List configured IDs and mark the selected one' \
|
||||||
|
' current Print the selected ID' \
|
||||||
|
' restart Restart the selected wallpaper' \
|
||||||
|
' stop Stop Wallpaper Engine for this session'
|
||||||
|
}
|
||||||
|
|
||||||
|
load_playlist() {
|
||||||
|
mapfile -t wallpaper_ids < <(awk '/^[0-9]+$/ && !seen[$0]++' "$playlist_file")
|
||||||
|
if [ "${#wallpaper_ids[@]}" -eq 0 ]; then
|
||||||
|
echo "wallpaperengine-wallpaper: no wallpaper IDs are configured in settings.nix" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
contains_id() {
|
||||||
|
local candidate="$1"
|
||||||
|
local id
|
||||||
|
|
||||||
|
for id in "${wallpaper_ids[@]}"; do
|
||||||
|
[ "$id" = "$candidate" ] && return 0
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
current_id() {
|
||||||
|
local saved_configuration=""
|
||||||
|
local saved_id=""
|
||||||
|
local -a saved_state=()
|
||||||
|
|
||||||
|
if [ -s "$state_file" ]; then
|
||||||
|
mapfile -t saved_state <"$state_file"
|
||||||
|
saved_configuration="${saved_state[0]:-}"
|
||||||
|
saved_id="${saved_state[1]:-}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$saved_configuration" = "$configuration_id" ] && contains_id "$saved_id"; then
|
||||||
|
printf '%s\n' "$saved_id"
|
||||||
|
else
|
||||||
|
printf '%s\n' "$default_id"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
select_id() {
|
||||||
|
local id="$1"
|
||||||
|
|
||||||
|
if ! contains_id "$id"; then
|
||||||
|
echo "wallpaperengine-wallpaper: ID is not declared in settings.nix: $id" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$state_dir"
|
||||||
|
printf '%s\n%s\n' "$configuration_id" "$id" >"$state_file"
|
||||||
|
systemctl --user restart linux-wallpaperengine.service
|
||||||
|
}
|
||||||
|
|
||||||
|
cycle() {
|
||||||
|
local step="$1"
|
||||||
|
local current
|
||||||
|
local index=0
|
||||||
|
local next_index
|
||||||
|
|
||||||
|
current=$(current_id)
|
||||||
|
for i in "${!wallpaper_ids[@]}"; do
|
||||||
|
if [ "${wallpaper_ids[$i]}" = "$current" ]; then
|
||||||
|
index="$i"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
next_index=$(((index + step + ${#wallpaper_ids[@]}) % ${#wallpaper_ids[@]}))
|
||||||
|
select_id "${wallpaper_ids[$next_index]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
load_playlist
|
||||||
|
|
||||||
|
command="${1:-}"
|
||||||
|
if [ -z "$command" ]; then
|
||||||
|
usage
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
|
||||||
|
case "$command" in
|
||||||
|
select)
|
||||||
|
[ "$#" -eq 1 ] || {
|
||||||
|
usage >&2
|
||||||
|
exit 2
|
||||||
|
}
|
||||||
|
select_id "$1"
|
||||||
|
;;
|
||||||
|
next)
|
||||||
|
[ "$#" -eq 0 ] || {
|
||||||
|
usage >&2
|
||||||
|
exit 2
|
||||||
|
}
|
||||||
|
cycle 1
|
||||||
|
;;
|
||||||
|
previous)
|
||||||
|
[ "$#" -eq 0 ] || {
|
||||||
|
usage >&2
|
||||||
|
exit 2
|
||||||
|
}
|
||||||
|
cycle -1
|
||||||
|
;;
|
||||||
|
list)
|
||||||
|
[ "$#" -eq 0 ] || {
|
||||||
|
usage >&2
|
||||||
|
exit 2
|
||||||
|
}
|
||||||
|
current=$(current_id)
|
||||||
|
for id in "${wallpaper_ids[@]}"; do
|
||||||
|
if [ "$id" = "$current" ]; then
|
||||||
|
printf '* %s\n' "$id"
|
||||||
|
else
|
||||||
|
printf ' %s\n' "$id"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
current)
|
||||||
|
[ "$#" -eq 0 ] || {
|
||||||
|
usage >&2
|
||||||
|
exit 2
|
||||||
|
}
|
||||||
|
current_id
|
||||||
|
;;
|
||||||
|
restart)
|
||||||
|
[ "$#" -eq 0 ] || {
|
||||||
|
usage >&2
|
||||||
|
exit 2
|
||||||
|
}
|
||||||
|
systemctl --user restart linux-wallpaperengine.service
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
[ "$#" -eq 0 ] || {
|
||||||
|
usage >&2
|
||||||
|
exit 2
|
||||||
|
}
|
||||||
|
systemctl --user stop linux-wallpaperengine.service
|
||||||
|
;;
|
||||||
|
help | -h | --help)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
usage >&2
|
||||||
|
exit 2
|
||||||
|
;;
|
||||||
|
esac
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
# shellcheck shell=bash
|
||||||
|
|
||||||
|
set -o errexit -o nounset -o pipefail
|
||||||
|
|
||||||
|
playlist_file="$1"
|
||||||
|
default_id="$2"
|
||||||
|
configuration_id="$3"
|
||||||
|
assets_dir="$4"
|
||||||
|
workshop_dir="$5"
|
||||||
|
scaling="$6"
|
||||||
|
shift 6
|
||||||
|
|
||||||
|
state_file="${XDG_RUNTIME_DIR:?}/linux-wallpaperengine/current"
|
||||||
|
wallpaper_id="$default_id"
|
||||||
|
saved_configuration=""
|
||||||
|
saved_id=""
|
||||||
|
saved_state=()
|
||||||
|
outputs=()
|
||||||
|
|
||||||
|
if [ -s "$state_file" ]; then
|
||||||
|
mapfile -t saved_state <"$state_file"
|
||||||
|
saved_configuration="${saved_state[0]:-}"
|
||||||
|
saved_id="${saved_state[1]:-}"
|
||||||
|
|
||||||
|
if [ "$saved_configuration" = "$configuration_id" ] &&
|
||||||
|
awk -v id="$saved_id" '$0 == id { found = 1 } END { exit !found }' "$playlist_file"; then
|
||||||
|
wallpaper_id="$saved_id"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
wallpaper_path="$workshop_dir/$wallpaper_id"
|
||||||
|
if [ ! -d "$wallpaper_path" ]; then
|
||||||
|
echo "linux-wallpaperengine: missing declared wallpaper: $wallpaper_path" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -d "$assets_dir" ]; then
|
||||||
|
echo "linux-wallpaperengine: missing Wallpaper Engine assets: $assets_dir" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mapfile -t outputs < <(wlr-randr --json | jq -r '.[] | select(.enabled == true) | .name')
|
||||||
|
if [ "${#outputs[@]}" -eq 0 ]; then
|
||||||
|
echo "linux-wallpaperengine: no enabled Wayland outputs were detected" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
engine_args=("$@" --assets-dir "$assets_dir")
|
||||||
|
for output in "${outputs[@]}"; do
|
||||||
|
engine_args+=(
|
||||||
|
--screen-root "$output"
|
||||||
|
--bg "$wallpaper_path"
|
||||||
|
--scaling "$scaling"
|
||||||
|
)
|
||||||
|
done
|
||||||
|
|
||||||
|
exec linux-wallpaperengine "${engine_args[@]}"
|
||||||
@@ -0,0 +1,158 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
settings = import ../settings.nix;
|
||||||
|
inherit (settings)
|
||||||
|
assetsDirectory
|
||||||
|
fps
|
||||||
|
mute
|
||||||
|
scaling
|
||||||
|
selectedWallpaperId
|
||||||
|
switchIntervalSeconds
|
||||||
|
wallpaperIds
|
||||||
|
workshopDirectory
|
||||||
|
;
|
||||||
|
|
||||||
|
resolveHomePath =
|
||||||
|
path:
|
||||||
|
if lib.hasPrefix "~/" path then
|
||||||
|
"${config.home.homeDirectory}/${lib.removePrefix "~/" path}"
|
||||||
|
else if lib.hasPrefix "/" path then
|
||||||
|
path
|
||||||
|
else
|
||||||
|
"${config.home.homeDirectory}/${path}";
|
||||||
|
|
||||||
|
hasWallpapers = wallpaperIds != [ ];
|
||||||
|
defaultWallpaperId =
|
||||||
|
if selectedWallpaperId != null then
|
||||||
|
selectedWallpaperId
|
||||||
|
else if hasWallpapers then
|
||||||
|
lib.head wallpaperIds
|
||||||
|
else
|
||||||
|
"";
|
||||||
|
configurationId = builtins.hashString "sha256" (builtins.toJSON settings);
|
||||||
|
resolvedAssetsDirectory = resolveHomePath assetsDirectory;
|
||||||
|
resolvedWorkshopDirectory = resolveHomePath workshopDirectory;
|
||||||
|
playlist = pkgs.writeText "linux-wallpaperengine-playlist" (
|
||||||
|
lib.concatMapStringsSep "\n" (id: id) wallpaperIds + "\n"
|
||||||
|
);
|
||||||
|
engineArguments = lib.optional mute "--silent" ++ [
|
||||||
|
"--fps"
|
||||||
|
(toString fps)
|
||||||
|
];
|
||||||
|
|
||||||
|
controller = pkgs.writeShellApplication {
|
||||||
|
name = "wallpaperengine-wallpaper";
|
||||||
|
runtimeInputs = [
|
||||||
|
pkgs.coreutils
|
||||||
|
pkgs.gawk
|
||||||
|
pkgs.systemd
|
||||||
|
];
|
||||||
|
text = ''
|
||||||
|
exec ${lib.getExe pkgs.bash} ${./controller.sh} \
|
||||||
|
${lib.escapeShellArg playlist} \
|
||||||
|
${lib.escapeShellArg defaultWallpaperId} \
|
||||||
|
${lib.escapeShellArg configurationId} \
|
||||||
|
"$@"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
launcher = pkgs.writeShellApplication {
|
||||||
|
name = "linux-wallpaperengine-launcher";
|
||||||
|
runtimeInputs = [
|
||||||
|
pkgs.coreutils
|
||||||
|
pkgs.gawk
|
||||||
|
pkgs.jq
|
||||||
|
pkgs.linux-wallpaperengine
|
||||||
|
pkgs.wlr-randr
|
||||||
|
];
|
||||||
|
text = ''
|
||||||
|
exec ${lib.getExe pkgs.bash} ${./launcher.sh} \
|
||||||
|
${lib.escapeShellArg playlist} \
|
||||||
|
${lib.escapeShellArg defaultWallpaperId} \
|
||||||
|
${lib.escapeShellArg configurationId} \
|
||||||
|
${lib.escapeShellArg resolvedAssetsDirectory} \
|
||||||
|
${lib.escapeShellArg resolvedWorkshopDirectory} \
|
||||||
|
${lib.escapeShellArg scaling} \
|
||||||
|
${lib.escapeShellArgs engineArguments}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
in
|
||||||
|
assert lib.assertMsg (lib.all (
|
||||||
|
id: builtins.isString id && builtins.match "[0-9]+" id != null
|
||||||
|
) wallpaperIds) "linux-wallpaperengine: wallpaperIds must contain only numeric strings";
|
||||||
|
assert lib.assertMsg (
|
||||||
|
lib.unique wallpaperIds == wallpaperIds
|
||||||
|
) "linux-wallpaperengine: wallpaperIds must not contain duplicates";
|
||||||
|
assert lib.assertMsg (
|
||||||
|
selectedWallpaperId == null || builtins.elem selectedWallpaperId wallpaperIds
|
||||||
|
) "linux-wallpaperengine: selectedWallpaperId must be null or a member of wallpaperIds";
|
||||||
|
assert lib.assertMsg (
|
||||||
|
switchIntervalSeconds == null || (builtins.isInt switchIntervalSeconds && switchIntervalSeconds > 0)
|
||||||
|
) "linux-wallpaperengine: switchIntervalSeconds must be null or a positive integer";
|
||||||
|
assert lib.assertMsg (
|
||||||
|
builtins.isInt fps && fps > 0
|
||||||
|
) "linux-wallpaperengine: fps must be a positive integer";
|
||||||
|
assert lib.assertMsg (
|
||||||
|
builtins.isString assetsDirectory && assetsDirectory != ""
|
||||||
|
) "linux-wallpaperengine: assetsDirectory must be a non-empty string";
|
||||||
|
assert lib.assertMsg (
|
||||||
|
builtins.isString workshopDirectory && workshopDirectory != ""
|
||||||
|
) "linux-wallpaperengine: workshopDirectory must be a non-empty string";
|
||||||
|
assert lib.assertMsg (builtins.elem scaling [
|
||||||
|
"default"
|
||||||
|
"fill"
|
||||||
|
"fit"
|
||||||
|
"stretch"
|
||||||
|
]) "linux-wallpaperengine: scaling must be default, fill, fit, or stretch";
|
||||||
|
{
|
||||||
|
home.packages = [
|
||||||
|
controller
|
||||||
|
pkgs.linux-wallpaperengine
|
||||||
|
];
|
||||||
|
|
||||||
|
systemd.user.services = lib.optionalAttrs hasWallpapers {
|
||||||
|
linux-wallpaperengine = {
|
||||||
|
Unit = {
|
||||||
|
Description = "Linux Wallpaper Engine";
|
||||||
|
After = [ "graphical-session.target" ];
|
||||||
|
PartOf = [ "graphical-session.target" ];
|
||||||
|
};
|
||||||
|
Service = {
|
||||||
|
ExecStart = lib.getExe launcher;
|
||||||
|
Restart = "on-abnormal";
|
||||||
|
};
|
||||||
|
Install.WantedBy = [ "graphical-session.target" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
linux-wallpaperengine-switch = {
|
||||||
|
Unit.Description = "Switch Linux Wallpaper Engine wallpaper";
|
||||||
|
Service = {
|
||||||
|
Type = "oneshot";
|
||||||
|
ExecStart = "${lib.getExe controller} next";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.user.timers =
|
||||||
|
lib.optionalAttrs
|
||||||
|
(hasWallpapers && builtins.length wallpaperIds > 1 && switchIntervalSeconds != null)
|
||||||
|
{
|
||||||
|
linux-wallpaperengine-switch = {
|
||||||
|
Unit = {
|
||||||
|
Description = "Periodically switch Linux Wallpaper Engine wallpaper";
|
||||||
|
PartOf = [ "graphical-session.target" ];
|
||||||
|
};
|
||||||
|
Timer = {
|
||||||
|
OnActiveSec = "${toString switchIntervalSeconds}s";
|
||||||
|
OnUnitActiveSec = "${toString switchIntervalSeconds}s";
|
||||||
|
Unit = "linux-wallpaperengine-switch.service";
|
||||||
|
};
|
||||||
|
Install.WantedBy = [ "graphical-session.target" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
description = "Wallpaper Engine backgrounds for Linux";
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
assetsDirectory = "~/.local/share/Steam/steamapps/common/wallpaper_engine/assets";
|
||||||
|
workshopDirectory = "~/.local/share/Steam/steamapps/workshop/content/431960";
|
||||||
|
|
||||||
|
wallpaperIds = [
|
||||||
|
"2833810156"
|
||||||
|
"2834355367"
|
||||||
|
"2836628501"
|
||||||
|
"2845095254"
|
||||||
|
"2859848175"
|
||||||
|
"2861661119"
|
||||||
|
"2982896307"
|
||||||
|
];
|
||||||
|
|
||||||
|
# null selects the first ID above.
|
||||||
|
selectedWallpaperId = null;
|
||||||
|
# Set a number such as 300 to rotate through multiple IDs.
|
||||||
|
switchIntervalSeconds = 300;
|
||||||
|
|
||||||
|
fps = 30;
|
||||||
|
mute = true;
|
||||||
|
scaling = "fill";
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
homebrew = {
|
||||||
|
enable = true;
|
||||||
|
casks = [ "nani" ];
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
_: {
|
||||||
|
programs.naniTranslateLinux.enable = true;
|
||||||
|
|
||||||
|
xdg.mimeApps.defaultApplications."x-scheme-handler/naniapp" = "nani.desktop";
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{ inputs, ... }:
|
||||||
|
{
|
||||||
|
description = "Nani Translate application";
|
||||||
|
|
||||||
|
imports.home = [
|
||||||
|
inputs.nani-translate-linux.homeManagerModules.default
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -25,6 +25,7 @@ in
|
|||||||
systemd.user.sessionVariables.NAUTILUS_4_EXTENSION_DIR = nautilusExtensionDir;
|
systemd.user.sessionVariables.NAUTILUS_4_EXTENSION_DIR = nautilusExtensionDir;
|
||||||
|
|
||||||
xdg.dataFile."nautilus-python/extensions/open-in-editor.py".text = ''
|
xdg.dataFile."nautilus-python/extensions/open-in-editor.py".text = ''
|
||||||
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
from gi.repository import GObject, Nautilus
|
from gi.repository import GObject, Nautilus
|
||||||
@@ -75,6 +76,12 @@ in
|
|||||||
|
|
||||||
return paths
|
return paths
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_working_directory(paths):
|
||||||
|
path = paths[0]
|
||||||
|
|
||||||
|
return path if os.path.isdir(path) else os.path.dirname(path)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def launch(_item, command):
|
def launch(_item, command):
|
||||||
subprocess.Popen(
|
subprocess.Popen(
|
||||||
@@ -101,6 +108,22 @@ in
|
|||||||
|
|
||||||
items.append(item)
|
items.append(item)
|
||||||
|
|
||||||
|
item = Nautilus.MenuItem(
|
||||||
|
name=f"OpenInEditor::{context}::ghostty",
|
||||||
|
label="Ghostty で開く",
|
||||||
|
)
|
||||||
|
|
||||||
|
item.connect(
|
||||||
|
"activate",
|
||||||
|
self.launch,
|
||||||
|
[
|
||||||
|
"${lib.getExe pkgs.ghostty}",
|
||||||
|
f"--working-directory={self.get_working_directory(paths)}",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
items.append(item)
|
||||||
|
|
||||||
return items
|
return items
|
||||||
|
|
||||||
def get_file_items(self, files):
|
def get_file_items(self, files):
|
||||||
|
|||||||
@@ -5,4 +5,38 @@
|
|||||||
NH_FLAKE = "${config.home.homeDirectory}/dotfiles";
|
NH_FLAKE = "${config.home.homeDirectory}/dotfiles";
|
||||||
NH_SHOW_ACTIVATION_LOGS = "1";
|
NH_SHOW_ACTIVATION_LOGS = "1";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
programs.zsh.initContent = ''
|
||||||
|
export SUDO_PROMPT=$'\a[sudo] authenticate for %u: '
|
||||||
|
|
||||||
|
nh() {
|
||||||
|
local notify=false
|
||||||
|
local argument
|
||||||
|
|
||||||
|
case "$1:$2" in
|
||||||
|
os:switch | os:build) notify=true ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
for argument in "$@"; do
|
||||||
|
if [[ "$argument" == "--update" ]]; then
|
||||||
|
notify=true
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
command nh "$@"
|
||||||
|
local status=$?
|
||||||
|
|
||||||
|
if [[ "$notify" == true ]]; then
|
||||||
|
printf '\a'
|
||||||
|
if ((status == 0)); then
|
||||||
|
print -P "%F{green}nh completed%f"
|
||||||
|
else
|
||||||
|
print -P "%F{red}nh failed (exit $status)%f"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
return "$status"
|
||||||
|
}
|
||||||
|
'';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
# niri のデフォルトキーバインド。編集しないこと。
|
||||||
{
|
{
|
||||||
"Mod+Shift+Slash".action.show-hotkey-overlay = { };
|
"Mod+Shift+Slash".action.show-hotkey-overlay = { };
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,24 @@
|
|||||||
{ lib, pkgs, ... }:
|
{ lib, pkgs, ... }:
|
||||||
let
|
let
|
||||||
keybindings = import ./keybindings.nix;
|
keybindings = import ./keybindings.nix;
|
||||||
|
naniTranslatePrimary = pkgs.writeShellApplication {
|
||||||
|
name = "nani-translate-primary";
|
||||||
|
runtimeInputs = with pkgs; [
|
||||||
|
jq
|
||||||
|
wl-clipboard
|
||||||
|
xdg-utils
|
||||||
|
];
|
||||||
|
text = ''
|
||||||
|
selected_text="$(wl-paste --primary --no-newline)" || exit 0
|
||||||
|
[ -n "$selected_text" ] || exit 0
|
||||||
|
encoded_text="$(printf '%s' "$selected_text" | jq -sRr @uri)"
|
||||||
|
exec xdg-open "naniapp://translate?source=$encoded_text"
|
||||||
|
'';
|
||||||
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
home.packages = [ naniTranslatePrimary ];
|
||||||
|
|
||||||
programs.niri.settings = {
|
programs.niri.settings = {
|
||||||
|
|
||||||
binds = keybindings // {
|
binds = keybindings // {
|
||||||
@@ -41,6 +57,19 @@ in
|
|||||||
hotkey-overlay.title = "Move Window to Monitor Down";
|
hotkey-overlay.title = "Move Window to Monitor Down";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
"Print".action.spawn = [
|
||||||
|
"screenshot"
|
||||||
|
"region"
|
||||||
|
];
|
||||||
|
"Ctrl+Print".action.spawn = [
|
||||||
|
"screenshot"
|
||||||
|
"output"
|
||||||
|
];
|
||||||
|
"Alt+Print".action.spawn = [
|
||||||
|
"screenshot"
|
||||||
|
"all"
|
||||||
|
];
|
||||||
|
|
||||||
# spawn applications (sync with labwc modules/applications/labwc/home.nix)
|
# spawn applications (sync with labwc modules/applications/labwc/home.nix)
|
||||||
"Mod+T" = {
|
"Mod+T" = {
|
||||||
action.spawn = "ghostty";
|
action.spawn = "ghostty";
|
||||||
@@ -83,6 +112,24 @@ in
|
|||||||
];
|
];
|
||||||
hotkey-overlay.title = "Clipboard History";
|
hotkey-overlay.title = "Clipboard History";
|
||||||
};
|
};
|
||||||
|
"Mod+J" = {
|
||||||
|
repeat = false;
|
||||||
|
action.spawn = [ "nani-translate-primary" ];
|
||||||
|
hotkey-overlay.title = "Translate Primary Selection";
|
||||||
|
};
|
||||||
|
"Mod+Shift+J" = {
|
||||||
|
repeat = false;
|
||||||
|
action.spawn = [ "normcap-translate" ];
|
||||||
|
hotkey-overlay.title = "OCR and Translate with Nani";
|
||||||
|
};
|
||||||
|
"Mod+Ctrl+J" = {
|
||||||
|
repeat = false;
|
||||||
|
action.spawn = [
|
||||||
|
(lib.getExe' pkgs.xdg-utils "xdg-open")
|
||||||
|
"naniapp://translate"
|
||||||
|
];
|
||||||
|
hotkey-overlay.title = "Open Nani Translate";
|
||||||
|
};
|
||||||
"Mod+Space" = {
|
"Mod+Space" = {
|
||||||
action.spawn = [
|
action.spawn = [
|
||||||
"ghostty"
|
"ghostty"
|
||||||
@@ -94,6 +141,25 @@ in
|
|||||||
action.spawn = "wdisplays";
|
action.spawn = "wdisplays";
|
||||||
hotkey-overlay.title = "Display Settings: wdisplays";
|
hotkey-overlay.title = "Display Settings: wdisplays";
|
||||||
};
|
};
|
||||||
|
"Mod+Z" = {
|
||||||
|
action.spawn = [
|
||||||
|
"wl-find-cursor"
|
||||||
|
"-c"
|
||||||
|
"0xCCFF453A"
|
||||||
|
"-s"
|
||||||
|
"160"
|
||||||
|
"-d"
|
||||||
|
"1200"
|
||||||
|
];
|
||||||
|
hotkey-overlay.title = "Find Cursor";
|
||||||
|
};
|
||||||
|
"Ctrl+Space" = {
|
||||||
|
action.spawn = [
|
||||||
|
"handy"
|
||||||
|
"--toggle-transcription"
|
||||||
|
];
|
||||||
|
hotkey-overlay.title = "Toggle Handy Transcription";
|
||||||
|
};
|
||||||
|
|
||||||
# Function keys (sync with labwc modules/applications/labwc/home.nix)
|
# Function keys (sync with labwc modules/applications/labwc/home.nix)
|
||||||
"XF86AudioRaiseVolume".action.spawn = [
|
"XF86AudioRaiseVolume".action.spawn = [
|
||||||
|
|||||||
@@ -2,7 +2,11 @@
|
|||||||
{
|
{
|
||||||
description = "niri Wayland compositor";
|
description = "niri Wayland compositor";
|
||||||
|
|
||||||
includes = [ "systems.wayland" ];
|
includes = [
|
||||||
|
"systems.wayland"
|
||||||
|
"applications.screenshot"
|
||||||
|
"applications.wl-find-cursor"
|
||||||
|
];
|
||||||
|
|
||||||
imports = {
|
imports = {
|
||||||
nixos = [
|
nixos = [
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
|
inputs,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
@@ -12,6 +13,14 @@ let
|
|||||||
--replace-fail "@codexbarPath@" "${lib.getExe codexbar}"
|
--replace-fail "@codexbarPath@" "${lib.getExe codexbar}"
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
noctaliaPatched =
|
||||||
|
inputs.noctalia.packages.${pkgs.stdenv.hostPlatform.system}.default.overrideAttrs
|
||||||
|
(oldAttrs: {
|
||||||
|
patches = (oldAttrs.patches or [ ]) ++ [
|
||||||
|
./patches/window-switcher-labwc.patch
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
wallpapers = pkgs.fetchFromGitHub {
|
wallpapers = pkgs.fetchFromGitHub {
|
||||||
owner = "moons-14";
|
owner = "moons-14";
|
||||||
repo = "wallpapers";
|
repo = "wallpapers";
|
||||||
@@ -41,6 +50,8 @@ in
|
|||||||
programs.noctalia = {
|
programs.noctalia = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
||||||
|
package = noctaliaPatched;
|
||||||
|
|
||||||
systemd.enable = true;
|
systemd.enable = true;
|
||||||
|
|
||||||
settings = {
|
settings = {
|
||||||
@@ -171,10 +182,11 @@ in
|
|||||||
"org.gnome.Nautilus"
|
"org.gnome.Nautilus"
|
||||||
"org.gnome.TextEditor"
|
"org.gnome.TextEditor"
|
||||||
"com.mitchellh.ghostty"
|
"com.mitchellh.ghostty"
|
||||||
|
"thunderbird"
|
||||||
"google-chrome"
|
"google-chrome"
|
||||||
"code"
|
"code"
|
||||||
"dev.zed.Zed"
|
"dev.zed.Zed"
|
||||||
"codex-desktop.desktop"
|
"codex-desktop"
|
||||||
"vesktop"
|
"vesktop"
|
||||||
];
|
];
|
||||||
show_all_outputs = true;
|
show_all_outputs = true;
|
||||||
@@ -193,7 +205,7 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
wallpaper = {
|
wallpaper = {
|
||||||
enabled = true;
|
enabled = lib.mkDefault true;
|
||||||
directory = "~/.wallpapers";
|
directory = "~/.wallpapers";
|
||||||
fill_mode = "crop";
|
fill_mode = "crop";
|
||||||
automation = {
|
automation = {
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
diff --git a/src/shell/bar/widgets/taskbar_widget.cpp b/src/shell/bar/widgets/taskbar_widget.cpp
|
||||||
|
--- a/src/shell/bar/widgets/taskbar_widget.cpp
|
||||||
|
+++ b/src/shell/bar/widgets/taskbar_widget.cpp
|
||||||
|
@@ -5,6 +5,7 @@
|
||||||
|
#include "compositors/workspace_backend.h"
|
||||||
|
#include "config/config_service.h"
|
||||||
|
#include "core/deferred_call.h"
|
||||||
|
+#include "core/process/process.h"
|
||||||
|
#include "i18n/i18n.h"
|
||||||
|
#include "render/core/color.h"
|
||||||
|
#include "render/core/renderer.h"
|
||||||
|
@@ -36,6 +37,18 @@
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
+ [[nodiscard]] bool launchTaskbarOverview(const std::string& appId) {
|
||||||
|
+ constexpr const char* command = "noctalia-taskbar-overview";
|
||||||
|
+ if (appId.empty() || !process::commandExists(command)) {
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ return process::runAsync({
|
||||||
|
+ command,
|
||||||
|
+ "--app-id",
|
||||||
|
+ appId.c_str(),
|
||||||
|
+ });
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
// Integer centering; optional odd spare pixel on the end side (right/bottom).
|
||||||
|
[[nodiscard]] float centeredOffset(float extent, float content, float inset = 0.0F, bool oddSpareOnEnd = true) {
|
||||||
|
const float inner = std::max(0.0F, extent - inset * 2.0F);
|
||||||
|
@@ -373,6 +386,12 @@ void TaskbarWidget::activateOrLaunchPinned(const TaskModel& task) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ const std::string overviewAppId =
|
||||||
|
+ !task.appId.empty() ? task.appId : (!task.desktopEntryId.empty() ? task.desktopEntryId : task.idLower);
|
||||||
|
+ if (launchTaskbarOverview(overviewAppId)) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
const std::string cycleKey = !task.desktopEntryId.empty() ? task.desktopEntryId : task.idLower;
|
||||||
|
std::size_t& cursor = m_groupedAppCycleCursor[cycleKey];
|
||||||
|
if (cursor >= windows.size()) {
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
diff --git a/src/shell/switcher/window_switcher.cpp b/src/shell/switcher/window_switcher.cpp
|
||||||
|
--- a/src/shell/switcher/window_switcher.cpp
|
||||||
|
+++ b/src/shell/switcher/window_switcher.cpp
|
||||||
|
@@ -286,12 +286,19 @@ indexLiveToplevelsByWindowId(const CompositorPlatform& platform, std::unordered_
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
- const auto mappedId = platform.compositorWindowIdForToplevelInfo(info);
|
||||||
|
- if (!mappedId.has_value() || mappedId->empty()) {
|
||||||
|
- continue;
|
||||||
|
+ std::string key;
|
||||||
|
+ if (const auto mappedId = platform.compositorWindowIdForToplevelInfo(info);
|
||||||
|
+ mappedId.has_value() && !mappedId->empty()) {
|
||||||
|
+ key = canonicalWindowId(*mappedId);
|
||||||
|
}
|
||||||
|
- const std::string key = canonicalWindowId(*mappedId);
|
||||||
|
+
|
||||||
|
+ // Generic wlroots compositors such as labwc do not provide a
|
||||||
|
+ // compositor-specific window ID. The wlr toplevel handle is stable
|
||||||
|
+ // for the lifetime of the window and is sufficient for switcher identity.
|
||||||
|
+ if (key.empty() && wlrHandle != 0) {
|
||||||
|
+ key = "toplevel:" + std::to_string(wlrHandle);
|
||||||
|
+ }
|
||||||
|
if (key.empty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
let
|
||||||
|
normcap = pkgs.normcap.override {
|
||||||
|
tesseract4 = pkgs.tesseract4.override {
|
||||||
|
enableLanguages = [
|
||||||
|
"chi_sim"
|
||||||
|
"jpn"
|
||||||
|
"eng"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
normcapTranslate = pkgs.writeShellApplication {
|
||||||
|
name = "normcap-translate";
|
||||||
|
|
||||||
|
runtimeInputs = [
|
||||||
|
normcap
|
||||||
|
pkgs.jq
|
||||||
|
pkgs.xdg-utils
|
||||||
|
];
|
||||||
|
|
||||||
|
text = ''
|
||||||
|
captured_text="$(
|
||||||
|
normcap \
|
||||||
|
--cli-mode \
|
||||||
|
--screenshot-handler grim \
|
||||||
|
--show-introduction False \
|
||||||
|
--update False \
|
||||||
|
--detect-codes False \
|
||||||
|
--notification False \
|
||||||
|
-l jpn eng chi_sim
|
||||||
|
)" || exit 0
|
||||||
|
[ -n "$captured_text" ] || exit 0
|
||||||
|
encoded_text="$(printf '%s' "$captured_text" | jq -sRr @uri)"
|
||||||
|
exec xdg-open "naniapp://translate?source=$encoded_text"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
home.packages = [
|
||||||
|
normcap
|
||||||
|
normcapTranslate
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
description = "NormCap OCR screen capture";
|
||||||
|
|
||||||
|
includes = [
|
||||||
|
"applications.nani"
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
home.packages = [
|
||||||
|
(pkgs.writeShellApplication {
|
||||||
|
name = "screenshot";
|
||||||
|
|
||||||
|
runtimeInputs = with pkgs; [
|
||||||
|
coreutils
|
||||||
|
grim
|
||||||
|
slurp
|
||||||
|
wl-clipboard
|
||||||
|
xdg-user-dirs
|
||||||
|
];
|
||||||
|
|
||||||
|
text = ''
|
||||||
|
mode="''${1:-region}"
|
||||||
|
|
||||||
|
pictures_dir="$(xdg-user-dir PICTURES)"
|
||||||
|
if [[ -z "$pictures_dir" ]]; then
|
||||||
|
pictures_dir="$HOME/Pictures"
|
||||||
|
fi
|
||||||
|
|
||||||
|
output_dir="$pictures_dir/Screenshots"
|
||||||
|
output_file="$output_dir/Screenshot from $(date '+%Y-%m-%d %H-%M-%S').png"
|
||||||
|
|
||||||
|
mkdir -p "$output_dir"
|
||||||
|
|
||||||
|
case "$mode" in
|
||||||
|
region)
|
||||||
|
geometry="$(slurp)" || exit 0
|
||||||
|
grim -g "$geometry" "$output_file"
|
||||||
|
;;
|
||||||
|
|
||||||
|
output)
|
||||||
|
geometry="$(slurp -o)" || exit 0
|
||||||
|
grim -g "$geometry" "$output_file"
|
||||||
|
;;
|
||||||
|
|
||||||
|
all)
|
||||||
|
grim "$output_file"
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo "Unknown screenshot mode: $mode" >&2
|
||||||
|
exit 2
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
wl-copy --type image/png < "$output_file"
|
||||||
|
'';
|
||||||
|
})
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
description = "Wayland screenshot command";
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
programs.thunderbird = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.thunderbird;
|
||||||
|
|
||||||
|
languagePacks = [ "ja" ];
|
||||||
|
|
||||||
|
policies = {
|
||||||
|
DisableTelemetry = true;
|
||||||
|
DisableAppUpdate = true;
|
||||||
|
InAppNotification_Disabled = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
"mailnews.start_page.enabled" = false;
|
||||||
|
"mail.shell.checkDefaultClient" = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
profiles.default = {
|
||||||
|
isDefault = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
_: {
|
||||||
|
xdg.mimeApps = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
defaultApplications = {
|
||||||
|
"x-scheme-handler/mailto" = "thunderbird.desktop";
|
||||||
|
"message/rfc822" = "thunderbird.desktop";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{ inputs, pkgs, ... }:
|
||||||
|
let
|
||||||
|
unstable = inputs.nixpkgs-unstable.legacyPackages.${pkgs.stdenv.hostPlatform.system};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
home.packages = [ unstable.wl-find-cursor ];
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
description = "Wayland cursor locator";
|
||||||
|
}
|
||||||
@@ -63,6 +63,17 @@ enables performance improvements, synced lyrics, tracker blocking, the album
|
|||||||
color theme, and custom output-device selection while preserving user-owned
|
color theme, and custom output-device selection while preserving user-owned
|
||||||
settings such as the selected device.
|
settings such as the selected device.
|
||||||
|
|
||||||
|
`workload.personal` also provides Handy for offline speech-to-text. It starts
|
||||||
|
hidden when the graphical session begins. On niri and labwc, `Ctrl+Space` is
|
||||||
|
owned by the compositor and invokes Handy's `--toggle-transcription` command;
|
||||||
|
Handy's own shortcut bindings are disabled on NixOS so it does not monitor
|
||||||
|
keyboard events under Wayland. Handy uses the Homebrew cask and starts at login
|
||||||
|
on macOS.
|
||||||
|
|
||||||
|
`workload.personal` provides ActivityWatch for local activity tracking. On
|
||||||
|
NixOS, its server and Wayland-compatible watcher run as Home Manager user
|
||||||
|
services. On macOS, the Homebrew cask starts at login.
|
||||||
|
|
||||||
On NixOS, `workload.game` provides Steam with Valve Proton and Proton-GE,
|
On NixOS, `workload.game` provides Steam with Valve Proton and Proton-GE,
|
||||||
Protontricks, Wayland-compatible Steam Input, GameMode, Gamescope, and MangoHud.
|
Protontricks, Wayland-compatible Steam Input, GameMode, Gamescope, and MangoHud.
|
||||||
Enabling Steam also activates the 32-bit graphics and PipeWire support required
|
Enabling Steam also activates the 32-bit graphics and PipeWire support required
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
{
|
{
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
alacritty
|
alacritty
|
||||||
grim
|
|
||||||
slurp
|
|
||||||
wf-recorder
|
wf-recorder
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
{ pkgs, ... }: {
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
home.packages = [
|
home.packages = [
|
||||||
pkgs.playerctl
|
pkgs.playerctl
|
||||||
];
|
];
|
||||||
|
|
||||||
|
programs.noctalia.settings.wallpaper.enabled = false;
|
||||||
|
|
||||||
xdg.userDirs = {
|
xdg.userDirs = {
|
||||||
enable = true;
|
enable = true;
|
||||||
createDirectories = true;
|
createDirectories = true;
|
||||||
|
|||||||
@@ -11,7 +11,9 @@
|
|||||||
"applications.ghostty"
|
"applications.ghostty"
|
||||||
"applications.gtk"
|
"applications.gtk"
|
||||||
"applications.loupe"
|
"applications.loupe"
|
||||||
|
"applications.linux-wallpaperengine"
|
||||||
"applications.nautilus"
|
"applications.nautilus"
|
||||||
|
"applications.normcap"
|
||||||
"applications.papers"
|
"applications.papers"
|
||||||
"applications.qalculate-gtk"
|
"applications.qalculate-gtk"
|
||||||
"applications.resources"
|
"applications.resources"
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
{
|
{
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
alacritty
|
alacritty
|
||||||
grim
|
|
||||||
slurp
|
|
||||||
wf-recorder
|
wf-recorder
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,13 +3,17 @@
|
|||||||
|
|
||||||
includes = [
|
includes = [
|
||||||
"applications.1password"
|
"applications.1password"
|
||||||
|
"applications.activitywatch"
|
||||||
"applications.chrome"
|
"applications.chrome"
|
||||||
"applications.discord"
|
"applications.discord"
|
||||||
"applications.gnome-text-editor"
|
"applications.gnome-text-editor"
|
||||||
|
"applications.handy"
|
||||||
"applications.kde"
|
"applications.kde"
|
||||||
"applications.moonlight"
|
"applications.moonlight"
|
||||||
"applications.slack"
|
"applications.slack"
|
||||||
"applications.zoom"
|
"applications.zoom"
|
||||||
"applications.obs"
|
"applications.obs"
|
||||||
|
"applications.nani"
|
||||||
|
"applications.thunderbird"
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,5 +21,29 @@ in
|
|||||||
pulse.enable = true;
|
pulse.enable = true;
|
||||||
jack.enable = true;
|
jack.enable = true;
|
||||||
wireplumber.enable = true;
|
wireplumber.enable = true;
|
||||||
|
|
||||||
|
extraConfig.pipewire."90-echo-cancel.conf" = {
|
||||||
|
"context.modules" = [
|
||||||
|
{
|
||||||
|
name = "libpipewire-module-echo-cancel";
|
||||||
|
|
||||||
|
args = {
|
||||||
|
"library.name" = "aec/libspa-aec-webrtc";
|
||||||
|
|
||||||
|
"monitor.mode" = true;
|
||||||
|
|
||||||
|
"capture.props" = {
|
||||||
|
"node.name" = "echo_cancel_capture";
|
||||||
|
"node.description" = "Echo Cancel Capture";
|
||||||
|
};
|
||||||
|
|
||||||
|
"source.props" = {
|
||||||
|
"node.name" = "echo_cancel_source";
|
||||||
|
"node.description" = "Echo Cancelled Microphone";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,98 @@
|
|||||||
{ lib, ... }:
|
{ lib, ... }:
|
||||||
{
|
let
|
||||||
networking.nameservers = lib.mkDefault [
|
dohPort = 5300;
|
||||||
"1.1.1.1"
|
|
||||||
"1.0.0.1"
|
dohLocalUpstream = "127.0.0.1#${toString dohPort}";
|
||||||
|
|
||||||
|
internalDns = [
|
||||||
"10.50.80.53"
|
"10.50.80.53"
|
||||||
"10.50.80.54"
|
"10.50.80.54"
|
||||||
|
|
||||||
|
# "fd00:50:80::53"
|
||||||
|
# "fd00:50:80::54"
|
||||||
];
|
];
|
||||||
|
|
||||||
services.resolved.enable = lib.mkDefault false;
|
internalZones = [
|
||||||
security.pki.certificateFiles = [ ./root_ca.crt ];
|
"app.homelabs.run"
|
||||||
|
];
|
||||||
|
|
||||||
|
internalDnsServers = lib.concatMap (zone: map (dns: "/${zone}/${dns}") internalDns) internalZones;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
services.resolved.enable = false;
|
||||||
|
|
||||||
|
networking.networkmanager.dns = "none";
|
||||||
|
|
||||||
|
services.dnscrypt-proxy = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
upstreamDefaults = true;
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
listen_addresses = [
|
||||||
|
"127.0.0.1:${toString dohPort}"
|
||||||
|
];
|
||||||
|
|
||||||
|
server_names = [
|
||||||
|
"cloudflare"
|
||||||
|
"cloudflare-ipv6"
|
||||||
|
];
|
||||||
|
|
||||||
|
ipv4_servers = true;
|
||||||
|
ipv6_servers = true;
|
||||||
|
|
||||||
|
dnscrypt_servers = false;
|
||||||
|
doh_servers = true;
|
||||||
|
odoh_servers = false;
|
||||||
|
|
||||||
|
cache = false;
|
||||||
|
|
||||||
|
block_ipv6 = false;
|
||||||
|
|
||||||
|
ignore_system_dns = true;
|
||||||
|
|
||||||
|
bootstrap_resolvers = [
|
||||||
|
"9.9.9.11:53"
|
||||||
|
"149.112.112.11:53"
|
||||||
|
"[2620:fe::11]:53"
|
||||||
|
"[2620:fe::fe:11]:53"
|
||||||
|
];
|
||||||
|
|
||||||
|
netprobe_address = "1.1.1.1:443";
|
||||||
|
|
||||||
|
timeout = 5000;
|
||||||
|
keepalive = 30;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.dnsmasq = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
resolveLocalQueries = true;
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
no-resolv = true;
|
||||||
|
|
||||||
|
local-service = "host";
|
||||||
|
|
||||||
|
server = [ dohLocalUpstream ] ++ internalDnsServers;
|
||||||
|
|
||||||
|
all-servers = true;
|
||||||
|
|
||||||
|
cache-size = 10000;
|
||||||
|
|
||||||
|
dns-loop-detect = true;
|
||||||
|
domain-needed = true;
|
||||||
|
bogus-priv = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.dnsmasq = {
|
||||||
|
wants = [ "dnscrypt-proxy.service" ];
|
||||||
|
after = [ "dnscrypt-proxy.service" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
security.pki.certificateFiles = [
|
||||||
|
./root_ca.crt
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,137 @@
|
|||||||
|
---
|
||||||
|
name: add-application-or-service
|
||||||
|
description: Add, install, configure, or enable an application or long-running service in this NixOS, nix-darwin, and Home Manager flake while preserving its Registry architecture and quality bar. Use for new GUI or CLI applications, packages, daemons, background services, application-service pairs, cross-platform installations, profile adoption, or substantial extensions to an existing application or service unit.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Add Application or Service
|
||||||
|
|
||||||
|
Add the smallest complete Registry unit change that has a clear owner, an
|
||||||
|
explicit dependency path, and evidence that every affected host class
|
||||||
|
evaluates. Treat `AGENTS.md` as the authoritative repository contract; never
|
||||||
|
replace it with generic Nix conventions.
|
||||||
|
|
||||||
|
## Follow the workflow
|
||||||
|
|
||||||
|
### 1. Establish the baseline
|
||||||
|
|
||||||
|
1. Read `AGENTS.md` completely before editing.
|
||||||
|
2. Run `git status --short`. Preserve all pre-existing user changes and identify
|
||||||
|
which later diffs belong to this task.
|
||||||
|
3. Translate the request into observable outcomes: package or program, desired
|
||||||
|
configuration, supported host classes, required daemon or permissions, and
|
||||||
|
the profile or user intent that should select it.
|
||||||
|
4. Inspect the nearest existing units, relevant profiles, `hosts/default.nix`,
|
||||||
|
and Registry implementation. Prefer repository evidence over memory.
|
||||||
|
5. Verify current package names, module options, external module exports, and
|
||||||
|
Homebrew cask names from the locked inputs or authoritative upstream
|
||||||
|
documentation. Do not guess an option path.
|
||||||
|
6. Read [references/review-checklist.md](references/review-checklist.md) before
|
||||||
|
choosing files or dependencies.
|
||||||
|
|
||||||
|
### 2. Choose ownership before code
|
||||||
|
|
||||||
|
Classify each concern independently:
|
||||||
|
|
||||||
|
- Put the user-facing program and its settings in
|
||||||
|
`modules/applications/<name>/`.
|
||||||
|
- Put a daemon, long-running process, firewall rule, permission, or user/group
|
||||||
|
membership in `modules/services/<name>/`.
|
||||||
|
- Split an application and independently meaningful daemon into two units.
|
||||||
|
Let the application include the service only when the service is a technical
|
||||||
|
requirement of that application.
|
||||||
|
- Put adoption of otherwise independent units in the narrowest coherent
|
||||||
|
`modules/profiles/` composition.
|
||||||
|
- Use another documented owner when the request is actually a system,
|
||||||
|
hardware, user, overlay, or host concern. Do not force it into an application
|
||||||
|
or service directory merely because this skill was invoked.
|
||||||
|
|
||||||
|
Choose only the reserved fragments that contain real configuration. Use
|
||||||
|
`common.nix`, `nixos.nix`, and `darwin.nix` for system-side configuration; use
|
||||||
|
`home.nix` or `home/{common,nixos,darwin}.nix` for Home Manager. Use `meta.nix`
|
||||||
|
only for description, fully qualified `includes`, and external module imports.
|
||||||
|
|
||||||
|
Before editing, formulate a short implementation contract containing:
|
||||||
|
|
||||||
|
- the unit ID and owner;
|
||||||
|
- each file to create or change and why;
|
||||||
|
- technical dependencies versus profile-level choices;
|
||||||
|
- supported and affected host classes;
|
||||||
|
- the evaluations or builds that will prove the change.
|
||||||
|
|
||||||
|
Rework the design if an ordinary addition appears to require Registry changes,
|
||||||
|
new global `specialArgs`, `_module.args`, direct host selection, or an overlay.
|
||||||
|
Use those mechanisms only with concrete evidence that the documented extension
|
||||||
|
points cannot express the requirement.
|
||||||
|
|
||||||
|
### 3. Implement the minimum complete change
|
||||||
|
|
||||||
|
1. Return configuration directly from every reserved fragment. Do not add
|
||||||
|
top-level `imports`, `options`, or `config`, and do not reproduce Registry
|
||||||
|
`mkEnableOption`, `cfg`, or `mkIf` boilerplate.
|
||||||
|
2. Put upstream NixOS, nix-darwin, or Home Manager modules in
|
||||||
|
`meta.imports.<class>`. Import ordinary helper files explicitly from the
|
||||||
|
fragment that uses them.
|
||||||
|
3. Declare unit-to-unit technical dependencies only through fully qualified
|
||||||
|
`meta.includes`. Never enable another unit by assigning its
|
||||||
|
`my.<path>.enable` option inside a fragment.
|
||||||
|
4. Add an independent application or service to an existing coherent profile,
|
||||||
|
or create a justified profile when no existing one expresses the user
|
||||||
|
intent. Do not use `hosts/default.nix` application or unit escape hatches for
|
||||||
|
normal composition.
|
||||||
|
5. Keep cross-platform purpose shared and installation differences in the
|
||||||
|
owning unit. Do not create thin `*-linux` profiles.
|
||||||
|
6. Use existing module arguments and standard options. Do not inject a
|
||||||
|
dependency through global arguments, Registry internals, import ordering, or
|
||||||
|
`lib.mkForce`. Use explicit module priorities only when a real ownership
|
||||||
|
boundary requires them and make that reason visible in the code or handoff.
|
||||||
|
7. Avoid speculative abstraction. Create a helper only when it separates
|
||||||
|
meaningful configuration or prevents real duplication. Do not add empty
|
||||||
|
fragments, compatibility aliases, unused options, redundant comments, or
|
||||||
|
copied boilerplate.
|
||||||
|
8. Update `modules/profiles/README.md`, `AGENTS.md`, profile selections, or
|
||||||
|
other contract documentation whenever the change makes an existing
|
||||||
|
statement stale. Do not edit them performatively when their meaning remains
|
||||||
|
accurate.
|
||||||
|
|
||||||
|
### 4. Prove the change
|
||||||
|
|
||||||
|
Run the validation matrix in
|
||||||
|
[references/review-checklist.md](references/review-checklist.md). At minimum:
|
||||||
|
|
||||||
|
1. Format the task-owned files with the repository formatter and run
|
||||||
|
`git diff --check`.
|
||||||
|
2. Inspect the complete task diff for accidental files, duplication, leaked
|
||||||
|
secrets, forced values, direct enable assignments, and unrelated rewrites.
|
||||||
|
3. Run `nix flake check`.
|
||||||
|
4. Run `pre-commit run --all-files`.
|
||||||
|
5. Evaluate every affected real host without switching it. For a
|
||||||
|
cross-platform unit or profile, evaluate both NixOS and nix-darwin even if
|
||||||
|
only one class changed. Build an affected configuration with `--no-link`
|
||||||
|
when the current platform can build it.
|
||||||
|
6. Verify selection as well as syntax: confirm that the expected package,
|
||||||
|
program, service, group, cask, or external module appears in the resulting
|
||||||
|
configuration.
|
||||||
|
|
||||||
|
If a command is unavailable, blocked by the environment, or fails for a
|
||||||
|
pre-existing reason, diagnose it and report the exact gap. Never silently skip
|
||||||
|
a required check or weaken the implementation to make a check pass.
|
||||||
|
|
||||||
|
### 5. Audit before completion
|
||||||
|
|
||||||
|
Reject the change until all of the following are true:
|
||||||
|
|
||||||
|
- Every line has one clear owner and is required by the requested behavior.
|
||||||
|
- Every dependency is either technical and declared in `meta.includes`, or a
|
||||||
|
user choice owned by a profile.
|
||||||
|
- The unit is reachable from the intended profile or has an explicit reason to
|
||||||
|
remain independently selectable.
|
||||||
|
- No host, Registry, flake root, global argument, or overlay was changed as a
|
||||||
|
shortcut.
|
||||||
|
- Reserved fragments, metadata, and profile documentation satisfy the current
|
||||||
|
repository contract.
|
||||||
|
- Validation covers every affected host class and all failures are resolved or
|
||||||
|
explicitly reported.
|
||||||
|
|
||||||
|
Conclude with the owner and selection rationale, affected hosts or profiles,
|
||||||
|
validation commands and results, and any manual activation or runtime check
|
||||||
|
that remains. Do not claim runtime behavior that was only evaluated.
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Add Application or Service"
|
||||||
|
short_description: "Add clean, validated Registry units"
|
||||||
|
default_prompt: "Use $add-application-or-service to add an application or service cleanly and verify every affected host class."
|
||||||
@@ -0,0 +1,139 @@
|
|||||||
|
# Application and Service Review Checklist
|
||||||
|
|
||||||
|
Use this reference during design and again during final review.
|
||||||
|
|
||||||
|
## Ownership and fragment matrix
|
||||||
|
|
||||||
|
| Concern | Owner | Typical fragment |
|
||||||
|
| -------------------------------------------------------- | ----------------------------------- | ----------------------------------------- |
|
||||||
|
| User-facing GUI, CLI, editor, or compositor | `modules/applications/<name>/` | `home*.nix`, `nixos.nix`, or `darwin.nix` |
|
||||||
|
| User-scoped package and program settings | Application unit | `home.nix` or `home/<class>.nix` |
|
||||||
|
| macOS Homebrew package or cask | Owning application or service | `darwin.nix` |
|
||||||
|
| Daemon or long-running service | `modules/services/<name>/` | `nixos.nix` or `darwin.nix` |
|
||||||
|
| Firewall, group, permission, or service account | Owning service | `nixos.nix` or `darwin.nix` |
|
||||||
|
| Upstream module defining options | Owning unit metadata | `meta.nix` under `imports.<class>` |
|
||||||
|
| Technical prerequisite unit | Owning unit metadata | Fully qualified `meta.includes` |
|
||||||
|
| A set of independent tools chosen for one purpose | Narrowest coherent profile | Profile `meta.includes` |
|
||||||
|
| Machine fact such as UUID, monitor ID, or static address | `hosts/<name>/` | Normal host module |
|
||||||
|
| Missing or replaced package | `overlays/` only after proving need | Overlay definition |
|
||||||
|
|
||||||
|
Use `home/common.nix` when Home Manager configuration is truly shared between
|
||||||
|
NixOS and Darwin. Use `home/nixos.nix` or `home/darwin.nix` for class-specific
|
||||||
|
Home Manager behavior. Root `common.nix` is system-side and never Home Manager.
|
||||||
|
Do not create an unused counterpart for symmetry.
|
||||||
|
|
||||||
|
## Dependency review
|
||||||
|
|
||||||
|
For every edge from unit A to unit B, answer these questions:
|
||||||
|
|
||||||
|
1. Does A fail to work without B? If yes, put the fully qualified ID of B in
|
||||||
|
A's `meta.includes`.
|
||||||
|
2. Are A and B merely useful together for a particular workflow? If yes, let a
|
||||||
|
profile include both.
|
||||||
|
3. Does the dependency exist only on one host? Keep the machine fact in the
|
||||||
|
host, but keep reusable behavior in its unit or profile.
|
||||||
|
4. Is a new `specialArgs`, `_module.args`, Registry field, or direct
|
||||||
|
`my.*.enable` assignment being proposed? Reject it unless the repository's
|
||||||
|
normal module and `meta.includes` mechanisms provably cannot model the
|
||||||
|
requirement.
|
||||||
|
5. Would adding the dependency make the depended-on application select a
|
||||||
|
compositor, desktop, personal workload, or unrelated tool? Reverse or remove
|
||||||
|
the edge; application metadata contains technical requirements, not taste.
|
||||||
|
|
||||||
|
Accept no circular dependency, shortened unit ID, duplicate include, stale
|
||||||
|
unit ID, or ordering-dependent override.
|
||||||
|
|
||||||
|
## Minimality and code-quality review
|
||||||
|
|
||||||
|
Reject any of these patterns:
|
||||||
|
|
||||||
|
- Empty or placeholder reserved fragments.
|
||||||
|
- Hand-written enable options or guards already generated by the Registry.
|
||||||
|
- Top-level `imports`, `options`, or `config` in a configuration fragment.
|
||||||
|
- External module imports hidden in a guarded configuration fragment.
|
||||||
|
- Helper files assumed to be auto-imported.
|
||||||
|
- A helper abstraction used once without reducing meaningful complexity.
|
||||||
|
- Configuration duplicated across fragments when a shared fragment can express
|
||||||
|
it cleanly.
|
||||||
|
- Direct host application or unit selection where a profile expresses the
|
||||||
|
concern.
|
||||||
|
- A new flake input or overlay when the locked package set already provides the
|
||||||
|
package and required module.
|
||||||
|
- Global argument injection for a value owned by one unit.
|
||||||
|
- `lib.mkForce` used to win an ordering fight instead of resolving ownership.
|
||||||
|
- Secret material, generated state, machine IDs, or mutable user preferences
|
||||||
|
committed as reusable configuration.
|
||||||
|
- Comments that repeat the code, compatibility aliases, dead options, or
|
||||||
|
opportunistic unrelated cleanup.
|
||||||
|
|
||||||
|
Prefer standard upstream module options over hand-written service definitions.
|
||||||
|
Prefer existing repository arguments and helpers over new plumbing. Preserve
|
||||||
|
user-owned mutable state unless the requested policy explicitly owns it.
|
||||||
|
|
||||||
|
## Validation matrix
|
||||||
|
|
||||||
|
Run checks from the repository root and keep the exact results for the handoff.
|
||||||
|
Do not switch or activate a live system merely to validate a change.
|
||||||
|
|
||||||
|
### Always
|
||||||
|
|
||||||
|
1. Format task-owned files. If the worktree contains unrelated user changes,
|
||||||
|
pass only task-owned paths to the configured formatter when supported.
|
||||||
|
2. Run `git diff --check`.
|
||||||
|
3. Review `git status --short`, `git diff --stat`, and the complete `git diff`.
|
||||||
|
4. Run `nix flake check`.
|
||||||
|
5. Run `pre-commit run --all-files`.
|
||||||
|
|
||||||
|
### NixOS or Home Manager on NixOS
|
||||||
|
|
||||||
|
- Evaluate each affected host's system toplevel derivation.
|
||||||
|
- Build at least one affected NixOS configuration with `--no-link` when the
|
||||||
|
current system supports it.
|
||||||
|
- Inspect the resulting option that proves selection: for example
|
||||||
|
`environment.systemPackages`, the user's `home.packages`,
|
||||||
|
`systemd.services`, `users.users.<name>.extraGroups`, or the upstream
|
||||||
|
`programs`/`services` option.
|
||||||
|
|
||||||
|
Typical build shape:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
nix build .#nixosConfigurations.<host>.config.system.build.toplevel --no-link
|
||||||
|
```
|
||||||
|
|
||||||
|
### nix-darwin or Home Manager on Darwin
|
||||||
|
|
||||||
|
- Evaluate every affected Darwin host even when running on Linux.
|
||||||
|
- Inspect `homebrew.casks` or `homebrew.brews` for Homebrew-backed additions.
|
||||||
|
- Evaluate the relevant Home Manager program or package option.
|
||||||
|
- Build a Darwin configuration only on a compatible Darwin builder; otherwise
|
||||||
|
report that build as an explicit runtime-validation gap.
|
||||||
|
|
||||||
|
Typical evaluation shapes:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
nix eval --raw .#darwinConfigurations.<host>.system.drvPath
|
||||||
|
nix eval --json .#darwinConfigurations.<host>.config.homebrew.casks
|
||||||
|
```
|
||||||
|
|
||||||
|
Confirm the exact output attribute against the current flake before using a
|
||||||
|
command; do not paste these shapes blindly.
|
||||||
|
|
||||||
|
### Profiles and cross-platform changes
|
||||||
|
|
||||||
|
- Determine transitive selection through `meta.includes`, not only direct
|
||||||
|
mentions.
|
||||||
|
- Evaluate every real host selecting the changed profile.
|
||||||
|
- Evaluate both host classes for a cross-platform profile, even if only one
|
||||||
|
current fragment changed.
|
||||||
|
- Re-read `modules/profiles/README.md` and `hosts/default.nix` for stale meaning,
|
||||||
|
compatibility, or role statements.
|
||||||
|
- If no real host selects the new unit, construct a non-persistent evaluation
|
||||||
|
that enables it or explain why the unit is intentionally dormant. Do not add
|
||||||
|
a fake host or permanent direct selection as a test harness.
|
||||||
|
|
||||||
|
### Runtime-dependent behavior
|
||||||
|
|
||||||
|
Evaluation and builds cannot prove GUI appearance, credentials, network access,
|
||||||
|
hardware behavior, or successful daemon interaction. State the precise manual
|
||||||
|
post-activation check needed for those behaviors. Never describe evaluation as
|
||||||
|
a runtime test.
|
||||||
Reference in New Issue
Block a user