diff --git a/.gitignore b/.gitignore index 1f3b05a..8acfc84 100755 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.codexis .DS_Store _scratch result diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..e01485a --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,118 @@ +# NixOS Configuration — Agent Guide + +This is a multi-host NixOS/nix-darwin configuration managed with [Snowfall Lib](https://github.com/snowfallorg/lib). It declaratively configures NixOS (Linux), nix-darwin (macOS), and Home Manager across many machines from a single flake. + +## Snowfall Lib Conventions + +Snowfall Lib auto-discovers everything by directory convention — there is no manual wiring. The namespace is `reichard`, so all custom options live under `reichard.*` (e.g. `reichard.services.tailscale`, `reichard.programs.terminal.nvim`). Modules use `lib.reichard.enabled` / `lib.reichard.disabled` helpers from `lib/module/default.nix`. + +**Important:** Files must be tracked by git (`git add`) for the flake to see them. + +## Layout + +### `flake.nix` + +Entrypoint. Defines inputs (nixpkgs, home-manager, sops-nix, disko, apple-silicon, snowfall-lib, etc.) and calls `snowfall-lib.mkFlake`. All system and home modules are auto-discovered from the directory structure below. + +### `systems/` + +System-level NixOS and nix-darwin configurations, organized by architecture: + +- `systems/aarch64-linux/` — ARM Linux hosts (e.g. Asahi MacBook, Oracle Cloud nodes, headscale) +- `systems/x86_64-linux/` — x86 Linux hosts (desktop, thinkpad, utility servers, Kubernetes nodes) +- `systems/aarch64-darwin/` — macOS hosts (work and personal MacBooks) +- `systems/aarch64-raw-efi/` — Raw EFI image builds (terminal image via nixos-generators) +- `systems/x86_64-vmware/` — VMware images (RKE2 node) + +Each host is a directory with a `default.nix` that composes modules via the `reichard.*` option namespace (e.g. `reichard.services.tailscale = enabled;`). Some hosts include `hardware-configuration.nix` or firmware directories. + +### `homes/` + +Home Manager configurations, organized by `/@/default.nix`. Each home config enables per-host programs and services (e.g. Neovim, Firefox, Hyprland, git, tmux) via the `reichard.*` namespace, same as system modules. + +### `modules/` + +Reusable NixOS, Home Manager, and Darwin modules. This is where most of the configuration logic lives. + +- **`modules/nixos/`** — NixOS system modules: + - `common/` — Packages applied to all NixOS systems + - `home/` — Home Manager integration (useGlobalPkgs, useUserPackages) + - `nix/` — Nix daemon settings, registries, binary caches, distributed builds + - `user/` — User account creation + - `security/sops/` — sops-nix secret decryption (age-based) + - `system/` — Boot, networking, NetworkManager, disko disk partitioning + - `services/` — Headscale, Tailscale, llama-swap (LLM model server), OpenSSH, RKE2, printing, Avahi, cloud-init, Sunshine, etc. + - `hardware/` — OpenGL, Asahi (Apple Silicon), battery/UPower + - `programs/graphical/wms/hyprland/` — System-level Hyprland WM setup + - `display-managers/sddm/` — SDDM display manager + - `virtualisation/` — Podman, libvirtd + +- **`modules/home/`** — Home Manager modules: + - `common/` — Packages applied to all home configs (sqlite, jq, ripgrep, ncdu, jnv) + - `user/` — Home Manager user identity + - `security/sops/` — Per-user secret decryption + - `services/` — Fusuma (touchpad gestures), swww (wallpaper), SSH agent, poweralertd + - `programs/terminal/` — CLI tools: bash, tmux, btop, git, k9s, zk, aws, Neovim, opencode, claude-code, pi + - `programs/graphical/` — GUI apps: Firefox (with extensions overlay), Ghostty, Hyprland (home-level), Remmina, GIMP, Wireshark, Ghidra, Strawberry + +- **`modules/darwin/`** — nix-darwin modules: user, OpenSSH, sops + +### `modules/home/programs/terminal/nvim/` — Neovim Configuration + +This is the full Neovim setup, frequently modified. The `default.nix` declares: +- All plugins (via nixpkgs vimPlugins + custom `buildVimPlugin` for codecompanion.nvim, none-ls-extras, llama.vim) +- LSP servers and formatters as `extraPackages` +- A generated `nix-vars.lua` that injects Nix store paths for LSP binaries + +The actual Neovim Lua configuration lives in `config/lua/`: +- `init.lua` — Main loader +- `base.lua` — Core Vim settings and keymaps +- `lsp-config.lua` — LSP server setup (uses paths from `nix-vars.lua`) +- `cmp-config.lua` — nvim-cmp completion +- `llm-config.lua` — LLM integration (codecompanion, llama.vim) +- `snacks-config.lua` — Snacks.nvim dashboard/picker +- `dap-config.lua` — Debug Adapter Protocol (Go, etc.) +- `diagnostics-config.lua`, `ts-config.lua`, `lualine-config.lua`, `noice-config.lua`, `git-config.lua`, `which-key-config.lua`, etc. + +When editing the Neovim config, note that **plugin declarations** happen in `default.nix` (Nix), while **plugin configuration** happens in the Lua files under `config/lua/`. LSP binary paths are bridged via the auto-generated `nix-vars.lua`. + +### `packages/` + +Custom package derivations, auto-discovered by Snowfall Lib and available as `pkgs.reichard.`: + +- `codexis/` — Go: code indexer using tree-sitter (built from gitea via `fetchgit`) +- `llama-cpp/` — LLaMA C++ inference engine +- `llama-swap/` — Go: LLM model swap proxy (with UI sub-derivation) +- `opencode/` — Go: terminal coding tool +- `pi-coding-agent/` — Node.js: coding agent CLI +- `qwen-code/` — Qwen code assistant +- `stable-diffusion-cpp/` — Stable Diffusion C++ inference + +### `overlays/` + +Nixpkgs overlays. Currently just `firefox-addons/` which imports the rycee Firefox addons repository. + +### `secrets/` + +sops-encrypted secrets (age keys). Managed via `.sops.yaml` which defines per-host and per-user key groups: +- `keys.yaml` — Master key definitions +- `common/evanreichard.yaml` — User-level secrets (shared across personal machines) +- `common/systems.yaml` — System-level secrets (e.g. builder SSH keys) + +### `shells/` + +Dev shell definitions. `shells/default/` provides the default `nix develop` environment for working on this repo. + +### `lib/` + +Shared library helpers. `lib/module/default.nix` exports `mkOpt`, `mkBoolOpt`, `enabled`, and `disabled` — used throughout all modules for consistent option declarations. + +## Common Tasks + +- **Adding a new system:** Create `systems///default.nix` and optionally `homes//@/default.nix`. Compose existing modules via `reichard.*` options. +- **Adding a new module:** Create `modules/{nixos,home,darwin}///default.nix` with an `enable` option under the `reichard` namespace. It will be auto-discovered. +- **Adding a new package:** Create `packages//default.nix`. Run `git add` so the flake sees it. Reference it in modules as `pkgs.reichard.`. +- **Editing Neovim plugins:** Modify `modules/home/programs/terminal/nvim/default.nix` (plugin list, extraPackages, nix-vars). +- **Editing Neovim config (Lua):** Modify files under `modules/home/programs/terminal/nvim/config/lua/`. +- **Managing secrets:** Edit `.sops.yaml` for key groups, use `sops` CLI to encrypt/decrypt files in `secrets/`. +- **Building/testing:** `nix build .#packages..` for packages, `nix build .#nixosConfigurations..config.system.build.toplevel` for full system builds. diff --git a/modules/home/common/default.nix b/modules/home/common/default.nix index 8ea89a4..d7e1e61 100644 --- a/modules/home/common/default.nix +++ b/modules/home/common/default.nix @@ -2,9 +2,11 @@ { home.packages = with pkgs; [ + sqlite-interactive jnv jq ncdu ripgrep + reichard.codexis ]; } diff --git a/modules/home/programs/terminal/pi/config/extensions/replace-pi-with-claude-code.ts b/modules/home/programs/terminal/pi/config/extensions/replace-pi-with-claude-code.ts new file mode 100644 index 0000000..efdb29e --- /dev/null +++ b/modules/home/programs/terminal/pi/config/extensions/replace-pi-with-claude-code.ts @@ -0,0 +1,18 @@ +import type { ExtensionAPI } from "@mariozechner/pi-coding-agent"; + +export default function replacePiWithClaudeCodeExtension(pi: ExtensionAPI) { + pi.on("before_agent_start", async (event) => { + const transformedSystemPrompt = event.systemPrompt.replace( + /pi/gi, + "claude code", + ); + + if (transformedSystemPrompt === event.systemPrompt) { + return undefined; + } + + return { + systemPrompt: transformedSystemPrompt, + }; + }); +} diff --git a/modules/home/programs/terminal/pi/default.nix b/modules/home/programs/terminal/pi/default.nix index 16a0367..78dda47 100755 --- a/modules/home/programs/terminal/pi/default.nix +++ b/modules/home/programs/terminal/pi/default.nix @@ -48,6 +48,10 @@ in source = ./config/prompts; recursive = true; }; + ".pi/agent/extensions" = { + source = ./config/extensions; + recursive = true; + }; }; }; } diff --git a/modules/home/programs/terminal/tmux/default.nix b/modules/home/programs/terminal/tmux/default.nix index 2259bdf..7a37748 100755 --- a/modules/home/programs/terminal/tmux/default.nix +++ b/modules/home/programs/terminal/tmux/default.nix @@ -45,9 +45,11 @@ in set -g status-position top set -g mouse on setw -g mode-keys vi + set -g default-terminal "tmux-256color" set -ag terminal-overrides ",xterm-256color:Tc:Ms=\\E]52;c%p1%.0s;%p2%s\\7" set -g extended-keys-format csi-u set -g extended-keys on + set -sg escape-time 0 # Start Index 1 set -g base-index 1 diff --git a/packages/codexis/default.nix b/packages/codexis/default.nix new file mode 100644 index 0000000..242daaa --- /dev/null +++ b/packages/codexis/default.nix @@ -0,0 +1,27 @@ +{ lib +, buildGoModule +, fetchgit +}: + +buildGoModule rec { + pname = "codexis"; + version = "unstable-2026-04-10"; + + src = fetchgit { + url = "https://gitea.va.reichard.io/evan/codexis.git"; + rev = "39fcfc296857f52b962388e454f8161ff0442d23"; + hash = "sha256-B1VKY82tBxkd/L71Lq8Hh+1whQ03DzddkTcR82a+YXk="; + }; + + vendorHash = "sha256-8B1utE6bicIn1YO0qIcZhF7RaIK5cOu1/vm41EG+yyQ="; + + subPackages = [ "." ]; + + meta = { + description = "Code index database tool using tree-sitter"; + homepage = "https://gitea.va.reichard.io/evan/codexis"; + license = lib.licenses.mit; + maintainers = with lib.maintainers; [ evanreichard ]; + mainProgram = "codexis"; + }; +}