From 2d2f535aee5f4ecdb74612789971e0c60743f2ed Mon Sep 17 00:00:00 2001 From: moons-14 Date: Sun, 31 May 2026 14:51:17 +0900 Subject: [PATCH] feat --- AGENTS.md | 376 ++++++++++++++++++++++++++---- modules/applications/codex.nix | 21 ++ modules/applications/default.nix | 2 + modules/applications/opencode.nix | 21 ++ modules/features/dev/agent.nix | 8 +- 5 files changed, 383 insertions(+), 45 deletions(-) create mode 100644 modules/applications/codex.nix create mode 100644 modules/applications/opencode.nix diff --git a/AGENTS.md b/AGENTS.md index 9611f51..265287a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,15 +1,14 @@ # AGENTS.md -NixOS + Home Manager flake。v2 リセット中 — flake-parts 導入済み、outputs はまだスケルトンのみ。 +NixOS + Home Manager flake (v2)。flake-parts ベース。 ## Commands ```sh -# flake の更新 -nix flake update - -# フォーマット -nix fmt +nix flake update # flake の更新 +nix fmt # フォーマット +sudo nixos-rebuild build --flake .# # ビルド確認 +sudo nixos-rebuild switch --flake .# # 適用 ``` ## Conventions @@ -17,67 +16,170 @@ nix fmt - User: `moons`, locale: `ja_JP.UTF-8`, timezone: `Asia/Tokyo` - Commits: conventional commits (`feat:`, `chore:`, `fix:`, etc.) - リモート: `git@github.com:moons-14/dotfiles.git` -- `modules/system/` や `modules/applications/` に新しいファイルを追加した際は、必ず同ディレクトリの `default.nix` の `imports` に追加する -- `environment.systemPackages` にパッケージを追加する際は、パッケージ名の横に簡単な説明をコメントで追加する +- `environment.systemPackages` にパッケージを追加する際はパッケージ名の横に簡単な説明をコメントで追加する +- 警告を抑制する設定は書かない。根本原因を調査して修正する +- home-manager の `sharedModules` 内で `lib.hm.*` を使う場合は、そのモジュール関数の引数で `lib` を受け取る必要がある(NixOSモジュールの `lib` とは別スコープ) +- `useGlobalPkgs = true` なので、home-manager 内で `nixpkgs.config` を設定しない(NixOSレベルで一括設定) +- `allowUnfree` は `hosts/default.nix` でグローバルに設定済み。各モジュールで個別設定しない -## Module Structure +## Architecture -### `modules/system/` +``` +flake.nix +└── hosts/default.nix # mkSystem でホスト構成を生成 + ├── modules/ # 全モジュール(常にインポートされる) + │ ├── applications/ # アプリケーション設定 + │ ├── system/ # システム設定 + │ ├── drivers/ # ドライバ設定 + │ ├── features/ # 機能バンドル(application/systemを束ねる) + │ └── integrations/ # home-manager 統合 + └── profiles/ # ホストごとに有効化するfeaturesの組み合わせ + ├── interfaces/ # 操作インターフェース (CLI/GUI) + ├── platforms/ # ハードウェア (desktop/laptop/vm) + └── workloads/ # 用途 (dev/personal/srv) +``` -システムレベル(NixOS)の設定。OS 全体に影響する設定を配置する。 +### 評価の流れ -- 例: boot, hardware, network, user, locale, fonts, power, secure-boot, caches, gc, version +``` +profile (featuresの有効化) + → features (application/systemの有効化 + パッケージ追加) + → applications (system.nix + home.nix) + → system (NixOS設定) +``` -### `modules/applications/` +## Layer Design -アプリケーション固有の設定。ユーザーが個別に有効/無効を切り替えたいアプリケーションを配置する。 +### `modules/system/` — NixOS システム設定 -- 例: niri, noctalia, greetd, fcitx5, kde, wayland +OS全体に影響する設定。`config.my.system.*` namespace。 -### Module Pattern +- boot, hardware, network, user, locale, fonts, power, secure-boot, gc, version +- 常にインポートされるが、`enable` オプションで実効性を制御 +- home-manager の設定は含めない -`modules/system/` と `modules/applications/` のモジュールは、デフォルトで `config.my.*` namespace で有効/無効を切り替えられる仕組みにする。 +### `modules/applications/` — アプリケーション設定 -#### Simple Module (NixOS のみ) +個別に有効/無効を切り替えたいアプリケーション。`config.my.applications.*` namespace。 -home-manager の設定を含まないモジュール: +- NixOS設定のみ、または NixOS + Home Manager の両方 +- Complex Module は system.nix と home.nix に分離 + +### `modules/features/` — 機能バンドル + +application や system より抽象度の高い「機能」単位で、複数の application/system を束ねて有効化する層。`config.my.features.*` namespace。 + +**features がやること:** + +1. 複数の `my.applications.*.enable` / `my.system.*.enable` をまとめて有効化 +2. application/system に属さないパッケージや設定を直接記述(`environment.systemPackages`、`home.activation` 等) +3. 追加オプションの受け渡し(例: tailscale の `acceptDns` を feature から application に passthrough) + +**features がやらないこと:** + +- 個別アプリケーションの詳細設定(それは applications 層の責務) + +### `profiles/` — ホスト構成 + +features の `enable` を指定するだけの薄い層。ロジックは書かない。 + +| カテゴリ | 役割 | 例 | +| ------------- | -------------------- | --------------------------------- | +| `interfaces/` | 操作インターフェース | cli-minimal, cli-interactive, gui | +| `platforms/` | ハードウェア固有設定 | desktop, laptop, thinkpad, vm | +| `workloads/` | 用途・ワークロード | dev, personal, srv | + +profiles は継承可能: ```nix +# cli-interactive.nix { - lib, - config, - ... -}: + imports = [ ./cli-minimal.nix ]; + my.features.cli.interactive.enable = true; +} +``` + +### `hosts/` — ホスト定義 + +`mkSystem` でホストを定義。profiles のリストを指定: + +```nix +nix-example = mkSystem { + host = "nix-example"; + system = "x86_64-linux"; + profiles = [ + "interfaces/cli-interactive" + "platforms/vm" + "workloads/dev" + ]; +}; +``` + +`specialArgs` で `inputs`, `username`, `unstable`, `host` が全モジュールに渡される。 + +## Module Patterns + +### Simple Module(NixOS のみ) + +home-manager の設定を含まない。1ファイルで完結: + +```nix +# modules/system/audio.nix +{ lib, config, ... }: let - cfg = config.my..; + cfg = config.my.system.audio; in { - options.my.. = { - enable = lib.mkEnableOption ""; + options.my.system.audio = { + enable = lib.mkEnableOption "Audio support (PipeWire)"; }; config = lib.mkIf cfg.enable { - # configuration here + # NixOS設定をここに書く }; } ``` -- `my.system.*` — system モジュール用 -- `my.applications.*` — applications モジュール用 +### Simple Module(Home Manager のみ) -#### Complex Module (NixOS + Home Manager) +NixOS設定を含まず、home-manager のみ: -home-manager の設定も含むモジュールは3つのフラグを設定する: +```nix +# modules/applications/zoom.nix +{ pkgs, lib, config, ... }: +let + cfg = config.my.applications.zoom; +in +{ + options.my.applications.zoom = { + enable = lib.mkEnableOption "Zoom video conferencing"; + }; + + config = lib.mkIf cfg.enable { + home-manager.sharedModules = [ + { + home.packages = with pkgs; [ + zoom-us # Video conferencing application + ]; + } + ]; + }; +} +``` + +### Complex Module(NixOS + Home Manager) + +ディレクトリ構造で system と home を分離: ``` modules/applications// -├── default.nix # my.applications..enable (マスター) -├── system.nix # my.applications..system.enable -├── home.nix # my.applications..homeManager.enable +├── default.nix # マスター enable + imports +├── system.nix # NixOS 設定 +├── home.nix # Home Manager 設定 └── (other files) # 設定ファイル等 ``` -`default.nix`: +**default.nix** — `enable` のみ宣言。`system.enable`/`homeManager.enable` は sub-file に任せる: ```nix { @@ -89,17 +191,15 @@ let cfg = config.my.applications.; in { + imports = [ + ./home.nix + ./system.nix + ]; + options.my.applications. = { enable = lib.mkEnableOption ""; - system.enable = lib.mkEnableOption " system configuration"; - homeManager.enable = lib.mkEnableOption " home-manager configuration"; }; - imports = [ - ./system.nix - ./home.nix - ]; - config = lib.mkIf cfg.enable { my.applications..system.enable = lib.mkDefault true; my.applications..homeManager.enable = lib.mkDefault true; @@ -107,4 +207,194 @@ in } ``` -マスターの `enable` を有効にすると、`lib.mkDefault` で system と homeManager の両方が有効化される。個別に無効化も可能。 +**system.nix:** + +```nix +{ + pkgs, + lib, + config, + ... +}: +let + cfg = config.my.applications..system; +in +{ + options.my.applications..system = { + enable = lib.mkEnableOption " system configuration"; + }; + + config = lib.mkIf cfg.enable { + environment.systemPackages = with pkgs; [ + # Description + ]; + }; +} +``` + +**home.nix** — `home-manager.sharedModules` を使用: + +```nix +{ + lib, + config, + ... +}: +let + cfg = config.my.applications.; + hmCfg = config.my.applications..homeManager; +in +{ + options.my.applications..homeManager = { + enable = lib.mkEnableOption " home-manager configuration"; + }; + + config.home-manager.sharedModules = [ + { + config = lib.mkIf hmCfg.enable { + # home-manager 設定をここに書く + }; + } + ]; +} +``` + +**注意点:** + +- `default.nix` では `enable` のみ宣言。`system.enable`/`homeManager.enable` は `system.nix`/`home.nix` で宣言する(重複宣言エラー回避) +- home.nix で親の `cfg` を参照する場合は `cfg` と `hmCfg` の両方を let で定義 +- Complex Module の home-manager 設定は `home-manager.sharedModules` で記述(`home-manager.users.` は使わない) + +### Feature Module + +**application/system を束ねる場合:** + +```nix +# modules/features/services/container.nix +{ lib, config, ... }: +let + cfg = config.my.features.services.container; +in +{ + options.my.features.services.container = { + enable = lib.mkEnableOption "Container runtime (Docker)"; + }; + + config = lib.mkIf cfg.enable { + my.applications.docker.enable = true; + }; +} +``` + +**パッケージを直接追加する場合(application/system に属さない):** + +```nix +# modules/features/gui/capture.nix +{ pkgs, lib, config, ... }: +let + cfg = config.my.features.gui.capture; +in +{ + options.my.features.gui.capture = { + enable = lib.mkEnableOption "Screen capture tools"; + }; + + config = lib.mkIf cfg.enable { + environment.systemPackages = with pkgs; [ + slurp # Tool for selecting a region of the screen + grim # Screenshot tool for Wayland + ]; + }; +} +``` + +**オプションを passthrough する場合:** + +```nix +# modules/features/network/tailscale.nix +{ + options.my.features.network.tailscale = { + enable = lib.mkEnableOption "Tailscale VPN"; + acceptDns = lib.mkOption { type = lib.types.bool; default = false; }; + }; + + config = lib.mkIf cfg.enable { + my.applications.tailscale = { + enable = true; + inherit (cfg) acceptDns; + }; + }; +} +``` + +**home.activation を使う場合(identity 等):** + +```nix +# modules/features/identity/ssh-default-key.nix +config.home-manager.sharedModules = [ + ( + { lib, ... }: + { + config = lib.mkIf cfg.enable { + home.activation.generateSshKey = lib.hm.dag.entryAfter [ "writeBoundary" ] '' + # shell script here + ''; + }; + } + ) +]; +``` + +### Profile + +features の有効化のみを記述: + +```nix +# profiles/platforms/laptop.nix +{ + my.features = { + boot.power.enable = true; + connect = { + wifi.enable = true; + bluetooth.enable = true; + }; + gui.camera.enable = true; + identity.fingerprint.enable = true; + network.tailscale.enable = true; + }; +} +``` + +## Adding New Features — Checklist + +### 新しいアプリケーションを追加する場合 + +1. `modules/applications/` にモジュール作成(Simple or Complex) +2. `modules/applications/default.nix` の `imports` に追加 +3. `modules/features/` の適切なカテゴリに feature を作成(既存の feature に追記でも可) +4. `modules/features//default.nix` の `imports` に追加 +5. `profiles/` の適切な profile で feature を有効化 + +### 新しいシステム設定を追加する場合 + +1. `modules/system/` にモジュール作成(Simple Module) +2. `modules/system/default.nix` の `imports` に追加 +3. `modules/features/` の適切なカテゴリに feature を作成 +4. `modules/features//default.nix` の `imports` に追加 +5. `profiles/` の適切な profile で feature を有効化 + +### 新しいホストを追加する場合 + +1. `hosts//default.nix` を作成(`hardware-configuration.nix` を import) +2. `hosts/default.nix` の `flake.nixosConfigurations` に `mkSystem` で追加 +3. profiles のリストを指定 + +## Key Technical Notes + +- **nixpkgs channel**: `nixos-26.05` (stable) + `nixpkgs-unstable` +- **unstable パッケージ**: `specialArgs.unstable` 経由で参照(`unstable.`) +- **llm-agents**: `inputs.llm-agents.packages.${pkgs.stdenv.hostPlatform.system}.` で参照 +- **nixvim**: `nixpkgs.source = pkgs.path` と `nixpkgs.config.allowUnfree = true` を vim/home/default.nix で設定 +- **home-manager**: `useGlobalPkgs = true`, `useUserPackages = true` +- **hostname**: `specialArgs.host` から `modules/system/network/default.nix` で `networking.hostName` に設定 +- **stateVersion**: `config.my.stateVersions.nixos` / `config.my.stateVersions.homeManager` で管理(`modules/system/version.nix`) diff --git a/modules/applications/codex.nix b/modules/applications/codex.nix new file mode 100644 index 0000000..f3faa31 --- /dev/null +++ b/modules/applications/codex.nix @@ -0,0 +1,21 @@ +{ + pkgs, + inputs, + lib, + config, + ... +}: +let + cfg = config.my.applications.codex; +in +{ + options.my.applications.codex = { + enable = lib.mkEnableOption "Codex AI coding assistant"; + }; + + config = lib.mkIf cfg.enable { + environment.systemPackages = [ + inputs.llm-agents.packages.${pkgs.stdenv.hostPlatform.system}.codex # OpenAI Codex CLI + ]; + }; +} diff --git a/modules/applications/default.nix b/modules/applications/default.nix index 2815c76..3c89747 100644 --- a/modules/applications/default.nix +++ b/modules/applications/default.nix @@ -3,6 +3,7 @@ ./btop ./chrome.nix ./claude + ./codex.nix ./direnv.nix ./discord.nix ./docker.nix @@ -17,6 +18,7 @@ ./nautilus.nix ./niri ./noctalia + ./opencode.nix ./openssh.nix ./slack.nix ./ssh diff --git a/modules/applications/opencode.nix b/modules/applications/opencode.nix new file mode 100644 index 0000000..0476c31 --- /dev/null +++ b/modules/applications/opencode.nix @@ -0,0 +1,21 @@ +{ + pkgs, + inputs, + lib, + config, + ... +}: +let + cfg = config.my.applications.opencode; +in +{ + options.my.applications.opencode = { + enable = lib.mkEnableOption "OpenCode AI coding assistant"; + }; + + config = lib.mkIf cfg.enable { + environment.systemPackages = [ + inputs.llm-agents.packages.${pkgs.stdenv.hostPlatform.system}.opencode # OpenCode CLI + ]; + }; +} diff --git a/modules/features/dev/agent.nix b/modules/features/dev/agent.nix index a273de0..da390e3 100644 --- a/modules/features/dev/agent.nix +++ b/modules/features/dev/agent.nix @@ -4,10 +4,14 @@ let in { options.my.features.dev.agent = { - enable = lib.mkEnableOption "AI coding agents (Claude Code)"; + enable = lib.mkEnableOption "AI coding agents (Claude Code, Codex, OpenCode)"; }; config = lib.mkIf cfg.enable { - my.applications.claude.enable = true; + my.applications = { + claude.enable = true; + codex.enable = true; + opencode.enable = true; + }; }; }