mirror of
https://github.com/moons-14/dotfiles.git
synced 2026-10-06 17:44:08 +09:00
Compare commits
238
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ec3770502d | ||
|
|
fda29cd08d | ||
|
|
db0a440da4 | ||
|
|
76f5dce9c0 | ||
|
|
3b61457718 | ||
|
|
c9f1584797 | ||
|
|
d51948c307 | ||
|
|
9a38e9f614 | ||
|
|
2cb7e76ca1 | ||
|
|
749410e032 | ||
|
|
d43f19c20a | ||
|
|
32a3067cb0 | ||
|
|
6e60bd8886 | ||
|
|
bcf7ef56cf | ||
|
|
63e2008423 | ||
|
|
3b8147ff46 | ||
|
|
c84f257149 | ||
|
|
6347292c1d | ||
|
|
2a82433754 | ||
|
|
847ee17b29 | ||
|
|
95f74aabcd | ||
|
|
717572ae24 | ||
|
|
8086c9a7f3 | ||
|
|
eba23455d4 | ||
|
|
b3b1031364 | ||
|
|
366ff54403 | ||
|
|
456e9946f4 | ||
|
|
c104404e5b | ||
|
|
cb41932fec | ||
|
|
fa4b7ca404 | ||
|
|
847d33e83b | ||
|
|
b2c700e1e4 | ||
|
|
c1540d8764 | ||
|
|
5b8c3b1415 | ||
|
|
6743569789 | ||
|
|
70253fc451 | ||
|
|
5107b80173 | ||
|
|
2bdea522cb | ||
|
|
c113d0d46d | ||
|
|
fa50be8feb | ||
|
|
33ebef4a1e | ||
|
|
94048ef8d5 | ||
|
|
c7627fa1b0 | ||
|
|
d68da620ac | ||
|
|
5f0df47775 | ||
|
|
119342e564 | ||
|
|
1f066e8937 | ||
|
|
0a440e3da8 | ||
|
|
bdf93ac6bb | ||
|
|
9ae5da4d30 | ||
|
|
872436b170 | ||
|
|
c14325e29c | ||
|
|
45bc66e25f | ||
|
|
78ee2d41ec | ||
|
|
0b1ae13048 | ||
|
|
458b0a2cdb | ||
|
|
01179f3dc6 | ||
|
|
42949fc06c | ||
|
|
a7f514c0f9 | ||
|
|
9bed1c3e25 | ||
|
|
791b6baa83 | ||
|
|
349f49e496 | ||
|
|
3166c12448 | ||
|
|
4c459e4aa7 | ||
|
|
9b9141dd84 | ||
|
|
16e3fda275 | ||
|
|
ca36b07839 | ||
|
|
5ebcbb4abf | ||
|
|
f8fd8a3d99 | ||
|
|
16742d2fd7 | ||
|
|
15da7affaa | ||
|
|
548647fec7 | ||
|
|
bcbd08c225 | ||
|
|
a0ae83d24e | ||
|
|
33e09f8e93 | ||
|
|
eff32fddcd | ||
|
|
8ce3a6082a | ||
|
|
a8246261ad | ||
|
|
8b51b5c55f | ||
|
|
e24d85da56 | ||
|
|
01ead9a385 | ||
|
|
328f11d0ed | ||
|
|
d877ffc76c | ||
|
|
fe40adaeee | ||
|
|
991dde5305 | ||
|
|
96ce4d768c | ||
|
|
30b1480e50 | ||
|
|
71011d7bd1 | ||
|
|
9cced59e58 | ||
|
|
20a601402e | ||
|
|
1b4a5fa5a2 | ||
|
|
5fb55f2e6a | ||
|
|
2a3f7ee6ff | ||
|
|
247db71f2d | ||
|
|
a44a83a587 | ||
|
|
1f1d46ea2a | ||
|
|
29c4815b88 | ||
|
|
28a46d9990 | ||
|
|
403971eef6 | ||
|
|
c62468396d | ||
|
|
9145b36412 | ||
|
|
f574b1d1e7 | ||
|
|
cf088a6998 | ||
|
|
e4eb1802d7 | ||
|
|
a7c6a1507c | ||
|
|
49141e3478 | ||
|
|
cc91ad88b0 | ||
|
|
bb1f81a598 | ||
|
|
c0fdd9b4ef | ||
|
|
aafcc1555d | ||
|
|
245f22e094 | ||
|
|
15ca59e43c | ||
|
|
3627587bc7 | ||
|
|
d90aed6903 | ||
|
|
3e57b6c4c1 | ||
|
|
bdca6fb2fb | ||
|
|
98397cf152 | ||
|
|
3162bc0eba | ||
|
|
c3bb2f4d43 | ||
|
|
5edbc6cbb4 | ||
|
|
bf28275b40 | ||
|
|
92b4bc7b8d | ||
|
|
9bbef37010 | ||
|
|
e708ceee26 | ||
|
|
7604dfb0e3 | ||
|
|
02f97f73df | ||
|
|
cde17e6a68 | ||
|
|
64fe5020d0 | ||
|
|
843dd0cbf4 | ||
|
|
0060fdae15 | ||
|
|
6402cdcf3a | ||
|
|
118d91f1d5 | ||
|
|
b261f4aec7 | ||
|
|
b146081ba8 | ||
|
|
6f19ea8f23 | ||
|
|
aaa4542f25 | ||
|
|
d3ce44ff63 | ||
|
|
fb3254daa1 | ||
|
|
e69203ce4c | ||
|
|
e84fa82710 | ||
|
|
d5e4c90710 | ||
|
|
d67d53644e | ||
|
|
f1dd96945a | ||
|
|
aceb3d4808 | ||
|
|
ac874a849e | ||
|
|
519f7dd54d | ||
|
|
233ba91309 | ||
|
|
e6c80ad5d6 | ||
|
|
847d7ee6dd | ||
|
|
5e12c1d953 | ||
|
|
dfc4dc79d6 | ||
|
|
5deab38d3c | ||
|
|
3c674e34c1 | ||
|
|
506602d7e1 | ||
|
|
6b4253e1d4 | ||
|
|
a3660b5733 | ||
|
|
894b18bd10 | ||
|
|
08effb9e29 | ||
|
|
605e63acdb | ||
|
|
12c9d5241b | ||
|
|
ac44bdf22f | ||
|
|
421ede5d57 | ||
|
|
7204e3e8f6 | ||
|
|
f696ed6b93 | ||
|
|
d1891382ea | ||
|
|
4a7516939c | ||
|
|
176cd60d68 | ||
|
|
7c66c15da5 | ||
|
|
dddb7e07ab | ||
|
|
9ede34fcfd | ||
|
|
855b8c55cf | ||
|
|
a51e9584b0 | ||
|
|
3dae1d26ef | ||
|
|
06cd9516b3 | ||
|
|
f3098f2674 | ||
|
|
2f9c8f3d33 | ||
|
|
82d00fb574 | ||
|
|
ad6dff2f6a | ||
|
|
54b84c0544 | ||
|
|
c3dbcda528 | ||
|
|
480a1c3194 | ||
|
|
37d4a4a7c5 | ||
|
|
e68e2f536f | ||
|
|
36f01a084f | ||
|
|
e9ab8c2caa | ||
|
|
7ef25c5e63 | ||
|
|
d6026a5bfc | ||
|
|
b477446f5c | ||
|
|
ee9ce66d55 | ||
|
|
ecabb8b630 | ||
|
|
831ae7bbc2 | ||
|
|
8dc9452d95 | ||
|
|
c566f426ec | ||
|
|
e56af06b04 | ||
|
|
acb5ed3449 | ||
|
|
9f40aadab3 | ||
|
|
55e1e0b5b4 | ||
|
|
aef1338d79 | ||
|
|
5bbf1d42e9 | ||
|
|
f02eeac2a3 | ||
|
|
e23e0058bd | ||
|
|
e474c38aff | ||
|
|
04e4bdaeff | ||
|
|
c02d6936fa | ||
|
|
3f35a54e0a | ||
|
|
601c94a5d8 | ||
|
|
7e8bd33c89 | ||
|
|
6f4f048f4c | ||
|
|
c2a5e174b9 | ||
|
|
b1954ba5be | ||
|
|
09a4fd83a7 | ||
|
|
1f4ec6b8cd | ||
|
|
5132a1af1b | ||
|
|
2a02beda38 | ||
|
|
ee0bd37915 | ||
|
|
a8113633db | ||
|
|
91bb7e80db | ||
|
|
9bb95535cf | ||
|
|
fcd0d75537 | ||
|
|
a8e9a4dce5 | ||
|
|
72ff60fb16 | ||
|
|
f65318b765 | ||
|
|
0257b2e2fd | ||
|
|
8fec0494ec | ||
|
|
89eeb23d1c | ||
|
|
bf94d1183f | ||
|
|
6bd05887db | ||
|
|
3e32c9874b | ||
|
|
684acef46c | ||
|
|
9061825c63 | ||
|
|
e703e1b31c | ||
|
|
79cc69045f | ||
|
|
5c2ff3cbcf | ||
|
|
c5d4de5a9d | ||
|
|
c58bdd30c3 | ||
|
|
9771a85e3f | ||
|
|
5b1bde7d90 | ||
|
|
1d82ab92b6 |
@@ -0,0 +1,27 @@
|
|||||||
|
# Reference: https://github.com/ryoppippi/dotfiles/blob/main/.github/workflows/nix-build.yaml
|
||||||
|
name: Check NixOS configurations
|
||||||
|
description: Build every NixOS configuration and the Registry tests
|
||||||
|
runs:
|
||||||
|
using: composite
|
||||||
|
steps:
|
||||||
|
- name: Build every NixOS configuration
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
mapfile -t hosts < <(
|
||||||
|
nix eval --raw .#nixosConfigurations \
|
||||||
|
--apply 'configs: builtins.concatStringsSep "\n" (builtins.attrNames configs)'
|
||||||
|
)
|
||||||
|
|
||||||
|
installables=(.#checks.x86_64-linux.registry)
|
||||||
|
for host in "${hosts[@]}"; do
|
||||||
|
installables+=(".#nixosConfigurations.${host}.config.system.build.toplevel")
|
||||||
|
done
|
||||||
|
|
||||||
|
nix build \
|
||||||
|
--keep-going \
|
||||||
|
--no-link \
|
||||||
|
--print-build-logs \
|
||||||
|
--show-trace \
|
||||||
|
"${installables[@]}"
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
# Reference: https://github.com/ryoppippi/dotfiles/blob/main/.github/actions/setup-nix/action.yaml
|
||||||
|
name: Setup Nix
|
||||||
|
description: Install Nix and cache the Nix store
|
||||||
|
runs:
|
||||||
|
using: composite
|
||||||
|
steps:
|
||||||
|
- name: Allow unprivileged user namespaces
|
||||||
|
if: runner.os == 'Linux'
|
||||||
|
shell: bash
|
||||||
|
run: sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 2>/dev/null || true
|
||||||
|
- name: Install Nix
|
||||||
|
uses: nixbuild/nix-quick-install-action@9f63be77f412a248c9d9a65a4c82cf066cdf8f0c # v35
|
||||||
|
with:
|
||||||
|
nix_conf: |
|
||||||
|
accept-flake-config = true
|
||||||
|
max-jobs = auto
|
||||||
|
- name: Cache Nix store
|
||||||
|
uses: nix-community/cache-nix-action@7df957e333c1e5da7721f60227dbba6d06080569 # v7.0.2
|
||||||
|
with:
|
||||||
|
primary-key: nix-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('flake.lock') }}
|
||||||
|
restore-prefixes-first-match: nix-${{ runner.os }}-${{ runner.arch }}-
|
||||||
|
gc-max-store-size-linux: 4G
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
# Reference: https://github.com/ryoppippi/dotfiles/blob/main/.github/workflows/nix-build.yaml
|
||||||
|
name: "CI: NixOS"
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
paths:
|
||||||
|
- flake.nix
|
||||||
|
- flake.lock
|
||||||
|
- "flake/**"
|
||||||
|
- "hosts/**"
|
||||||
|
- "libs/**"
|
||||||
|
- "modules/**"
|
||||||
|
- "overlays/**"
|
||||||
|
- "shells/**"
|
||||||
|
- "tests/**"
|
||||||
|
- ".github/actions/check-nixos/**"
|
||||||
|
- ".github/actions/setup-nix/**"
|
||||||
|
- ".github/workflows/nixos.yaml"
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- flake.nix
|
||||||
|
- flake.lock
|
||||||
|
- "flake/**"
|
||||||
|
- "hosts/**"
|
||||||
|
- "libs/**"
|
||||||
|
- "modules/**"
|
||||||
|
- "overlays/**"
|
||||||
|
- "shells/**"
|
||||||
|
- "tests/**"
|
||||||
|
- ".github/actions/check-nixos/**"
|
||||||
|
- ".github/actions/setup-nix/**"
|
||||||
|
- ".github/workflows/nixos.yaml"
|
||||||
|
workflow_dispatch:
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
jobs:
|
||||||
|
check:
|
||||||
|
name: Check all NixOS configurations
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 120
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
||||||
|
- name: Setup Nix
|
||||||
|
uses: ./.github/actions/setup-nix
|
||||||
|
- name: Check NixOS configurations
|
||||||
|
uses: ./.github/actions/check-nixos
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
# Reference: https://github.com/ryoppippi/dotfiles/blob/main/.github/workflows/update-flake.yaml
|
||||||
|
name: "Bot: Update flake inputs"
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: "0 6 * * *"
|
||||||
|
workflow_dispatch:
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}
|
||||||
|
cancel-in-progress: false
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
|
jobs:
|
||||||
|
update:
|
||||||
|
name: Update and validate flake inputs
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 120
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
||||||
|
- name: Setup Nix
|
||||||
|
uses: ./.github/actions/setup-nix
|
||||||
|
- name: Update flake inputs
|
||||||
|
id: update
|
||||||
|
run: |
|
||||||
|
nix flake update
|
||||||
|
if git diff --quiet -- flake.lock; then
|
||||||
|
echo 'changed=false' >> "$GITHUB_OUTPUT"
|
||||||
|
else
|
||||||
|
echo 'changed=true' >> "$GITHUB_OUTPUT"
|
||||||
|
fi
|
||||||
|
- name: Check updated NixOS configurations
|
||||||
|
if: steps.update.outputs.changed == 'true'
|
||||||
|
uses: ./.github/actions/check-nixos
|
||||||
|
- name: Create update pull request
|
||||||
|
if: steps.update.outputs.changed == 'true'
|
||||||
|
uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
add-paths: flake.lock
|
||||||
|
branch: automation/update-flake-lock
|
||||||
|
delete-branch: true
|
||||||
|
commit-message: "flake: update inputs"
|
||||||
|
title: "flake: update inputs"
|
||||||
|
body: |
|
||||||
|
Automated update of `flake.lock`.
|
||||||
|
|
||||||
|
The updated inputs passed the Registry tests and a build of every NixOS configuration.
|
||||||
+12
-6
@@ -4,6 +4,7 @@
|
|||||||
!README.md
|
!README.md
|
||||||
!LICENSE
|
!LICENSE
|
||||||
!AGENTS.md
|
!AGENTS.md
|
||||||
|
!/docs/
|
||||||
|
|
||||||
!.github/
|
!.github/
|
||||||
!.gitea/
|
!.gitea/
|
||||||
@@ -19,9 +20,14 @@
|
|||||||
!/flake/
|
!/flake/
|
||||||
!/overlays/
|
!/overlays/
|
||||||
|
|
||||||
!/modules/applications/
|
!/images/
|
||||||
!/modules/hardwares/
|
!/secrets/
|
||||||
!/modules/profiles/
|
|
||||||
!/modules/services/
|
!/windows/
|
||||||
!/modules/systems/
|
|
||||||
!/modules/users/
|
!/hosts/
|
||||||
|
!/libs/
|
||||||
|
!/modules/
|
||||||
|
|
||||||
|
!/tests/
|
||||||
|
!/skills/
|
||||||
|
|||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
keys:
|
||||||
|
- &admin_yubikey1 age1yubikey1qvy5y8kxqc63y7fk0tfv43u499a8z8q332ff087lythry9cc6hdxxkznc6t
|
||||||
|
- &host_x1g13 age12g85cuvg4kjfr79lqf5fx2k0d82tchrgv88xgkt7ukk2cfcsw98s2rjyat
|
||||||
|
- &host_ops age18rtm2dq2r62zvnhwdq0gkm24hu85r7zyleyk3jqv22zpdtw064eq7ay7dl
|
||||||
|
- &host_internal-app-01 age1mcp5gma7y0k59equhzqfsnn0ed335ljjtn0k08ua77htlxf0x54qsravch
|
||||||
|
- &host_galleria age1wh7r9wnvyrgt5efjvg2324khsf4w6e9atpmz2udr4uw7frhnvvwquzcu72
|
||||||
|
creation_rules:
|
||||||
|
- path_regex: ^secrets/common/[^/]+\.ya?ml$
|
||||||
|
key_groups:
|
||||||
|
- age:
|
||||||
|
- *admin_yubikey1
|
||||||
|
- *host_x1g13
|
||||||
|
- *host_ops
|
||||||
|
- *host_internal-app-01
|
||||||
|
- *host_galleria
|
||||||
|
- path_regex: ^secrets/hosts/x1g13/[^/]+\.ya?ml$
|
||||||
|
key_groups:
|
||||||
|
- age:
|
||||||
|
- *admin_yubikey1
|
||||||
|
- *host_x1g13
|
||||||
@@ -1,28 +1,849 @@
|
|||||||
# Repository Guidelines
|
# Repository Guidelines
|
||||||
|
|
||||||
## Project Structure & Module Organization
|
## Project Structure and Ownership
|
||||||
|
|
||||||
This repository manages NixOS and Home Manager configuration as a flake. `flake.nix` defines inputs and imports the project modules. Keep flake-level plumbing in `flake/`, reusable package overlays in `overlays/`, and development environments in `shells/`. Add configuration under the appropriate `modules/` category: `applications/`, `hardwares/`, `profiles/`, `services/`, `systems/`, or `users/`. Keep host- or user-specific choices near their owning module rather than in the root flake.
|
This repository manages NixOS, nix-darwin, and Home Manager configurations as a
|
||||||
|
flake. `flake.nix` defines inputs and delegates flake outputs through
|
||||||
|
flake-parts. Keep configuration with the component that owns it, rather than in
|
||||||
|
the root flake or an unrelated host.
|
||||||
|
|
||||||
|
This file documents the current repository contract, not a hypothetical future
|
||||||
|
layout. When a structural, ownership, profile, host-role, or validation change
|
||||||
|
makes any statement here stale, update `AGENTS.md` in the same change.
|
||||||
|
|
||||||
|
| Path | Responsibility |
|
||||||
|
| ----------------------- | ----------------------------------------------------------------------------------------------------------------- |
|
||||||
|
| `modules/applications/` | One software component, including GUI applications, window managers, desktop environments, CLI tools, and editors |
|
||||||
|
| `modules/systems/` | OS foundations such as Nix, boot, locale, Wayland, and networking |
|
||||||
|
| `modules/services/` | Daemons, long-running services, and configuration that involves permissions or user groups |
|
||||||
|
| `modules/hardwares/` | Reusable drivers, hardware families, and VM or WSL guest configuration |
|
||||||
|
| `modules/users/` | User identity and the user's NixOS-, nix-darwin-, and Home Manager-specific definitions |
|
||||||
|
| `modules/profiles/` | Purpose- or form-factor-oriented compositions of multiple units |
|
||||||
|
| `hosts/` | Machine-specific facts and the profiles selected for each machine; direct unit selections are exceptional |
|
||||||
|
| `libs/` | Registry, unit discovery, and host construction logic |
|
||||||
|
| `overlays/` | Package replacements and additions |
|
||||||
|
| `shells/` | Development shells |
|
||||||
|
| `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
|
||||||
|
**profile** for a unit that composes multiple units. Do not introduce a
|
||||||
|
`features/` layer. Window managers and desktop environments such as niri and
|
||||||
|
labwc belong in `modules/applications/`; do not create a separate `desktop/`
|
||||||
|
module category.
|
||||||
|
|
||||||
|
Before adding configuration, decide whether it is owned by an application,
|
||||||
|
system foundation, service, hardware family, user, profile, or individual host.
|
||||||
|
Prefer the following placements:
|
||||||
|
|
||||||
|
| Configuration | Placement |
|
||||||
|
| ---------------------------------------------------- | --------------------------------------------------------- |
|
||||||
|
| Nix settings shared by every system host | `modules/systems/nix/common.nix` |
|
||||||
|
| NixOS-only boot configuration | `modules/systems/boot/.../nixos.nix` |
|
||||||
|
| Disko NixOS module and CLI | `modules/systems/disko/` |
|
||||||
|
| macOS-wide input, document, and dialog defaults | `modules/systems/macos-defaults/darwin.nix` |
|
||||||
|
| macOS Dock defaults | `modules/systems/dock/darwin.nix` |
|
||||||
|
| macOS trackpad defaults | `modules/systems/trackpad/darwin.nix` |
|
||||||
|
| Finder-specific preferences | `modules/applications/finder/darwin.nix` |
|
||||||
|
| Ghostty-specific configuration | `modules/applications/ghostty/` |
|
||||||
|
| niri-specific configuration | `modules/applications/niri/` |
|
||||||
|
| Desktop applications shared by labwc and niri | `modules/profiles/interface/linux-desktop/meta.nix` |
|
||||||
|
| Applications and services specific to niri | `modules/profiles/interface/niri/meta.nix` |
|
||||||
|
| labwc and its session configuration | `modules/applications/labwc/` |
|
||||||
|
| A Linux package plus its macOS Homebrew cask | `modules/applications/<name>/home.nix` and `darwin.nix` |
|
||||||
|
| Docker daemon and Docker group membership | `modules/services/docker/nixos.nix` |
|
||||||
|
| The laptop unit composition | `modules/profiles/platform/laptop/meta.nix` |
|
||||||
|
| The Intel ThinkPad X1 composition | `modules/profiles/platform/thinkpad-x1/meta.nix` |
|
||||||
|
| The Intel/NVIDIA desktop composition | `modules/profiles/platform/intel-nvidia-desktop/meta.nix` |
|
||||||
|
| NVIDIA GPU driver configuration | `modules/hardwares/nvidia/` |
|
||||||
|
| The development-environment unit composition | `modules/profiles/workload/development/meta.nix` |
|
||||||
|
| Cross-platform fingerprint selection | `modules/profiles/security/fingerprint/meta.nix` |
|
||||||
|
| A user's OS- and Home Manager-specific configuration | `modules/users/<name>/` |
|
||||||
|
| Host-specific monitor layout | `hosts/<name>/home.nix` |
|
||||||
|
| Generated host disk UUIDs | `hosts/<name>/hardware-configuration.nix` |
|
||||||
|
| Package replacement or addition | `overlays/` |
|
||||||
|
| Formatter, checks, or Git hooks | `flake/` |
|
||||||
|
|
||||||
|
## Unit Discovery and Identity
|
||||||
|
|
||||||
|
A directory below `modules/` is a unit if, and only if, it contains at least one
|
||||||
|
reserved root file or reserved Home Manager fragment. Directories used only for
|
||||||
|
classification, such as `modules/applications/` or
|
||||||
|
`modules/profiles/interface/`, are namespaces rather than units when they have
|
||||||
|
no reserved fragment of their own.
|
||||||
|
|
||||||
|
The Registry recognizes exactly these eight reserved paths relative to a unit:
|
||||||
|
|
||||||
|
| File | Target and responsibility |
|
||||||
|
| ----------------- | -------------------------------------------------------------------------------- |
|
||||||
|
| `common.nix` | System-side configuration fragment shared by NixOS and nix-darwin |
|
||||||
|
| `nixos.nix` | NixOS-only system configuration fragment |
|
||||||
|
| `darwin.nix` | nix-darwin-only system configuration fragment |
|
||||||
|
| `home.nix` | Home Manager fragment shared by NixOS and nix-darwin |
|
||||||
|
| `home/common.nix` | Home Manager fragment shared by NixOS and nix-darwin |
|
||||||
|
| `home/nixos.nix` | Home Manager fragment loaded only on NixOS |
|
||||||
|
| `home/darwin.nix` | Home Manager fragment loaded only on nix-darwin |
|
||||||
|
| `meta.nix` | Registry descriptor for dependencies, external modules, and descriptive metadata |
|
||||||
|
|
||||||
|
Root `common.nix` is never applied to Home Manager. `home.nix` and
|
||||||
|
`home/common.nix` have identical dispatch semantics; use either or both when a
|
||||||
|
useful file split exists. The `home/` directory is a reserved fragment directory
|
||||||
|
of its parent unit when it contains `common.nix`, `nixos.nix`, or `darwin.nix`;
|
||||||
|
it is not discovered as a child unit in that case.
|
||||||
|
|
||||||
|
The Registry derives a unit ID from the path relative to `modules/`, joining
|
||||||
|
path components with dots. Category names remain plural. It also derives the
|
||||||
|
enable option by prefixing the same components with `my` and appending `enable`.
|
||||||
|
|
||||||
|
| Unit directory | Unit ID | Enable option |
|
||||||
|
| ---------------------------------- | ------------------------- | ----------------------------------- |
|
||||||
|
| `modules/applications/ghostty/` | `applications.ghostty` | `my.applications.ghostty.enable` |
|
||||||
|
| `modules/applications/niri/` | `applications.niri` | `my.applications.niri.enable` |
|
||||||
|
| `modules/systems/boot/uefi/` | `systems.boot.uefi` | `my.systems.boot.uefi.enable` |
|
||||||
|
| `modules/services/docker/` | `services.docker` | `my.services.docker.enable` |
|
||||||
|
| `modules/hardwares/qemu-guest/` | `hardwares.qemu-guest` | `my.hardwares.qemu-guest.enable` |
|
||||||
|
| `modules/users/moons/` | `users.moons` | `my.users.moons.enable` |
|
||||||
|
| `modules/profiles/interface/niri/` | `profiles.interface.niri` | `my.profiles.interface.niri.enable` |
|
||||||
|
|
||||||
|
Represent option paths as attribute-path lists, never as Nix source encoded in
|
||||||
|
strings or evaluated dynamically. Generate and read attributes with helpers such
|
||||||
|
as `lib.setAttrByPath` and `lib.getAttrFromPath`:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
id = "applications.ghostty";
|
||||||
|
|
||||||
|
optionPath = [
|
||||||
|
"my"
|
||||||
|
"applications"
|
||||||
|
"ghostty"
|
||||||
|
"enable"
|
||||||
|
];
|
||||||
|
|
||||||
|
kind = "applications";
|
||||||
|
name = "ghostty";
|
||||||
|
|
||||||
|
relativePath = [
|
||||||
|
"applications"
|
||||||
|
"ghostty"
|
||||||
|
];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
For `modules/profiles/interface/niri/`, path inference additionally gives
|
||||||
|
`kind = "profiles"`, `group = "interface"`, and `name = "niri"`. The path is
|
||||||
|
always authoritative for identity. `meta.nix` may provide display metadata such
|
||||||
|
as `description`, but it must not override or alias the unit ID.
|
||||||
|
|
||||||
|
## Unit Files and Fragment Contract
|
||||||
|
|
||||||
|
Only reserved files that a unit actually needs should exist. The Registry
|
||||||
|
registers present fragments and does not require empty or placeholder files. All
|
||||||
|
of the following are valid units:
|
||||||
|
|
||||||
|
```text
|
||||||
|
# Home Manager only
|
||||||
|
modules/applications/ghostty/
|
||||||
|
├── home.nix
|
||||||
|
├── home/
|
||||||
|
│ ├── nixos.nix
|
||||||
|
│ └── darwin.nix
|
||||||
|
└── settings.nix
|
||||||
|
|
||||||
|
# NixOS only
|
||||||
|
modules/services/docker/
|
||||||
|
└── nixos.nix
|
||||||
|
|
||||||
|
# nix-darwin only
|
||||||
|
modules/systems/macos-defaults/
|
||||||
|
└── darwin.nix
|
||||||
|
|
||||||
|
# NixOS and Home Manager, with metadata and helpers
|
||||||
|
modules/applications/niri/
|
||||||
|
├── nixos.nix
|
||||||
|
├── home.nix
|
||||||
|
├── meta.nix
|
||||||
|
├── settings.nix
|
||||||
|
└── keybindings.nix
|
||||||
|
|
||||||
|
# Metadata only, commonly a composition profile
|
||||||
|
modules/profiles/interface/niri/
|
||||||
|
└── meta.nix
|
||||||
|
|
||||||
|
# System configuration shared by NixOS and nix-darwin
|
||||||
|
modules/systems/nix/
|
||||||
|
└── common.nix
|
||||||
|
```
|
||||||
|
|
||||||
|
Each fragment is optional and registered independently. A unit may therefore
|
||||||
|
contain only `home/nixos.nix` or `home/darwin.nix`; it does not need a
|
||||||
|
placeholder `home.nix` or `home/common.nix`.
|
||||||
|
|
||||||
|
### Configuration fragments
|
||||||
|
|
||||||
|
Every reserved path except `meta.nix` is a configuration fragment to which the
|
||||||
|
Registry adds the enable condition. These fragments return the configuration
|
||||||
|
for their class directly and must not define top-level `imports`, `options`, or
|
||||||
|
`config` attributes:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# modules/services/docker/nixos.nix
|
||||||
|
{ primaryUser, ... }:
|
||||||
|
{
|
||||||
|
virtualisation.docker = {
|
||||||
|
enable = true;
|
||||||
|
autoPrune.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
users.users.${primaryUser}.extraGroups = [
|
||||||
|
"docker"
|
||||||
|
];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Conceptually, the Registry supplies a wrapper like this:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{ config, lib, ... }@args:
|
||||||
|
{
|
||||||
|
config =
|
||||||
|
lib.mkIf
|
||||||
|
config.my.services.docker.enable
|
||||||
|
(import dockerNixosPath args);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Do not add hand-written `mkEnableOption`, `cfg`, or `mkIf` boilerplate to each
|
||||||
|
unit. The Registry generates the enable option from the unit path and guards the
|
||||||
|
fragment.
|
||||||
|
|
||||||
|
### Helper files and directories
|
||||||
|
|
||||||
|
Every path other than the eight reserved paths is an ordinary helper, regardless
|
||||||
|
of its extension. The Registry neither discovers nor automatically imports
|
||||||
|
helper files such as `settings.nix`, `keybindings.nix`, `packages.nix`,
|
||||||
|
`colors.nix`, `rules.nix`, or `helpers.nix`. Import a helper explicitly from the
|
||||||
|
reserved fragment that uses it:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# modules/applications/niri/home.nix
|
||||||
|
{ lib, ... }:
|
||||||
|
let
|
||||||
|
settings = import ./settings.nix;
|
||||||
|
keybindings = import ./keybindings.nix;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
programs.niri.settings = lib.recursiveUpdate settings {
|
||||||
|
binds = keybindings;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Do not use a leading underscore to mark a file private; `_settings.nix` has no
|
||||||
|
special meaning. Give helper files descriptive names instead. When helpers are
|
||||||
|
configuration functions, pass the module arguments explicitly and combine them
|
||||||
|
with normal Nix expressions:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# modules/applications/example/home.nix
|
||||||
|
{ lib, ... }@args:
|
||||||
|
lib.mkMerge [
|
||||||
|
(import ./packages.nix args)
|
||||||
|
(import ./settings.nix args)
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
The same discovery rule applies recursively to helper directories:
|
||||||
|
|
||||||
|
```text
|
||||||
|
modules/applications/niri/
|
||||||
|
├── home.nix
|
||||||
|
└── parts/
|
||||||
|
├── appearance.nix
|
||||||
|
└── keybindings.nix
|
||||||
|
```
|
||||||
|
|
||||||
|
Here `parts/` is not a unit because it directly contains no reserved file. A
|
||||||
|
helper directory that directly contains a root reserved file is itself
|
||||||
|
discovered as a unit, so never use reserved filenames inside a directory that
|
||||||
|
is intended to contain helpers only. The reserved `home/` fragment directory is
|
||||||
|
the sole exception to ordinary recursive child-unit discovery.
|
||||||
|
|
||||||
|
### Registry metadata
|
||||||
|
|
||||||
|
`meta.nix` is a Registry descriptor, not a NixOS, nix-darwin, or Home Manager
|
||||||
|
module. It may declare `description`, `includes`, and class-specific external
|
||||||
|
module imports:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# modules/applications/niri/meta.nix
|
||||||
|
{ inputs, ... }:
|
||||||
|
{
|
||||||
|
description = "Niri Wayland compositor";
|
||||||
|
|
||||||
|
includes = [
|
||||||
|
"systems.wayland"
|
||||||
|
"services.xdg-portal"
|
||||||
|
];
|
||||||
|
|
||||||
|
imports.nixos = [
|
||||||
|
inputs.niri-flake.nixosModules.niri
|
||||||
|
];
|
||||||
|
|
||||||
|
imports.home = [
|
||||||
|
inputs.niri-flake.homeModules.niri
|
||||||
|
];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
External modules, including modules supplied by flake inputs, define Nix module
|
||||||
|
options and therefore belong in `meta.nix` under `imports.nixos`,
|
||||||
|
`imports.darwin`, or `imports.home`. Do not place them in a configuration
|
||||||
|
fragment's top-level `imports`: the Nix module system resolves imports before a
|
||||||
|
configuration-level enable condition.
|
||||||
|
|
||||||
|
`includes` lists units to enable whenever the declaring unit is enabled. Always
|
||||||
|
use fully qualified unit IDs:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# modules/profiles/interface/niri/meta.nix
|
||||||
|
{
|
||||||
|
includes = [
|
||||||
|
"profiles.interface.linux-desktop"
|
||||||
|
"applications.niri"
|
||||||
|
"applications.noctalia"
|
||||||
|
"services.ly"
|
||||||
|
"services.swayidle"
|
||||||
|
];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Never omit a prefix such as `applications.` merely because the including unit is
|
||||||
|
a profile. Fully qualified IDs make ownership explicit and allow moves, name
|
||||||
|
collisions, and missing dependencies to be detected. Do not enable another unit
|
||||||
|
by assigning to its enable option from a class fragment; declare the dependency
|
||||||
|
in `meta.includes`.
|
||||||
|
|
||||||
|
Application metadata should include only dependencies technically required for
|
||||||
|
the application to work. A profile owns the user's choice to adopt several
|
||||||
|
otherwise independent applications together. For example, the niri application
|
||||||
|
includes the Wayland foundation as a technical dependency. The
|
||||||
|
`profiles.interface.linux-desktop` profile selects Ghostty and Nautilus because
|
||||||
|
both labwc and niri use them, while the cross-platform `profiles.interface.gui`
|
||||||
|
profile selects Vicinae for graphical hosts. The labwc and niri profiles select
|
||||||
|
their compositor, Noctalia, and the session services they require. Ghostty and
|
||||||
|
Vicinae must not depend on either compositor, and compositor-specific
|
||||||
|
keybindings remain owned by the corresponding application unit.
|
||||||
|
|
||||||
|
## Profiles
|
||||||
|
|
||||||
|
Profiles compose units by purpose or form factor; they do not replace clear
|
||||||
|
application, system, service, or hardware ownership. The current profile
|
||||||
|
structure is:
|
||||||
|
|
||||||
|
```text
|
||||||
|
modules/profiles/
|
||||||
|
├── README.md
|
||||||
|
├── base/
|
||||||
|
├── interface/
|
||||||
|
│ ├── cli/
|
||||||
|
│ ├── gui/
|
||||||
|
│ ├── macos/
|
||||||
|
│ ├── linux-desktop/
|
||||||
|
│ ├── labwc/
|
||||||
|
│ └── niri/
|
||||||
|
├── networking/
|
||||||
|
│ ├── homelab-cache-client/
|
||||||
|
│ ├── tailscale-client/
|
||||||
|
│ └── tailscale-subnet-router/
|
||||||
|
├── platform/
|
||||||
|
│ ├── nixos/
|
||||||
|
│ ├── intel-nvidia-desktop/
|
||||||
|
│ ├── laptop/
|
||||||
|
│ ├── thinkpad-x1/
|
||||||
|
│ ├── desktop/
|
||||||
|
│ └── vm/
|
||||||
|
├── workload/
|
||||||
|
│ ├── camera/
|
||||||
|
│ ├── development/
|
||||||
|
│ ├── game/
|
||||||
|
│ ├── machine-learning/
|
||||||
|
│ ├── nix-builder/
|
||||||
|
│ ├── personal/
|
||||||
|
│ ├── server/
|
||||||
|
│ └── remote-access/
|
||||||
|
└── security/
|
||||||
|
├── fingerprint/
|
||||||
|
├── secrets/
|
||||||
|
├── secure-boot/
|
||||||
|
└── tpm-storage/
|
||||||
|
```
|
||||||
|
|
||||||
|
`modules/profiles/README.md` is the compatibility inventory for this structure.
|
||||||
|
Whenever a profile is added, removed, renamed, changes host-class support, or
|
||||||
|
changes meaning, update that README and every affected `hosts/default.nix`
|
||||||
|
selection in the same change. Remove stale profile directories and references;
|
||||||
|
do not retain compatibility aliases.
|
||||||
|
|
||||||
|
The profile layers have these responsibilities:
|
||||||
|
|
||||||
|
- `base` contains only invariants required by every supported host. It includes
|
||||||
|
`systems.nix` and the universal Atuin, tealdeer, trippy, and xh CLI tools;
|
||||||
|
optional secrets, interface, hardware, and workloads do not belong there.
|
||||||
|
- `interface` describes how the host is operated. `interface.cli` is shared by
|
||||||
|
NixOS and macOS and includes `tio`. `interface.gui` owns cross-platform
|
||||||
|
graphical interface applications such as Vicinae. `interface.macos` owns the
|
||||||
|
macOS Finder, Dock, trackpad, and shared default preferences and includes
|
||||||
|
`interface.gui`.
|
||||||
|
`interface.linux-desktop` owns the common labwc/niri desktop selection,
|
||||||
|
including Ghostty and Nautilus, and also includes `interface.gui`. Labwc and
|
||||||
|
niri remain independently selectable and do not imply CLI or personal
|
||||||
|
workloads.
|
||||||
|
- `platform` describes NixOS foundations and physical or virtual form factors.
|
||||||
|
macOS does not need an empty symmetric platform profile.
|
||||||
|
- `workload` describes optional host uses. `workload.development` and
|
||||||
|
`workload.personal` are cross-platform profiles, not `*-linux` variants.
|
||||||
|
- `networking` describes network roles and topology rather than user workloads.
|
||||||
|
- `security` describes optional security policies. Select
|
||||||
|
`security.fingerprint` instead of listing `systems.fingerprint` directly in a
|
||||||
|
host. The underlying `systems.fingerprint` unit owns NixOS fingerprint
|
||||||
|
authentication and macOS Touch ID sudo configuration through its class
|
||||||
|
fragments.
|
||||||
|
|
||||||
|
Do not split a semantic profile into `*-linux` and cross-platform variants merely
|
||||||
|
because an application is installed differently on each OS. Keep the semantic
|
||||||
|
profile cross-platform when its purpose is shared, and implement OS differences
|
||||||
|
inside the owning application unit. For example, Chrome, Vesktop, draw.io,
|
||||||
|
Slack, and Zoom use Linux Home Manager configuration in `home.nix` and macOS
|
||||||
|
Homebrew casks in `darwin.nix`. Guard a Linux-only Home Manager package with the
|
||||||
|
host platform when the same unit also has a Darwin implementation.
|
||||||
|
|
||||||
|
An explicitly OS-specific profile is appropriate when the composition itself is
|
||||||
|
OS-specific, such as `interface.macos`, `interface.linux-desktop`,
|
||||||
|
`platform.nixos`, or a NixOS
|
||||||
|
subnet-router. Do not create an OS suffix for a thin package difference that the
|
||||||
|
owning application unit can express.
|
||||||
|
|
||||||
|
The `desktop/` name above is a form-factor profile under `profiles/platform/`,
|
||||||
|
not a top-level module category.
|
||||||
|
|
||||||
|
A profile may consist only of `meta.includes`. Small settings that belong only
|
||||||
|
to the composition and have no useful independent identity may go directly in
|
||||||
|
the profile's `nixos.nix`, `darwin.nix`, or `home.nix`. Extract configuration to
|
||||||
|
an appropriate application, system, service, or hardware unit when any of these
|
||||||
|
conditions holds:
|
||||||
|
|
||||||
|
- It should be independently enableable.
|
||||||
|
- Multiple profiles reuse it.
|
||||||
|
- It owns separate configuration files.
|
||||||
|
- Its NixOS, nix-darwin, and Home Manager implementations differ.
|
||||||
|
- Other units depend on it.
|
||||||
|
- It involves a daemon, permissions, or user groups.
|
||||||
|
|
||||||
|
`security.tpm-storage` intentionally does not own a disk identifier. A host that
|
||||||
|
selects it must define `boot.initrd.luks.devices.cryptroot.device` in its own
|
||||||
|
NixOS module.
|
||||||
|
|
||||||
|
## Registry Responsibilities
|
||||||
|
|
||||||
|
Implement unit discovery with Nix standard functionality such as
|
||||||
|
`builtins.readDir`. Do not depend on an external indiscriminate auto-import
|
||||||
|
mechanism, and do not design the repository around `import-tree`. Registry logic
|
||||||
|
has these responsibilities:
|
||||||
|
|
||||||
|
1. Recursively visit directories below `modules/`.
|
||||||
|
2. Check the five reserved root filenames and the three reserved filenames
|
||||||
|
directly inside the unit's `home/` fragment directory.
|
||||||
|
3. Register a directory as a unit when at least one reserved fragment exists
|
||||||
|
there, including a unit that has only a reserved `home/` fragment.
|
||||||
|
4. Derive the unit ID from the path relative to `modules/`.
|
||||||
|
5. Record only class fragments that exist.
|
||||||
|
6. Evaluate `meta.nix` as a descriptor only when it exists.
|
||||||
|
7. Exclude non-reserved files from discovery and implicit imports.
|
||||||
|
8. Generate every unit's `my.<unit path>.enable` option.
|
||||||
|
9. Enable included units from `meta.includes`.
|
||||||
|
10. Raise a clear evaluation error for a reference to a missing unit ID.
|
||||||
|
11. Apply only the fragments appropriate to the current host class.
|
||||||
|
12. Pass `home.nix`, `home/common.nix`, and the matching OS-specific Home
|
||||||
|
Manager fragment only for hosts that enable Home Manager.
|
||||||
|
|
||||||
|
A unit record may conceptually look like this; the implementation need not use
|
||||||
|
this exact representation:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
id = "applications.ghostty";
|
||||||
|
directory = ./applications/ghostty;
|
||||||
|
|
||||||
|
fragments = {
|
||||||
|
common = null;
|
||||||
|
nixos = null;
|
||||||
|
darwin = null;
|
||||||
|
home = ./applications/ghostty/home.nix;
|
||||||
|
homeCommon = null;
|
||||||
|
homeNixos = ./applications/ghostty/home/nixos.nix;
|
||||||
|
homeDarwin = ./applications/ghostty/home/darwin.nix;
|
||||||
|
};
|
||||||
|
|
||||||
|
meta = { };
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Keep the custom Registry limited to unit discovery, enable-option generation,
|
||||||
|
`includes`, and class dispatch. Do not reimplement general Nix imports or Nix
|
||||||
|
module evaluation. In particular, never infer a unit ID from metadata or
|
||||||
|
implicitly load a non-reserved file.
|
||||||
|
|
||||||
|
## Hosts and Class Dispatch
|
||||||
|
|
||||||
|
`hosts/` is outside Registry discovery. A host contains machine-specific facts,
|
||||||
|
differences, and unit selection, not reusable shared configuration. Appropriate
|
||||||
|
host-owned data includes:
|
||||||
|
|
||||||
|
- Generated `hardware-configuration.nix`.
|
||||||
|
- Disk UUIDs and disko target devices.
|
||||||
|
- Monitor identifiers, layout, and scale.
|
||||||
|
- MAC addresses and static IP addresses.
|
||||||
|
- Kernel parameters required by one machine only.
|
||||||
|
- `system.stateVersion`.
|
||||||
|
- Host-specific secret references.
|
||||||
|
- The profiles enabled on that host and, only in exceptional cases, direct
|
||||||
|
application or other unit selections that cannot be expressed by a coherent
|
||||||
|
reusable profile.
|
||||||
|
|
||||||
|
A host registry may use a specification like this:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# hosts/default.nix
|
||||||
|
{
|
||||||
|
nix-example = {
|
||||||
|
system = "x86_64-linux";
|
||||||
|
stateVersion = "26.05";
|
||||||
|
user = "moons";
|
||||||
|
path = ./nix-example;
|
||||||
|
|
||||||
|
profiles = [
|
||||||
|
"base"
|
||||||
|
"interface.cli"
|
||||||
|
"platform.vm"
|
||||||
|
"workload.development"
|
||||||
|
"workload.remote-access"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
ops = {
|
||||||
|
system = "x86_64-linux";
|
||||||
|
stateVersion = "26.05";
|
||||||
|
user = "moons";
|
||||||
|
path = ./ops;
|
||||||
|
|
||||||
|
profiles = [
|
||||||
|
"base"
|
||||||
|
"interface.cli"
|
||||||
|
"platform.vm"
|
||||||
|
"workload.remote-access"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
internal-app-01 = {
|
||||||
|
system = "x86_64-linux";
|
||||||
|
stateVersion = "26.05";
|
||||||
|
user = "moons";
|
||||||
|
path = ./internal-app-01;
|
||||||
|
|
||||||
|
profiles = [
|
||||||
|
"base"
|
||||||
|
"interface.cli"
|
||||||
|
"platform.vm"
|
||||||
|
"workload.server"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
installer = {
|
||||||
|
system = "x86_64-linux";
|
||||||
|
stateVersion = "26.05";
|
||||||
|
user = "moons";
|
||||||
|
path = ./installer;
|
||||||
|
homeManager = false;
|
||||||
|
|
||||||
|
profiles = [ "base" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
x1g9 = {
|
||||||
|
system = "x86_64-linux";
|
||||||
|
stateVersion = "26.05";
|
||||||
|
user = "moons";
|
||||||
|
path = ./x1g9;
|
||||||
|
|
||||||
|
profiles = [
|
||||||
|
"base"
|
||||||
|
"interface.cli"
|
||||||
|
"interface.labwc"
|
||||||
|
"interface.niri"
|
||||||
|
"platform.thinkpad-x1"
|
||||||
|
"security.fingerprint"
|
||||||
|
"workload.personal"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
x1g13 = {
|
||||||
|
system = "x86_64-linux";
|
||||||
|
stateVersion = "26.05";
|
||||||
|
user = "moons";
|
||||||
|
path = ./x1g13;
|
||||||
|
|
||||||
|
profiles = [
|
||||||
|
"base"
|
||||||
|
"interface.cli"
|
||||||
|
"interface.labwc"
|
||||||
|
"interface.niri"
|
||||||
|
"networking.tailscale-client"
|
||||||
|
"platform.thinkpad-x1"
|
||||||
|
"security.fingerprint"
|
||||||
|
"security.secrets"
|
||||||
|
"security.secure-boot"
|
||||||
|
"security.tpm-storage"
|
||||||
|
"workload.camera"
|
||||||
|
"workload.development"
|
||||||
|
"workload.personal"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
galleria = {
|
||||||
|
system = "x86_64-linux";
|
||||||
|
stateVersion = "26.05";
|
||||||
|
user = "moons";
|
||||||
|
path = ./galleria;
|
||||||
|
|
||||||
|
profiles = [
|
||||||
|
"base"
|
||||||
|
"interface.cli"
|
||||||
|
"interface.labwc"
|
||||||
|
"interface.niri"
|
||||||
|
"platform.intel-nvidia-desktop"
|
||||||
|
"security.secrets"
|
||||||
|
"security.secure-boot"
|
||||||
|
"security.tpm-storage"
|
||||||
|
"workload.development"
|
||||||
|
"workload.game"
|
||||||
|
"workload.machine-learning"
|
||||||
|
"workload.personal"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
m2 = {
|
||||||
|
system = "aarch64-darwin";
|
||||||
|
stateVersion = "26.05";
|
||||||
|
user = "moons";
|
||||||
|
path = ./m2;
|
||||||
|
|
||||||
|
profiles = [
|
||||||
|
"base"
|
||||||
|
"interface.cli"
|
||||||
|
"interface.macos"
|
||||||
|
"security.fingerprint"
|
||||||
|
"workload.development"
|
||||||
|
"workload.personal"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The current role assignment is intentional: nix-example is the development VM;
|
||||||
|
ops is the remote-access VM with host-specific static networking;
|
||||||
|
internal-app-01 is the container server VM; and installer builds the minimal
|
||||||
|
installation ISO without Home Manager. x1g9 is a full NixOS desktop with niri,
|
||||||
|
labwc, ly, the shared Linux desktop applications, and the personal workload.
|
||||||
|
x1g13 is the secure NixOS development and personal ThinkPad, with the same
|
||||||
|
desktop sessions plus Tailscale client, SOPS, Secure Boot, and TPM-backed disk
|
||||||
|
unlock. galleria is the Intel/NVIDIA physical desktop shared with Windows; it
|
||||||
|
uses dedicated NixOS partitions, LUKS, Secure Boot, and TPM-backed disk unlock.
|
||||||
|
m2 is the daily-use macOS development and personal machine with the macOS
|
||||||
|
interface defaults. Keep the desktop sessions independently selectable, and
|
||||||
|
keep the development and personal profiles usable across NixOS and Darwin.
|
||||||
|
|
||||||
|
Treat entries in `profiles` and the exceptional `applications` field as IDs
|
||||||
|
relative to their respective category roots. Add the category prefixes during
|
||||||
|
host construction:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
selectedUnits =
|
||||||
|
[ "users.${spec.user}" ]
|
||||||
|
++ map (name: "profiles.${name}") spec.profiles
|
||||||
|
++ map (name: "applications.${name}") spec.applications
|
||||||
|
++ spec.units or [ ];
|
||||||
|
```
|
||||||
|
|
||||||
|
`applications` and `units` are escape hatches, not normal host composition.
|
||||||
|
Do not add either field when an existing profile expresses the concern, when an
|
||||||
|
existing profile can coherently include the unit, or when the concern is
|
||||||
|
reusable enough to deserve a small profile. For example, add a development tool
|
||||||
|
to `workload.development` and select `security.fingerprint`; do not write
|
||||||
|
`applications = [ "ghostty" ];` or `units = [ "systems.fingerprint" ];` in a
|
||||||
|
host. A direct selection is permitted only for a genuinely exceptional,
|
||||||
|
machine-specific unit that would make every reasonable profile misleading; add
|
||||||
|
an adjacent comment explaining that exception. Prefer profiles for host
|
||||||
|
composition and omit both escape-hatch fields by default.
|
||||||
|
|
||||||
|
Host modules use normal Nix module semantics and are not Registry-guarded
|
||||||
|
configuration fragments. For example:
|
||||||
|
|
||||||
|
```text
|
||||||
|
hosts/
|
||||||
|
├── installer/
|
||||||
|
│ └── nixos.nix
|
||||||
|
├── internal-app-01/
|
||||||
|
│ ├── nixos.nix
|
||||||
|
│ └── hardware-configuration.nix
|
||||||
|
├── nix-example/
|
||||||
|
│ ├── nixos.nix
|
||||||
|
│ └── hardware-configuration.nix
|
||||||
|
├── ops/
|
||||||
|
│ ├── nixos.nix
|
||||||
|
│ └── hardware-configuration.nix
|
||||||
|
├── galleria/
|
||||||
|
│ ├── disk-identifiers.nix
|
||||||
|
│ ├── disko.nix
|
||||||
|
│ ├── hardware-configuration.nix
|
||||||
|
│ └── nixos.nix
|
||||||
|
├── x1g9/
|
||||||
|
│ ├── nixos.nix
|
||||||
|
│ └── hardware-configuration.nix
|
||||||
|
├── x1g13/
|
||||||
|
│ ├── nixos.nix
|
||||||
|
│ ├── home.nix
|
||||||
|
│ ├── disko.nix
|
||||||
|
│ └── hardware-configuration.nix
|
||||||
|
└── m2/
|
||||||
|
└── darwin.nix
|
||||||
|
```
|
||||||
|
|
||||||
|
`hosts/x1g9/nixos.nix` explicitly loads `hardware-configuration.nix` with the
|
||||||
|
normal top-level Nix module `imports`. `hosts/x1g13/nixos.nix` loads its
|
||||||
|
generated hardware configuration and host-local `disko.nix` the same way. Do
|
||||||
|
not confuse these host imports with the prohibition on top-level `imports` in
|
||||||
|
unit configuration fragments. `hosts/galleria/disko.nix` manages only the two
|
||||||
|
dedicated NixOS partitions by PARTUUID and deliberately excludes the Windows
|
||||||
|
disk, Windows partitions, and the Windows EFI System Partition.
|
||||||
|
|
||||||
|
Derive the system class from the host's `system`:
|
||||||
|
|
||||||
|
- A Linux NixOS host receives `common.nix` and `nixos.nix`.
|
||||||
|
- A nix-darwin host receives `common.nix` and `darwin.nix`.
|
||||||
|
- A NixOS host with integrated Home Manager additionally receives `home.nix`,
|
||||||
|
`home/common.nix`, and `home/nixos.nix`.
|
||||||
|
- A nix-darwin host with integrated Home Manager additionally receives
|
||||||
|
`home.nix`, `home/common.nix`, and `home/darwin.nix`.
|
||||||
|
|
||||||
|
Home Manager is additive, not a system class mutually exclusive with NixOS or
|
||||||
|
nix-darwin. Normal machine configurations combine NixOS or nix-darwin with Home
|
||||||
|
Manager; the installer ISO explicitly sets `homeManager = false`. If standalone
|
||||||
|
Home Manager is supported later, add an explicit host kind because `system`
|
||||||
|
alone cannot distinguish it from NixOS.
|
||||||
|
|
||||||
|
Do not duplicate reusable settings in hosts, but do not force genuinely
|
||||||
|
machine-specific values into a common unit merely to remove a host-local line.
|
||||||
|
|
||||||
|
## Coding Style and Implementation Rules
|
||||||
|
|
||||||
|
Use two-space indentation in Nix files and let `nixfmt` decide layout. Prefer
|
||||||
|
small units, explicit imports, and descriptive kebab-case names, for example
|
||||||
|
`modules/services/media-server/nixos.nix`. Use camelCase for Nix attributes
|
||||||
|
unless an upstream option dictates otherwise. Shell snippets must pass `shfmt`
|
||||||
|
and `shellcheck`; YAML, TOML, and Markdown are formatted by the configured
|
||||||
|
treefmt tools.
|
||||||
|
|
||||||
|
When implementing or modifying modules:
|
||||||
|
|
||||||
|
- Do not create `features/` or a top-level `desktop/` module category.
|
||||||
|
- Do not add per-unit `mkEnableOption`, `cfg`, or `mkIf` boilerplate; the Registry
|
||||||
|
derives and guards enable options from paths.
|
||||||
|
- Put unit dependencies in `meta.includes`, not in direct assignments to another
|
||||||
|
unit's enable option from a class fragment.
|
||||||
|
- Do not assume any non-reserved file is discovered or loaded automatically.
|
||||||
|
- Do not require an `_` prefix for helper or private files.
|
||||||
|
- Do not create unused reserved fragments, including placeholder files under the
|
||||||
|
reserved `home/` fragment directory.
|
||||||
|
- Do not override a path-derived unit ID from `meta.nix`.
|
||||||
|
- Keep technical application dependencies separate from the applications a
|
||||||
|
personal environment chooses to combine in a profile.
|
||||||
|
- Keep cross-platform profile names semantic. Put Linux package installation in
|
||||||
|
an application's `home.nix` and the corresponding macOS Homebrew cask in its
|
||||||
|
`darwin.nix`; do not create a thin `*-linux` profile for that difference.
|
||||||
|
- Keep shared labwc/niri selections in `profiles.interface.linux-desktop` and
|
||||||
|
session-specific applications or services in the respective labwc or niri
|
||||||
|
profile.
|
||||||
|
- Keep `modules/profiles/README.md`, the profile directories, and host profile
|
||||||
|
selections synchronized whenever any of them changes.
|
||||||
|
- Do not select applications or units directly in `hosts/default.nix` unless
|
||||||
|
they meet the documented exceptional, machine-specific escape-hatch rule.
|
||||||
|
Prefer adding the unit to an existing coherent profile or creating a small,
|
||||||
|
justified reusable profile.
|
||||||
|
- Do not rely on module-list ordering to override values. Use Nix module
|
||||||
|
priorities such as `lib.mkDefault`, `lib.mkForce`, `lib.mkBefore`, or
|
||||||
|
`lib.mkAfter` explicitly when required.
|
||||||
|
- Keep Registry responsibilities narrow; use normal Nix imports and module
|
||||||
|
evaluation for everything outside discovery, generated enables, includes, and
|
||||||
|
class dispatch.
|
||||||
|
|
||||||
## Build, Test, and Development Commands
|
## Build, Test, and Development Commands
|
||||||
|
|
||||||
- `nix develop .#dotnix` enters the main development shell and installs the repository's pre-commit hooks.
|
- `nix develop .#dotnix` enters the main development shell and installs the
|
||||||
- `nix develop .#android` provides Android platform tools such as `adb` and `fastboot`.
|
repository's pre-commit hooks.
|
||||||
|
- `nix develop .#android` provides Android platform tools such as `adb` and
|
||||||
|
`fastboot`.
|
||||||
- `nix fmt` formats all supported files through treefmt.
|
- `nix fmt` formats all supported files through treefmt.
|
||||||
- `nix flake check` evaluates flake outputs and runs configured checks.
|
- `nix flake check` evaluates flake outputs and runs configured checks.
|
||||||
- `pre-commit run --all-files` runs formatting, dead-code and static Nix checks, shell linting, and secret scanning.
|
- `pre-commit run --all-files` runs formatting, dead-code and static Nix checks,
|
||||||
- `nix flake update` refreshes pinned inputs in `flake.lock`; review lockfile changes before committing.
|
shell linting, and secret scanning.
|
||||||
|
- `nix flake update` refreshes pinned inputs in `flake.lock`; review lockfile
|
||||||
|
changes before committing.
|
||||||
|
|
||||||
If direnv is installed, `direnv allow` activates the `dotnix` shell from `.envrc` automatically.
|
If direnv is installed, `direnv allow` activates the `dotnix` shell from `.envrc`
|
||||||
|
automatically.
|
||||||
## Coding Style & Naming Conventions
|
|
||||||
|
|
||||||
Use two-space indentation in Nix files and let `nixfmt` decide layout. Prefer small modules with explicit imports and descriptive kebab-case filenames, for example `modules/services/media-server.nix`. Use camelCase for Nix attributes unless an upstream option dictates otherwise. Shell snippets must pass `shfmt` and `shellcheck`; YAML, TOML, and Markdown are formatted by the configured treefmt tools.
|
|
||||||
|
|
||||||
## Testing Guidelines
|
## Testing Guidelines
|
||||||
|
|
||||||
There is no separate unit-test suite. Before submitting changes, run `nix flake check` and `pre-commit run --all-files`. For system-specific changes, also build or evaluate the affected NixOS/Home Manager configuration without switching the live machine. Never commit generated secrets, `.age` plaintext, or local `.direnv/` state.
|
There is no separate unit-test suite. Before submitting changes, run
|
||||||
|
`nix flake check` and `pre-commit run --all-files`. For system-specific changes,
|
||||||
|
also build or evaluate the affected NixOS, nix-darwin, or Home Manager
|
||||||
|
configuration without switching the live machine. Never commit generated
|
||||||
|
secrets, `.age` plaintext, or local `.direnv/` state.
|
||||||
|
|
||||||
## Commit & Pull Request Guidelines
|
For Registry changes, test discovery of each supported fragment combination,
|
||||||
|
dependency closure through `meta.includes`, missing-unit errors, and class
|
||||||
|
dispatch. Verify that helper files are ignored until explicitly imported and
|
||||||
|
that directories without a directly contained reserved file remain namespaces.
|
||||||
|
|
||||||
Recent history favors short, lowercase, imperative subjects such as `fix` and `update action`; automated dependency commits use `chore(deps): ...`. Prefer a specific summary that states the affected area, such as `shells: add deployment tools`. Keep commits focused. Pull requests should explain the motivation, list affected hosts or profiles, report validation commands, and note any manual migration or secret-management steps. Include screenshots only for visible desktop or application configuration changes.
|
For profile changes, additionally:
|
||||||
|
|
||||||
|
- Check for stale profile IDs after every add, removal, or rename.
|
||||||
|
- Evaluate every affected real host without switching it.
|
||||||
|
- Evaluate a cross-platform profile on both NixOS and nix-darwin, even when only
|
||||||
|
one current host selects it.
|
||||||
|
- Confirm `modules/profiles/README.md` accurately states compatibility and any
|
||||||
|
required host-owned values.
|
||||||
|
- When adding a Darwin application fragment, verify the resulting
|
||||||
|
`homebrew.casks` selection as well as module evaluation.
|
||||||
|
- Preserve the intended host roles: nix-example remains the development VM;
|
||||||
|
ops remains the statically networked remote-access VM; internal-app-01 remains
|
||||||
|
the container server VM; installer remains the Home Manager-free installation
|
||||||
|
ISO; x1g9 provides niri, labwc, ly, and the personal application set; x1g13
|
||||||
|
additionally provides the development, Tailscale client, secrets, Secure Boot,
|
||||||
|
and TPM storage roles; galleria remains the Intel/NVIDIA dual-boot desktop
|
||||||
|
with LUKS, Secure Boot, and TPM storage; m2 remains the daily-use development
|
||||||
|
and personal machine.
|
||||||
|
|
||||||
|
## Commit and Pull Request Guidelines
|
||||||
|
|
||||||
|
Recent history favors short, lowercase, imperative subjects such as `fix` and
|
||||||
|
`update action`; automated dependency commits use `chore(deps): ...`. Prefer a
|
||||||
|
specific summary that states the affected area, such as
|
||||||
|
`shells: add deployment tools`. Keep commits focused. Pull requests should
|
||||||
|
explain the motivation, list affected hosts or profiles, report validation
|
||||||
|
commands, and note any manual migration or secret-management steps. Include
|
||||||
|
screenshots only for visible desktop or application configuration changes.
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
# Fingerprint Commands
|
||||||
|
|
||||||
|
This note covers the basic `fprintd` commands used by the fingerprint module.
|
||||||
|
|
||||||
|
## Enroll a new fingerprint
|
||||||
|
|
||||||
|
Register a fingerprint for the current user:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
fprintd-enroll $USER
|
||||||
|
```
|
||||||
|
|
||||||
|
To enroll a specific finger, pass the finger name:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
fprintd-enroll -f right-index-finger $USER
|
||||||
|
```
|
||||||
|
|
||||||
|
Common finger names include:
|
||||||
|
|
||||||
|
- `left-thumb`
|
||||||
|
- `left-index-finger`
|
||||||
|
- `right-thumb`
|
||||||
|
- `right-index-finger`
|
||||||
|
|
||||||
|
Follow the prompts and swipe or touch the sensor until enrollment completes.
|
||||||
|
|
||||||
|
## List enrolled fingerprints
|
||||||
|
|
||||||
|
Show fingerprints registered for the current user:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
fprintd-list $USER
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also list fingerprints for another user:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
fprintd-list <username>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Delete fingerprints
|
||||||
|
|
||||||
|
Delete one enrolled fingerprint for the current user:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
fprintd-delete
|
||||||
|
```
|
||||||
|
|
||||||
|
Delete all enrolled fingerprints for the current user:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
fprintd-delete $USER
|
||||||
|
```
|
||||||
|
|
||||||
|
Delete fingerprints for another user:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
fprintd-delete <username>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Verify authentication
|
||||||
|
|
||||||
|
Test fingerprint authentication for the current user:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
fprintd-verify
|
||||||
|
```
|
||||||
+157
@@ -0,0 +1,157 @@
|
|||||||
|
# NixOSインストール手順
|
||||||
|
|
||||||
|
## 事前準備
|
||||||
|
|
||||||
|
1. [ISOビルド](iso-build.md)を参照してISOを作成
|
||||||
|
2. USBに書き込んで対象マシンでブート
|
||||||
|
|
||||||
|
## ネットワーク接続
|
||||||
|
|
||||||
|
### 有線LAN
|
||||||
|
|
||||||
|
DHCPで自動設定される。
|
||||||
|
|
||||||
|
### WiFi(有線が使えない場合)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nmcli device wifi connect <SSID> --ask
|
||||||
|
```
|
||||||
|
|
||||||
|
## SSH接続
|
||||||
|
|
||||||
|
コンソールに表示されたIPアドレスに接続:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh root@<ip-address>
|
||||||
|
```
|
||||||
|
|
||||||
|
## インストール手順
|
||||||
|
|
||||||
|
### 1. dotfilesのクローン
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone [email protected]:moons-14/dotfiles.git ~/dotfiles
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. SSHホストキーの生成
|
||||||
|
|
||||||
|
新しいホスト用のSSHホストキーを生成:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh-keygen -t ed25519 -f /tmp/ssh_host_ed25519_key -N ""
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. age公開鍵の取得
|
||||||
|
|
||||||
|
SSHホストキーからage公開鍵を取得:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh-to-age -i /tmp/ssh_host_ed25519_key.pub
|
||||||
|
```
|
||||||
|
|
||||||
|
出力されたage公開鍵をコピー。
|
||||||
|
|
||||||
|
### 4. .sops.yamlの編集
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ~/dotfiles
|
||||||
|
vim .sops.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
以下を追加:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
keys:
|
||||||
|
- &host_<hostname> <age公開鍵>
|
||||||
|
|
||||||
|
creation_rules:
|
||||||
|
- path_regex: ^secrets/hosts/<hostname>/[^/]+\.ya?ml$
|
||||||
|
key_groups:
|
||||||
|
- age:
|
||||||
|
- *admin_yubikey1
|
||||||
|
- *host_<hostname>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. シークレットの再暗号化
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sops updatekeys secrets/common/system.yaml
|
||||||
|
sops updatekeys secrets/hosts/<hostname>/*.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6. disko設定の作成
|
||||||
|
|
||||||
|
新しいホスト用の`hosts/<hostname>/disko.nix`を作成。
|
||||||
|
|
||||||
|
#### シンプル構成(暗号化なし)
|
||||||
|
|
||||||
|
```nix
|
||||||
|
_:
|
||||||
|
{
|
||||||
|
disko.enableConfig = true;
|
||||||
|
|
||||||
|
disko.devices.disk.main = {
|
||||||
|
type = "disk";
|
||||||
|
device = "/dev/sda";
|
||||||
|
content = {
|
||||||
|
type = "gpt";
|
||||||
|
partitions = {
|
||||||
|
ESP = {
|
||||||
|
size = "512M";
|
||||||
|
type = "EF00";
|
||||||
|
content = {
|
||||||
|
type = "filesystem";
|
||||||
|
format = "vfat";
|
||||||
|
mountpoint = "/boot";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
root = {
|
||||||
|
size = "100%";
|
||||||
|
content = {
|
||||||
|
type = "filesystem";
|
||||||
|
format = "ext4";
|
||||||
|
mountpoint = "/";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### LUKS暗号化 + btrfs
|
||||||
|
|
||||||
|
`hosts/x1g13/disko.nix`を参照。
|
||||||
|
|
||||||
|
### 7. ディスクのパーティション
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ~/dotfiles
|
||||||
|
nix run github:nix-community/disko -- --mode disko hosts/<hostname>/disko.nix
|
||||||
|
```
|
||||||
|
|
||||||
|
### 8. ホストキーのコピー
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p /mnt/etc/ssh
|
||||||
|
cp /tmp/ssh_host_ed25519_key* /mnt/etc/ssh/
|
||||||
|
chmod 600 /mnt/etc/ssh/ssh_host_ed25519_key
|
||||||
|
```
|
||||||
|
|
||||||
|
### 9. NixOSインストール
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nixos-install --flake ~/dotfiles#<hostname>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 10. 再起動
|
||||||
|
|
||||||
|
```bash
|
||||||
|
reboot
|
||||||
|
```
|
||||||
|
|
||||||
|
## インストール後の確認
|
||||||
|
|
||||||
|
- SSHでログインできるか
|
||||||
|
- sopsシークレットが復号できるか
|
||||||
|
- diskoでパーティションが正しく設定されているか
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
# iOS Simulator 初期セットアップ
|
||||||
|
|
||||||
|
この手順は `m2` の macOS 環境で、stable Xcode と最新の stable iOS Simulator Runtime を使える状態にするためのもの。
|
||||||
|
|
||||||
|
## 前提
|
||||||
|
|
||||||
|
- `m2` が `workload.development` profile を有効にしていること
|
||||||
|
- Mac App Store に Apple Account でサインイン済みであること
|
||||||
|
- dotfiles を最新化していること
|
||||||
|
|
||||||
|
Xcode 本体は `applications.xcode` が Mac App Store 版を管理する。Simulator Runtime は Apple が管理する mutable state のため、Nix store には入れず専用 dev shell から導入する。
|
||||||
|
|
||||||
|
## 1. macOS 設定を反映する
|
||||||
|
|
||||||
|
リポジトリ直下で nix-darwin の設定を反映する。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo darwin-rebuild switch --flake .#m2
|
||||||
|
```
|
||||||
|
|
||||||
|
これにより `/Applications/Xcode.app` に stable Xcode がインストールされる。
|
||||||
|
|
||||||
|
Xcode のインストールで Mac App Store の認証エラーになる場合は、App Store を一度開いてサインイン状態を確認してから再実行する。
|
||||||
|
|
||||||
|
## 2. iOS Simulator Runtime を導入する
|
||||||
|
|
||||||
|
初回セットアップは次の1コマンドで行う。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nix develop .#ios -c ios-simulator-install
|
||||||
|
```
|
||||||
|
|
||||||
|
`ios-simulator-install` は次を順に実行する。
|
||||||
|
|
||||||
|
1. `/Applications/Xcode.app` が存在することを確認
|
||||||
|
2. `xcode-select` の Developer Directory を stable Xcode に切り替え
|
||||||
|
3. Xcode の first-launch components を導入
|
||||||
|
4. 利用可能な新しい hardware support components を確認
|
||||||
|
5. 選択中の Xcode に対応する最新の iOS Simulator Runtime をダウンロードしてインストール
|
||||||
|
6. Xcode のバージョンとインストール済み Simulator Runtime を表示
|
||||||
|
|
||||||
|
途中で `sudo` の認証を求められる場合がある。
|
||||||
|
|
||||||
|
## 3. インストールを確認する
|
||||||
|
|
||||||
|
```bash
|
||||||
|
xcodebuild -version
|
||||||
|
xcode-select -p
|
||||||
|
xcrun simctl list runtimes
|
||||||
|
xcrun simctl list devices available
|
||||||
|
```
|
||||||
|
|
||||||
|
`xcode-select -p` は次を指していること。
|
||||||
|
|
||||||
|
```text
|
||||||
|
/Applications/Xcode.app/Contents/Developer
|
||||||
|
```
|
||||||
|
|
||||||
|
`xcrun simctl list runtimes` に iOS runtime が表示されればセットアップ完了。
|
||||||
|
|
||||||
|
## 4. Simulator を起動する
|
||||||
|
|
||||||
|
```bash
|
||||||
|
open -a Simulator
|
||||||
|
```
|
||||||
|
|
||||||
|
Simulator の Device メニューから、インストール済み runtime で利用可能な iPhone を選択する。
|
||||||
|
|
||||||
|
## Runtime の更新
|
||||||
|
|
||||||
|
Xcode を stable の新しいバージョンへ更新した後は、同じコマンドを再実行する。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nix develop .#ios -c ios-simulator-install
|
||||||
|
```
|
||||||
|
|
||||||
|
Xcode の選択、first-launch components、hardware support、iOS Simulator Runtime の状態をまとめて更新できる。
|
||||||
|
|
||||||
|
## トラブルシューティング
|
||||||
|
|
||||||
|
### Xcode が見つからない
|
||||||
|
|
||||||
|
次のエラーが出る場合、先に nix-darwin の設定を反映する。
|
||||||
|
|
||||||
|
```text
|
||||||
|
Xcode is not installed at /Applications/Xcode.app.
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo darwin-rebuild switch --flake .#m2
|
||||||
|
```
|
||||||
|
|
||||||
|
### Simulator Runtime が見えない
|
||||||
|
|
||||||
|
まず runtime 一覧を確認する。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
xcrun simctl list runtimes
|
||||||
|
```
|
||||||
|
|
||||||
|
iOS runtime がない場合は再度インストーラーを実行する。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nix develop .#ios -c ios-simulator-install
|
||||||
|
```
|
||||||
|
|
||||||
|
### Command Line Tools 側を参照している
|
||||||
|
|
||||||
|
```bash
|
||||||
|
xcode-select -p
|
||||||
|
```
|
||||||
|
|
||||||
|
が `/Library/Developer/CommandLineTools` を指している場合でも、`ios-simulator-install` が `/Applications/Xcode.app/Contents/Developer` へ切り替える。
|
||||||
|
|
||||||
|
手動で直す場合は次を実行する。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
|
||||||
|
```
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
# カスタムISOビルド
|
||||||
|
|
||||||
|
## ビルド
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nix build .#nixosConfigurations.installer.config.system.build.isoImage
|
||||||
|
```
|
||||||
|
|
||||||
|
## ISO書き込み
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# USBデバイスの確認
|
||||||
|
lsblk
|
||||||
|
|
||||||
|
# 書き込み(/dev/sdXは実際のデバイスに置き換える)
|
||||||
|
sudo dd if=./result/nixos-minimal-*.iso of=/dev/sdX bs=4M status=progress
|
||||||
|
sync
|
||||||
|
```
|
||||||
|
|
||||||
|
## ISOの特徴
|
||||||
|
|
||||||
|
- SSH鍵認証でrootログイン可能
|
||||||
|
- 有線LANはDHCPで自動設定
|
||||||
|
- WiFiは`nmcli`で手動設定可能
|
||||||
|
- disko/sops/ageなどのツールを内蔵
|
||||||
|
- ブート時にIPアドレスとヘルプを表示
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Generate Sops key file
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p ~/.config/sops/age
|
||||||
|
chmod 700 ~/.config/sops/age
|
||||||
|
|
||||||
|
age-plugin-yubikey --identity --slot 1 \
|
||||||
|
> ~/.config/sops/age/yubikey-identity.txt
|
||||||
|
|
||||||
|
chmod 600 ~/.config/sops/age/yubikey-identity.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
## Edit sops file
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sops secrets/common/system.yaml
|
||||||
|
```
|
||||||
Generated
+932
-270
File diff suppressed because it is too large
Load Diff
@@ -11,6 +11,11 @@
|
|||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
nix-darwin = {
|
||||||
|
url = "github:nix-darwin/nix-darwin/nix-darwin-26.05";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
|
||||||
# Hardware / Platform
|
# Hardware / Platform
|
||||||
nixos-hardware.url = "github:NixOS/nixos-hardware/master";
|
nixos-hardware.url = "github:NixOS/nixos-hardware/master";
|
||||||
nixos-wsl.url = "github:nix-community/NixOS-WSL";
|
nixos-wsl.url = "github:nix-community/NixOS-WSL";
|
||||||
@@ -18,6 +23,11 @@
|
|||||||
# Desktop
|
# Desktop
|
||||||
niri-flake.url = "github:sodiboo/niri-flake";
|
niri-flake.url = "github:sodiboo/niri-flake";
|
||||||
|
|
||||||
|
nix-hazkey = {
|
||||||
|
url = "github:aster-void/nix-hazkey";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
|
||||||
stylix = {
|
stylix = {
|
||||||
url = "github:nix-community/stylix";
|
url = "github:nix-community/stylix";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
@@ -25,7 +35,7 @@
|
|||||||
|
|
||||||
# Terminal
|
# Terminal
|
||||||
ghostty = {
|
ghostty = {
|
||||||
url = "github:moons-14/ghostty";
|
url = "github:ghostty-org/ghostty";
|
||||||
};
|
};
|
||||||
|
|
||||||
# Shell / Launcher
|
# Shell / Launcher
|
||||||
@@ -36,10 +46,7 @@
|
|||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
|
||||||
noctalia = {
|
noctalia.url = "github:noctalia-dev/noctalia/cachix";
|
||||||
url = "github:noctalia-dev/noctalia";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
};
|
|
||||||
|
|
||||||
# Editor
|
# Editor
|
||||||
nixvim = {
|
nixvim = {
|
||||||
@@ -53,6 +60,11 @@
|
|||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
deploy-rs = {
|
||||||
|
url = "github:serokell/deploy-rs";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
|
||||||
# Disk management
|
# Disk management
|
||||||
disko = {
|
disko = {
|
||||||
url = "github:nix-community/disko";
|
url = "github:nix-community/disko";
|
||||||
@@ -84,6 +96,13 @@
|
|||||||
url = "github:ilysenko/codex-desktop-linux";
|
url = "github:ilysenko/codex-desktop-linux";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
codex-session-usage.url = "github:moons-14/codex-session-usage";
|
||||||
|
|
||||||
|
skills = {
|
||||||
|
url = "github:mattpocock/skills";
|
||||||
|
flake = false;
|
||||||
|
};
|
||||||
|
|
||||||
# Index / Search
|
# Index / Search
|
||||||
nix-index-database = {
|
nix-index-database = {
|
||||||
url = "github:nix-community/nix-index-database";
|
url = "github:nix-community/nix-index-database";
|
||||||
@@ -91,7 +110,15 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
# Systems
|
# Systems
|
||||||
systems.url = "github:nix-systems/default-linux";
|
systems.url = "github:nix-systems/default";
|
||||||
|
|
||||||
|
browser-previews = {
|
||||||
|
url = "github:nix-community/browser-previews";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
|
||||||
|
nani-translate-linux.url = "git+https://github.com/zunoser/nani-translate-linux.git";
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs =
|
outputs =
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
|
./deploy.nix
|
||||||
./formatter.nix
|
./formatter.nix
|
||||||
./git-hooks.nix
|
./git-hooks.nix
|
||||||
|
./registry.nix
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
inputs,
|
||||||
|
self,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
flake.deploy = {
|
||||||
|
nodes.nix-builder = {
|
||||||
|
hostname = "nix-builder";
|
||||||
|
sshUser = "moons";
|
||||||
|
user = "root";
|
||||||
|
|
||||||
|
interactiveSudo = true;
|
||||||
|
remoteBuild = true;
|
||||||
|
autoRollback = true;
|
||||||
|
magicRollback = true;
|
||||||
|
|
||||||
|
profiles.system.path = inputs.deploy-rs.lib.x86_64-linux.activate.nixos self.nixosConfigurations.nix-builder;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
perSystem =
|
||||||
|
{ system, ... }:
|
||||||
|
{
|
||||||
|
apps.deploy = inputs.deploy-rs.apps.${system}.default;
|
||||||
|
checks = inputs.deploy-rs.lib.${system}.deployChecks self.deploy;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
{
|
||||||
|
inputs,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
dotfilesLib = import ../libs {
|
||||||
|
inherit inputs lib;
|
||||||
|
root = ../.;
|
||||||
|
};
|
||||||
|
hostSpecsPath = ../hosts/default.nix;
|
||||||
|
hostSpecs =
|
||||||
|
if builtins.pathExists hostSpecsPath then
|
||||||
|
let
|
||||||
|
value = import hostSpecsPath;
|
||||||
|
in
|
||||||
|
if builtins.isFunction value then
|
||||||
|
value (
|
||||||
|
builtins.intersectAttrs (builtins.functionArgs value) {
|
||||||
|
inherit inputs lib;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
else
|
||||||
|
value
|
||||||
|
else
|
||||||
|
{ };
|
||||||
|
configurations = dotfilesLib.hosts.mkConfigurations hostSpecs;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
flake = {
|
||||||
|
inherit (configurations) darwinConfigurations nixosConfigurations;
|
||||||
|
lib = dotfilesLib;
|
||||||
|
};
|
||||||
|
|
||||||
|
perSystem =
|
||||||
|
{ pkgs, system, ... }:
|
||||||
|
let
|
||||||
|
nixosChecks =
|
||||||
|
lib.mapAttrs' (name: nixos: lib.nameValuePair "nixos-${name}" nixos.config.system.build.toplevel)
|
||||||
|
(
|
||||||
|
lib.filterAttrs (
|
||||||
|
_: nixos: nixos.pkgs.stdenv.hostPlatform.system == system
|
||||||
|
) configurations.nixosConfigurations
|
||||||
|
);
|
||||||
|
in
|
||||||
|
{
|
||||||
|
checks = {
|
||||||
|
registry = import ../tests/registry.nix {
|
||||||
|
inherit inputs lib pkgs;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// nixosChecks;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
{
|
||||||
|
nix-builder = {
|
||||||
|
system = "x86_64-linux";
|
||||||
|
stateVersion = "26.05";
|
||||||
|
user = "moons";
|
||||||
|
path = ./nix-builder;
|
||||||
|
|
||||||
|
profiles = [
|
||||||
|
"base"
|
||||||
|
"interface.cli"
|
||||||
|
"networking.tailscale-client"
|
||||||
|
"platform.vm"
|
||||||
|
"workload.nix-builder"
|
||||||
|
"workload.remote-access"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
installer = {
|
||||||
|
system = "x86_64-linux";
|
||||||
|
stateVersion = "26.05";
|
||||||
|
user = "moons";
|
||||||
|
path = ./installer;
|
||||||
|
homeManager = false;
|
||||||
|
|
||||||
|
profiles = [ "base" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
x1g9 = {
|
||||||
|
system = "x86_64-linux";
|
||||||
|
stateVersion = "26.05";
|
||||||
|
user = "moons";
|
||||||
|
path = ./x1g9;
|
||||||
|
|
||||||
|
profiles = [
|
||||||
|
"base"
|
||||||
|
"interface.cli"
|
||||||
|
"interface.labwc"
|
||||||
|
"interface.niri"
|
||||||
|
"platform.thinkpad-x1"
|
||||||
|
"security.fingerprint"
|
||||||
|
# "security.secrets"
|
||||||
|
"workload.personal"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
x1g13 = {
|
||||||
|
system = "x86_64-linux";
|
||||||
|
stateVersion = "26.05";
|
||||||
|
user = "moons";
|
||||||
|
path = ./x1g13;
|
||||||
|
|
||||||
|
profiles = [
|
||||||
|
"base"
|
||||||
|
"interface.cli"
|
||||||
|
"interface.labwc"
|
||||||
|
"interface.niri"
|
||||||
|
"networking.tailscale-client"
|
||||||
|
"platform.thinkpad-x1"
|
||||||
|
"security.fingerprint"
|
||||||
|
"security.secrets"
|
||||||
|
"security.secure-boot"
|
||||||
|
"security.tpm-storage"
|
||||||
|
"workload.development"
|
||||||
|
"workload.game"
|
||||||
|
"workload.personal"
|
||||||
|
];
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
galleria = {
|
||||||
|
system = "x86_64-linux";
|
||||||
|
stateVersion = "26.05";
|
||||||
|
user = "moons";
|
||||||
|
path = ./galleria;
|
||||||
|
|
||||||
|
profiles = [
|
||||||
|
"base"
|
||||||
|
"interface.cli"
|
||||||
|
"interface.labwc"
|
||||||
|
"interface.niri"
|
||||||
|
"networking.tailscale-client"
|
||||||
|
"platform.intel-nvidia-desktop"
|
||||||
|
"security.secrets"
|
||||||
|
"security.secure-boot"
|
||||||
|
"security.tpm-storage"
|
||||||
|
"security.fingerprint"
|
||||||
|
"workload.development"
|
||||||
|
"workload.game"
|
||||||
|
"workload.machine-learning"
|
||||||
|
"workload.personal"
|
||||||
|
"workload.camera"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
m2 = {
|
||||||
|
system = "aarch64-darwin";
|
||||||
|
stateVersion = "26.05";
|
||||||
|
user = "moons";
|
||||||
|
path = ./m2;
|
||||||
|
|
||||||
|
profiles = [
|
||||||
|
"base"
|
||||||
|
"interface.cli"
|
||||||
|
"interface.macos"
|
||||||
|
"security.fingerprint"
|
||||||
|
# "security.secrets"
|
||||||
|
"workload.development"
|
||||||
|
"workload.game"
|
||||||
|
"workload.personal"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
_:
|
||||||
|
let
|
||||||
|
espPart = "/dev/disk/by-partuuid/008b04ef-9c06-4049-bffb-3906f5c3a9c1";
|
||||||
|
nixosPart = "/dev/disk/by-partuuid/04295552-cbb8-4511-ac1e-1171ec20f8d1";
|
||||||
|
|
||||||
|
btrfsMountOptions = [
|
||||||
|
"compress=zstd"
|
||||||
|
"noatime"
|
||||||
|
"ssd"
|
||||||
|
"space_cache=v2"
|
||||||
|
];
|
||||||
|
in
|
||||||
|
{
|
||||||
|
disko.enableConfig = true;
|
||||||
|
|
||||||
|
# These are deliberately partition paths, not the whole Windows disk. Disko
|
||||||
|
# must never own or destroy the disk's GPT or any Windows partition.
|
||||||
|
disko.devices.disk = {
|
||||||
|
esp = {
|
||||||
|
type = "disk";
|
||||||
|
device = espPart;
|
||||||
|
destroy = false;
|
||||||
|
|
||||||
|
content = {
|
||||||
|
type = "filesystem";
|
||||||
|
format = "vfat";
|
||||||
|
mountpoint = "/boot";
|
||||||
|
mountOptions = [ "umask=0077" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
nixos = {
|
||||||
|
type = "disk";
|
||||||
|
device = nixosPart;
|
||||||
|
destroy = false;
|
||||||
|
|
||||||
|
content = {
|
||||||
|
type = "luks";
|
||||||
|
name = "cryptroot";
|
||||||
|
askPassword = true;
|
||||||
|
settings.allowDiscards = true;
|
||||||
|
|
||||||
|
extraFormatArgs = [
|
||||||
|
"--type"
|
||||||
|
"luks2"
|
||||||
|
"--pbkdf"
|
||||||
|
"argon2id"
|
||||||
|
"--label"
|
||||||
|
"NixOS-LUKS"
|
||||||
|
];
|
||||||
|
|
||||||
|
content = {
|
||||||
|
type = "btrfs";
|
||||||
|
extraArgs = [
|
||||||
|
"-f"
|
||||||
|
"-L"
|
||||||
|
"NixOS"
|
||||||
|
];
|
||||||
|
|
||||||
|
subvolumes = {
|
||||||
|
"@root" = {
|
||||||
|
mountpoint = "/";
|
||||||
|
mountOptions = btrfsMountOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
"@home" = {
|
||||||
|
mountpoint = "/home";
|
||||||
|
mountOptions = btrfsMountOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
"@nix" = {
|
||||||
|
mountpoint = "/nix";
|
||||||
|
mountOptions = btrfsMountOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
"@log" = {
|
||||||
|
mountpoint = "/var/log";
|
||||||
|
mountOptions = btrfsMountOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
"@swap" = {
|
||||||
|
mountpoint = "/.swapvol";
|
||||||
|
mountOptions = [ "noatime" ];
|
||||||
|
swap.swapfile.size = "32G";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||||
|
# and may be overwritten by future invocations. Please make changes
|
||||||
|
# to /etc/nixos/configuration.nix instead.
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
modulesPath,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
(modulesPath + "/installer/scan/not-detected.nix")
|
||||||
|
];
|
||||||
|
|
||||||
|
boot.initrd.availableKernelModules = [
|
||||||
|
"xhci_pci"
|
||||||
|
"ahci"
|
||||||
|
"nvme"
|
||||||
|
"usbhid"
|
||||||
|
"usb_storage"
|
||||||
|
"sd_mod"
|
||||||
|
];
|
||||||
|
boot.initrd.kernelModules = [ ];
|
||||||
|
boot.kernelModules = [ "kvm-intel" ];
|
||||||
|
boot.extraModulePackages = [ ];
|
||||||
|
|
||||||
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
|
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
{
|
||||||
|
lib,
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
# This desktop is permanently connected to AC power.
|
||||||
|
systemd.user.services.swayidle.Service.Environment = [
|
||||||
|
"SWAYIDLE_ASSUME_AC=1"
|
||||||
|
];
|
||||||
|
|
||||||
|
services.kanshi = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
settings = [
|
||||||
|
{
|
||||||
|
profile = {
|
||||||
|
name = "galleria";
|
||||||
|
|
||||||
|
outputs = [
|
||||||
|
{
|
||||||
|
criteria = "HDMI-A-1";
|
||||||
|
status = "enable";
|
||||||
|
position = "0,0";
|
||||||
|
scale = 1.5;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
criteria = "DP-1";
|
||||||
|
status = "enable";
|
||||||
|
position = "2560,0";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
criteria = "DP-2";
|
||||||
|
status = "enable";
|
||||||
|
position = "5120,0";
|
||||||
|
scale = 1.5;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
home.file.".wallpapers" = {
|
||||||
|
source = lib.mkForce (
|
||||||
|
config.lib.file.mkOutOfStoreSymlink "${config.home.homeDirectory}/Pictures/wallpapers"
|
||||||
|
);
|
||||||
|
|
||||||
|
recursive = lib.mkForce false;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
{ inputs, pkgs, ... }:
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./hardware-configuration.nix
|
||||||
|
./disko.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
boot.initrd.luks.devices.cryptroot.device =
|
||||||
|
"/dev/disk/by-partuuid/04295552-cbb8-4511-ac1e-1171ec20f8d1";
|
||||||
|
|
||||||
|
# Keep Windows data and recovery partitions out of UDisks-based file
|
||||||
|
# managers. The shared EFI System Partition stays available as /boot.
|
||||||
|
services.udev.extraRules = ''
|
||||||
|
ENV{ID_PART_ENTRY_UUID}=="0480f887-d1f9-489d-b8fe-78549ced1938", ENV{UDISKS_IGNORE}="1"
|
||||||
|
ENV{ID_PART_ENTRY_UUID}=="6c70041b-3f65-4eb1-8b08-18ed20001877", ENV{UDISKS_IGNORE}="1"
|
||||||
|
'';
|
||||||
|
|
||||||
|
environment.systemPackages = with inputs.browser-previews.packages.${pkgs.system}; [
|
||||||
|
google-chrome-beta
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,195 @@
|
|||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
modulesPath,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
imports = [ "${modulesPath}/installer/cd-dvd/installation-cd-minimal.nix" ];
|
||||||
|
|
||||||
|
boot.zfs.forceImportRoot = false;
|
||||||
|
|
||||||
|
networking = {
|
||||||
|
hostName = "nixos-installer";
|
||||||
|
|
||||||
|
networkmanager = {
|
||||||
|
enable = true;
|
||||||
|
wifi.powersave = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.openssh = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
PermitRootLogin = "prohibit-password";
|
||||||
|
PasswordAuthentication = false;
|
||||||
|
KbdInteractiveAuthentication = false;
|
||||||
|
PubkeyAuthentication = "yes";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
users.users.root.openssh.authorizedKeys.keys = [
|
||||||
|
"sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIKhxDkucmeCor6CKoXAua7DgDSzuXrZOtpdkyzQxz5+aAAAABHNzaDo= moons@moons14.com"
|
||||||
|
"sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIN6hZJyng/5LgFKPjR6uZAd/00UkO0vN0uQOoIvfSELdAAAABHNzaDo= moons@moons14.com"
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLwReAiwhXoO34S2+MrvqUhi8IWp4IzUq4OSp3niJdq"
|
||||||
|
];
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
git
|
||||||
|
disko
|
||||||
|
sops
|
||||||
|
age
|
||||||
|
ssh-to-age
|
||||||
|
age-plugin-yubikey
|
||||||
|
yubikey-manager
|
||||||
|
pcsc-tools
|
||||||
|
mkpasswd
|
||||||
|
rsync
|
||||||
|
vim
|
||||||
|
wget
|
||||||
|
curl
|
||||||
|
jq
|
||||||
|
parted
|
||||||
|
cryptsetup
|
||||||
|
btrfs-progs
|
||||||
|
efibootmgr
|
||||||
|
pciutils
|
||||||
|
sbctl
|
||||||
|
tpm2-tools
|
||||||
|
util-linux
|
||||||
|
];
|
||||||
|
|
||||||
|
services.pcscd.enable = true;
|
||||||
|
|
||||||
|
environment.etc."installer-help.txt".text = ''
|
||||||
|
|
||||||
|
╔══════════════════════════════════════════════════════════════╗
|
||||||
|
║ NixOS Installer ISO ║
|
||||||
|
╠══════════════════════════════════════════════════════════════╣
|
||||||
|
║ ║
|
||||||
|
║ SSH Access: ║
|
||||||
|
║ ssh root@<ip-address> ║
|
||||||
|
║ ║
|
||||||
|
║ Network Setup: ║
|
||||||
|
║ Wired: Auto-configured via DHCP ║
|
||||||
|
║ WiFi: nmcli device wifi connect <SSID> --ask ║
|
||||||
|
║ ║
|
||||||
|
║ Installation Workflow: ║
|
||||||
|
║ ║
|
||||||
|
║ 1. Clone dotfiles: ║
|
||||||
|
║ git clone git@github.com:moons-14/dotfiles.git ~/dotfiles║
|
||||||
|
║ ║
|
||||||
|
║ 2. Generate SSH host key for new host: ║
|
||||||
|
║ ssh-keygen -t ed25519 -f /tmp/ssh_host_ed25519_key -N "" ║
|
||||||
|
║ ║
|
||||||
|
║ 3. Get age public key from SSH host key: ║
|
||||||
|
║ ssh-to-age -i /tmp/ssh_host_ed25519_key.pub ║
|
||||||
|
║ ║
|
||||||
|
║ 4. Add age key to .sops.yaml: ║
|
||||||
|
║ cd ~/dotfiles ║
|
||||||
|
║ # Edit .sops.yaml and add the age key ║
|
||||||
|
║ # Add new host entry to creation_rules ║
|
||||||
|
║ ║
|
||||||
|
║ 5. Re-encrypt secrets: ║
|
||||||
|
║ sops updatekeys secrets/common/system.yaml ║
|
||||||
|
║ sops updatekeys secrets/hosts/<host>/*.yaml ║
|
||||||
|
║ ║
|
||||||
|
║ 6. Create disko.nix for new host: ║
|
||||||
|
║ # Check disk devices ║
|
||||||
|
║ lsblk -f ║
|
||||||
|
║ ║
|
||||||
|
║ # Create hosts/<host>/disko.nix ║
|
||||||
|
║ # Example: LUKS + btrfs ║
|
||||||
|
║ # See hosts/x1g13/disko.nix for reference ║
|
||||||
|
║ ║
|
||||||
|
║ 7. Partition disk with disko: ║
|
||||||
|
║ nix run github:nix-community/disko -- \ ║
|
||||||
|
║ --mode disko hosts/<host>/disko.nix ║
|
||||||
|
║ ║
|
||||||
|
║ 8. Copy host key to installed system: ║
|
||||||
|
║ mkdir -p /mnt/etc/ssh ║
|
||||||
|
║ cp /tmp/ssh_host_ed25519_key* /mnt/etc/ssh/ ║
|
||||||
|
║ chmod 600 /mnt/etc/ssh/ssh_host_ed25519_key ║
|
||||||
|
║ ║
|
||||||
|
║ 9. Install NixOS: ║
|
||||||
|
║ nixos-install --flake ~/dotfiles#<host> ║
|
||||||
|
║ ║
|
||||||
|
║ Disko Configuration Examples: ║
|
||||||
|
║ ║
|
||||||
|
║ Simple (no encryption): ║
|
||||||
|
║ disko.devices.disk.main = { ║
|
||||||
|
║ type = "disk"; ║
|
||||||
|
║ device = "/dev/sda"; ║
|
||||||
|
║ content = { ║
|
||||||
|
║ type = "gpt"; ║
|
||||||
|
║ partitions = { ║
|
||||||
|
║ ESP = { size = "512M"; type = "EF00"; ║
|
||||||
|
║ content = { type = "filesystem"; ║
|
||||||
|
║ format = "vfat"; mountpoint = "/boot"; }; }; ║
|
||||||
|
║ root = { size = "100%"; ║
|
||||||
|
║ content = { type = "filesystem"; ║
|
||||||
|
║ format = "ext4"; mountpoint = "/"; }; }; ║
|
||||||
|
║ }; ║
|
||||||
|
║ }; ║
|
||||||
|
║ }; ║
|
||||||
|
║ ║
|
||||||
|
║ LUKS + btrfs (see hosts/x1g13/disko.nix): ║
|
||||||
|
║ - Use partuuid for device path ║
|
||||||
|
║ - Set askPassword = true for LUKS ║
|
||||||
|
║ - Configure btrfs subvolumes ║
|
||||||
|
║ ║
|
||||||
|
╚══════════════════════════════════════════════════════════════╝
|
||||||
|
|
||||||
|
'';
|
||||||
|
|
||||||
|
systemd.services.installer-banner = {
|
||||||
|
description = "Display installer help on console";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
ExecStart = "${pkgs.coreutils}/bin/cat /etc/installer-help.txt";
|
||||||
|
StandardOutput = "tty";
|
||||||
|
TTYPath = "/dev/tty1";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.display-ip = {
|
||||||
|
description = "Display IP address on console";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
after = [ "network-online.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
ExecStart = pkgs.writeShellScript "display-ip" ''
|
||||||
|
sleep 2
|
||||||
|
echo ""
|
||||||
|
echo "=== Network Interfaces ==="
|
||||||
|
${pkgs.iproute2}/bin/ip -4 addr show | ${pkgs.gnugrep}/bin/grep inet
|
||||||
|
echo ""
|
||||||
|
echo "=== SSH Access ==="
|
||||||
|
for ip in $(${pkgs.iproute2}/bin/ip -4 addr show | ${pkgs.gnugrep}/bin/grep -oP 'inet \K[\d.]+' | ${pkgs.gnugrep}/bin/grep -v '127.0.0.1'); do
|
||||||
|
echo " ssh root@$ip"
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
'';
|
||||||
|
StandardOutput = "tty";
|
||||||
|
TTYPath = "/dev/tty1";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
nix = {
|
||||||
|
settings = {
|
||||||
|
experimental-features = [
|
||||||
|
"nix-command"
|
||||||
|
"flakes"
|
||||||
|
];
|
||||||
|
trusted-users = [ "root" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
extraOptions = ''
|
||||||
|
experimental-features = nix-command flakes
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
{ hostName, ... }:
|
||||||
|
{
|
||||||
|
# networking.hostName and networking.localHostName are derived from the
|
||||||
|
# registry name; computerName controls the user-visible macOS name.
|
||||||
|
networking.computerName = hostName;
|
||||||
|
|
||||||
|
# Keep this value stable after the first activation. It is independent of
|
||||||
|
# the Home Manager stateVersion in hosts/default.nix.
|
||||||
|
system.stateVersion = 7;
|
||||||
|
}
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
# nix-builder bootstrap
|
||||||
|
|
||||||
|
The host configuration can be built before its cache signing secret exists.
|
||||||
|
Harmonia's socket remains stopped until SOPS installs the signing key at
|
||||||
|
`/run/secrets/harmonia/signing-key`.
|
||||||
|
|
||||||
|
## Proxmox storage layout
|
||||||
|
|
||||||
|
The host configuration expects three filesystems. Keep the build scratch space
|
||||||
|
separate from the store so a large build cannot fill the root filesystem.
|
||||||
|
|
||||||
|
| Mount point | Suggested size | Contents |
|
||||||
|
| -------------------- | -------------- | ------------------------------- |
|
||||||
|
| `/` | 48 GiB | NixOS and mutable system state |
|
||||||
|
| `/var/lib/nix-build` | 192 GiB | Disposable build scratch space |
|
||||||
|
| `/nix/store` | 1 TiB | Fleet closures and binary cache |
|
||||||
|
|
||||||
|
The build-server policy starts emergency store GC below 64 GiB free and aims
|
||||||
|
for 128 GiB free. Persistent roots under `/var/lib/nix-fleet/roots` protect the
|
||||||
|
latest fleet builds from that GC. It also limits Nix to two concurrent
|
||||||
|
derivations while allowing each derivation to use every vCPU assigned to the
|
||||||
|
VM.
|
||||||
|
|
||||||
|
For the two dedicated ext4 data filesystems, remove the default root-reserved
|
||||||
|
blocks once after formatting; keep the root filesystem's reserve intact:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo tune2fs -m 0 /dev/disk/by-label/nix-build
|
||||||
|
sudo tune2fs -m 0 /dev/disk/by-label/nix-store
|
||||||
|
```
|
||||||
|
|
||||||
|
## Initial deployment
|
||||||
|
|
||||||
|
Once the VM is reachable as `moons@nix-builder`, deploy it from the repository:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nix run .#deploy -- .#nix-builder
|
||||||
|
```
|
||||||
|
|
||||||
|
deploy-rs uses the target's `ssh-ng` store, so the system closure is built on
|
||||||
|
the builder rather than copied from the laptop. Automatic and magic rollback
|
||||||
|
remain enabled.
|
||||||
|
|
||||||
|
## Add the host SOPS recipient
|
||||||
|
|
||||||
|
After the VM has a stable SSH host key, derive its age recipient:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh-keyscan -t ed25519 nix-builder 2>/dev/null | ssh-to-age
|
||||||
|
```
|
||||||
|
|
||||||
|
Add the recipient to `.sops.yaml` and add a creation rule for
|
||||||
|
`secrets/hosts/nix-builder/*.yaml`. The admin YubiKey recipient should remain in
|
||||||
|
the same key group for recovery.
|
||||||
|
|
||||||
|
## Generate the cache signing key
|
||||||
|
|
||||||
|
Run this on a trusted Nix machine, preferably with the temporary files on a
|
||||||
|
tmpfs:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nix-store --generate-binary-cache-key \
|
||||||
|
cache.app.homelabs.run-1 \
|
||||||
|
harmonia.private \
|
||||||
|
harmonia.public
|
||||||
|
```
|
||||||
|
|
||||||
|
Create `secrets/hosts/nix-builder/system.yaml` with SOPS and store the complete
|
||||||
|
contents of `harmonia.private` at `harmonia.signing-key`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
harmonia:
|
||||||
|
signing-key: cache.app.homelabs.run-1:REDACTED
|
||||||
|
```
|
||||||
|
|
||||||
|
Copy the complete contents of `harmonia.public` to
|
||||||
|
`modules/systems/nix/homelab-cache/public-key`. The private plaintext file must
|
||||||
|
not be committed or retained.
|
||||||
|
|
||||||
|
After committing both encrypted/public files, select
|
||||||
|
`networking.homelab-cache-client` on each client host.
|
||||||
|
|
||||||
|
Redeploy the builder and verify the cache after installing the secret:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nix run .#deploy -- .#nix-builder
|
||||||
|
curl --fail http://nix-builder:5000/nix-cache-info
|
||||||
|
```
|
||||||
|
|
||||||
|
## Normal operation
|
||||||
|
|
||||||
|
Run `fleet-build` on the builder to build and root every NixOS host, or pass a
|
||||||
|
list of host names to build only those hosts. Run `fleet-deploy` with the normal
|
||||||
|
deploy-rs target syntax when additional fleet nodes have been added to
|
||||||
|
`flake/deploy.nix`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
fleet-build
|
||||||
|
fleet-build x1g13 galleria
|
||||||
|
fleet-deploy .#nix-builder
|
||||||
|
```
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
fileSystems."/nix/store" = {
|
||||||
|
device = "/dev/disk/by-label/nix-store";
|
||||||
|
fsType = "ext4";
|
||||||
|
|
||||||
|
options = [
|
||||||
|
"noatime"
|
||||||
|
];
|
||||||
|
|
||||||
|
neededForBoot = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/var/lib/nix-build" = {
|
||||||
|
device = "/dev/disk/by-label/nix-build";
|
||||||
|
fsType = "ext4";
|
||||||
|
|
||||||
|
options = [
|
||||||
|
"noatime"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
nix.settings.build-dir = "/var/lib/nix-build";
|
||||||
|
|
||||||
|
services.fstrim.enable = true;
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||||
|
# and may be overwritten by future invocations. Please make changes
|
||||||
|
# to /etc/nixos/configuration.nix instead.
|
||||||
|
{ lib, modulesPath, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
(modulesPath + "/profiles/qemu-guest.nix")
|
||||||
|
];
|
||||||
|
|
||||||
|
boot.initrd.availableKernelModules = [
|
||||||
|
"ata_piix"
|
||||||
|
"uhci_hcd"
|
||||||
|
"virtio_pci"
|
||||||
|
"virtio_scsi"
|
||||||
|
"sd_mod"
|
||||||
|
"sr_mod"
|
||||||
|
];
|
||||||
|
boot.initrd.kernelModules = [ ];
|
||||||
|
boot.kernelModules = [ ];
|
||||||
|
boot.extraModulePackages = [ ];
|
||||||
|
|
||||||
|
fileSystems."/" = {
|
||||||
|
device = "/dev/disk/by-uuid/49fc2e1c-7909-41cc-ac78-55b4d9a01e62";
|
||||||
|
fsType = "ext4";
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/boot" = {
|
||||||
|
device = "/dev/disk/by-uuid/40D4-ABBE";
|
||||||
|
fsType = "vfat";
|
||||||
|
options = [
|
||||||
|
"fmask=0077"
|
||||||
|
"dmask=0077"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
swapDevices = [ ];
|
||||||
|
|
||||||
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
{ lib, ... }:
|
||||||
|
let
|
||||||
|
hostSecrets = ../../secrets/hosts/nix-builder/system.yaml;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./filesystem.nix
|
||||||
|
./hardware-configuration.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
sops.secrets = lib.mkIf (builtins.pathExists hostSecrets) {
|
||||||
|
"harmonia/signing-key" = {
|
||||||
|
sopsFile = hostSecrets;
|
||||||
|
restartUnits = [ "harmonia.service" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.firewall.interfaces."tailscale0".allowedTCPPorts = [ 5000 ];
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
# Do not modify this file! It was generated by `nixos-generate-config` and may
|
||||||
|
# be overwritten by future invocations.
|
||||||
|
{ lib, modulesPath, ... }:
|
||||||
|
{
|
||||||
|
imports = [ (modulesPath + "/profiles/qemu-guest.nix") ];
|
||||||
|
|
||||||
|
boot.initrd.availableKernelModules = [
|
||||||
|
"ata_piix"
|
||||||
|
"uhci_hcd"
|
||||||
|
"virtio_pci"
|
||||||
|
"virtio_scsi"
|
||||||
|
"sd_mod"
|
||||||
|
"sr_mod"
|
||||||
|
];
|
||||||
|
boot.initrd.kernelModules = [ ];
|
||||||
|
boot.kernelModules = [ ];
|
||||||
|
boot.extraModulePackages = [ ];
|
||||||
|
|
||||||
|
fileSystems."/" = {
|
||||||
|
device = "/dev/disk/by-uuid/8f0eaec6-5dc9-4821-aa8d-fb6809b5a5bf";
|
||||||
|
fsType = "ext4";
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/boot" = {
|
||||||
|
device = "/dev/disk/by-uuid/201C-961B";
|
||||||
|
fsType = "vfat";
|
||||||
|
options = [
|
||||||
|
"fmask=0077"
|
||||||
|
"dmask=0077"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
swapDevices = [ ];
|
||||||
|
|
||||||
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
imports = [ ./hardware-configuration.nix ];
|
||||||
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
_:
|
||||||
|
let
|
||||||
|
espPart = "/dev/disk/by-partuuid/a53e3b19-67de-40de-9ded-3eac3117689a";
|
||||||
|
nixosPart = "/dev/disk/by-partuuid/311d0f9c-f35f-42e6-b6fc-a4d67dd21b2e";
|
||||||
|
|
||||||
|
btrfsMountOptions = [
|
||||||
|
"compress=zstd"
|
||||||
|
"noatime"
|
||||||
|
"ssd"
|
||||||
|
"space_cache=v2"
|
||||||
|
];
|
||||||
|
in
|
||||||
|
{
|
||||||
|
disko.enableConfig = true;
|
||||||
|
|
||||||
|
disko.devices.disk = {
|
||||||
|
esp = {
|
||||||
|
type = "disk";
|
||||||
|
device = espPart;
|
||||||
|
destroy = false;
|
||||||
|
|
||||||
|
content = {
|
||||||
|
type = "filesystem";
|
||||||
|
format = "vfat";
|
||||||
|
mountpoint = "/boot";
|
||||||
|
mountOptions = [ "umask=0077" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
nixos = {
|
||||||
|
type = "disk";
|
||||||
|
device = nixosPart;
|
||||||
|
destroy = false;
|
||||||
|
|
||||||
|
content = {
|
||||||
|
type = "luks";
|
||||||
|
name = "cryptroot";
|
||||||
|
askPassword = true;
|
||||||
|
settings.allowDiscards = true;
|
||||||
|
|
||||||
|
extraFormatArgs = [
|
||||||
|
"--type"
|
||||||
|
"luks2"
|
||||||
|
"--pbkdf"
|
||||||
|
"argon2id"
|
||||||
|
"--label"
|
||||||
|
"NixOS-LUKS"
|
||||||
|
];
|
||||||
|
|
||||||
|
content = {
|
||||||
|
type = "btrfs";
|
||||||
|
extraArgs = [
|
||||||
|
"-f"
|
||||||
|
"-L"
|
||||||
|
"NixOS"
|
||||||
|
];
|
||||||
|
|
||||||
|
subvolumes = {
|
||||||
|
"@root" = {
|
||||||
|
mountpoint = "/";
|
||||||
|
mountOptions = btrfsMountOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
"@home" = {
|
||||||
|
mountpoint = "/home";
|
||||||
|
mountOptions = btrfsMountOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
"@nix" = {
|
||||||
|
mountpoint = "/nix";
|
||||||
|
mountOptions = btrfsMountOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
"@log" = {
|
||||||
|
mountpoint = "/var/log";
|
||||||
|
mountOptions = btrfsMountOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
"@swap" = {
|
||||||
|
mountpoint = "/.swapvol";
|
||||||
|
mountOptions = [ "noatime" ];
|
||||||
|
swap.swapfile.size = "32G";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
# Do not modify this file! It was generated by `nixos-generate-config`
|
||||||
|
# and may be overwritten by future invocations. Make changes in nixos.nix.
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
modulesPath,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
(modulesPath + "/installer/scan/not-detected.nix")
|
||||||
|
];
|
||||||
|
|
||||||
|
boot.initrd.availableKernelModules = [
|
||||||
|
"xhci_pci"
|
||||||
|
"thunderbolt"
|
||||||
|
"nvme"
|
||||||
|
"usb_storage"
|
||||||
|
"sd_mod"
|
||||||
|
];
|
||||||
|
boot.initrd.kernelModules = [ ];
|
||||||
|
boot.kernelModules = [ "kvm-intel" ];
|
||||||
|
boot.extraModulePackages = [ ];
|
||||||
|
|
||||||
|
swapDevices = [ ];
|
||||||
|
|
||||||
|
networking.useDHCP = lib.mkDefault true;
|
||||||
|
|
||||||
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
|
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
services.kanshi = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
settings = [
|
||||||
|
{
|
||||||
|
profile = {
|
||||||
|
name = "x1g13";
|
||||||
|
|
||||||
|
outputs = [
|
||||||
|
{
|
||||||
|
criteria = "eDP-1";
|
||||||
|
status = "enable";
|
||||||
|
position = "0,0";
|
||||||
|
scale = 1.5;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./hardware-configuration.nix
|
||||||
|
./disko.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
boot.initrd.luks.devices.cryptroot.device =
|
||||||
|
"/dev/disk/by-partuuid/311d0f9c-f35f-42e6-b6fc-a4d67dd21b2e";
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||||
|
# and may be overwritten by future invocations. Please make changes
|
||||||
|
# to /etc/nixos/configuration.nix instead.
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
modulesPath,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
(modulesPath + "/installer/scan/not-detected.nix")
|
||||||
|
];
|
||||||
|
|
||||||
|
boot.initrd.availableKernelModules = [
|
||||||
|
"xhci_pci"
|
||||||
|
"thunderbolt"
|
||||||
|
"nvme"
|
||||||
|
"usb_storage"
|
||||||
|
"sd_mod"
|
||||||
|
];
|
||||||
|
boot.initrd.kernelModules = [ ];
|
||||||
|
boot.kernelModules = [ ];
|
||||||
|
boot.extraModulePackages = [ ];
|
||||||
|
|
||||||
|
fileSystems."/" = {
|
||||||
|
device = "/dev/disk/by-uuid/16b29578-6836-414b-a5e1-863bc21c5fc3";
|
||||||
|
fsType = "ext4";
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/boot" = {
|
||||||
|
device = "/dev/disk/by-uuid/209A-C8C9";
|
||||||
|
fsType = "vfat";
|
||||||
|
options = [
|
||||||
|
"fmask=0077"
|
||||||
|
"dmask=0077"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
swapDevices = [ ];
|
||||||
|
|
||||||
|
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
||||||
|
# (the default) this is the recommended approach. When using systemd-networkd it's
|
||||||
|
# still possible to use this option, but it's recommended to use it in conjunction
|
||||||
|
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
|
||||||
|
networking.useDHCP = lib.mkDefault true;
|
||||||
|
# networking.interfaces.wlp0s20f3.useDHCP = lib.mkDefault true;
|
||||||
|
|
||||||
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
|
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./hardware-configuration.nix
|
||||||
|
];
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 42 KiB |
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
inputs,
|
||||||
|
lib ? inputs.nixpkgs.lib,
|
||||||
|
root,
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
registry = import ./registry.nix {
|
||||||
|
inherit inputs lib;
|
||||||
|
modulesRoot = root + "/modules";
|
||||||
|
};
|
||||||
|
hosts = import ./hosts.nix {
|
||||||
|
inherit inputs lib registry;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
inherit hosts registry;
|
||||||
|
}
|
||||||
+191
@@ -0,0 +1,191 @@
|
|||||||
|
{
|
||||||
|
inputs,
|
||||||
|
lib,
|
||||||
|
registry,
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
ensure =
|
||||||
|
condition: message: value:
|
||||||
|
if condition then value else throw "host registry: ${message}";
|
||||||
|
|
||||||
|
isLinux = system: lib.hasSuffix "-linux" system;
|
||||||
|
isDarwin = system: lib.hasSuffix "-darwin" system;
|
||||||
|
|
||||||
|
hostFile =
|
||||||
|
spec: name:
|
||||||
|
let
|
||||||
|
path = spec.path + "/${name}";
|
||||||
|
in
|
||||||
|
if builtins.pathExists path then path else null;
|
||||||
|
|
||||||
|
selectedUnits =
|
||||||
|
spec:
|
||||||
|
[ "users.${spec.user}" ]
|
||||||
|
++ map (name: "profiles.${name}") (spec.profiles or [ ])
|
||||||
|
++ map (name: "applications.${name}") (spec.applications or [ ])
|
||||||
|
++ (spec.units or [ ]);
|
||||||
|
|
||||||
|
validateSpec =
|
||||||
|
name: spec:
|
||||||
|
ensure (builtins.isAttrs spec) "${name}: host specification must be an attribute set" (
|
||||||
|
ensure (spec ? system && builtins.isString spec.system) "${name}: system is required" (
|
||||||
|
ensure (isLinux spec.system || isDarwin spec.system)
|
||||||
|
"${name}: unsupported system '${spec.system}'; expected a Linux NixOS or Darwin system"
|
||||||
|
(
|
||||||
|
ensure (spec ? user && builtins.isString spec.user && spec.user != "") "${name}: user is required" (
|
||||||
|
ensure (spec ? path && builtins.pathExists spec.path)
|
||||||
|
"${name}: path must name an existing host directory"
|
||||||
|
(
|
||||||
|
ensure
|
||||||
|
(
|
||||||
|
spec ? stateVersion
|
||||||
|
&& builtins.isString spec.stateVersion
|
||||||
|
&& builtins.match "[0-9][0-9]\\.[0-9][0-9]" spec.stateVersion != null
|
||||||
|
)
|
||||||
|
"${name}: stateVersion is required and must have the form YY.MM"
|
||||||
|
(
|
||||||
|
ensure
|
||||||
|
(lib.all
|
||||||
|
(field: builtins.isList (spec.${field} or [ ]) && lib.all builtins.isString (spec.${field} or [ ]))
|
||||||
|
[
|
||||||
|
"profiles"
|
||||||
|
"applications"
|
||||||
|
"units"
|
||||||
|
]
|
||||||
|
)
|
||||||
|
"${name}: profiles, applications, and units must be lists of strings"
|
||||||
|
(ensure (builtins.isBool (spec.homeManager or true)) "${name}: homeManager must be a boolean" spec)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
mkSpecialArgs = name: spec: {
|
||||||
|
inherit inputs registry;
|
||||||
|
inherit (spec) system;
|
||||||
|
hostName = name;
|
||||||
|
primaryUser = spec.user;
|
||||||
|
};
|
||||||
|
|
||||||
|
mkHomeManagerModule =
|
||||||
|
name: spec: selected:
|
||||||
|
let
|
||||||
|
homePath = hostFile spec "home.nix";
|
||||||
|
homeModules = [
|
||||||
|
(registry.mkModule {
|
||||||
|
class = "home";
|
||||||
|
systemClass = "nixos";
|
||||||
|
})
|
||||||
|
(registry.mkSelectionModule selected)
|
||||||
|
{ home.stateVersion = spec.stateVersion; }
|
||||||
|
]
|
||||||
|
++ lib.optional (homePath != null) homePath;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [ inputs.home-manager.nixosModules.home-manager ];
|
||||||
|
|
||||||
|
home-manager = {
|
||||||
|
useGlobalPkgs = true;
|
||||||
|
useUserPackages = true;
|
||||||
|
extraSpecialArgs = mkSpecialArgs name spec;
|
||||||
|
users.${spec.user}.imports = homeModules;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
mkDarwinHomeManagerModule =
|
||||||
|
name: spec: selected:
|
||||||
|
let
|
||||||
|
homePath = hostFile spec "home.nix";
|
||||||
|
homeModules = [
|
||||||
|
(registry.mkModule {
|
||||||
|
class = "home";
|
||||||
|
systemClass = "darwin";
|
||||||
|
})
|
||||||
|
(registry.mkSelectionModule selected)
|
||||||
|
{ home.stateVersion = spec.stateVersion; }
|
||||||
|
]
|
||||||
|
++ lib.optional (homePath != null) homePath;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [ inputs.home-manager.darwinModules.home-manager ];
|
||||||
|
|
||||||
|
home-manager = {
|
||||||
|
useGlobalPkgs = true;
|
||||||
|
useUserPackages = true;
|
||||||
|
extraSpecialArgs = mkSpecialArgs name spec;
|
||||||
|
users.${spec.user}.imports = homeModules;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
mkNixos =
|
||||||
|
name: rawSpec:
|
||||||
|
let
|
||||||
|
spec = validateSpec name rawSpec;
|
||||||
|
selected = registry.validateUnitIds (selectedUnits spec);
|
||||||
|
nixosPath = hostFile spec "nixos.nix";
|
||||||
|
modules = [
|
||||||
|
(registry.mkModule { class = "nixos"; })
|
||||||
|
(registry.mkSelectionModule selected)
|
||||||
|
{
|
||||||
|
networking.hostName = lib.mkDefault name;
|
||||||
|
system.stateVersion = spec.stateVersion;
|
||||||
|
}
|
||||||
|
]
|
||||||
|
++ lib.optional (spec.homeManager or true) (mkHomeManagerModule name spec selected)
|
||||||
|
++ lib.optional (nixosPath != null) nixosPath;
|
||||||
|
in
|
||||||
|
inputs.nixpkgs.lib.nixosSystem {
|
||||||
|
inherit (spec) system;
|
||||||
|
specialArgs = mkSpecialArgs name spec;
|
||||||
|
inherit modules;
|
||||||
|
};
|
||||||
|
|
||||||
|
mkDarwin =
|
||||||
|
name: rawSpec:
|
||||||
|
let
|
||||||
|
spec = validateSpec name rawSpec;
|
||||||
|
selected = registry.validateUnitIds (selectedUnits spec);
|
||||||
|
darwinPath = hostFile spec "darwin.nix";
|
||||||
|
modules = [
|
||||||
|
(registry.mkModule { class = "darwin"; })
|
||||||
|
(registry.mkSelectionModule selected)
|
||||||
|
{
|
||||||
|
networking.hostName = lib.mkDefault name;
|
||||||
|
system.primaryUser = lib.mkDefault spec.user;
|
||||||
|
}
|
||||||
|
]
|
||||||
|
++ lib.optional (spec.homeManager or true) (mkDarwinHomeManagerModule name spec selected)
|
||||||
|
++ lib.optional (darwinPath != null) darwinPath;
|
||||||
|
in
|
||||||
|
ensure (inputs ? nix-darwin) "${name}: the nix-darwin input is required" (
|
||||||
|
inputs.nix-darwin.lib.darwinSystem {
|
||||||
|
inherit (spec) system;
|
||||||
|
specialArgs = mkSpecialArgs name spec;
|
||||||
|
inherit modules;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
mkConfigurations =
|
||||||
|
hostSpecs:
|
||||||
|
let
|
||||||
|
validated = lib.mapAttrs validateSpec hostSpecs;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
nixosConfigurations = lib.mapAttrs mkNixos (
|
||||||
|
lib.filterAttrs (_: spec: isLinux spec.system) validated
|
||||||
|
);
|
||||||
|
darwinConfigurations = lib.mapAttrs mkDarwin (
|
||||||
|
lib.filterAttrs (_: spec: isDarwin spec.system) validated
|
||||||
|
);
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
inherit
|
||||||
|
mkConfigurations
|
||||||
|
mkDarwin
|
||||||
|
mkNixos
|
||||||
|
selectedUnits
|
||||||
|
;
|
||||||
|
}
|
||||||
@@ -0,0 +1,386 @@
|
|||||||
|
{
|
||||||
|
inputs,
|
||||||
|
lib,
|
||||||
|
modulesRoot,
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
rootFragmentFiles = {
|
||||||
|
common = "common.nix";
|
||||||
|
nixos = "nixos.nix";
|
||||||
|
darwin = "darwin.nix";
|
||||||
|
home = "home.nix";
|
||||||
|
meta = "meta.nix";
|
||||||
|
};
|
||||||
|
|
||||||
|
homeFragmentFiles = {
|
||||||
|
homeCommon = "common.nix";
|
||||||
|
homeNixos = "nixos.nix";
|
||||||
|
homeDarwin = "darwin.nix";
|
||||||
|
};
|
||||||
|
|
||||||
|
fragmentFileNames = rootFragmentFiles // lib.mapAttrs (_: name: "home/${name}") homeFragmentFiles;
|
||||||
|
|
||||||
|
isFile = kind: kind == "regular" || kind == "symlink";
|
||||||
|
|
||||||
|
ensure =
|
||||||
|
condition: message: value:
|
||||||
|
if condition then value else throw "unit registry: ${message}";
|
||||||
|
|
||||||
|
callWithAvailableArgs =
|
||||||
|
value: availableArgs:
|
||||||
|
if builtins.isFunction value then
|
||||||
|
value (builtins.intersectAttrs (builtins.functionArgs value) availableArgs)
|
||||||
|
else
|
||||||
|
value;
|
||||||
|
|
||||||
|
pathFor =
|
||||||
|
relativePath:
|
||||||
|
if relativePath == [ ] then
|
||||||
|
modulesRoot
|
||||||
|
else
|
||||||
|
modulesRoot + "/${lib.concatStringsSep "/" relativePath}";
|
||||||
|
|
||||||
|
entryIsFile = entries: name: builtins.hasAttr name entries && isFile entries.${name};
|
||||||
|
|
||||||
|
normalizeMeta =
|
||||||
|
unit:
|
||||||
|
let
|
||||||
|
metaPath = unit.fragments.meta;
|
||||||
|
importedValue =
|
||||||
|
if metaPath == null then
|
||||||
|
{ }
|
||||||
|
else
|
||||||
|
callWithAvailableArgs (import metaPath) {
|
||||||
|
inherit inputs lib unit;
|
||||||
|
};
|
||||||
|
imported =
|
||||||
|
ensure (builtins.isAttrs importedValue) "${unit.id}: meta.nix must return an attribute set"
|
||||||
|
importedValue;
|
||||||
|
allowedKeys = [
|
||||||
|
"description"
|
||||||
|
"includes"
|
||||||
|
"imports"
|
||||||
|
];
|
||||||
|
unknownKeys = lib.filter (name: !(builtins.elem name allowedKeys)) (builtins.attrNames imported);
|
||||||
|
description = imported.description or null;
|
||||||
|
includes = imported.includes or [ ];
|
||||||
|
imports = imported.imports or { };
|
||||||
|
allowedImportKeys = [
|
||||||
|
"nixos"
|
||||||
|
"darwin"
|
||||||
|
"home"
|
||||||
|
];
|
||||||
|
unknownImportKeys =
|
||||||
|
if builtins.isAttrs imports then
|
||||||
|
lib.filter (name: !(builtins.elem name allowedImportKeys)) (builtins.attrNames imports)
|
||||||
|
else
|
||||||
|
[ ];
|
||||||
|
normalized = {
|
||||||
|
inherit description includes;
|
||||||
|
imports = {
|
||||||
|
nixos = imports.nixos or [ ];
|
||||||
|
darwin = imports.darwin or [ ];
|
||||||
|
home = imports.home or [ ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
ensure (unknownKeys == [ ])
|
||||||
|
"${unit.id}: meta.nix has unsupported keys: ${lib.concatStringsSep ", " unknownKeys}"
|
||||||
|
(
|
||||||
|
ensure (description == null || builtins.isString description)
|
||||||
|
"${unit.id}: meta.description must be a string"
|
||||||
|
(
|
||||||
|
ensure (builtins.isList includes && lib.all builtins.isString includes)
|
||||||
|
"${unit.id}: meta.includes must be a list of fully qualified unit IDs"
|
||||||
|
(
|
||||||
|
ensure (lib.unique includes == includes) "${unit.id}: meta.includes contains duplicate unit IDs" (
|
||||||
|
ensure (builtins.isAttrs imports) "${unit.id}: meta.imports must be an attribute set" (
|
||||||
|
ensure (unknownImportKeys == [ ])
|
||||||
|
"${unit.id}: meta.imports has unsupported classes: ${lib.concatStringsSep ", " unknownImportKeys}"
|
||||||
|
(
|
||||||
|
ensure (lib.all builtins.isList [
|
||||||
|
normalized.imports.nixos
|
||||||
|
normalized.imports.darwin
|
||||||
|
normalized.imports.home
|
||||||
|
]) "${unit.id}: every meta.imports.<class> value must be a list" normalized
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
makeUnit =
|
||||||
|
relativePath: entries: homeEntries:
|
||||||
|
let
|
||||||
|
directory = pathFor relativePath;
|
||||||
|
id = lib.concatStringsSep "." relativePath;
|
||||||
|
rootFragments = lib.mapAttrs (
|
||||||
|
_class: fileName: if entryIsFile entries fileName then directory + "/${fileName}" else null
|
||||||
|
) rootFragmentFiles;
|
||||||
|
homeFragments = lib.mapAttrs (
|
||||||
|
_class: fileName: if entryIsFile homeEntries fileName then directory + "/home/${fileName}" else null
|
||||||
|
) homeFragmentFiles;
|
||||||
|
fragments = rootFragments // homeFragments;
|
||||||
|
baseUnit = {
|
||||||
|
inherit
|
||||||
|
id
|
||||||
|
directory
|
||||||
|
fragments
|
||||||
|
relativePath
|
||||||
|
;
|
||||||
|
optionPath = [ "my" ] ++ relativePath ++ [ "enable" ];
|
||||||
|
kind = builtins.head relativePath;
|
||||||
|
name = lib.last relativePath;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
lib.optionalAttrs (builtins.length relativePath > 2 && builtins.head relativePath == "profiles")
|
||||||
|
{
|
||||||
|
group = builtins.elemAt relativePath 1;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
ensure (relativePath != [ ]) "the modules root cannot itself be a unit" (
|
||||||
|
ensure (lib.all (component: component != "" && !(lib.hasInfix "." component)) relativePath)
|
||||||
|
"${id}: path components must be non-empty and must not contain dots"
|
||||||
|
(baseUnit // { meta = normalizeMeta baseUnit; })
|
||||||
|
);
|
||||||
|
|
||||||
|
walk =
|
||||||
|
relativePath:
|
||||||
|
let
|
||||||
|
directory = pathFor relativePath;
|
||||||
|
entries = builtins.readDir directory;
|
||||||
|
homeEntries =
|
||||||
|
if relativePath != [ ] && (entries.home or null) == "directory" then
|
||||||
|
builtins.readDir (directory + "/home")
|
||||||
|
else
|
||||||
|
{ };
|
||||||
|
hasRootFragment = lib.any (fileName: entryIsFile entries fileName) (
|
||||||
|
builtins.attrValues rootFragmentFiles
|
||||||
|
);
|
||||||
|
hasHomeFragment = lib.any (fileName: entryIsFile homeEntries fileName) (
|
||||||
|
builtins.attrValues homeFragmentFiles
|
||||||
|
);
|
||||||
|
hasFragment = hasRootFragment || hasHomeFragment;
|
||||||
|
childDirectories = lib.filter (
|
||||||
|
name: entries.${name} == "directory" && !(name == "home" && hasHomeFragment)
|
||||||
|
) (builtins.attrNames entries);
|
||||||
|
current = lib.optional hasFragment (makeUnit relativePath entries homeEntries);
|
||||||
|
children = lib.concatMap (name: walk (relativePath ++ [ name ])) childDirectories;
|
||||||
|
in
|
||||||
|
current ++ children;
|
||||||
|
|
||||||
|
discoveredUnits =
|
||||||
|
ensure (builtins.pathExists modulesRoot) "modules root does not exist: ${toString modulesRoot}"
|
||||||
|
(walk [ ]);
|
||||||
|
unitsById = builtins.listToAttrs (map (unit: lib.nameValuePair unit.id unit) discoveredUnits);
|
||||||
|
|
||||||
|
dependencyValidation = lib.foldl' (
|
||||||
|
valid: unit:
|
||||||
|
lib.foldl' (
|
||||||
|
inner: includedId:
|
||||||
|
if builtins.hasAttr includedId unitsById then
|
||||||
|
inner
|
||||||
|
else
|
||||||
|
throw "unit registry: ${unit.id} includes missing unit '${includedId}'"
|
||||||
|
) valid unit.meta.includes
|
||||||
|
) true discoveredUnits;
|
||||||
|
|
||||||
|
units = builtins.seq dependencyValidation unitsById;
|
||||||
|
unitIds = builtins.attrNames units;
|
||||||
|
|
||||||
|
getUnit =
|
||||||
|
id: if builtins.hasAttr id units then units.${id} else throw "unit registry: unknown unit '${id}'";
|
||||||
|
|
||||||
|
validateUnitIds =
|
||||||
|
ids:
|
||||||
|
ensure (
|
||||||
|
builtins.isList ids && lib.all builtins.isString ids
|
||||||
|
) "selected units must be a list of strings" (map (id: builtins.seq (getUnit id) id) ids);
|
||||||
|
|
||||||
|
optionDefinitions = lib.foldl' lib.recursiveUpdate { } (
|
||||||
|
map (
|
||||||
|
unit:
|
||||||
|
lib.setAttrByPath unit.optionPath (
|
||||||
|
lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = false;
|
||||||
|
description =
|
||||||
|
if unit.meta.description == null then
|
||||||
|
"Whether to enable the ${unit.id} unit."
|
||||||
|
else
|
||||||
|
"Whether to enable ${unit.meta.description}.";
|
||||||
|
}
|
||||||
|
)
|
||||||
|
) discoveredUnits
|
||||||
|
);
|
||||||
|
|
||||||
|
enabled = config: unit: lib.getAttrFromPath unit.optionPath config;
|
||||||
|
|
||||||
|
enableUnit = id: lib.setAttrByPath (getUnit id).optionPath true;
|
||||||
|
|
||||||
|
includeConfig =
|
||||||
|
config: unit: lib.mkIf (enabled config unit) (lib.mkMerge (map enableUnit unit.meta.includes));
|
||||||
|
|
||||||
|
fragmentClasses = {
|
||||||
|
nixos = [
|
||||||
|
"common"
|
||||||
|
"nixos"
|
||||||
|
];
|
||||||
|
darwin = [
|
||||||
|
"common"
|
||||||
|
"darwin"
|
||||||
|
];
|
||||||
|
home = {
|
||||||
|
nixos = [
|
||||||
|
"home"
|
||||||
|
"homeCommon"
|
||||||
|
"homeNixos"
|
||||||
|
];
|
||||||
|
darwin = [
|
||||||
|
"home"
|
||||||
|
"homeCommon"
|
||||||
|
"homeDarwin"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
fragmentClassesFor =
|
||||||
|
{
|
||||||
|
class,
|
||||||
|
systemClass,
|
||||||
|
}:
|
||||||
|
ensure (builtins.hasAttr class fragmentClasses) "unsupported module class '${class}'" (
|
||||||
|
if class == "home" then
|
||||||
|
ensure
|
||||||
|
(builtins.elem systemClass [
|
||||||
|
"nixos"
|
||||||
|
"darwin"
|
||||||
|
])
|
||||||
|
"the home module class requires systemClass to be 'nixos' or 'darwin'"
|
||||||
|
fragmentClasses.home.${systemClass}
|
||||||
|
else
|
||||||
|
ensure (
|
||||||
|
systemClass == null
|
||||||
|
) "systemClass is only supported for the home module class" fragmentClasses.${class}
|
||||||
|
);
|
||||||
|
|
||||||
|
applyFragment =
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
fragmentName,
|
||||||
|
fragmentPath,
|
||||||
|
options,
|
||||||
|
specialArgs,
|
||||||
|
unit,
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
fragment = import fragmentPath;
|
||||||
|
directArgs = specialArgs // {
|
||||||
|
inherit
|
||||||
|
config
|
||||||
|
lib
|
||||||
|
options
|
||||||
|
specialArgs
|
||||||
|
unit
|
||||||
|
;
|
||||||
|
};
|
||||||
|
fragmentArgSpec = builtins.functionArgs fragment;
|
||||||
|
fragmentArgs = builtins.listToAttrs (
|
||||||
|
lib.concatMap (
|
||||||
|
name:
|
||||||
|
if builtins.hasAttr name directArgs then
|
||||||
|
[ (lib.nameValuePair name directArgs.${name}) ]
|
||||||
|
else if fragmentArgSpec.${name} then
|
||||||
|
[ ]
|
||||||
|
else
|
||||||
|
[ (lib.nameValuePair name config._module.args.${name}) ]
|
||||||
|
) (builtins.attrNames fragmentArgSpec)
|
||||||
|
);
|
||||||
|
resultValue = if builtins.isFunction fragment then fragment fragmentArgs else fragment;
|
||||||
|
result =
|
||||||
|
ensure (builtins.isAttrs resultValue) "${unit.id}: ${fragmentName} must return an attribute set"
|
||||||
|
resultValue;
|
||||||
|
forbiddenKeys = lib.filter (name: builtins.hasAttr name result) [
|
||||||
|
"imports"
|
||||||
|
"options"
|
||||||
|
"config"
|
||||||
|
];
|
||||||
|
in
|
||||||
|
ensure (forbiddenKeys == [ ])
|
||||||
|
"${unit.id}: ${fragmentName} is a configuration fragment and cannot define top-level ${lib.concatStringsSep ", " forbiddenKeys}"
|
||||||
|
result;
|
||||||
|
|
||||||
|
externalImports = class: lib.concatMap (unit: unit.meta.imports.${class}) discoveredUnits;
|
||||||
|
|
||||||
|
mkModule =
|
||||||
|
{
|
||||||
|
class,
|
||||||
|
systemClass ? null,
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
selectedFragmentClasses = fragmentClassesFor { inherit class systemClass; };
|
||||||
|
in
|
||||||
|
builtins.seq selectedFragmentClasses (
|
||||||
|
builtins.seq dependencyValidation (
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
options,
|
||||||
|
specialArgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
fragmentConfigs = lib.concatMap (
|
||||||
|
unit:
|
||||||
|
lib.filter (value: value != null) (
|
||||||
|
map (
|
||||||
|
fragmentClass:
|
||||||
|
let
|
||||||
|
fragmentName = fragmentFileNames.${fragmentClass};
|
||||||
|
fragmentPath = unit.fragments.${fragmentClass};
|
||||||
|
in
|
||||||
|
if fragmentPath == null then
|
||||||
|
null
|
||||||
|
else
|
||||||
|
lib.mkIf (enabled config unit) (applyFragment {
|
||||||
|
inherit
|
||||||
|
config
|
||||||
|
fragmentName
|
||||||
|
fragmentPath
|
||||||
|
options
|
||||||
|
specialArgs
|
||||||
|
unit
|
||||||
|
;
|
||||||
|
})
|
||||||
|
) selectedFragmentClasses
|
||||||
|
)
|
||||||
|
) discoveredUnits;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = externalImports class;
|
||||||
|
options = optionDefinitions;
|
||||||
|
config = lib.mkMerge ((map (includeConfig config) discoveredUnits) ++ fragmentConfigs);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
mkSelectionModule =
|
||||||
|
selectedIds:
|
||||||
|
let
|
||||||
|
checkedIds = validateUnitIds (lib.unique selectedIds);
|
||||||
|
in
|
||||||
|
{
|
||||||
|
config = lib.mkMerge (map enableUnit checkedIds);
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
inherit
|
||||||
|
getUnit
|
||||||
|
mkModule
|
||||||
|
mkSelectionModule
|
||||||
|
unitIds
|
||||||
|
units
|
||||||
|
validateUnitIds
|
||||||
|
;
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
_: {
|
||||||
|
programs._1password-gui.enable = true;
|
||||||
|
programs._1password.enable = true;
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{ primaryUser, lib, ... }:
|
||||||
|
{
|
||||||
|
programs._1password-gui.polkitPolicyOwners = [ primaryUser ];
|
||||||
|
|
||||||
|
# 1Password SSH Agentと競合するagentを無効化
|
||||||
|
programs.ssh.startAgent = lib.mkForce false;
|
||||||
|
programs.gnupg.agent.enableSSHSupport = lib.mkForce false;
|
||||||
|
services.gnome.gcr-ssh-agent.enable = lib.mkForce false;
|
||||||
|
}
|
||||||
@@ -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";
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
home.packages = [ pkgs.arduino-cli ];
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
let
|
||||||
|
arduinoIdeX11 = pkgs.arduino-ide.overrideAttrs (old: {
|
||||||
|
nativeBuildInputs = (old.nativeBuildInputs or [ ]) ++ [ pkgs.makeWrapper ];
|
||||||
|
|
||||||
|
postFixup = (old.postFixup or "") + ''
|
||||||
|
wrapProgram $out/bin/arduino-ide \
|
||||||
|
--add-flags "--ozone-platform=x11"
|
||||||
|
'';
|
||||||
|
});
|
||||||
|
in
|
||||||
|
{
|
||||||
|
environment.systemPackages = [ arduinoIdeX11 ];
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
programs.atuin = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
enableZshIntegration = true;
|
||||||
|
enableBashIntegration = true;
|
||||||
|
enableFishIntegration = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
home.packages = [ pkgs.baobab ];
|
||||||
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
# Bashtop theme with Nord palette (https://www.nordtheme.com)
|
||||||
|
# by Justin Zobel <[email protected]>
|
||||||
|
|
||||||
|
# Colors should be in 6 or 2 character hexadecimal or single spaced rgb decimal: "#RRGGBB", "#BW" or "0-255 0-255 0-255"
|
||||||
|
# example for white: "#ffffff", "#ff" or "255 255 255".
|
||||||
|
|
||||||
|
# All graphs and meters can be gradients
|
||||||
|
# For single color graphs leave "mid" and "end" variable empty.
|
||||||
|
# Use "start" and "end" variables for two color gradient
|
||||||
|
# Use "start", "mid" and "end" for three color gradient
|
||||||
|
|
||||||
|
# Main background, empty for terminal default, need to be empty if you want transparent background
|
||||||
|
theme[main_bg]="#282A36"
|
||||||
|
|
||||||
|
# Main text color
|
||||||
|
theme[main_fg]="#BD93F9"
|
||||||
|
|
||||||
|
# Title color for boxes
|
||||||
|
theme[title]="#f8f8f2"
|
||||||
|
|
||||||
|
# Highlight color for keyboard shortcuts
|
||||||
|
theme[hi_fg]="#ff79c6"
|
||||||
|
|
||||||
|
# Background color of selected item in processes box
|
||||||
|
theme[selected_bg]="#44475A"
|
||||||
|
|
||||||
|
# Foreground color of selected item in processes box
|
||||||
|
theme[selected_fg]="#ECEFF4"
|
||||||
|
|
||||||
|
# Color of inactive/disabled text
|
||||||
|
theme[inactive_fg]="#6272a4"
|
||||||
|
|
||||||
|
# Misc colors for processes box including mini cpu graphs, details memory graph and details status text
|
||||||
|
theme[proc_misc]="#BD93F9"
|
||||||
|
|
||||||
|
# Cpu box outline color
|
||||||
|
theme[cpu_box]="#ff79c6"
|
||||||
|
|
||||||
|
# Memory/disks box outline color
|
||||||
|
theme[mem_box]="#ff79c6"
|
||||||
|
|
||||||
|
# Net up/down box outline color
|
||||||
|
theme[net_box]="#ff79c6"
|
||||||
|
|
||||||
|
# Processes box outline color
|
||||||
|
theme[proc_box]="#ff79c6"
|
||||||
|
|
||||||
|
# Box divider line and small boxes line color
|
||||||
|
theme[div_line]="#ff79c6"
|
||||||
|
|
||||||
|
# Temperature graph colors
|
||||||
|
theme[temp_start]="#bd93f9"
|
||||||
|
theme[temp_mid]="#bd93f9"
|
||||||
|
theme[temp_end]="#bd93f9"
|
||||||
|
|
||||||
|
# CPU graph colors
|
||||||
|
theme[cpu_start]="#bd93f9"
|
||||||
|
theme[cpu_mid]="#bd93f9"
|
||||||
|
theme[cpu_end]="#bd93f9"
|
||||||
|
|
||||||
|
# Mem/Disk free meter
|
||||||
|
theme[free_start]="#bd93f9"
|
||||||
|
theme[free_mid]="#bd93f9"
|
||||||
|
theme[free_end]="#bd93f9"
|
||||||
|
|
||||||
|
# Mem/Disk cached meter
|
||||||
|
theme[cached_start]="#bd93f9"
|
||||||
|
theme[cached_mid]="#bd93f9"
|
||||||
|
theme[cached_end]="#bd93f9"
|
||||||
|
|
||||||
|
# Mem/Disk available meter
|
||||||
|
theme[available_start]="#bd93f9"
|
||||||
|
theme[available_mid]="#bd93f9"
|
||||||
|
theme[available_end]="#bd93f9"
|
||||||
|
|
||||||
|
# Mem/Disk used meter
|
||||||
|
theme[used_start]="#bd93f9"
|
||||||
|
theme[used_mid]="#bd93f9"
|
||||||
|
theme[used_end]="#bd93f9"
|
||||||
|
|
||||||
|
# Download graph colors
|
||||||
|
theme[download_start]="#bd93f9"
|
||||||
|
theme[download_mid]="#bd93f9"
|
||||||
|
theme[download_end]="#bd93f9"
|
||||||
|
|
||||||
|
# Upload graph colors
|
||||||
|
theme[upload_start]="#bd93f9"
|
||||||
|
theme[upload_mid]="#bd93f9"
|
||||||
|
theme[upload_end]="#bd93f9"
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
programs.btop = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
settings.color_theme = "dracula";
|
||||||
|
themes.dracula = builtins.readFile ./dracula.theme;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
home.packages = [ pkgs.celluloid ];
|
||||||
|
|
||||||
|
xdg.mimeApps = {
|
||||||
|
enable = true;
|
||||||
|
defaultApplicationPackages = [ pkgs.celluloid ];
|
||||||
|
defaultApplications = builtins.listToAttrs (
|
||||||
|
map
|
||||||
|
(mime: {
|
||||||
|
name = mime;
|
||||||
|
value = [ "io.github.celluloid_player.Celluloid.desktop" ];
|
||||||
|
})
|
||||||
|
[
|
||||||
|
"video/3gpp"
|
||||||
|
"video/3gpp2"
|
||||||
|
"video/mp2t"
|
||||||
|
"video/mp4"
|
||||||
|
"video/mpeg"
|
||||||
|
"video/ogg"
|
||||||
|
"video/quicktime"
|
||||||
|
"video/webm"
|
||||||
|
"video/x-flv"
|
||||||
|
"video/x-m4v"
|
||||||
|
"video/x-matroska"
|
||||||
|
"video/x-msvideo"
|
||||||
|
"video/x-ms-wmv"
|
||||||
|
]
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
homebrew = {
|
||||||
|
enable = true;
|
||||||
|
casks = [ "google-chrome" ];
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
chrome = pkgs.google-chrome.overrideAttrs (old: {
|
||||||
|
nativeBuildInputs = (old.nativeBuildInputs or [ ]) ++ [ pkgs.makeWrapper ];
|
||||||
|
|
||||||
|
postFixup = (old.postFixup or "") + ''
|
||||||
|
wrapProgram $out/bin/google-chrome-stable \
|
||||||
|
--set LIBVA_DRIVER_NAME nvidia \
|
||||||
|
--set NVD_BACKEND direct
|
||||||
|
'';
|
||||||
|
});
|
||||||
|
|
||||||
|
features = [
|
||||||
|
"MiddleClickAutoscroll"
|
||||||
|
"AcceleratedVideoDecoder"
|
||||||
|
"AcceleratedVideoDecodeLinuxGL"
|
||||||
|
"PlatformHEVCDecoderSupport"
|
||||||
|
]
|
||||||
|
++ lib.optional config.my.hardwares.nvidia.enable "VaapiOnNvidiaGPUs";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
programs.google-chrome = {
|
||||||
|
enable = true;
|
||||||
|
package = if config.my.hardwares.nvidia.enable then chrome else pkgs.google-chrome;
|
||||||
|
|
||||||
|
commandLineArgs = [
|
||||||
|
"--enable-features=${lib.concatStringsSep "," features}"
|
||||||
|
"--use-gl=angle"
|
||||||
|
"--use-angle=gl"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
xdg.mimeApps = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
defaultApplications = {
|
||||||
|
"text/html" = "google-chrome.desktop";
|
||||||
|
"x-scheme-handler/http" = "google-chrome.desktop";
|
||||||
|
"x-scheme-handler/https" = "google-chrome.desktop";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
inputs,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
home.packages = [
|
||||||
|
inputs.llm-agents.packages.${pkgs.stdenv.hostPlatform.system}.claude-code
|
||||||
|
];
|
||||||
|
|
||||||
|
home.file.".claude/settings.json".text = builtins.toJSON {
|
||||||
|
statusLine = {
|
||||||
|
type = "command";
|
||||||
|
command = "bun x ccusage statusline --no-offline";
|
||||||
|
padding = 0;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
# The former Codex app cask is deprecated in favor of ChatGPT, whose desktop
|
||||||
|
# application includes the current Codex experience on macOS.
|
||||||
|
homebrew = {
|
||||||
|
enable = true;
|
||||||
|
casks = [ "chatgpt" ];
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
_: {
|
||||||
|
description = "Codex Desktop for Linux";
|
||||||
|
|
||||||
|
includes = [ "applications.codex" ];
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
inputs,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
environment.systemPackages = [
|
||||||
|
inputs.llm-agents.packages.${pkgs.stdenv.hostPlatform.system}.chatgpt
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
{
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
inputs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
codexSessionUsage = inputs.codex-session-usage.packages.${pkgs.stdenv.hostPlatform.system}.default;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
home.packages = [ codexSessionUsage ];
|
||||||
|
|
||||||
|
xdg.dataFile = {
|
||||||
|
"vicinae/scripts/codex-session-usage/start" = {
|
||||||
|
executable = true;
|
||||||
|
text = ''
|
||||||
|
#!${lib.getExe pkgs.bash}
|
||||||
|
# @vicinae.schemaVersion 1
|
||||||
|
# @vicinae.title Start Codex Session Usage
|
||||||
|
# @vicinae.description Start the local Codex session usage dashboard
|
||||||
|
# @vicinae.mode compact
|
||||||
|
# @vicinae.icon 📊
|
||||||
|
# @vicinae.argument1 { "type": "text", "placeholder": "Port (optional)", "optional": true }
|
||||||
|
|
||||||
|
if [[ -z "$1" ]]; then
|
||||||
|
exec ${lib.getExe codexSessionUsage} start
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$1" =~ ^[0-9]+$ ]] && (( 10#$1 >= 1 && 10#$1 <= 65535 )); then
|
||||||
|
exec ${lib.getExe codexSessionUsage} start --port "$1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf '%s\n' 'Port must be an integer between 1 and 65535.' >&2
|
||||||
|
exit 2
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
"vicinae/scripts/codex-session-usage/stop" = {
|
||||||
|
executable = true;
|
||||||
|
text = ''
|
||||||
|
#!${lib.getExe pkgs.bash}
|
||||||
|
# @vicinae.schemaVersion 1
|
||||||
|
# @vicinae.title Stop Codex Session Usage
|
||||||
|
# @vicinae.description Stop the local Codex session usage dashboard
|
||||||
|
# @vicinae.mode compact
|
||||||
|
# @vicinae.icon 📊
|
||||||
|
|
||||||
|
exec ${lib.getExe codexSessionUsage} stop
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
model = "gpt-5.6-sol"
|
||||||
|
model_reasoning_effort = "medium"
|
||||||
|
|
||||||
|
approval_policy = "on-request"
|
||||||
|
approvals_reviewer = "auto_review"
|
||||||
|
sandbox_mode = "workspace-write"
|
||||||
|
web_search = "cached"
|
||||||
|
|
||||||
|
[sandbox_workspace_write]
|
||||||
|
network_access = false
|
||||||
|
|
||||||
|
[projects."/home/moons/dotfiles"]
|
||||||
|
trust_level = "trusted"
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
inputs,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
configDirectory =
|
||||||
|
if config.home.preferXdgDirectories then
|
||||||
|
"${config.xdg.configHome}/codex"
|
||||||
|
else
|
||||||
|
"${config.home.homeDirectory}/.codex";
|
||||||
|
configFile = "${configDirectory}/config.toml";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
programs.codex = {
|
||||||
|
enable = true;
|
||||||
|
package = inputs.llm-agents.packages.${pkgs.stdenv.hostPlatform.system}.codex;
|
||||||
|
|
||||||
|
skills = {
|
||||||
|
grilling = inputs.skills + "/skills/productivity/grilling";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Keep the repository copy as an initial value. Codex may mutate the live
|
||||||
|
# file between activations; each Home Manager switch resets it from here.
|
||||||
|
home.activation.resetCodexConfig = {
|
||||||
|
after = [ "writeBoundary" ];
|
||||||
|
before = [ ];
|
||||||
|
data = ''
|
||||||
|
${pkgs.coreutils}/bin/mkdir -p ${lib.escapeShellArg configDirectory}
|
||||||
|
${pkgs.coreutils}/bin/install -m 0600 ${./config.toml} ${lib.escapeShellArg configFile}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
programs.direnv = {
|
||||||
|
enable = true;
|
||||||
|
nix-direnv.enable = true;
|
||||||
|
|
||||||
|
config.global = {
|
||||||
|
warn_timeout = "10s";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
{
|
||||||
|
inputs,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
unstable = inputs.nixpkgs-unstable.legacyPackages.${pkgs.stdenv.hostPlatform.system};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
programs.vesktop = {
|
||||||
|
enable = true;
|
||||||
|
package = unstable.vesktop;
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
discordBranch = "stable";
|
||||||
|
|
||||||
|
hardwareAcceleration = true;
|
||||||
|
hardwareVideoAcceleration = true;
|
||||||
|
|
||||||
|
tray = true;
|
||||||
|
minimizeToTray = true;
|
||||||
|
|
||||||
|
# Discord Rich Presence
|
||||||
|
arRPC = true;
|
||||||
|
|
||||||
|
openLinksWithElectron = false;
|
||||||
|
|
||||||
|
# Keep WebRTC on the public interface selected by the default route.
|
||||||
|
# Secondary private interfaces can otherwise stall voice at DTLS.
|
||||||
|
webRTCIPHandlingPolicy = "default_public_interface_only";
|
||||||
|
|
||||||
|
spellCheckLanguages = [
|
||||||
|
"ja-JP"
|
||||||
|
"en-US"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
vencord = {
|
||||||
|
useSystem = false;
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
autoUpdate = true;
|
||||||
|
autoUpdateNotification = false;
|
||||||
|
|
||||||
|
useQuickCss = false;
|
||||||
|
|
||||||
|
cloud.settingsSync = false;
|
||||||
|
|
||||||
|
notifications = {
|
||||||
|
position = "bottom-right";
|
||||||
|
useNative = "not-focused";
|
||||||
|
timeout = 5000;
|
||||||
|
logLimit = 50;
|
||||||
|
};
|
||||||
|
|
||||||
|
plugins = {
|
||||||
|
# プライバシー・安全性
|
||||||
|
NoTrack.enabled = true;
|
||||||
|
ClearURLs.enabled = true;
|
||||||
|
|
||||||
|
# 設定・セッション
|
||||||
|
BetterSettings.enabled = true;
|
||||||
|
BetterSessions.enabled = true;
|
||||||
|
|
||||||
|
# 画像・添付ファイル
|
||||||
|
FixImagesQuality.enabled = true;
|
||||||
|
ImageZoom.enabled = true;
|
||||||
|
ViewIcons.enabled = true;
|
||||||
|
CopyFileContents.enabled = true;
|
||||||
|
|
||||||
|
# メッセージ操作
|
||||||
|
QuickReply.enabled = true;
|
||||||
|
SendTimestamps.enabled = true;
|
||||||
|
FullSearchContext.enabled = true;
|
||||||
|
MessageLinkEmbeds.enabled = true;
|
||||||
|
Unindent.enabled = true;
|
||||||
|
ValidReply.enabled = true;
|
||||||
|
|
||||||
|
# 通知・誤操作対策
|
||||||
|
ReadAllNotificationsButton.enabled = true;
|
||||||
|
NoReplyMention.enabled = true;
|
||||||
|
NotificationVolume.enabled = true;
|
||||||
|
|
||||||
|
# UI・パフォーマンス
|
||||||
|
NoTypingAnimation.enabled = true;
|
||||||
|
FavoriteEmojiFirst.enabled = true;
|
||||||
|
KeepCurrentChannel.enabled = true;
|
||||||
|
|
||||||
|
# サーバー・権限確認
|
||||||
|
PermissionsViewer.enabled = true;
|
||||||
|
MemberCount.enabled = true;
|
||||||
|
|
||||||
|
# ボイス・アクティビティ
|
||||||
|
CallTimer.enabled = true;
|
||||||
|
GameActivityToggle.enabled = true;
|
||||||
|
|
||||||
|
# Vesktop向け
|
||||||
|
WebKeybinds.enabled = true;
|
||||||
|
WebScreenShareFixes.enabled = true;
|
||||||
|
|
||||||
|
# Message history
|
||||||
|
MessageLogger.enabled = true;
|
||||||
|
ShowHiddenChannels.enabled = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
homebrew = {
|
||||||
|
enable = true;
|
||||||
|
casks = [ "orbstack" ];
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
home.packages = [
|
||||||
|
pkgs.docker-client
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
home.packages = [
|
||||||
|
pkgs.oxker
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
description = "Docker command-line client and NixOS daemon";
|
||||||
|
|
||||||
|
includes = [ "services.docker" ];
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
home.packages = [ pkgs.drawio ];
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
home.packages = [ pkgs.easyeffects ];
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
{ inputs, pkgs, ... }:
|
||||||
|
{
|
||||||
|
|
||||||
|
services.hazkey = {
|
||||||
|
enable = true;
|
||||||
|
server.package =
|
||||||
|
inputs.nix-hazkey.packages.${pkgs.stdenv.hostPlatform.system}.hazkey-server.override
|
||||||
|
{ enableVulkan = true; };
|
||||||
|
};
|
||||||
|
|
||||||
|
i18n.inputMethod = {
|
||||||
|
enable = true;
|
||||||
|
type = "fcitx5";
|
||||||
|
|
||||||
|
fcitx5 = {
|
||||||
|
waylandFrontend = true;
|
||||||
|
|
||||||
|
addons = with pkgs; [
|
||||||
|
fcitx5-gtk
|
||||||
|
kdePackages.fcitx5-qt
|
||||||
|
qt6Packages.fcitx5-configtool
|
||||||
|
];
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
inputMethod = {
|
||||||
|
GroupOrder."0" = "Default";
|
||||||
|
|
||||||
|
"Groups/0" = {
|
||||||
|
Name = "Default";
|
||||||
|
"Default Layout" = "jp";
|
||||||
|
DefaultIM = "hazkey";
|
||||||
|
};
|
||||||
|
|
||||||
|
"Groups/0/Items/0" = {
|
||||||
|
Name = "keyboard-jp";
|
||||||
|
};
|
||||||
|
|
||||||
|
"Groups/0/Items/1" = {
|
||||||
|
Name = "hazkey";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
globalOptions = {
|
||||||
|
Hotkey = {
|
||||||
|
EnumerateWithTriggerKeys = false;
|
||||||
|
EnumerateSkipFirst = false;
|
||||||
|
ModifierOnlyKeyTimeout = 250;
|
||||||
|
};
|
||||||
|
|
||||||
|
"Hotkey/TriggerKeys"."1" = "Zenkaku_Hankaku";
|
||||||
|
"Hotkey/ActivateKeys"."0" = "Henkan";
|
||||||
|
"Hotkey/DeactivateKeys"."0" = "Muhenkan";
|
||||||
|
"Hotkey/PrevPage"."0" = "Up";
|
||||||
|
"Hotkey/NextPage"."0" = "Down";
|
||||||
|
"Hotkey/PrevCandidate"."0" = "Shift+Tab";
|
||||||
|
"Hotkey/NextCandidate"."0" = "Tab";
|
||||||
|
"Hotkey/TogglePreedit"."0" = "Control+Alt+P";
|
||||||
|
|
||||||
|
Behavior = {
|
||||||
|
ActiveByDefault = false;
|
||||||
|
resetStateWhenFocusIn = "No";
|
||||||
|
ShareInputState = "No";
|
||||||
|
PreeditEnabledByDefault = true;
|
||||||
|
ShowInputMethodInformation = true;
|
||||||
|
showInputMethodInformationWhenFocusIn = false;
|
||||||
|
CompactInputMethodInformation = true;
|
||||||
|
ShowFirstInputMethodInformation = true;
|
||||||
|
DefaultPageSize = 5;
|
||||||
|
OverrideXkbOption = false;
|
||||||
|
CustomXkbOption = "";
|
||||||
|
EnabledAddons = "";
|
||||||
|
DisabledAddons = "";
|
||||||
|
PreloadInputMethod = true;
|
||||||
|
AllowInputMethodForPassword = false;
|
||||||
|
ShowPreeditForPassword = false;
|
||||||
|
AutoSavePeriod = 30;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{ inputs, ... }:
|
||||||
|
{
|
||||||
|
description = "Fcitx 5 input method framework with Hazkey Japanese input";
|
||||||
|
|
||||||
|
imports.home = [ inputs.nix-hazkey.homeModules.hazkey ];
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
home.packages = [ pkgs.ffmpeg ];
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
system.defaults.finder = {
|
||||||
|
AppleShowAllExtensions = true;
|
||||||
|
AppleShowAllFiles = false;
|
||||||
|
ShowPathbar = true;
|
||||||
|
ShowStatusBar = true;
|
||||||
|
_FXShowPosixPathInTitle = true;
|
||||||
|
_FXSortFoldersFirst = true;
|
||||||
|
FXDefaultSearchScope = "SCcf";
|
||||||
|
FXPreferredViewStyle = "Nlsv";
|
||||||
|
NewWindowTarget = "Home";
|
||||||
|
FXEnableExtensionChangeWarning = true;
|
||||||
|
FXRemoveOldTrashItems = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
programs.gamemode = {
|
||||||
|
enable = true;
|
||||||
|
enableRenice = true;
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
general = {
|
||||||
|
softrealtime = "auto";
|
||||||
|
renice = 10;
|
||||||
|
};
|
||||||
|
custom = {
|
||||||
|
start = "notify-send -a 'Gamemode' 'Optimizations activated'";
|
||||||
|
end = "notify-send -a 'Gamemode' 'Optimizations deactivated'";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
programs.gamescope = {
|
||||||
|
enable = true;
|
||||||
|
capSysNice = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
homebrew = {
|
||||||
|
enable = true;
|
||||||
|
casks = [ "ghostty" ];
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
_: {
|
||||||
|
programs.ghostty = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
theme = "dracula";
|
||||||
|
background-blur-radius = 20;
|
||||||
|
background-opacity = 0.9;
|
||||||
|
background-opacity-cells = true;
|
||||||
|
font-family = "BlexMono Nerd Font Mono";
|
||||||
|
mouse-hide-while-typing = true;
|
||||||
|
window-decoration = "auto";
|
||||||
|
|
||||||
|
keybind = [
|
||||||
|
"performable:ctrl+shift+c=copy_to_clipboard"
|
||||||
|
"ctrl+shift+v=paste_from_clipboard"
|
||||||
|
"ctrl+shift+t=new_tab"
|
||||||
|
"ctrl+alt+left_bracket=previous_tab"
|
||||||
|
"ctrl+alt+right_bracket=next_tab"
|
||||||
|
"alt+q=close_window"
|
||||||
|
"global:alt+space=toggle_quick_terminal"
|
||||||
|
"global:alt+t=new_window"
|
||||||
|
"ctrl+shift+semicolon=increase_font_size:1"
|
||||||
|
"ctrl+shift+minus=decrease_font_size:1"
|
||||||
|
];
|
||||||
|
|
||||||
|
quick-terminal-screen = "mouse";
|
||||||
|
quick-terminal-position = "top";
|
||||||
|
quick-terminal-size = "98%,100%";
|
||||||
|
quick-terminal-autohide = false;
|
||||||
|
quick-terminal-keyboard-interactivity = "on-demand";
|
||||||
|
gtk-quick-terminal-layer = "top";
|
||||||
|
quit-after-last-window-closed = false;
|
||||||
|
shell-integration-features = "no-ssh-env,no-ssh-terminfo";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
xdg.configFile."ghostty/themes/dracula".source = ./dracula.theme;
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
_: {
|
||||||
|
# Global Ghostty keybindings are handled by the running app. Start it hidden
|
||||||
|
# at login so Option+T and Option+Space work before opening a terminal.
|
||||||
|
launchd.agents.ghostty-global-keybindings = {
|
||||||
|
enable = true;
|
||||||
|
config = {
|
||||||
|
ProgramArguments = [
|
||||||
|
"/usr/bin/open"
|
||||||
|
"-gja"
|
||||||
|
"Ghostty"
|
||||||
|
];
|
||||||
|
RunAtLoad = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.ghostty.package = null;
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
# MIT License
|
||||||
|
#
|
||||||
|
# Copyright (c) 2023 Dracula Theme
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in all
|
||||||
|
# copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
palette = 0=#21222c
|
||||||
|
palette = 1=#ff5555
|
||||||
|
palette = 2=#50fa7b
|
||||||
|
palette = 3=#f1fa8c
|
||||||
|
palette = 4=#bd93f9
|
||||||
|
palette = 5=#ff79c6
|
||||||
|
palette = 6=#8be9fd
|
||||||
|
palette = 7=#f8f8f2
|
||||||
|
palette = 8=#6272a4
|
||||||
|
palette = 9=#ff6e6e
|
||||||
|
palette = 10=#69ff94
|
||||||
|
palette = 11=#ffffa5
|
||||||
|
palette = 12=#d6acff
|
||||||
|
palette = 13=#ff92df
|
||||||
|
palette = 14=#a4ffff
|
||||||
|
palette = 15=#ffffff
|
||||||
|
background = #282a36
|
||||||
|
foreground = #f8f8f2
|
||||||
|
cursor-color = #f8f8f2
|
||||||
|
cursor-text = #282a36
|
||||||
|
selection-foreground = #f8f8f2
|
||||||
|
selection-background = #44475a
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{ inputs, system, ... }: {
|
||||||
|
programs.ghostty = {
|
||||||
|
# Labwc's Close action correctly targets one xdg-toplevel, but Ghostty's
|
||||||
|
# systemd service runs every window in one GTK single-instance process.
|
||||||
|
# If that process exits while handling the request, every Ghostty window
|
||||||
|
# disappears together. Keep each launcher invocation independent instead.
|
||||||
|
systemd.enable = false;
|
||||||
|
package = inputs.ghostty.packages.${system}.default;
|
||||||
|
|
||||||
|
settings.gtk-single-instance = false;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
let
|
||||||
|
signingKeyPath = ".ssh/1password-git-signing.pub";
|
||||||
|
signingKeyFile = "~/${signingKeyPath}";
|
||||||
|
|
||||||
|
gitSshSign = pkgs.writeShellScript "git-ssh-sign" ''
|
||||||
|
one_password_sock="$HOME/.1password/agent.sock"
|
||||||
|
|
||||||
|
if { [ -n "''${SSH_CONNECTION:-}" ] || [ -n "''${SSH_CLIENT:-}" ]; } \
|
||||||
|
&& [ -n "''${SSH_AUTH_SOCK:-}" ] \
|
||||||
|
&& [ -S "$SSH_AUTH_SOCK" ]; then
|
||||||
|
exec ${pkgs.openssh}/bin/ssh-keygen "$@"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -S "$one_password_sock" ]; then
|
||||||
|
export SSH_AUTH_SOCK="$one_password_sock"
|
||||||
|
exec ${pkgs.openssh}/bin/ssh-keygen "$@"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "''${SSH_AUTH_SOCK:-}" ] && [ -S "$SSH_AUTH_SOCK" ]; then
|
||||||
|
exec ${pkgs.openssh}/bin/ssh-keygen "$@"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "git ssh signing failed: no forwarded SSH agent or 1Password agent socket found" >&2
|
||||||
|
echo "expected: forwarded SSH_AUTH_SOCK or $one_password_sock" >&2
|
||||||
|
exit 1
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
{
|
||||||
|
home.packages = [ pkgs.gh ];
|
||||||
|
|
||||||
|
home.file.${signingKeyPath}.text = ''
|
||||||
|
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLwReAiwhXoO34S2+MrvqUhi8IWp4IzUq4OSp3niJdq 1password-git-signing
|
||||||
|
'';
|
||||||
|
|
||||||
|
programs.git = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
ignores = [
|
||||||
|
".direnv/"
|
||||||
|
".envrc"
|
||||||
|
"!.envrc.example"
|
||||||
|
];
|
||||||
|
|
||||||
|
signing = {
|
||||||
|
key = signingKeyFile;
|
||||||
|
format = "ssh";
|
||||||
|
signByDefault = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
user = {
|
||||||
|
name = "moons";
|
||||||
|
email = "moons@moons14.com";
|
||||||
|
};
|
||||||
|
|
||||||
|
push.default = "simple";
|
||||||
|
credential.helper = "cache --timeout=7200";
|
||||||
|
init.defaultBranch = "main";
|
||||||
|
log.decorate = "full";
|
||||||
|
log.date = "iso";
|
||||||
|
merge.conflictStyle = "diff3";
|
||||||
|
|
||||||
|
gpg.ssh.program = "${gitSshSign}";
|
||||||
|
|
||||||
|
alias = {
|
||||||
|
br = "branch --sort=-committerdate";
|
||||||
|
co = "checkout";
|
||||||
|
df = "diff";
|
||||||
|
com = "commit -a";
|
||||||
|
gs = "stash";
|
||||||
|
gp = "pull";
|
||||||
|
lg = "log --graph --pretty=format:'%Cred%h%Creset - %C(yellow)%d%Creset %s %C(green)(%cr)%C(bold blue) <%an>%Creset' --abbrev-commit";
|
||||||
|
st = "status";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
home.packages = [ pkgs.gnome-disk-utility ];
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
home.packages = [ pkgs.gnome-text-editor ];
|
||||||
|
|
||||||
|
dconf.settings."org/gnome/TextEditor" = {
|
||||||
|
style-variant = "follow";
|
||||||
|
wrap-text = true;
|
||||||
|
spellcheck = true;
|
||||||
|
restore-session = true;
|
||||||
|
show-line-numbers = false;
|
||||||
|
show-right-margin = false;
|
||||||
|
show-map = false;
|
||||||
|
highlight-current-line = false;
|
||||||
|
auto-indent = false;
|
||||||
|
discover-settings = false;
|
||||||
|
enable-snippets = false;
|
||||||
|
keybindings = "default";
|
||||||
|
};
|
||||||
|
|
||||||
|
xdg.mimeApps = {
|
||||||
|
enable = true;
|
||||||
|
defaultApplicationPackages = [ pkgs.gnome-text-editor ];
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
home.packages = [ pkgs.gnupg ];
|
||||||
|
|
||||||
|
services.gpg-agent = {
|
||||||
|
enable = false;
|
||||||
|
enableSshSupport = false;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
programs.gnupg.agent = {
|
||||||
|
enable = true;
|
||||||
|
enableSSHSupport = false;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{ inputs, pkgs, ... }:
|
||||||
|
{
|
||||||
|
home.packages = [
|
||||||
|
inputs.llm-agents.packages.${pkgs.stdenv.hostPlatform.system}.grok
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
gtk = {
|
||||||
|
enable = true;
|
||||||
|
theme = {
|
||||||
|
name = "Dracula";
|
||||||
|
package = pkgs.dracula-theme;
|
||||||
|
};
|
||||||
|
cursorTheme = {
|
||||||
|
package = pkgs.adwaita-icon-theme;
|
||||||
|
name = "Adwaita";
|
||||||
|
};
|
||||||
|
iconTheme = {
|
||||||
|
package = pkgs.papirus-icon-theme;
|
||||||
|
name = "Papirus-Dark";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
dconf.settings."org/gnome/desktop/wm/preferences" = {
|
||||||
|
button-layout = ":minimize,maximize,close";
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
programs.dconf.enable = true;
|
||||||
|
programs.seahorse.enable = true;
|
||||||
|
services.gnome.gnome-keyring.enable = true;
|
||||||
|
security.pam.services.ly.enableGnomeKeyring = true;
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
home.packages = [ pkgs.python314Packages.huggingface-hub ];
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
programs.java = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.jdk25;
|
||||||
|
};
|
||||||
|
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
maven
|
||||||
|
gradle
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
homebrew = {
|
||||||
|
enable = true;
|
||||||
|
casks = [ "kde-connect" ];
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
programs.kdeconnect.enable = true;
|
||||||
|
}
|
||||||
@@ -0,0 +1,225 @@
|
|||||||
|
{ lib, pkgs, ... }:
|
||||||
|
let
|
||||||
|
systemctl = lib.getExe' pkgs.systemd "systemctl";
|
||||||
|
|
||||||
|
keybind = key: actionAttrs: {
|
||||||
|
"@key" = key;
|
||||||
|
action = actionAttrs;
|
||||||
|
};
|
||||||
|
|
||||||
|
action =
|
||||||
|
key: name:
|
||||||
|
keybind key {
|
||||||
|
"@name" = name;
|
||||||
|
};
|
||||||
|
|
||||||
|
execute =
|
||||||
|
key: command:
|
||||||
|
keybind key {
|
||||||
|
"@name" = "Execute";
|
||||||
|
"@command" = command;
|
||||||
|
};
|
||||||
|
|
||||||
|
snapToEdge =
|
||||||
|
key: direction:
|
||||||
|
keybind key {
|
||||||
|
"@name" = "SnapToEdge";
|
||||||
|
"@direction" = direction;
|
||||||
|
"@combine" = "yes";
|
||||||
|
};
|
||||||
|
|
||||||
|
confirmAction = key: message: name: {
|
||||||
|
"@key" = key;
|
||||||
|
action = {
|
||||||
|
"@name" = "If";
|
||||||
|
prompt."@message" = message;
|
||||||
|
"then".action."@name" = name;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
menuExecute = label: command: {
|
||||||
|
inherit label;
|
||||||
|
action = {
|
||||||
|
name = "Execute";
|
||||||
|
inherit command;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
showMenu = button: menu: {
|
||||||
|
"@button" = button;
|
||||||
|
"@action" = "Press";
|
||||||
|
action = {
|
||||||
|
"@name" = "ShowMenu";
|
||||||
|
"@menu" = menu;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
menuAction = label: name: {
|
||||||
|
inherit label;
|
||||||
|
action.name = name;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
wayland.windowManager.labwc = {
|
||||||
|
enable = true;
|
||||||
|
# NixOS owns the package so Home Manager only generates the user config.
|
||||||
|
package = null;
|
||||||
|
|
||||||
|
systemd = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
variables = [
|
||||||
|
"DISPLAY"
|
||||||
|
"WAYLAND_DISPLAY"
|
||||||
|
"XDG_CURRENT_DESKTOP"
|
||||||
|
"XDG_SESSION_TYPE"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
menu = [
|
||||||
|
{
|
||||||
|
menuId = "root-menu";
|
||||||
|
items = [
|
||||||
|
(menuExecute "ターミナル" "ghostty")
|
||||||
|
(menuExecute "Vicinae" "vicinae toggle")
|
||||||
|
(menuExecute "ファイル" "nautilus --new-window")
|
||||||
|
|
||||||
|
{ separator = true; }
|
||||||
|
|
||||||
|
(menuAction "Reconfigure" "Reconfigure")
|
||||||
|
(menuAction "Exit" "Exit")
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
rc = {
|
||||||
|
|
||||||
|
keyboard = {
|
||||||
|
default = true;
|
||||||
|
numlock = "on";
|
||||||
|
keybind = [
|
||||||
|
# labwc window management
|
||||||
|
(action "W-q" "Close")
|
||||||
|
(action "W-f" "ToggleMaximize")
|
||||||
|
(action "W-c" "Iconify")
|
||||||
|
(action "W-Up" "Lower")
|
||||||
|
(action "W-Down" "Raise")
|
||||||
|
(action "W-Left" "NextWindow")
|
||||||
|
(action "W-Right" "PreviousWindow")
|
||||||
|
(snapToEdge "W-C-Left" "left")
|
||||||
|
(snapToEdge "W-C-Right" "right")
|
||||||
|
(snapToEdge "W-C-Up" "up")
|
||||||
|
(snapToEdge "W-C-Down" "down")
|
||||||
|
(confirmAction "W-S-e" "Exit labwc?" "Exit")
|
||||||
|
(execute "Print" "screenshot region")
|
||||||
|
(execute "C-Print" "screenshot output")
|
||||||
|
(execute "A-Print" "screenshot all")
|
||||||
|
|
||||||
|
# spawn applications (sync with niri modules/applications/niri/home.nix)
|
||||||
|
(execute "W-t" "ghostty")
|
||||||
|
(execute "W-d" "vicinae toggle")
|
||||||
|
(execute "W-s" "noctalia msg panel-toggle launcher")
|
||||||
|
(execute "W-e" "nautilus --new-window")
|
||||||
|
(execute "W-l" "loginctl lock-session")
|
||||||
|
(execute "W-v" "vicinae vicinae://launch/clipboard/history")
|
||||||
|
(execute "W-j" "nani-translate-primary")
|
||||||
|
(execute "W-S-j" "nani-translate-ocr")
|
||||||
|
(execute "W-C-j" "${lib.getExe' pkgs.xdg-utils "xdg-open"} naniapp://translate")
|
||||||
|
(execute "W-space" "ghostty +toggle-quick-terminal")
|
||||||
|
(execute "W-p" "wdisplays")
|
||||||
|
(execute "W-z" "wl-find-cursor -c 0xCCFF453A -s 160 -d 1200")
|
||||||
|
|
||||||
|
# Function keys (sync with niri modules/applications/niri/home.nix)
|
||||||
|
(execute "XF86AudioRaiseVolume" "noctalia msg volume-up")
|
||||||
|
(execute "XF86AudioLowerVolume" "noctalia msg volume-down")
|
||||||
|
(execute "XF86AudioMute" "noctalia msg volume-mute")
|
||||||
|
(execute "XF86AudioMicMute" "noctalia msg mic-mute")
|
||||||
|
(execute "XF86MonBrightnessUp" "noctalia msg brightness-up")
|
||||||
|
(execute "XF86MonBrightnessDown" "noctalia msg brightness-down")
|
||||||
|
(execute "XF86Favorites" "noctalia msg caffeine-toggle")
|
||||||
|
(execute "XF86AudioPlay" "playerctl play-pause")
|
||||||
|
(execute "XF86AudioPause" "playerctl play-pause")
|
||||||
|
(execute "XF86AudioStop" "playerctl stop")
|
||||||
|
(execute "XF86AudioPrev" "playerctl previous")
|
||||||
|
(execute "XF86AudioNext" "playerctl next")
|
||||||
|
(execute "XF86Display" "wdisplays")
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
core = {
|
||||||
|
decoration = "client";
|
||||||
|
gap = 10;
|
||||||
|
autoEnableOutputs = "yes";
|
||||||
|
reuseOutputMode = "yes";
|
||||||
|
};
|
||||||
|
|
||||||
|
theme = {
|
||||||
|
name = "Dracula";
|
||||||
|
cornerRadius = 8;
|
||||||
|
dropShadows = "yes";
|
||||||
|
dropShadowsOnTiled = "yes";
|
||||||
|
};
|
||||||
|
|
||||||
|
windowSwitcher = {
|
||||||
|
"@preview" = "yes";
|
||||||
|
"@outlines" = "yes";
|
||||||
|
osd = {
|
||||||
|
"@style" = "thumbnail";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
focus = {
|
||||||
|
followMouse = "yes";
|
||||||
|
followMouseRequiresMovement = "yes";
|
||||||
|
raiseOnFocus = "no";
|
||||||
|
};
|
||||||
|
|
||||||
|
desktops = {
|
||||||
|
"@number" = 1;
|
||||||
|
"@popupTime" = 500;
|
||||||
|
"@prefix" = "Workspace";
|
||||||
|
};
|
||||||
|
|
||||||
|
mouse = {
|
||||||
|
default = true;
|
||||||
|
|
||||||
|
context = {
|
||||||
|
"@name" = "Desktop";
|
||||||
|
|
||||||
|
mousebind = [
|
||||||
|
(showMenu "Right" "root-menu")
|
||||||
|
(showMenu "Middle" "client-list-combined-menu")
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
libinput.device = [
|
||||||
|
{
|
||||||
|
"@category" = "touchpad";
|
||||||
|
naturalScroll = "yes";
|
||||||
|
tap = "yes";
|
||||||
|
tapAndDrag = "yes";
|
||||||
|
dragLock = "yes";
|
||||||
|
clickMethod = "clickfinger";
|
||||||
|
scrollMethod = "twoFinger";
|
||||||
|
scrollFactor = "4.0";
|
||||||
|
disableWhileTyping = "yes";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
"@category" = "non-touch";
|
||||||
|
pointerSpeed = "-0.1";
|
||||||
|
accelProfile = "flat";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
environment = [
|
||||||
|
"XKB_DEFAULT_LAYOUT=jp"
|
||||||
|
"XKB_DEFAULT_OPTIONS=ctrl:nocaps"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
xdg.configFile."labwc/shutdown".text = lib.mkAfter ''
|
||||||
|
${systemctl} --user stop graphical-session.target
|
||||||
|
'';
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
description = "labwc Wayland stacking compositor";
|
||||||
|
|
||||||
|
includes = [
|
||||||
|
"systems.wayland"
|
||||||
|
"applications.screenshot"
|
||||||
|
"applications.wl-find-cursor"
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
{
|
||||||
|
inputs,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
unstable = inputs.nixpkgs-unstable.legacyPackages.${pkgs.stdenv.hostPlatform.system};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
programs.labwc = {
|
||||||
|
enable = true;
|
||||||
|
package = unstable.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
|
||||||
|
# itself by checking XDG_CURRENT_DESKTOP against a hard-coded list. Labwc is
|
||||||
|
# currently absent from that list, so NixOS starts
|
||||||
|
# nixos-fake-graphical-session.target before Labwc is ready.
|
||||||
|
#
|
||||||
|
# This configuration uses Home Manager's Labwc systemd integration, which
|
||||||
|
# imports the Wayland environment and starts labwc-session.target correctly.
|
||||||
|
# Mark the Labwc session as systemd-aware before the display-manager wrapper
|
||||||
|
# performs its hard-coded check. Otherwise services such as Fcitx5 can start
|
||||||
|
# before WAYLAND_DISPLAY is available.
|
||||||
|
#
|
||||||
|
# Despite the services.xserver namespace, this session wrapper is also used
|
||||||
|
# for Wayland sessions by display managers such as Ly.
|
||||||
|
services.xserver.displayManager.sessionCommands = lib.mkAfter ''
|
||||||
|
case ":''${XDG_CURRENT_DESKTOP:-}:" in
|
||||||
|
*:labwc:*)
|
||||||
|
case ":$XDG_CURRENT_DESKTOP:" in
|
||||||
|
*:X-NIXOS-SYSTEMD-AWARE:*)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
export XDG_CURRENT_DESKTOP="$XDG_CURRENT_DESKTOP:X-NIXOS-SYSTEMD-AWARE"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
'';
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
home.packages = [ pkgs.loupe ];
|
||||||
|
|
||||||
|
xdg.mimeApps = {
|
||||||
|
enable = true;
|
||||||
|
defaultApplicationPackages = [ pkgs.loupe ];
|
||||||
|
|
||||||
|
defaultApplications = {
|
||||||
|
"image/avif" = [ "org.gnome.Loupe.desktop" ];
|
||||||
|
"image/bmp" = [ "org.gnome.Loupe.desktop" ];
|
||||||
|
"image/gif" = [ "org.gnome.Loupe.desktop" ];
|
||||||
|
"image/heic" = [ "org.gnome.Loupe.desktop" ];
|
||||||
|
"image/heif" = [ "org.gnome.Loupe.desktop" ];
|
||||||
|
"image/jpeg" = [ "org.gnome.Loupe.desktop" ];
|
||||||
|
"image/jxl" = [ "org.gnome.Loupe.desktop" ];
|
||||||
|
"image/png" = [ "org.gnome.Loupe.desktop" ];
|
||||||
|
"image/svg+xml" = [ "org.gnome.Loupe.desktop" ];
|
||||||
|
"image/webp" = [ "org.gnome.Loupe.desktop" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
_: {
|
||||||
|
programs.mangohud.enable = true;
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
homebrew = {
|
||||||
|
enable = true;
|
||||||
|
casks = [ "prismlauncher" ];
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
{ pkgs, ... }: {
|
||||||
|
home.packages = [ pkgs.packwiz ];
|
||||||
|
|
||||||
|
programs.prismlauncher = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
package = null;
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
UseSystemLocale = true;
|
||||||
|
|
||||||
|
# Minecraftのバージョンに応じてJavaを切り替える。
|
||||||
|
AutomaticJavaSwitch = true;
|
||||||
|
|
||||||
|
IgnoreJavaCompatibility = false;
|
||||||
|
|
||||||
|
# 軽量~中規模構成のグローバル既定値。
|
||||||
|
MinMemAlloc = 512;
|
||||||
|
MaxMemAlloc = 4096;
|
||||||
|
LowMemWarning = true;
|
||||||
|
|
||||||
|
# 通常はコンソールを隠し、異常時だけ表示する。
|
||||||
|
ShowConsole = false;
|
||||||
|
ShowConsoleOnError = true;
|
||||||
|
LogPrePostOutput = true;
|
||||||
|
ConsoleMaxLines = 100000;
|
||||||
|
ConsoleOverflowStop = true;
|
||||||
|
|
||||||
|
# Mod管理。
|
||||||
|
ModMetadataDisabled = false;
|
||||||
|
ModDependenciesDisabled = false;
|
||||||
|
SkipModpackUpdatePrompt = false;
|
||||||
|
ShowModIncompat = true;
|
||||||
|
DownloadGameFilesDuringInstanceCreation = true;
|
||||||
|
|
||||||
|
# プレイ時間。
|
||||||
|
RecordGameTime = true;
|
||||||
|
ShowGameTime = true;
|
||||||
|
ShowGlobalGameTime = true;
|
||||||
|
|
||||||
|
MetaRefreshOnLaunch = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
_: {
|
||||||
|
programs.prismlauncher.settings = {
|
||||||
|
AutomaticJavaDownload = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user