diff --git a/AGENTS.md b/AGENTS.md index 81c65df..459e9ba 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,7 +2,7 @@ ## Overview -Nix flake managing 3 devices: Mac Mini, MacBook Air (both aarch64-darwin via nix-darwin), and a Windows PC via NixOS-WSL (x86_64-linux). Single user `imbytecat` everywhere. Uses **Lix** (not stock Nix). +Nix flake — 3 devices (Mac Mini, MacBook Air: aarch64-darwin; WSL: x86_64-linux). Single user `imbytecat`. Uses **Lix**. ## Architecture @@ -13,85 +13,61 @@ flake.nix └── nixosConfigurations.wsl (x86_64-linux) ``` -- `lib/default.nix` — builders `mkDarwin`/`mkNixos`, shared `sshKeys` constant (passed via `specialArgs`), `homeManagerConfig` helper -- `modules/shared/` — both platforms: nix/nixpkgs settings (Lix, overlays), fonts, `programs.fish.enable`, `services.openssh.enable`, `programs._1password.enable` -- `modules/darwin/` — macOS: system preferences, homebrew (casks/brews/masApps), user -- `modules/nixos/` — NixOS: system packages, locale/timezone, docker, user -- `home/` — home-manager (shared across all hosts via `useGlobalPkgs`), catppuccin theme -- `hosts/*/` — per-host overrides (mac-mini: 24/7 server; macbook-air: portable; wsl: NixOS-WSL) -- `overlays/` + `pkgs/` — custom packages (comment-checker) +- `lib/default.nix` — `mkDarwin`/`mkNixos` builders, `sshKeys` (via `specialArgs`), `homeManagerConfig` +- `modules/shared/` — cross-platform: Lix, overlays, fonts, fish, openssh, 1password +- `modules/darwin/` — system preferences, homebrew, user +- `modules/nixos/` — system packages, locale, docker, user +- `home/` — home-manager (shared, `useGlobalPkgs`), catppuccin +- `hosts/*/` — per-host overrides +- `overlays/` + `pkgs/` — custom packages -Config flows: `hosts/*` (host-specific) → `modules/*` (platform) → `home/*` (user-level, cross-platform) +Flow: `hosts/*` → `modules/*` → `home/*` ## Commands ```bash -# Justfile shortcuts (preferred) -just rebuild mac-mini # rebuild macOS host +just rebuild mac-mini # macOS host just rebuild macbook-air -just rebuild # rebuild WSL (linux default) -just rollback # rollback to previous generation (linux only) -just check # eval configs without building (platform-aware) +just rebuild # WSL (linux default) +just check # eval without building just update # nix flake update -just up nixpkgs # update a single flake input +just up nixpkgs # update single input just clean # nix-collect-garbage -d (user-level only) -just lsp mac-mini # generate .vscode/settings.json for nixd option completion - -# Direct -sudo darwin-rebuild switch --flake .#mac-mini -sudo nixos-rebuild switch --flake .#wsl - -# First-time macOS bootstrap (nix-darwin not yet installed) -sudo nix run nix-darwin -- switch --flake .#mac-mini - -# First-time WSL bootstrap (fresh NixOS-WSL has no git) -nix-shell -p git --run "git clone ~/nix-config" -cd ~/nix-config && sudo nixos-rebuild switch --flake .#wsl +just lsp mac-mini # nixd option completion for VSCode ``` -## Critical gotchas +## Gotchas -- **Shared settings live in `modules/shared/`**: Fish, openssh, 1password, fonts, nix settings are enabled once in shared — don't re-declare in platform modules. -- **SSH keys are centralized**: Defined as `sshKeys` in `lib/default.nix`, passed via `specialArgs`. Don't hardcode keys in platform modules. -- **NixOS default shell aliases are force-cleared**: `hosts/wsl/default.nix` sets `environment.shellAliases = lib.mkForce {}` to remove NixOS defaults (`l`, `ll`, `ls`). All shell aliases are managed exclusively by Home Manager (eza integration + `fish.nix`). Don't set `environment.shellAliases` in NixOS modules — it would be ignored anyway. -- **Neovim uses lazyvim-nix**: `programs.lazyvim` in `home/dev/neovim.nix` manages neovim via the `lazyvim-nix` flake input (loaded as `sharedModules` in `lib/default.nix`). Catppuccin nvim integration is explicitly disabled (`catppuccin.nvim.enable = false`) because LazyVim manages its own colorscheme. -- **catppuccin module names**: Home-manager uses `catppuccin.homeModules.catppuccin` (in `home/default.nix`). NixOS uses `catppuccin.nixosModules.catppuccin` (in `lib/default.nix`). Don't use the old `homeManagerModules` name. -- **Homebrew `cleanup = "zap"`**: Any brew formula/cask NOT declared WILL be removed on rebuild. Be comprehensive. Casks from taps need full path (e.g. `"goooler/repo/fl-clash"`). Shared casks go in `modules/darwin/default.nix`; host-specific casks go in `hosts/*/default.nix` (nix-darwin merges `homebrew.casks` lists automatically). -- **mise for version management**: Configured via `programs.mise` in `home/dev/languages.nix`. Config trusts all config paths (`trusted_config_paths = [ "/" ]`). -- **Ghostty is macOS-only**: `programs.ghostty.enable = pkgs.stdenv.isDarwin` with `package = null` (installed via Homebrew cask). Terminfo is propagated to NixOS via `ghostty.terminfo` in `modules/nixos/default.nix`. +- **Shared settings in `modules/shared/`** — don't re-declare fish/openssh/1password/fonts in platform modules. +- **`sshKeys` centralized** in `lib/default.nix` via `specialArgs`. Don't hardcode. +- **WSL aliases force-cleared** — `hosts/wsl/default.nix` uses `lib.mkForce {}`. All aliases via Home Manager only. +- **Neovim = lazyvim-nix** — `programs.lazyvim` in `home/dev/neovim.nix`. `catppuccin.nvim.enable = false` (LazyVim manages colorscheme). +- **catppuccin modules** — `catppuccin.homeModules.catppuccin` (home), `catppuccin.nixosModules.catppuccin` (NixOS). Not the old `homeManagerModules`. +- **Homebrew `cleanup = "zap"`** — undeclared casks/brews get removed. Shared → `modules/darwin/`, host-specific → `hosts/*/`. Tap casks need full path (e.g. `"goooler/repo/fl-clash"`). +- **Ghostty macOS-only** — `package = null` (Homebrew cask). Terminfo propagated via `ghostty.terminfo` in `modules/nixos/`. +- **nix-ld on WSL** — `programs.nix-ld.enable = true` for VSCode Remote. -## Secrets (1Password CLI) +## Environment -- **Not sops-nix** — secrets are injected at shell startup via `op inject` (1Password CLI). -- Template: `home/shell/fish.nix` generates `~/.config/op-env/env.tpl` with `op://` references (safe to commit). -- Fish function `op-env` runs on interactive shell init, calling `op inject --in-file` to set env vars. -- Auth via `OP_SERVICE_ACCOUNT_TOKEN` env var (set in `~/.config/fish/local.fish`, which is gitignored via `local.fish` in `conf.d`). - -## Shell - -Fish (not zsh). All tool integrations use `enableFishIntegration`. Key files: -- `home/shell/fish.nix` — abbreviations, aliases, interactiveShellInit, 1Password `op-env` -- `home/shell/tools.nix` — fzf, atuin, zoxide (`--cmd cd`), direnv, bat, eza (`enableFishIntegration = true` provides `ls`/`ll`/`la`/`lt`/`lla` aliases; `fish.nix` overrides `ll`/`lla`), yazi, btop, zellij -- `home/shell/starship.nix` — prompt -- `home/shell/ghostty.nix` — Ghostty terminal config (macOS only) +1Password CLI `op inject` at shell startup. Template in `home/shell/fish.nix` → `~/.config/op-env/env.tpl` (`op://` refs, safe to commit). Auth via `OP_SERVICE_ACCOUNT_TOKEN` in `~/.config/fish/local.fish` (gitignored). ## Home Manager option API -These options were renamed in recent home-manager; use the new names: +Use the new names: - `programs.git.settings.user.{name,email}` (not `userName`/`userEmail`) - `programs.git.settings.*` (not `extraConfig`) - `programs.delta.{enable,options}` (not `programs.git.delta.*`) - `programs.delta.enableGitIntegration = true` (must be explicit) -- `programs.ssh.matchBlocks."*".addKeysToAgent` (not top-level `addKeysToAgent`) -- `programs.ssh.enableDefaultConfig = false` (set explicitly) +- `programs.ssh.matchBlocks."*".addKeysToAgent` (not top-level) +- `programs.ssh.enableDefaultConfig = false` -## Nix LSP & formatter +## Nix tooling -- LSP: `nixd` (not `nil`). Provides nixpkgs/option completion. -- Formatter: `nixfmt`. Run: `nixfmt ` -- Both installed via `home/dev/languages.nix`. -- VSCode settings for nixd option completion: `just lsp ` (generates `.vscode/settings.json` from `.vscode/settings.base.json`; the generated file is gitignored). +- LSP: `nixd`. Formatter: `nixfmt`. Linter: `statix`. +- All in `home/dev/languages.nix`. +- `just lsp ` generates `.vscode/settings.json` (gitignored). ## Tool usage -- **Always use the `nixos_nix` MCP tool** when searching for nix-darwin / NixOS / home-manager options. Query with `source=darwin/nixos/home-manager` and `type=options/packages` to find available options before writing config. Do not guess option names or value types — verify first. +- `opencode.jsonc` configures `just-lsp` (LSP) and `mcp-nixos` (MCP). +- **Always use `nixos_nix` MCP** to look up nix-darwin/NixOS/home-manager options before writing config. Don't guess option names. diff --git a/README.md b/README.md index 3e17b95..3908777 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Nix Config -使用 [nix-darwin](https://github.com/nix-darwin/nix-darwin) + [NixOS-WSL](https://github.com/nix-community/NixOS-WSL) + [Home Manager](https://github.com/nix-community/home-manager) + [Flakes](https://nix.dev/concepts/flakes) 声明式管理三台设备的系统配置。 +nix-darwin + NixOS-WSL + Home Manager + Flakes 声明式管理三台设备的系统配置。 ## 设备 @@ -12,26 +12,31 @@ ## 快速开始 -### macOS (Mac Mini / MacBook Air) +### macOS -1. 安装 [Lix](https://lix.systems/)(Nix 的社区分支,nix-darwin 官方推荐): +1. 安装 [Lix](https://lix.systems/): ```bash curl -sSf -L https://install.lix.systems/lix | sh -s -- install ``` -2. 克隆仓库并首次构建: +2. 安装 [Homebrew](https://brew.sh/)(nix-darwin 不会自动安装): + +```bash +/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" +``` + +3. 克隆仓库并首次构建: ```bash git clone ~/nix-config cd ~/nix-config -# 首次(nix-darwin 尚未安装): sudo nix run nix-darwin -- switch --flake .#mac-mini -# 之后日常重建: -sudo darwin-rebuild switch --flake .#mac-mini ``` -### WSL (Windows PC) +之后日常重建:`just rebuild mac-mini` + +### WSL 1. 安装 [NixOS-WSL](https://github.com/nix-community/NixOS-WSL/releases): @@ -40,7 +45,7 @@ wsl --import NixOS C:\wsl\nixos nixos-wsl.tar.gz wsl -d NixOS ``` -2. 首次初始化(全新的 NixOS-WSL 没有 `git`,需要借助 `nix-shell` 临时引入): +2. 首次构建: ```bash nix-shell -p git --run "git clone ~/nix-config" @@ -48,87 +53,58 @@ cd ~/nix-config sudo nixos-rebuild switch --flake .#wsl ``` -> 首次 rebuild 完成后 `git`、`just` 等工具会由配置声明安装,此后可直接使用 `just rebuild` 重建。 +之后日常重建:`just rebuild` ## 仓库结构 ``` -├── flake.nix # 入口:输入源 + 输出配置 -├── flake.lock # 依赖锁定文件 -├── hosts/ -│ ├── mac-mini/default.nix # Mac Mini 特定配置 -│ ├── macbook-air/default.nix# MacBook Air 特定配置 -│ └── wsl/default.nix # WSL 特定配置 -├── modules/ -│ ├── darwin/default.nix # macOS 模块(Homebrew、系统偏好等) -│ ├── nixos/ # NixOS 模块 -│ │ ├── default.nix # 系统包、区域、用户 -│ │ └── docker.nix # Docker 配置 -│ └── shared/ # 共享模块(Nix 设置) -├── home/ # Home Manager 配置 -│ ├── default.nix # 入口 + 用户级包 + Catppuccin 主题 -│ ├── dev/ # 开发工具 -│ │ ├── neovim.nix -│ │ ├── languages.nix # 语言运行时、LSP -│ │ └── git.nix -│ └── shell/ # Shell 配置 -│ ├── fish.nix # Fish shell -│ ├── ghostty.nix # Ghostty 终端(仅 macOS) -│ ├── starship.nix # Prompt -│ └── tools.nix # fzf, atuin, zoxide 等 -├── lib/default.nix # 构建辅助函数 -├── overlays/ # 自定义包覆盖 -└── pkgs/ # 自定义包 +flake.nix # 入口 +hosts/ # 主机特定配置 +modules/ + ├── darwin/ # macOS 模块 + ├── nixos/ # NixOS 模块 + └── shared/ # 共享模块 +home/ # Home Manager 配置 + ├── dev/ # 开发工具 + └── shell/ # Shell 配置 +lib/default.nix # 构建辅助函数 +overlays/ + pkgs/ # 自定义包 ``` -**配置层级**:`hosts/*`(主机特定) → `modules/*`(平台模块) → `home/*`(用户级,跨平台共享) +配置层级:`hosts/*` → `modules/*` → `home/*` ## 日常使用 -项目提供 [`justfile`](justfile),首次 rebuild 后即可使用: - ```bash -just rebuild # 重建系统(自动选择 darwin-rebuild / nixos-rebuild) +just rebuild # 重建系统 just update # 更新所有 flake 输入 -just up # 更新单个输入,如 just up nixpkgs -just check # 检查配置是否能正常 evaluate -just clean # 清理旧 generation 并回收空间 -just rollback # 回滚到上一个 generation(仅 NixOS) -just history # 查看系统 profile 历史 +just up # 更新单个输入 +just check # 检查配置 +just clean # 清理旧 generation +just rollback # 回滚(仅 NixOS) +just history # 查看 profile 历史 just show # 显示 flake 输出 ``` -> **注意**:`just clean` 仅清理用户级 generation。NixOS 上如需清理系统级旧 generation,需要 `sudo nix-collect-garbage -d`。 - ## Shell -使用 **Fish** 作为默认 shell,搭配: +Fish + Starship + Atuin + Zoxide + FZF + Direnv,Catppuccin Mocha 主题。 -- **Starship** — 跨平台 prompt -- **Atuin** — shell 历史搜索 -- **Zoxide** — 智能 cd(`cd` = zoxide, `cdi` = 交互选择) -- **FZF** — 模糊搜索(Ctrl-R 历史, Ctrl-T 文件, Alt-C 目录) -- **Direnv** — 自动加载项目环境 -- **Catppuccin Mocha** — 统一主题 +常用自定义: +- fish abbreviation → `home/shell/fish.nix` +- 添加包 → `home/default.nix` 或 `home/dev/languages.nix` +- Homebrew cask → `modules/darwin/default.nix` -### 自定义 +## Environment -- 添加 fish abbreviation: 编辑 `home/shell/fish.nix` 中的 `shellAbbrs` -- 添加包: 编辑 `home/default.nix` 或 `home/dev/languages.nix` -- 添加 Homebrew cask: 编辑 `modules/darwin/default.nix` 中的 `homebrew.casks` -- 查包名: `nix search nixpkgs <关键词>` 或 [search.nixos.org](https://search.nixos.org/packages) +1Password CLI `op inject` 在 Fish 启动时注入环境变量。 -## Secrets(1Password CLI) +模板文件 `~/.config/op-env/env.tpl` 由 `home/shell/fish.nix` 生成,仅包含 `op://` 引用,可安全提交。 -项目使用 [1Password CLI](https://developer.1password.com/docs/cli/) 的 `op inject` 在 Fish shell 启动时注入环境变量(如 API Key),而非 sops-nix。 - -**工作原理**:`home/shell/fish.nix` 生成模板文件 `~/.config/op-env/env.tpl`(仅包含 `op://` 引用,无真实密钥,可安全提交),每次打开交互式 shell 时自动调用 `op inject` 解析模板并 `source` 到环境中。 - -**前置条件**:需要设置 `OP_SERVICE_ACCOUNT_TOKEN` 环境变量来认证 1Password CLI。建议将其写入 `~/.config/fish/local.fish`(该文件被 gitignore,不会提交): +认证需要在 `~/.config/fish/local.fish`(gitignored)中设置: ```bash -# ~/.config/fish/local.fish set -gx OP_SERVICE_ACCOUNT_TOKEN "your-service-account-token" ``` -> Service Account Token 可在 [1Password 开发者工具](https://my.1password.com/developer-tools/active/service-accounts) 中创建管理。若未设置该 token,`op-env` 会静默跳过,不影响 shell 正常使用。 +未设置 token 时 `op-env` 静默跳过,不影响使用。