Compare commits

132 Commits

Author SHA1 Message Date
9234782492 Update modules/nixos/services/openssh/default.nix 2026-02-27 01:03:38 +00:00
bf7cc81a61 feat: add coding model filtering and CUDA acceleration
- claude: filter model completion to coding/synthetic models only
- llama-swap: update model to IQ4_XS and add CUDA device selection
2026-02-26 15:47:25 -05:00
8e1a2ad85a feat: add claude-code package
- Add Nix package for @anthropic-ai/claude-code (v2.1.59)
- Add package-lock.json with optional dependencies for all platforms
- Include update script for automated version updates
- Add module integration with custom package reference
- Rename claude shell alias to claude-custom

Refs: https://github.com/anthropics/claude-code
2026-02-26 08:49:13 -05:00
ff5cd52dce feat(systems): add trackpad gesture, 24-hour time, and Touch ID sudo
- Enable NSWindowShouldDragOnGesture for drag gestures
- Force 24-hour time format via AppleICUForce24HourTime
- Add Touch ID authentication for sudo commands
- Remove outdated comment about Three Finger Drag
2026-02-25 11:49:23 -05:00
0ee4bbfbfe chore(llama-cpp): bump version from 8089 to 8147 2026-02-24 20:32:08 -05:00
7649de4472 feat(llama-swap): add Qwen3.5 models and update model configurations
- Add Qwen3.5-35B-A3B and Qwen3.5-27B thinking model configs
- Remove deprecated Qwen2.5-Coder-7B model
- Update synthetic models list with new HF endpoints
2026-02-24 19:52:42 -05:00
9b2b7add1c chore: add sops for terminal 2026-02-23 16:45:58 -05:00
45e61d92cf build: update pi-coding-agent to 0.54.0 and git config
- Updated pi-coding-agent package from 0.52.0 to 0.54.0
- Added forceUpdateTags to git fetch configuration
2026-02-20 21:07:47 -05:00
e8cb059051 chore: update llama-cpp & llama-swap 2026-02-18 08:56:25 -05:00
9d5d256af8 chore: custom fastfetch logo 2026-02-18 08:37:43 -05:00
d97649859a chore: switch providers 2026-02-17 20:07:12 -05:00
de6f3ee6ba feat: base darwin config 2026-02-11 16:57:37 -08:00
4514e4223b chore: dev env image 2026-02-09 12:44:53 -05:00
979f9b4b47 fix: nvim deps 2026-02-09 12:41:26 -05:00
f47505af0b build: add determinate nix support for darwin
- Add determinateSystems/determinate flake input
- Include determinate darwin modules in configuration
- Disable legacy nix module configuration
- Remove modules/darwin/nix/default.nix
- Add mac-va-mbp-work system using determinate nix
2026-02-08 17:42:21 -05:00
d685773604 refactor: update llm model configurations and add AI agent guidelines
- Update nvim to use qwen3-coder-next-80b-instruct model
- Add AGENTS.md with AI agent best practices for timeout and file writing
- Update pi config to include agent guidelines
- Refactor llama-swap: remove old models, update quantizations, add tensor splits,
  remove GGML_CUDA_ENABLE_UNIFIED_MEMORY flags, and simplify configuration
2026-02-06 21:28:31 -05:00
ec15ebb262 refactor(terminal): filter models by coding type
Change opencode and pi model filtering to use 'coding' type instead of
more generic 'text-generation' type. Update llama-swap model configs to
include 'coding' in metadata type list for relevant models (deepseek-coder,
qwen-coder, mistral, codellama, llama3-8b-instruct-q5).
2026-02-06 08:33:01 -05:00
234c4f2b8b feat[pi]: add review prompt and sync prompts to pi config 2026-02-06 08:28:50 -05:00
bdd1f50a48 chore(config): update git-commit skill and configuration 2026-02-06 08:20:56 -05:00
933cac59d0 chore(pi-coding-agent): bump to version 0.52.0 2026-02-05 15:17:40 -05:00
3cca4a0c58 feat(homes): enable pi tool and update opencode hash
- Add pi to enabled tools in personal macOS home configuration
- Update opencode package hash for darwin platform
2026-02-05 14:16:47 -05:00
f2b821b122 feat(home): add pi coding agent configuration
- Add pi module for terminal configuration
- Include pi-coding-agent package in home.packages
- Configure pi with llama-swap provider via models.json
- Enable pi for mac-va-mbp-work profile
2026-02-05 13:57:02 -05:00
4aa1a9bc5f feat(runtime): add pi-coding-agent package with CLI tools
- Added pi-coding-agent package definition with buildNpmPackage
- Includes npm dependencies and native/build inputs for GUI libraries
- Skips generate-models step during build (models already in repo)
- Creates 'pi' executable pointing to coding-agent dist/cli.js

Fixes build issues where generate-models would fail during build phase
2026-02-05 10:23:55 -05:00
6a48a33caa chore(opencode): update to v1.1.51 and refactor build configuration
- Update opencode from v1.1.48 to v1.1.51
- Refactor build dependencies: remove fzf, add sysctl conditionally for Darwin
- Fix bun to use nixpkgs-unstable input instead of direct dependency
- Add platform-specific outputHash for Darwin and Linux
- Move wrapProgram from postFixup to installPhase
- Remove unnecessary build patch and postPatch/postBuild workarounds
- Fix config path to use absolute home directory
- Add git and home-manager to default shell inputs
- Minor README documentation reordering
2026-02-04 10:04:37 -05:00
57d50992bf chore(llama-swap): bump to version 189
Updated llama-swap to version 189 with corresponding hash updates.
Adjusted UI sourceRoot from "ui" to "ui-svelte" to match upstream
directory structure changes.
2026-02-04 08:33:40 -05:00
682b7d8b4b feat(llama-swap): add Qwen3 Coder Next 80B model configuration
Add new model "Qwen3 Coder Next (80B) - Instruct" with 262144 context window
and optimized parameters for coding tasks. Uses CUDA unified memory support.
2026-02-03 20:53:47 -05:00
7080727dce chore: update llama-cpp to b7898 and opencode to v1.1.48
- Update llama-cpp from b7867 to b7898
- Update opencode from v1.1.12 to v1.1.48 with improved build process:
  - Replace custom bundle script with official script/build.ts
  - Add shell completion support
  - Add version check testing
  - Simplify node_modules handling
- Update llama-swap service config with new llama.cpp options
- Clarify opencode agent testing workflow in developer and reviewer configs
2026-02-03 20:33:14 -05:00
15259b5ec3 chore: update nix 2026-02-03 11:03:21 -05:00
0dca9802e6 feat(llama-swap): increase context window and add GPU configuration
- Increase context window from 80k to 202,752 tokens
- Add repeat penalty parameter (1.0)
- Enable CUDA device for GPU acceleration
2026-01-29 21:18:34 -05:00
72ddbb288e chore: update dependencies and add OpenCode commit command
- Update llama.cpp from b7789 to b7867
- Update llama-swap from v182 to v186
- Add OpenCode conventional commit command configuration
- Add moonshotai Kimi-K2.5 model to llama-swap
2026-01-29 21:01:56 -05:00
abcbc3250a fix: printer 2026-01-23 18:32:10 -05:00
cbcf476002 chore: add octoprint & orca slicer 2026-01-21 15:35:19 -05:00
385773ed26 chore: utlity update 2026-01-20 21:18:59 -05:00
58fa210eb5 update llamacpp 2026-01-20 20:20:50 -05:00
6a8501bbe9 fix: rke2 config 2026-01-19 19:40:57 -05:00
33abdb0cfc add: printers, fix: fullbleed printing 2026-01-19 12:08:12 -05:00
00a486c5e6 fix: hyprland keys 2026-01-18 20:28:46 -05:00
3a67a3fe99 chore: printing, tailscale, and opencode 2026-01-18 14:16:41 -05:00
68fada8d38 fix: asahi notch 2026-01-17 12:14:03 -05:00
107397ce78 fix: disable omnisharp until upstream fix 2026-01-17 10:19:01 -05:00
0968aa12e3 chore: update asahi 2026-01-17 10:14:01 -05:00
6cfe7228f3 chore: rename sops 2026-01-17 10:10:26 -05:00
94249ce86b chore: update flake 2026-01-17 09:35:36 -05:00
408151b2ec chore: various improvements & refactor 2026-01-17 09:28:38 -05:00
51cd993f89 chore: update .gitignore 2026-01-11 22:23:38 -05:00
c8f5e744d0 chore(cleanup): sops, opencode, etc 2026-01-11 22:19:31 -05:00
1fe9396284 fix: sddm theme 2026-01-07 12:04:41 -05:00
0b01da43b8 chore: update packages 2026-01-07 12:04:18 -05:00
685d12dabd update llama-swap defs 2026-01-02 19:49:00 -05:00
f3ceb57e5e feat: stable-diffussion & updates 2026-01-02 09:50:44 -05:00
bb3305adbf chore: update llama-swap 2025-12-28 12:40:27 -05:00
9965ca8816 chore: better swap behavior 2025-12-28 12:02:31 -05:00
dce002cc24 chore: update llamacpp 2025-12-28 10:04:00 -05:00
ece872fdeb chore: update flake & llama-cpp 2025-12-26 21:38:46 -05:00
1c1f976186 chore: asahi flake 2025-12-26 20:55:10 -05:00
d40596d56f chore: up fsnotify on rke2 2025-12-26 20:51:59 -05:00
93edba05a9 chore: update model paths 2025-12-26 09:00:25 -05:00
9b1514243b chore: update nix-darwin to 25.11 and enable opencode 2025-12-21 15:22:51 -05:00
bf4e50a970 refactor: migrate from opencode to codecompanion with updated model configurations 2025-12-21 10:50:01 -05:00
a33790cfc7 feat: add opencode package and update models 2025-12-20 20:19:19 -05:00
c3aa7802ad feat(nvim): reorganize and modernize Neovim configuration
- Remove deprecated config files: git-ref.lua, git-signs.lua, diffview-config.lua, lsp-lines-config.lua, neotree-config.lua, fidget-spinner.lua, silicon-config.lua, telescope-config.lua, llm.lua
- Add new configuration files: diagnostics-config.lua, git-config.lua, llm-config.lua, snacks-config.lua
- Update existing config files: base.lua, dap-config.lua, init.lua, lsp-config.lua, lualine-config.lua, noice-config.lua, octo-config.lua, toggleterm-config.lua, which-key-config.lua
- Update nvim and opencode module configurations
2025-12-18 13:42:16 -05:00
b93249daf7 feat(llm): add Qwen3-VL-8B and Qwen2.5-Coder support, update CUDA config
- Add new `qwen3-8b-vision` model with multimodal support using mmproj file
- Add new `qwen2.5-coder-7b-instruct` model with FIM enabled via `--fim-qwen-7b-default`
- Update CUDA device usage from `CUDA0` to `CUDA1` for `olmoe-7b-instruct` and `phi-mini-8b-instruct`
- Upgrade llama.cpp to version 7426 with updated hash and CUDA architectures (61;86)
- Add Copilot acceptance shortcut `<C-J>` in insert mode and disable tab mapping
- Improve cache type settings across multiple models for better performance
2025-12-17 09:27:15 -05:00
e947e13a02 feat: comprehensive NixOS and home-manager configuration updates
This commit includes significant updates to the Nix configuration including:
- Added common NixOS module with system packages
- Updated home-manager configurations for various systems
- Enhanced terminal programs including Claude Code integration
- Updated LLM server configurations with new models
- Improved btop configuration with custom package
- Added opencode support with permission settings
- Updated tmux and nvim configurations

The changes introduce new features, update existing configurations, and improve the overall system setup.
2025-12-14 16:24:11 -05:00
80033fd2ae chore(release): bump NixOS to 25.11 and update channels
Upgrade the NixOS `stateVersion` from 25.05 to 25.11 in all system configuration files and update all nix channel URLs to the 25.11 releases. Adjust Home Manager and terminal module configurations accordingly, clean up duplicated SSH keys, and update LLaMA server command lines. Minor housekeeping changes to package definitions and other configuration files are also included.
2025-12-12 12:40:09 -05:00
a367f724ce feat: add opencode 2025-12-10 13:51:05 -05:00
c1a650a90e chore(llm): clean up models & fix llama-cpp issue 2025-12-10 12:12:50 -05:00
30934c8f7c switch llm endpoint 2025-12-06 08:55:48 -05:00
6dc1ee512e chore(llm): add vulkan support and update llama.cpp to 7278 2025-12-05 16:53:44 -05:00
d64cc0e47b feat(nvim): integrate CodeCompanion with LlamaSwap and Copilot
- Remove old code-companion-config.lua file
- Move LLM configuration to llm.lua with LlamaSwap and Copilot integration
- Add copilot-vim plugin to default.nix
- Update which-key bindings to include new CodeCompanion commands
- Configure CodeCompanion with chat, inline, and command strategies using LlamaSwap adapter
- Add memory configuration with default project files
- Update LSP configuration for CodeCompanion markdown rendering
2025-12-04 17:36:45 -05:00
50b03508e1 update llama-cpp 2025-12-03 21:07:13 -05:00
0ed577e815 more things 2025-12-03 11:40:01 -05:00
3089d6fdd1 chore: switch to qwen3 coder 30b FIM 2025-12-02 10:41:31 -05:00
8a5e2a9823 chore: llama-swap + fim 2025-12-02 09:47:35 -05:00
cf5fadf040 chore: add desktop 2025-12-01 21:09:44 -05:00
23a871a1c9 chore: upgrade 25.11 2025-11-30 19:35:10 -05:00
e804894036 fix: use nvtop for intel gpus 2025-11-20 17:00:00 -05:00
c60cb58d14 chore: native lsp 2025-11-15 16:04:57 -05:00
167c1d811c chore: update flake 2025-11-10 16:23:48 -05:00
bf9e3a044b fix: determinate nix + nix darwin 2025-11-08 11:32:50 -05:00
56921235b3 fix: actually fix user shell 2025-11-08 11:28:35 -05:00
b111cf4197 chore: remove csharp_ls 2025-11-08 11:19:44 -05:00
567e8c10d2 feat(nvim): add omnisharp 2025-11-06 09:26:34 -05:00
3480837c26 add: common tools 2025-11-04 21:02:25 -05:00
ad6de45681 add: strawberry 2025-11-03 08:58:33 -05:00
e7ee14a3c1 feat: add csharp lsp 2025-11-02 18:27:34 -05:00
667df4e8e6 fix: thinkpad sleep 2025-10-31 09:26:05 -04:00
5c429b8a6b block firefox ai crap 2025-10-28 08:41:12 -04:00
4f054051e5 fix: thinkpad L14 S4 hibernate 2025-10-25 13:02:36 -04:00
318c6f6984 asahi update 2025-10-22 10:19:21 -04:00
0c2bf58cfa fix: prevent clangd from formatting proto files 2025-10-15 10:36:09 -04:00
70df72a6f5 fix: incorrect bash shell in toggleterm 2025-10-10 14:24:22 -04:00
8c417d8e56 add aws stuff 2025-10-10 10:29:17 -04:00
7ce476adb3 update libvirt & add clangd lsp 2025-10-03 13:10:09 -04:00
e173ddffc9 fix tmux over mosh copy & boot config 2025-10-01 17:55:44 -04:00
eb0c28d2f0 add qemu & battery notifs 2025-09-29 20:37:53 -04:00
2a40dc791d more 2025-09-28 18:32:02 -04:00
1098c68073 wip 2025-09-27 12:28:43 -04:00
74e6684783 add ssh key 2025-09-23 20:32:31 -04:00
5b05dffb20 enable ts 2025-09-23 20:31:07 -04:00
1d9517a37f enable mosh 2025-09-23 19:23:35 -04:00
ff62814436 update nameserver 2025-09-23 16:18:43 -04:00
be5c3e9cb8 tmux 2025-09-23 15:44:57 -04:00
bf4148dab0 split bash from ghostty 2025-09-22 19:05:18 -04:00
fbb274a50a more systems 2025-09-19 14:37:17 -04:00
9159465836 add headscale specific node 2025-09-16 16:30:56 -04:00
cff9bcaecc alias 2025-09-07 21:03:27 -04:00
2492bb8825 tailscale 2025-09-07 15:20:47 -04:00
788697561a add kubectl 2025-09-06 20:33:36 -04:00
f6dbe8ad1d mkopt systemd vs grub 2025-09-06 09:47:27 -04:00
26f32d3225 chore: added llama-cpp and migrate office 2025-09-05 22:58:00 -04:00
9433abcaf4 update nix flake, remote nix-anywhere, update readme 2025-09-03 08:12:35 -04:00
f5c4e6c9db back to vmware 2025-09-01 20:51:48 -04:00
b970f6f550 add cloud 2025-09-01 20:09:23 -04:00
93b7c6ee25 update nix 2025-09-01 15:10:31 -04:00
cc045f225b feat(nvim): add octo 2025-08-28 17:04:54 -04:00
e63dd8d5d1 add: remmina & thinkpad hardware mod 2025-07-28 16:55:28 -04:00
6b42b3cc22 vim deprecated functions 2025-07-27 18:22:11 -04:00
73b9bf063e update 25.05 2025-07-27 18:17:35 -04:00
dea1fc8790 chore: update vim stuff 2025-07-27 18:09:57 -04:00
57dbafb5a4 update 24.11 2025-07-27 17:57:35 -04:00
5bb653f561 add bt to tp 2025-07-27 17:49:29 -04:00
f09e2a9ec1 chore: nvim autopep8 line limit 2025-07-23 20:21:10 -04:00
6cd0437fb5 feat: add wireshark 2025-07-23 11:17:48 -04:00
d6c908dc70 git signs tweak 2025-06-09 13:22:03 -04:00
b1981a2dcc autopep8 2025-05-01 14:06:05 -04:00
a58d02d1bd nvim: use pyright for starlark 2025-04-30 13:12:00 -04:00
c2af87fce5 add telescope undo tree 2025-04-22 19:11:08 -04:00
93d50641c1 macos update instructions 2025-04-22 11:47:10 -04:00
a6a9a97650 add pin hyprland bind 2025-04-22 07:46:05 -04:00
5455230930 add gimp 2025-04-20 21:16:56 -04:00
b632c0c3af sync system clipboard 2025-04-20 21:10:15 -04:00
cf0fa75058 Migrate to Snowfall (#1)
Reviewed-on: #1
Co-authored-by: Evan Reichard <evan@reichard.io>
Co-committed-by: Evan Reichard <evan@reichard.io>
2025-04-21 00:56:53 +00:00
143 changed files with 6533 additions and 1536 deletions

1
.envrc Normal file
View File

@@ -0,0 +1 @@
use flake

1
.gitignore vendored
View File

@@ -2,3 +2,4 @@
_scratch _scratch
result result
._* ._*
.direnv

View File

@@ -1,15 +1,35 @@
keys: keys:
# Admin - Age Native # Global Admin
- &admin_reichard age1sac93wpnjcv62s7583jv6a4yspndh6k0r25g3qx3k7gq748uvafst6nz4w - &admin_reichard age1sac93wpnjcv62s7583jv6a4yspndh6k0r25g3qx3k7gq748uvafst6nz4w
# lin-va-mbp-personal@evanreichard - SSH Derived
# User SSH Derived
- &user_lin-va-desktop age15hdlen5dgjvdfgg2j0uzvchs5vs3xuptkhsw9xeuatcuk6uwrvcsz7hcsg
- &user_lin-va-mbp-personal age17ayje4uv2mhwehhp9jr3u9l0ds07396kt7ef40sufx89vm7cgfjq6d5d4y - &user_lin-va-mbp-personal age17ayje4uv2mhwehhp9jr3u9l0ds07396kt7ef40sufx89vm7cgfjq6d5d4y
- &user_lin-va-thinkpad age1avlhszrryt4gf4ya536jhzm7qwt9xfttm8x4sns6h9w2tahzqp8sspz9y5
- &user_mac-va-mbp-personal age1dccte7xtwswgef089nd80dutp96xnezx5lrqnneh9cusegsnda8sj3dj6c
- &user_mac-va-mbp-work age1jf7yuycuajc5m8vupgrndjvw8knekr2v9979j68xc5ykvcxag4lss454au
- &user_lin-va-terminal age1w6avj7gd4f5frk90lsyh4e2k5am6z92hzlr0vpgrm767muyj59qsnuah62
# System SSH Derived
- &system_lin-va-desktop age1mxjrvjxkn69kfn2np3wpd73g44fuhsgykw7l5ss9rx30em5jfp2scnrq32
- &system_lin-va-thinkpad age13gymlygyac9z2slecl53jp8spq7e8n4zkan86n0gmnm3nrj4muxqa5ullm
creation_rules: creation_rules:
- path_regex: secrets/[^/]+\.(yaml|json|env|ini)$ - path_regex: secrets/[^/]+\.(yaml|json|env|ini)$
key_groups: key_groups:
- age: - age:
- *admin_reichard - *admin_reichard
- path_regex: secrets/lin-va-mbp-personal/evanreichard/[^/]+\.(yaml|json|env|ini)$ - path_regex: secrets/common/systems.yaml
key_groups:
- age:
- *admin_reichard
- *system_lin-va-desktop
- *system_lin-va-thinkpad
- path_regex: secrets/common/evanreichard.yaml
key_groups: key_groups:
- age: - age:
- *admin_reichard - *admin_reichard
- *user_lin-va-mbp-personal - *user_lin-va-mbp-personal
- *user_lin-va-terminal
- *user_lin-va-thinkpad
- *user_mac-va-mbp-personal
- *user_mac-va-mbp-work

110
README.md
View File

@@ -2,65 +2,101 @@
This repository contains the configuration for multiple machines, as well as my home / IDE config (home-manager). This repository contains the configuration for multiple machines, as well as my home / IDE config (home-manager).
### NixOS ```bash
# Install NixOS
./bootstrap.sh install --name lin-va-nix-builder
# Remote Image Build (NixOS Builder)
./bootstrap.sh image --name lin-va-rke2 --remote
# Home Manager Install
home-manager switch --flake .#evanreichard@mac-va-mbp-personal
# Update Flake
nix flake update
```
## Manual
```bash ```bash
# Install NixOS
sudo nixos-rebuild switch --flake .#lin-va-mbp-personal sudo nixos-rebuild switch --flake .#lin-va-mbp-personal
# Install NixOS (Remote)
nix run github:nix-community/nixos-anywhere -- --flake .#lin-cloud-kube1 --target-host \<USER\>@\<IP\>
# Build Image
nix build .#vmwareConfigurations.lin-va-rke2
``` ```
### NixOS Generators ## Nix Darwin
```bash ```bash
nix build .#vmwareConfigurations.rke2-node # Install Nix Without Determinate
curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install
# Switch Nix Darwin
sudo nix run nix-darwin#darwin-rebuild -- switch --flake .#mac-va-mbp-personal
sudo darwin-rebuild switch --flake .#mac-va-mbp-personal
``` ```
### Home Manager ## Clean Garbage
NOTE: This will remove previous generations
```bash ```bash
home-manager switch --flake .#evanreichard@MBP-Personal sudo nix-collect-garbage --delete-old
nix-collect-garbage --delete-old
``` ```
### NixOS Hosts ## Home Manager
#### Copy Config
```bash ```bash
rsync -av --exclude='.git' . root@HOST:/etc/nixos # Update System Channels
sudo nix-channel --add https://nixos.org/channels/nixpkgs-25.11-darwin nixpkgs
sudo nix-channel --update
# Update Home Manager
nix-channel --add https://github.com/nix-community/home-manager/archive/release-25.11.tar.gz home-manager
nix-channel --update
# Link Repo
ln -s /Users/evanreichard/Development/git/personal/nix/home-manager ~/.config/home-manager
# Build Home Manager
home-manager switch
``` ```
#### Partition Drives ### OS Update
`/etc/bashrc` may get overridden. To properly load Nix, prepend the following:
```bash ```bash
# Validate Disk # Nix
ls -l /dev/disk/by-id if [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then
. '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'
# Partition Disk fi
# WARNING: This will destroy all data on the disk(s) # End Nix
sudo nix \
--experimental-features "nix-command flakes" \
run github:nix-community/disko -- \
--mode disko \
--flake /etc/nixos#HOST_CONFIG
``` ```
#### Install NixOS #### SOPS
1. Convert your SSH key to an age key
2. Get age public key
3. Update `.sops.yaml` with rules
4. Edit file
```bash ```bash
# Install # Convert SSH to Age
sudo nixos-install --flake /etc/nixos#HOST_CONFIG mkdir -p ~/.config/sops/age
ssh-to-age -private-key -i $HOME/.ssh/id_ed25519 -o ~/.config/sops/age/keys.txt
# Reboot # Get Public Key
sudo reboot age-keygen -y ~/.config/sops/age/keys.txt
``` ssh-to-age -private-key -i ~/.ssh/id_ed25519 | age-keygen -y
SOPS_AGE_KEY_FILE=<ADMIN_KEY> sops -d --extract '["lin-va-desktop"]["host"]' ./secrets/keys.yaml | ssh-to-age -private-key | age-keygen -y
#### Copy Config Back to Host
# Edit File
```bash # NOTE: You can specify key with - `SOPS_AGE_KEY_FILE=~/.config/sops/age/other.txt`
rsync -av --exclude='.git' . root@HOST:/etc/nixos sops secrets/lin-va-thinkpad/evanreichard/default.yaml
```
#### Rebuild NixOS
```bash
sudo nixos-rebuild switch
``` ```

View File

@@ -31,13 +31,13 @@ function cmd_image() {
# Validate Config Exists # Validate Config Exists
if ! nix eval --json --impure \ if ! nix eval --json --impure \
".#qcowConfigurations" \ ".#vmwareConfigurations" \
--apply "s: builtins.hasAttr \"$name\" s" 2>/dev/null | grep -q "true"; then --apply "s: builtins.hasAttr \"$name\" s" 2>/dev/null | grep -q "true"; then
echo "Error: NixOS Generator Config '$name' not found" echo "Error: NixOS Generator Config '$name' not found"
exit 1 exit 1
fi fi
build_args=(".#qcowConfigurations.$name") build_args=(".#vmwareConfigurations.$name")
if [ "$remote" = true ]; then if [ "$remote" = true ]; then
build_args+=("-j0") build_args+=("-j0")
fi fi
@@ -51,8 +51,9 @@ function cmd_image() {
} }
function cmd_install() { function cmd_install() {
local usage="Usage: $0 install --name <system-name>" local usage="Usage: $0 install --name <system-name> [--remote <user@remote-host>]"
local name="" local name=""
local remote=""
while [[ $# -gt 0 ]]; do while [[ $# -gt 0 ]]; do
case "$1" in case "$1" in
@@ -60,6 +61,10 @@ function cmd_install() {
name="$2" name="$2"
shift 2 shift 2
;; ;;
--remote)
remote="$2"
shift 2
;;
*) *)
echo "$usage" echo "$usage"
exit 1 exit 1
@@ -87,6 +92,18 @@ function cmd_install() {
exit 1 exit 1
fi fi
# Remote or Local
if [ -n "$remote" ]; then
cmd_install_remote "$name" "$remote"
else
cmd_install_local "$name" "$disk_id"
fi
}
function cmd_install_local(){
local name="$1"
local disk_id="$2"
# Validate Disk Exists # Validate Disk Exists
if [ ! -e "$disk_id" ]; then if [ ! -e "$disk_id" ]; then
echo "Error: Disk $disk_id not found on system" echo "Error: Disk $disk_id not found on system"
@@ -133,6 +150,27 @@ function cmd_install() {
sudo reboot sudo reboot
} }
function cmd_install_remote(){
local name="$1"
local remote="$2"
# Prompt Install
read -p "This will completely wipe and install NixOS on $remote with configuration $name. Continue? (y/n) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo "Operation Cancelled"
exit 1
fi
# Install NixOS
echo "Installing $name to remote host: $remote"
if ! nix run github:nix-community/nixos-anywhere -- --flake ".#$name" --target-host "$remote"; then
echo "Error: Remote NixOS installation failed"
exit 1
fi
echo "Successfully installed $name to remote host: $remote"
}
case "$1" in case "$1" in
image) image)
shift shift

371
flake.lock generated
View File

@@ -5,34 +5,111 @@
"flake-compat": "flake-compat", "flake-compat": "flake-compat",
"nixpkgs": [ "nixpkgs": [
"nixpkgs" "nixpkgs"
], ]
"rust-overlay": "rust-overlay"
}, },
"locked": { "locked": {
"lastModified": 1738646032, "lastModified": 1770051625,
"narHash": "sha256-57BdBE9anNpIpf48EiTVLGxg4mOQ04XjHCEP0gLTsFA=", "narHash": "sha256-TvePW8C3Bh/yC2cjCWBy2kjeCtfLDj/lsB4dLnfOYn0=",
"owner": "tpwrules", "owner": "nix-community",
"repo": "nixos-apple-silicon", "repo": "nixos-apple-silicon",
"rev": "e77031211944723a38bebc043e48847c36e43668", "rev": "7b90aeb40c4eeecc7b53caf23d6acb05d99fcd4f",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "tpwrules", "owner": "nix-community",
"ref": "releasep2-2024-12-25",
"repo": "nixos-apple-silicon", "repo": "nixos-apple-silicon",
"type": "github" "type": "github"
} }
}, },
"disko": { "darwin": {
"inputs": { "inputs": {
"nixpkgs": "nixpkgs" "nixpkgs": [
"nixpkgs"
]
}, },
"locked": { "locked": {
"lastModified": 1743598667, "lastModified": 1767634391,
"narHash": "sha256-ViE7NoFWytYO2uJONTAX35eGsvTYXNHjWALeHAg8OQY=", "narHash": "sha256-owcSz2ICqTSvhBbhPP+1eWzi88e54rRZtfCNE5E/wwg=",
"owner": "nix-darwin",
"repo": "nix-darwin",
"rev": "08585aacc3d6d6c280a02da195fdbd4b9cf083c2",
"type": "github"
},
"original": {
"owner": "nix-darwin",
"ref": "nix-darwin-25.11",
"repo": "nix-darwin",
"type": "github"
}
},
"determinate": {
"inputs": {
"determinate-nixd-aarch64-darwin": "determinate-nixd-aarch64-darwin",
"determinate-nixd-aarch64-linux": "determinate-nixd-aarch64-linux",
"determinate-nixd-x86_64-linux": "determinate-nixd-x86_64-linux",
"nix": "nix",
"nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 1770325739,
"narHash": "sha256-TPDWnhzKW/1+FPMiagZ9mZiQN0aKcGC09yYSUBuv8Mo=",
"owner": "determinatesystems",
"repo": "determinate",
"rev": "1b3259b71c81508ffd409114525df6a55c0f337f",
"type": "github"
},
"original": {
"owner": "determinatesystems",
"repo": "determinate",
"type": "github"
}
},
"determinate-nixd-aarch64-darwin": {
"flake": false,
"locked": {
"narHash": "sha256-zK2dgNHh/p92rk5jN+Y1LOMn0HEdTsS+7XXwb2g52oM=",
"type": "file",
"url": "https://install.determinate.systems/determinate-nixd/tag/v3.15.2/macOS"
},
"original": {
"type": "file",
"url": "https://install.determinate.systems/determinate-nixd/tag/v3.15.2/macOS"
}
},
"determinate-nixd-aarch64-linux": {
"flake": false,
"locked": {
"narHash": "sha256-ckvZP0zFcbzLXWYOJUqYXkKBt0b2IZcQEr7YjEVtwOI=",
"type": "file",
"url": "https://install.determinate.systems/determinate-nixd/tag/v3.15.2/aarch64-linux"
},
"original": {
"type": "file",
"url": "https://install.determinate.systems/determinate-nixd/tag/v3.15.2/aarch64-linux"
}
},
"determinate-nixd-x86_64-linux": {
"flake": false,
"locked": {
"narHash": "sha256-8dLtm8FJrpyBmrNpspJj30/6I5HGEfjjXuFqURcZ8pk=",
"type": "file",
"url": "https://install.determinate.systems/determinate-nixd/tag/v3.15.2/x86_64-linux"
},
"original": {
"type": "file",
"url": "https://install.determinate.systems/determinate-nixd/tag/v3.15.2/x86_64-linux"
}
},
"disko": {
"inputs": {
"nixpkgs": "nixpkgs_3"
},
"locked": {
"lastModified": 1769524058,
"narHash": "sha256-zygdD6X1PcVNR2PsyK4ptzrVEiAdbMqLos7utrMDEWE=",
"owner": "nix-community", "owner": "nix-community",
"repo": "disko", "repo": "disko",
"rev": "329d3d7e8bc63dd30c39e14e6076db590a6eabe6", "rev": "71a3fc97d80881e91710fe721f1158d3b96ae14d",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -43,18 +120,17 @@
}, },
"firefox-addons": { "firefox-addons": {
"inputs": { "inputs": {
"flake-utils": "flake-utils",
"nixpkgs": [ "nixpkgs": [
"nixpkgs" "nixpkgs"
] ]
}, },
"locked": { "locked": {
"dir": "pkgs/firefox-addons", "dir": "pkgs/firefox-addons",
"lastModified": 1743861198, "lastModified": 1770091431,
"narHash": "sha256-PzbPHoSI5U1juWd01Spf3ST7ylR9mQ84v5p7NksBplY=", "narHash": "sha256-9Sqq/hxq8ZDLRSzu+edn0OfWG+FAPWFpwMKaJobeLec=",
"owner": "rycee", "owner": "rycee",
"repo": "nur-expressions", "repo": "nur-expressions",
"rev": "7408ed5bbc9009741094f4dd4cc1abec79e79e7e", "rev": "4f827ff035c6ddc58d04c45abe5b777d356b926a",
"type": "gitlab" "type": "gitlab"
}, },
"original": { "original": {
@@ -66,11 +142,11 @@
}, },
"flake-compat": { "flake-compat": {
"locked": { "locked": {
"lastModified": 1688025799, "lastModified": 1761640442,
"narHash": "sha256-ktpB4dRtnksm9F5WawoIkEneh1nrEvuxb5lJFt1iOyw=", "narHash": "sha256-AtrEP6Jmdvrqiv4x2xa5mrtaIp3OEe8uBYCDZDS+hu8=",
"owner": "nix-community", "owner": "nix-community",
"repo": "flake-compat", "repo": "flake-compat",
"rev": "8bf105319d44f6b9f0d764efa4fdef9f1cc9ba1c", "rev": "4a56054d8ffc173222d09dad23adf4ba946c8884",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -80,6 +156,22 @@
} }
}, },
"flake-compat_2": { "flake-compat_2": {
"flake": false,
"locked": {
"lastModified": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-compat_3": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1650374568, "lastModified": 1650374568,
@@ -95,41 +187,28 @@
"type": "github" "type": "github"
} }
}, },
"flake-utils": { "flake-parts": {
"locked": {
"lastModified": 1629284811,
"narHash": "sha256-JHgasjPR0/J1J3DRm4KxM4zTyAj4IOJY8vIl75v/kPI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "c5d161cc0af116a2e17f54316f0bf43f0819785c",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils-plus": {
"inputs": { "inputs": {
"flake-utils": "flake-utils_2" "nixpkgs-lib": [
"determinate",
"nix",
"nixpkgs"
]
}, },
"locked": { "locked": {
"lastModified": 1715533576, "lastModified": 1748821116,
"narHash": "sha256-fT4ppWeCJ0uR300EH3i7kmgRZnAVxrH+XtK09jQWihk=", "narHash": "sha256-F82+gS044J1APL0n4hH50GYdPRv/5JWm34oCJYmVKdE=",
"owner": "gytis-ivaskevicius", "rev": "49f0870db23e8c1ca0b5259734a02cd9e1e371a1",
"repo": "flake-utils-plus", "revCount": 377,
"rev": "3542fe9126dc492e53ddd252bb0260fe035f2c0f", "type": "tarball",
"type": "github" "url": "https://api.flakehub.com/f/pinned/hercules-ci/flake-parts/0.1.377%2Brev-49f0870db23e8c1ca0b5259734a02cd9e1e371a1/01972f28-554a-73f8-91f4-d488cc502f08/source.tar.gz"
}, },
"original": { "original": {
"owner": "gytis-ivaskevicius", "type": "tarball",
"repo": "flake-utils-plus", "url": "https://flakehub.com/f/hercules-ci/flake-parts/0.1"
"rev": "3542fe9126dc492e53ddd252bb0260fe035f2c0f",
"type": "github"
} }
}, },
"flake-utils_2": { "flake-utils": {
"inputs": { "inputs": {
"systems": "systems" "systems": "systems"
}, },
@@ -147,6 +226,51 @@
"type": "github" "type": "github"
} }
}, },
"flake-utils-plus": {
"inputs": {
"flake-utils": "flake-utils"
},
"locked": {
"lastModified": 1715533576,
"narHash": "sha256-fT4ppWeCJ0uR300EH3i7kmgRZnAVxrH+XtK09jQWihk=",
"owner": "gytis-ivaskevicius",
"repo": "flake-utils-plus",
"rev": "3542fe9126dc492e53ddd252bb0260fe035f2c0f",
"type": "github"
},
"original": {
"owner": "gytis-ivaskevicius",
"repo": "flake-utils-plus",
"rev": "3542fe9126dc492e53ddd252bb0260fe035f2c0f",
"type": "github"
}
},
"git-hooks-nix": {
"inputs": {
"flake-compat": "flake-compat_2",
"gitignore": [
"determinate",
"nix"
],
"nixpkgs": [
"determinate",
"nix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1747372754,
"narHash": "sha256-2Y53NGIX2vxfie1rOW0Qb86vjRZ7ngizoo+bnXU9D9k=",
"rev": "80479b6ec16fefd9c1db3ea13aeb038c60530f46",
"revCount": 1026,
"type": "tarball",
"url": "https://api.flakehub.com/f/pinned/cachix/git-hooks.nix/0.1.1026%2Brev-80479b6ec16fefd9c1db3ea13aeb038c60530f46/0196d79a-1b35-7b8e-a021-c894fb62163d/source.tar.gz"
},
"original": {
"type": "tarball",
"url": "https://flakehub.com/f/cachix/git-hooks.nix/0.1.941"
}
},
"home-manager": { "home-manager": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
@@ -154,20 +278,41 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1743808813, "lastModified": 1769580047,
"narHash": "sha256-2lDQBOmlz9ggPxcS7/GvcVdzXMIiT+PpMao6FbLJSr0=", "narHash": "sha256-tNqCP/+2+peAXXQ2V8RwsBkenlfWMERb+Uy6xmevyhM=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "a9f8b3db211b4609ddd83683f9db89796c7f6ac6", "rev": "366d78c2856de6ab3411c15c1cb4fb4c2bf5c826",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "nix-community", "owner": "nix-community",
"ref": "release-24.11", "ref": "release-25.11",
"repo": "home-manager", "repo": "home-manager",
"type": "github" "type": "github"
} }
}, },
"nix": {
"inputs": {
"flake-parts": "flake-parts",
"git-hooks-nix": "git-hooks-nix",
"nixpkgs": "nixpkgs",
"nixpkgs-23-11": "nixpkgs-23-11",
"nixpkgs-regression": "nixpkgs-regression"
},
"locked": {
"lastModified": 1768960381,
"narHash": "sha256-32oMe1y+kwvIJNiJsIvozTuSmDxcwST06i+0ak+L4AU=",
"rev": "45ce621408cb8c9a724193d5fe858eb839662db8",
"revCount": 24453,
"type": "tarball",
"url": "https://api.flakehub.com/f/pinned/DeterminateSystems/nix-src/3.15.2/019bde75-b4ee-74b2-a812-28dc2ee83d58/source.tar.gz"
},
"original": {
"type": "tarball",
"url": "https://flakehub.com/f/DeterminateSystems/nix-src/%2A"
}
},
"nixlib": { "nixlib": {
"locked": { "locked": {
"lastModified": 1736643958, "lastModified": 1736643958,
@@ -191,11 +336,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1742568034, "lastModified": 1769813415,
"narHash": "sha256-QaMEhcnscfF2MqB7flZr+sLJMMYZPnvqO4NYf9B4G38=", "narHash": "sha256-nnVmNNKBi1YiBNPhKclNYDORoHkuKipoz7EtVnXO50A=",
"owner": "nix-community", "owner": "nix-community",
"repo": "nixos-generators", "repo": "nixos-generators",
"rev": "42ee229088490e3777ed7d1162cb9e9d8c3dbb11", "rev": "8946737ff703382fda7623b9fab071d037e897d5",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -206,27 +351,57 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1743259260, "lastModified": 1761597516,
"narHash": "sha256-ArWLUgRm1tKHiqlhnymyVqi5kLNCK5ghvm06mfCl4QY=", "narHash": "sha256-wxX7u6D2rpkJLWkZ2E932SIvDJW8+ON/0Yy8+a5vsDU=",
"rev": "daf6dc47aa4b44791372d6139ab7b25269184d55",
"revCount": 811874,
"type": "tarball",
"url": "https://api.flakehub.com/f/pinned/NixOS/nixpkgs/0.2505.811874%2Brev-daf6dc47aa4b44791372d6139ab7b25269184d55/019a3494-3498-707e-9086-1fb81badc7fe/source.tar.gz"
},
"original": {
"type": "tarball",
"url": "https://flakehub.com/f/NixOS/nixpkgs/0.2505"
}
},
"nixpkgs-23-11": {
"locked": {
"lastModified": 1717159533,
"narHash": "sha256-oamiKNfr2MS6yH64rUn99mIZjc45nGJlj9eGth/3Xuw=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "eb0e0f21f15c559d2ac7633dc81d079d1caf5f5f", "rev": "a62e6edd6d5e1fa0329b8653c801147986f8d446",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "a62e6edd6d5e1fa0329b8653c801147986f8d446",
"type": "github"
}
},
"nixpkgs-regression": {
"locked": {
"lastModified": 1643052045,
"narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
"type": "github" "type": "github"
} }
}, },
"nixpkgs-unstable": { "nixpkgs-unstable": {
"locked": { "locked": {
"lastModified": 1744098102, "lastModified": 1770115704,
"narHash": "sha256-tzCdyIJj9AjysC3OuKA+tMD/kDEDAF9mICPDU7ix0JA=", "narHash": "sha256-KHFT9UWOF2yRPlAnSXQJh6uVcgNcWlFqqiAZ7OVlHNc=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "c8cd81426f45942bb2906d5ed2fe21d2f19d95b7", "rev": "e6eae2ee2110f3d31110d5c222cd395303343b08",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -238,16 +413,46 @@
}, },
"nixpkgs_2": { "nixpkgs_2": {
"locked": { "locked": {
"lastModified": 1743813633, "lastModified": 1768783163,
"narHash": "sha256-BgkBz4NpV6Kg8XF7cmHDHRVGZYnKbvG0Y4p+jElwxaM=", "narHash": "sha256-tLj4KcRDLakrlpvboTJDKsrp6z2XLwyQ4Zmo+w8KsY4=",
"rev": "bde09022887110deb780067364a0818e89258968",
"revCount": 930106,
"type": "tarball",
"url": "https://api.flakehub.com/f/pinned/DeterminateSystems/nixpkgs-weekly/0.1.930106%2Brev-bde09022887110deb780067364a0818e89258968/019bd9ed-5f0b-7074-afb0-8bb5e13a7598/source.tar.gz"
},
"original": {
"type": "tarball",
"url": "https://flakehub.com/f/DeterminateSystems/nixpkgs-weekly/0.1"
}
},
"nixpkgs_3": {
"locked": {
"lastModified": 1769330179,
"narHash": "sha256-yxgb4AmkVHY5OOBrC79Vv6EVd4QZEotqv+6jcvA212M=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "7819a0d29d1dd2bc331bec4b327f0776359b1fa6", "rev": "48698d12cc10555a4f3e3222d9c669b884a49dfe",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"ref": "nixos-24.11", "ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_4": {
"locked": {
"lastModified": 1770056022,
"narHash": "sha256-yvCz+Qmci1bVucXEyac3TdoSPMtjqVJmVy5wro6j/70=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "d04d8548aed39902419f14a8537006426dc1e4fa",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-25.11",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }
@@ -255,46 +460,32 @@
"root": { "root": {
"inputs": { "inputs": {
"apple-silicon": "apple-silicon", "apple-silicon": "apple-silicon",
"darwin": "darwin",
"determinate": "determinate",
"disko": "disko", "disko": "disko",
"firefox-addons": "firefox-addons", "firefox-addons": "firefox-addons",
"home-manager": "home-manager", "home-manager": "home-manager",
"nixos-generators": "nixos-generators", "nixos-generators": "nixos-generators",
"nixpkgs": "nixpkgs_2", "nixpkgs": "nixpkgs_4",
"nixpkgs-unstable": "nixpkgs-unstable", "nixpkgs-unstable": "nixpkgs-unstable",
"snowfall-lib": "snowfall-lib", "snowfall-lib": "snowfall-lib",
"sops-nix": "sops-nix" "sops-nix": "sops-nix"
} }
}, },
"rust-overlay": {
"flake": false,
"locked": {
"lastModified": 1686795910,
"narHash": "sha256-jDa40qRZ0GRQtP9EMZdf+uCbvzuLnJglTUI2JoHfWDc=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "5c2b97c0a9bc5217fc3dfb1555aae0fb756d99f9",
"type": "github"
},
"original": {
"owner": "oxalica",
"repo": "rust-overlay",
"type": "github"
}
},
"snowfall-lib": { "snowfall-lib": {
"inputs": { "inputs": {
"flake-compat": "flake-compat_2", "flake-compat": "flake-compat_3",
"flake-utils-plus": "flake-utils-plus", "flake-utils-plus": "flake-utils-plus",
"nixpkgs": [ "nixpkgs": [
"nixpkgs" "nixpkgs"
] ]
}, },
"locked": { "locked": {
"lastModified": 1736130495, "lastModified": 1765361626,
"narHash": "sha256-4i9nAJEZFv7vZMmrE0YG55I3Ggrtfo5/T07JEpEZ/RM=", "narHash": "sha256-kX0Dp/kYSRbQ+yd9e3lmmUWdNbipufvKfL2IzbrSpnY=",
"owner": "snowfallorg", "owner": "snowfallorg",
"repo": "lib", "repo": "lib",
"rev": "02d941739f98a09e81f3d2d9b3ab08918958beac", "rev": "c566ad8b7352c30ec3763435de7c8f1c46ebb357",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -310,11 +501,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1743910657, "lastModified": 1770110318,
"narHash": "sha256-zr2jmWeWyhCD8WmO2aWov2g0WPPuZfcJDKzMJZYGq3Y=", "narHash": "sha256-NUVGVtYBTC96WhPh4Y3SVM7vf0o1z5W4uqRBn9v1pfo=",
"owner": "Mic92", "owner": "Mic92",
"repo": "sops-nix", "repo": "sops-nix",
"rev": "523f58a4faff6c67f5f685bed33a7721e984c304", "rev": "f990b0a334e96d3ef9ca09d4bd92778b42fd84f9",
"type": "github" "type": "github"
}, },
"original": { "original": {

View File

@@ -2,19 +2,20 @@
description = "NixOS Hosts"; description = "NixOS Hosts";
inputs = { inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11"; nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable"; nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable";
disko.url = "github:nix-community/disko"; disko.url = "github:nix-community/disko";
determinate.url = "github:determinatesystems/determinate";
snowfall-lib = { snowfall-lib = {
url = "github:snowfallorg/lib"; url = "github:snowfallorg/lib";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
home-manager = { home-manager = {
url = "github:nix-community/home-manager/release-24.11"; url = "github:nix-community/home-manager/release-25.11";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
apple-silicon = { apple-silicon = {
url = "github:tpwrules/nixos-apple-silicon/releasep2-2024-12-25"; url = "github:nix-community/nixos-apple-silicon";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
nixos-generators = { nixos-generators = {
@@ -29,9 +30,14 @@
url = "github:Mic92/sops-nix"; url = "github:Mic92/sops-nix";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
darwin = {
url = "github:nix-darwin/nix-darwin/nix-darwin-25.11";
inputs.nixpkgs.follows = "nixpkgs";
};
}; };
outputs = inputs: outputs =
inputs:
inputs.snowfall-lib.mkFlake { inputs.snowfall-lib.mkFlake {
inherit inputs; inherit inputs;
src = ./.; src = ./.;
@@ -51,6 +57,12 @@
]; ];
}; };
outputs-builder = channels: {
devShells = {
default = import ./shells/default/default.nix { pkgs = channels.nixpkgs; };
};
};
homes.modules = with inputs; [ homes.modules = with inputs; [
sops-nix.homeManagerModules.sops sops-nix.homeManagerModules.sops
]; ];
@@ -59,6 +71,12 @@
nixos = with inputs; [ nixos = with inputs; [
disko.nixosModules.disko disko.nixosModules.disko
sops-nix.nixosModules.sops sops-nix.nixosModules.sops
./modules/nixos/common
];
darwin = with inputs; [
determinate.darwinModules.default
home-manager.darwinModules.home-manager
sops-nix.darwinModules.sops
]; ];
}; };
}; };

View File

@@ -1,9 +1,13 @@
{ lib, config, namespace, ... }: { lib
, config
, namespace
, ...
}:
let let
inherit (lib.${namespace}) enabled; inherit (lib.${namespace}) enabled;
in in
{ {
home.stateVersion = "24.11"; home.stateVersion = "25.11";
reichard = { reichard = {
user = { user = {
@@ -11,15 +15,6 @@ in
inherit (config.snowfallorg.user) name; inherit (config.snowfallorg.user) name;
}; };
services = {
# TODO
# sops = {
# enable = true;
# defaultSopsFile = lib.snowfall.fs.get-file "secrets/mac-va-mbp-personal/evanreichard/default.yaml";
# sshKeyPaths = [ "${config.home.homeDirectory}/.ssh/id_ed25519" ];
# };
};
programs = { programs = {
graphical = { graphical = {
ghostty = enabled; ghostty = enabled;
@@ -32,26 +27,12 @@ in
git = enabled; git = enabled;
k9s = enabled; k9s = enabled;
nvim = enabled; nvim = enabled;
opencode = enabled;
}; };
}; };
security = {
sops = enabled;
};
}; };
# Global Packages
# programs.jq = enabled;
# programs.pandoc = enabled;
# home.packages = with pkgs; [
# android-tools
# imagemagick
# mosh
# python311
# texliveSmall # Pandoc PDF Dep
# google-cloud-sdk
# tldr
# ];
# SQLite Configuration
home.file.".sqliterc".text = ''
.headers on
.mode column
'';
} }

View File

@@ -1,9 +1,14 @@
{ pkgs, lib, config, namespace, ... }: { pkgs
, lib
, config
, namespace
, ...
}:
let let
inherit (lib.${namespace}) enabled; inherit (lib.${namespace}) enabled;
in in
{ {
home.stateVersion = "24.11"; home.stateVersion = "25.11";
reichard = { reichard = {
user = { user = {
@@ -11,47 +16,39 @@ in
inherit (config.snowfallorg.user) name; inherit (config.snowfallorg.user) name;
}; };
services = {
# TODO
# sops = {
# enable = true;
# defaultSopsFile = lib.snowfall.fs.get-file "secrets/mac-va-mbp-work/evanreichard/default.yaml";
# sshKeyPaths = [ "${config.home.homeDirectory}/.ssh/id_ed25519" ];
# };
};
programs = { programs = {
graphical = { graphical = {
ghostty = enabled; ghostty = enabled;
}; };
terminal = { terminal = {
bash = {
enable = true;
customFastFetchLogo = ./prophet.txt;
};
aws = enabled;
btop = enabled; btop = enabled;
claude-code = enabled;
direnv = enabled; direnv = enabled;
git = enabled; git = enabled;
k9s = enabled; k9s = enabled;
nvim = enabled; nvim = enabled;
aws = enabled; opencode = enabled;
pi = enabled;
}; };
}; };
security = {
sops = enabled;
};
}; };
# Global Packages # Global Packages
programs.jq = enabled; programs.jq = enabled;
programs.pandoc = enabled; programs.pandoc = enabled;
home.packages = with pkgs; [ home.packages = with pkgs; [
android-tools colima
imagemagick docker
mosh keycastr
python311
texliveSmall # Pandoc PDF Dep
google-cloud-sdk
tldr
]; ];
# SQLite Configuration
home.file.".sqliterc".text = ''
.headers on
.mode column
'';
} }

View File

@@ -0,0 +1,19 @@
                :+++++++=.        
                 =++++++++:       
                  -++++++++:      
                   -++++++++-     
                    :++++++++-    
          .-=======. :++++++++=   
         :********+   .++++++++=  
        -********=     .=+++++++=.
       -********-        =++++++++
      =********-          =++++++:
     =********:            -++++. 
    +********.              -+=.  
  .+*******+.                     
 .+*******+. :%#%%%%%%%%%%#%-     
:********=    +%%%%%%%%%%%%*      
********=      =%%%%%%%%%%+       
.+*****-        -%%%%%%%%=        
  +***-           ......          
   =*:                            

View File

@@ -1,9 +1,15 @@
{ pkgs, lib, config, namespace, osConfig, ... }: { pkgs
, lib
, config
, namespace
, osConfig
, ...
}:
let let
inherit (lib.${namespace}) enabled; inherit (lib.${namespace}) enabled;
in in
{ {
home.stateVersion = "24.11"; home.stateVersion = "25.11";
reichard = { reichard = {
user = { user = {
@@ -15,23 +21,22 @@ in
ssh-agent = enabled; ssh-agent = enabled;
fusuma = enabled; fusuma = enabled;
swww = enabled; swww = enabled;
sops = { };
enable = true;
defaultSopsFile = lib.snowfall.fs.get-file "secrets/default.yaml"; security = {
sshKeyPaths = [ "${config.home.homeDirectory}/.ssh/id_ed25519" ]; sops = enabled;
};
}; };
programs = { programs = {
graphical = { graphical = {
wms.hyprland = { wms.hyprland = {
enable = true; enable = true;
monitors = [ mainMod = "ALT";
",highres,auto,2" # Optional - 1.68 monitors = [ ",highres,auto,2" ]; # Alternatively - 1.68
];
}; };
ghostty = enabled; ghostty = enabled;
ghidra = enabled; ghidra = enabled;
gimp = enabled;
browsers.firefox = { browsers.firefox = {
enable = true; enable = true;
gpuAcceleration = true; gpuAcceleration = true;
@@ -45,13 +50,15 @@ in
git = enabled; git = enabled;
k9s = enabled; k9s = enabled;
nvim = enabled; nvim = enabled;
opencode = enabled;
pi = enabled;
}; };
}; };
}; };
# home.packages = with pkgs; [ home.packages = with pkgs; [
# catppuccin-gtk orca-slicer
# ]; ];
dconf = { dconf = {
settings = { settings = {
@@ -59,15 +66,10 @@ in
color-scheme = "prefer-dark"; color-scheme = "prefer-dark";
cursor-theme = "catppuccin-macchiato-mauve-cursors"; cursor-theme = "catppuccin-macchiato-mauve-cursors";
cursor-size = 24; cursor-size = 24;
# enable-hot-corners = false;
# font-name = osConfig.${namespace}.system.fonts.default;
# gtk-theme = cfg.theme.name;
# icon-theme = cfg.icon.name;
}; };
}; };
}; };
home.pointerCursor = { home.pointerCursor = {
gtk.enable = true; gtk.enable = true;
name = "catppuccin-macchiato-mauve-cursors"; name = "catppuccin-macchiato-mauve-cursors";
@@ -78,26 +80,7 @@ in
# Kubernetes Secrets # Kubernetes Secrets
sops.secrets = lib.mkIf osConfig.${namespace}.security.sops.enable { sops.secrets = lib.mkIf osConfig.${namespace}.security.sops.enable {
rke2_kubeconfig = { rke2_kubeconfig = {
path = "${config.home.homeDirectory}/.kube/rke2"; path = "${config.home.homeDirectory}/.kube/lin-va-kube";
}; };
}; };
# Global Packages
# programs.jq = enabled;
# programs.pandoc = enabled;
# home.packages = with pkgs; [
# android-tools
# imagemagick
# mosh
# python311
# texliveSmall # Pandoc PDF Dep
# google-cloud-sdk
# tldr
# ];
# SQLite Configuration
home.file.".sqliterc".text = ''
.headers on
.mode column
'';
} }

View File

@@ -0,0 +1,29 @@
{ lib
, config
, namespace
, ...
}:
let
inherit (lib.${namespace}) enabled;
in
{
home.stateVersion = "25.11";
reichard = {
user = {
enable = true;
inherit (config.snowfallorg.user) name;
};
programs = {
terminal = {
btop = enabled;
direnv = enabled;
nvim = enabled;
tmux = enabled;
};
};
};
programs.jq = enabled;
}

View File

@@ -0,0 +1,31 @@
{ lib
, config
, namespace
, ...
}:
let
inherit (lib.${namespace}) enabled;
in
{
home.stateVersion = "25.11";
reichard = {
user = {
enable = true;
inherit (config.snowfallorg.user) name;
};
services = {
ssh-agent = enabled;
};
programs = {
terminal = {
bash = enabled;
btop = enabled;
direnv = enabled;
tmux = enabled;
};
};
};
}

View File

@@ -0,0 +1,40 @@
{ lib
, config
, namespace
, ...
}:
let
inherit (lib.${namespace}) enabled;
in
{
home.stateVersion = "25.11";
reichard = {
user = {
enable = true;
inherit (config.snowfallorg.user) name;
};
services = {
ssh-agent = enabled;
};
security = {
sops = enabled;
};
programs = {
terminal = {
bash = enabled;
btop = enabled;
direnv = enabled;
git = enabled;
k9s = enabled;
nvim = enabled;
opencode = enabled;
pi = enabled;
tmux = enabled;
};
};
};
}

View File

@@ -1,9 +1,15 @@
{ pkgs, lib, config, namespace, osConfig, ... }: { pkgs
, lib
, config
, namespace
, osConfig
, ...
}:
let let
inherit (lib.${namespace}) enabled; inherit (lib.${namespace}) enabled;
in in
{ {
home.stateVersion = "24.11"; home.stateVersion = "25.11";
reichard = { reichard = {
user = { user = {
@@ -15,18 +21,22 @@ in
ssh-agent = enabled; ssh-agent = enabled;
fusuma = enabled; fusuma = enabled;
swww = enabled; swww = enabled;
sops = { poweralertd = enabled;
enable = true; };
defaultSopsFile = lib.snowfall.fs.get-file "secrets/default.yaml";
sshKeyPaths = [ "${config.home.homeDirectory}/.ssh/id_ed25519" ]; security = {
}; sops = enabled;
}; };
programs = { programs = {
graphical = { graphical = {
wms.hyprland = enabled; wms.hyprland = enabled;
ghostty = enabled; ghostty = enabled;
strawberry = enabled;
gimp = enabled;
wireshark = enabled;
ghidra = enabled; ghidra = enabled;
remmina = enabled;
browsers.firefox = { browsers.firefox = {
enable = true; enable = true;
gpuAcceleration = true; gpuAcceleration = true;
@@ -40,29 +50,21 @@ in
git = enabled; git = enabled;
k9s = enabled; k9s = enabled;
nvim = enabled; nvim = enabled;
opencode = enabled;
}; };
}; };
}; };
# home.packages = with pkgs; [
# catppuccin-gtk
# ];
dconf = { dconf = {
settings = { settings = {
"org/gnome/desktop/interface" = { "org/gnome/desktop/interface" = {
color-scheme = "prefer-dark"; color-scheme = "prefer-dark";
cursor-theme = "catppuccin-macchiato-mauve-cursors"; cursor-theme = "catppuccin-macchiato-mauve-cursors";
cursor-size = 24; cursor-size = 24;
# enable-hot-corners = false;
# font-name = osConfig.${namespace}.system.fonts.default;
# gtk-theme = cfg.theme.name;
# icon-theme = cfg.icon.name;
}; };
}; };
}; };
home.pointerCursor = { home.pointerCursor = {
gtk.enable = true; gtk.enable = true;
name = "catppuccin-macchiato-mauve-cursors"; name = "catppuccin-macchiato-mauve-cursors";
@@ -73,13 +75,7 @@ in
# Kubernetes Secrets # Kubernetes Secrets
sops.secrets = lib.mkIf osConfig.${namespace}.security.sops.enable { sops.secrets = lib.mkIf osConfig.${namespace}.security.sops.enable {
rke2_kubeconfig = { rke2_kubeconfig = {
path = "${config.home.homeDirectory}/.kube/rke2"; path = "${config.home.homeDirectory}/.kube/lin-va-kube";
}; };
}; };
# SQLite Configuration
home.file.".sqliterc".text = ''
.headers on
.mode column
'';
} }

View File

@@ -1,9 +1,15 @@
{ pkgs, lib, config, namespace, osConfig, ... }: { pkgs
, lib
, config
, namespace
, osConfig
, ...
}:
let let
inherit (lib.${namespace}) enabled; inherit (lib.${namespace}) enabled;
in in
{ {
home.stateVersion = "24.11"; home.stateVersion = "25.05";
reichard = { reichard = {
user = { user = {
@@ -15,11 +21,10 @@ in
ssh-agent = enabled; ssh-agent = enabled;
fusuma = enabled; fusuma = enabled;
swww = enabled; swww = enabled;
sops = { };
enable = true;
defaultSopsFile = lib.snowfall.fs.get-file "secrets/default.yaml"; security = {
sshKeyPaths = [ "${config.home.homeDirectory}/.ssh/id_ed25519" ]; sops = enabled;
};
}; };
programs = { programs = {
@@ -44,25 +49,16 @@ in
}; };
}; };
# home.packages = with pkgs; [
# catppuccin-gtk
# ];
dconf = { dconf = {
settings = { settings = {
"org/gnome/desktop/interface" = { "org/gnome/desktop/interface" = {
color-scheme = "prefer-dark"; color-scheme = "prefer-dark";
cursor-theme = "catppuccin-macchiato-mauve-cursors"; cursor-theme = "catppuccin-macchiato-mauve-cursors";
cursor-size = 24; cursor-size = 24;
# enable-hot-corners = false;
# font-name = osConfig.${namespace}.system.fonts.default;
# gtk-theme = cfg.theme.name;
# icon-theme = cfg.icon.name;
}; };
}; };
}; };
home.pointerCursor = { home.pointerCursor = {
gtk.enable = true; gtk.enable = true;
name = "catppuccin-macchiato-mauve-cursors"; name = "catppuccin-macchiato-mauve-cursors";
@@ -73,26 +69,7 @@ in
# Kubernetes Secrets # Kubernetes Secrets
sops.secrets = lib.mkIf osConfig.${namespace}.security.sops.enable { sops.secrets = lib.mkIf osConfig.${namespace}.security.sops.enable {
rke2_kubeconfig = { rke2_kubeconfig = {
path = "${config.home.homeDirectory}/.kube/rke2"; path = "${config.home.homeDirectory}/.kube/lin-va-kube";
}; };
}; };
# Global Packages
# programs.jq = enabled;
# programs.pandoc = enabled;
# home.packages = with pkgs; [
# android-tools
# imagemagick
# mosh
# python311
# texliveSmall # Pandoc PDF Dep
# google-cloud-sdk
# tldr
# ];
# SQLite Configuration
home.file.".sqliterc".text = ''
.headers on
.mode column
'';
} }

View File

@@ -0,0 +1,9 @@
{
config = {
nix.enable = false;
home-manager = {
useGlobalPkgs = true;
useUserPackages = true;
};
};
}

View File

@@ -0,0 +1,35 @@
{ config
, lib
, namespace
, ...
}:
let
inherit (lib) mkIf mkEnableOption types;
inherit (lib.${namespace}) mkOpt;
getFile = lib.snowfall.fs.get-file;
user = config.users.users.${config.${namespace}.user.name};
cfg = config.${namespace}.security.sops;
in
{
options.${namespace}.security.sops = with types; {
enable = mkEnableOption "Enable sops";
defaultSopsFile = mkOpt str "secrets/systems/${config.system.name}.yaml" "Default sops file.";
sshKeyPaths = mkOpt (listOf path) [ ] "Additional SSH key paths to use.";
};
config = mkIf cfg.enable {
sops = {
defaultSopsFile = getFile cfg.defaultSopsFile;
age = {
keyFile = "${user.home}/.config/sops/age/keys.txt";
sshKeyPaths = [ "${config.home.homeDirectory}/.ssh/id_ed25519" ] ++ cfg.sshKeyPaths;
};
};
sops.secrets.builder_ssh_key = {
sopsFile = getFile "secrets/common/systems.yaml";
};
};
}

View File

@@ -0,0 +1,20 @@
{ config, namespace, lib, ... }:
let
inherit (lib.${namespace}) mkOpt;
cfg = config.${namespace}.security.sops;
in
{
options.${namespace}.services.openssh = with lib.types; {
enable = lib.mkEnableOption "OpenSSH support";
authorizedKeys = mkOpt (listOf str) [ ] "The public keys to apply.";
extraConfig = mkOpt str "" "Extra configuration to apply.";
port = mkOpt port 2222 "The port to listen on (in addition to 22).";
};
config = lib.mkIf cfg.enable {
services.openssh = {
enable = true;
};
};
}

View File

@@ -0,0 +1,23 @@
{ config, lib, namespace, pkgs, ... }:
let
inherit (lib) types mkIf;
inherit (lib.${namespace}) mkOpt;
cfg = config.${namespace}.user;
in
{
options.${namespace}.user = with types; {
name = mkOpt str "evanreichard" "The name to use for the user account.";
email = mkOpt str "evan@reichard.io" "The email of the user.";
fullName = mkOpt str "Evan Reichard" "The full name of the user.";
uid = mkOpt (types.nullOr types.int) 501 "The uid for the user account.";
};
config = {
users.users.${cfg.name} = {
uid = mkIf (cfg.uid != null) cfg.uid;
shell = pkgs.bashInteractive;
home = "/Users/${cfg.name}";
};
};
}

View File

@@ -38,6 +38,12 @@ in
ExtensionRecommendations = false; ExtensionRecommendations = false;
SkipOnboarding = true; SkipOnboarding = true;
}; };
GenerativeAI = {
Chatbot = false;
LinkPreviews = false;
TabGroups = false;
Locked = false;
};
ExtensionSettings = { ExtensionSettings = {
# Block All # Block All
# "*".installation_mode = "blocked"; # "*".installation_mode = "blocked";
@@ -53,7 +59,7 @@ in
settings = mkOpt attrs { } "Settings to apply to the profile."; settings = mkOpt attrs { } "Settings to apply to the profile.";
extensions = mkOpt (with lib.types; listOf package) extensions.packages = mkOpt (with lib.types; listOf package)
(with pkgs.firefox-addons; [ (with pkgs.firefox-addons; [
bitwarden bitwarden
darkreader darkreader

View File

@@ -1,93 +0,0 @@
{
"modules": [
{
"type": "separator",
"string": "",
"length": 35,
},
{
"type": "title",
"format": "Hardware Information",
},
{
"type": "cpu",
"key": " ",
},
{
"type": "memory",
"key": " ",
},
{
"type": "display",
"key": "󰍹 ",
},
{
"type": "separator",
},
{
"type": "title",
"format": "Software Information",
},
{
"type": "os",
"key": " ",
},
{
"type": "kernel",
"key": " ",
},
{
"type": "terminal",
"key": " ",
},
{
"type": "packages",
"key": "󰏖 ",
},
{
"type": "terminalfont",
"key": " ",
},
{
"type": "separator",
},
{
"type": "title",
"format": "Network Information",
},
{
"type": "publicip",
"key": " ",
},
{
"type": "localip",
"key": " ",
},
{
"type": "separator",
},
{
"type": "custom",
"format": " {#white} {#red} {#green} {#yellow} {#blue} {#magenta} {#cyan} {#white}\n",
},
],
"display": {
"separator": "  ",
"key": {
"width": 7,
},
"color": {
"keys": "yellow",
"title": "blue",
},
},
"settings": {
"kernelFormat": "minimal",
"memoryUnit": "gib",
"temperatureUnit": "celsius",
"publicIpTimeout": 2000,
"publicIpHost": "http://ident.me",
"diskUnit": "gib",
"showDisks": ["/"],
},
}

View File

@@ -10,62 +10,14 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
programs.bash = { # Enable Bash
enable = true; ${namespace}.programs.terminal.bash.enable = true;
shellAliases = {
grep = "grep --color";
ssh = "TERM=xterm-256color ssh";
flush_dns = "sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder";
};
profileExtra = ''
SHELL="$BASH"
PATH=~/.bin:$PATH
bind "set show-mode-in-prompt on"
set -o vi || true # Pending Darwin @ https://github.com/NixOS/nixpkgs/pull/369788
VISUAL=vim home.packages = with pkgs; optionals isLinux [
EDITOR="$VISUAL"
fastfetch
eval "$(thefuck --alias)"
'';
};
programs.powerline-go = {
enable = true;
settings = {
git-mode = "compact";
theme = "gruvbox";
};
modules = [
"host"
"cwd"
"git"
"docker"
"venv"
];
};
programs.readline = {
enable = true;
extraConfig = ''
# Approximate VIM Dracula Colors
set vi-ins-mode-string \1\e[01;38;5;23;48;5;231m\2 I \1\e[38;5;231;48;5;238m\2\1\e[0m\2
set vi-cmd-mode-string \1\e[01;38;5;22;48;5;148m\2 C \1\e[38;5;148;48;5;238m\2\1\e[0m\2
'';
};
home.packages = with pkgs; [
thefuck
fastfetch
bashInteractive
(nerdfonts.override { fonts = [ "Meslo" ]; })
] ++ optionals isLinux [
# Pending Darwin @ https://github.com/NixOS/nixpkgs/pull/369788
ghostty ghostty
]; ];
home.file.".config/fastfetch/config.jsonc".text = builtins.readFile ./config/fastfetch.jsonc;
home.file.".config/ghostty/config".text = home.file.".config/ghostty/config".text =
let let
bashPath = "${pkgs.bashInteractive}/bin/bash"; bashPath = "${pkgs.bashInteractive}/bin/bash";

View File

@@ -0,0 +1,24 @@
{ pkgs
, lib
, config
, namespace
, ...
}:
let
inherit (lib) mkIf mkEnableOption;
cfg = config.${namespace}.programs.graphical.gimp;
in
{
options.${namespace}.programs.graphical.gimp = {
enable = mkEnableOption "GIMP";
};
config = mkIf cfg.enable {
home.packages = with pkgs; [
darktable
gimp-with-plugins
gthumb
];
};
}

View File

@@ -0,0 +1,17 @@
{ pkgs, lib, config, namespace, ... }:
let
inherit (lib) mkIf mkEnableOption;
cfg = config.${namespace}.programs.graphical.remmina;
in
{
options.${namespace}.programs.graphical.remmina = {
enable = mkEnableOption "Remmina";
};
config = mkIf cfg.enable {
home.packages = with pkgs; [
remmina
];
};
}

View File

@@ -0,0 +1,17 @@
{ pkgs, lib, config, namespace, ... }:
let
inherit (lib) mkIf mkEnableOption;
cfg = config.${namespace}.programs.graphical.strawberry;
in
{
options.${namespace}.programs.graphical.strawberry = {
enable = mkEnableOption "Enable Strawberry";
};
config = mkIf cfg.enable {
home.packages = with pkgs; [
strawberry
libgpod
];
};
}

View File

@@ -0,0 +1,17 @@
{ pkgs, lib, config, namespace, ... }:
let
inherit (lib) mkIf mkEnableOption;
cfg = config.${namespace}.programs.graphical.wireshark;
in
{
options.${namespace}.programs.graphical.wireshark = {
enable = mkEnableOption "Wireshark";
};
config = mkIf cfg.enable {
home.packages = with pkgs; [
wireshark
];
};
}

View File

@@ -44,7 +44,6 @@ decoration {
} }
# https://wiki.hyprland.org/Configuring/Variables/#animations # https://wiki.hyprland.org/Configuring/Variables/#animations
#https://wiki.hyprland.org/Configuring/Animations/
animations { animations {
enabled = yes, please :) enabled = yes, please :)
@@ -127,11 +126,7 @@ input {
} }
# https://wiki.hyprland.org/Configuring/Variables/#gestures # https://wiki.hyprland.org/Configuring/Variables/#gestures
gestures { gesture = 4, horizontal, workspace, invert
workspace_swipe = true
workspace_swipe_fingers = 4
workspace_swipe_invert = true
}
# Thinkpad Trackpoint # Thinkpad Trackpoint
device { device {

View File

@@ -1,4 +1,9 @@
{ lib, pkgs, config, namespace, ... }: { lib
, pkgs
, config
, namespace
, ...
}:
let let
inherit (lib) types mkIf; inherit (lib) types mkIf;
inherit (lib.${namespace}) mkOpt enabled; inherit (lib.${namespace}) mkOpt enabled;
@@ -8,10 +13,9 @@ in
{ {
options.${namespace}.programs.graphical.wms.hyprland = { options.${namespace}.programs.graphical.wms.hyprland = {
enable = lib.mkEnableOption "Hyprland"; enable = lib.mkEnableOption "Hyprland";
mainMod = mkOpt types.str "SUPER" "Hyprland main modifier key"; mainMod = mkOpt types.str "SUPER" "main modifier key";
monitors = mkOpt (with types; listOf str) [ menuMod = mkOpt types.str "SUPER" "menu modifier key (i.e. menuMod + space)";
", preferred, auto, 1" monitors = mkOpt (with types; listOf str) [ ", preferred, auto, 1" ] "monitor configuration";
] "Hyprland monitor configuration";
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
@@ -22,25 +26,26 @@ in
extraConfig = builtins.readFile ./config/hyprland.conf; extraConfig = builtins.readFile ./config/hyprland.conf;
settings = { settings = {
"$mainMod" = cfg.mainMod; "$mainMod" = cfg.mainMod;
"$menuMod" = cfg.menuMod;
"$terminal" = "ghostty"; "$terminal" = "ghostty";
"$menu" = "wofi --show drun"; "$menu" = "wofi --show drun";
monitor = cfg.monitors; monitor = cfg.monitors;
bind = [ bind = [
# Super Bindings (macOS Transition) # Menu Mod Bindings (macOS Transition - Spotlight & Screenshots)
"ALT_SHIFT, 1, exec, hyprshot -m output" "$menuMod, SPACE, exec, $menu"
"ALT_SHIFT, 2, exec, hyprshot -m window" "$menuMod SHIFT, 1, exec, hyprshot -m output"
"ALT_SHIFT, 3, exec, hyprshot -m region" "$menuMod SHIFT, 2, exec, hyprshot -m window"
"$menuMod SHIFT, 3, exec, hyprshot -m region"
"$menuMod, Q, killactive"
# Primary Bindings # Primary Bindings
"$mainMod, SPACE, exec, $menu"
"$mainMod, RETURN, exec, $terminal" "$mainMod, RETURN, exec, $terminal"
"$mainMod, Q, killactive"
"$mainMod, M, exit" "$mainMod, M, exit"
"$mainMod, V, togglefloating" "$mainMod, V, togglefloating"
"$mainMod, P, pseudo" # dwindle "$mainMod, P, pin"
"$mainMod, J, togglesplit" # dwindle "$mainMod, J, togglesplit"
"$mainMod, S, togglespecialworkspace, magic" "$mainMod, S, togglespecialworkspace, magic"
"$mainMod SHIFT, S, movetoworkspace, special:magic" "$mainMod SHIFT, S, movetoworkspace, special:magic"
@@ -91,8 +96,8 @@ in
",XF86MonBrightnessDown, exec, brightnessctl s 10%-" ",XF86MonBrightnessDown, exec, brightnessctl s 10%-"
# macOS Keyboard Brightness # macOS Keyboard Brightness
"ALT, XF86MonBrightnessUp, exec, brightnessctl -d kbd_backlight s 10%+" "$menuMod, XF86MonBrightnessUp, exec, brightnessctl -d kbd_backlight s 10%+"
"ALT, XF86MonBrightnessDown, exec, brightnessctl -d kbd_backlight s 10%-" "$menuMod, XF86MonBrightnessDown, exec, brightnessctl -d kbd_backlight s 10%-"
]; ];
bindl = [ bindl = [
# Player Controls # Player Controls
@@ -107,153 +112,161 @@ in
programs.waybar = { programs.waybar = {
enable = true; enable = true;
style = builtins.readFile ./config/waybar-style.css; style = builtins.readFile ./config/waybar-style.css;
settings = [{ settings = [
layer = "top"; {
position = "top"; layer = "top";
mod = "dock"; position = "top";
exclusive = true; mod = "dock";
passtrough = false; exclusive = true;
gtk-layer-shell = true; passtrough = false;
height = 0; gtk-layer-shell = true;
modules-left = [ height = 0;
"hyprland/workspaces" modules-left = [
"hyprland/window" "hyprland/workspaces"
]; "hyprland/window"
# modules-center = [ "hyprland/window" ];
modules-right = [
"tray"
"cpu"
"memory"
"pulseaudio"
"network"
"backlight"
"battery"
"clock"
];
"hyprland/window" = { format = "{}"; };
"wlr/workspaces" = {
on-scroll-up = "hyprctl dispatch workspace e+1";
on-scroll-down = "hyprctl dispatch workspace e-1";
all-outputs = true;
on-click = "activate";
};
battery = {
states = {
warning = 30;
critical = 15;
};
format = "{icon}";
format-charging = "󰂄";
format-plugged = "󰂄";
format-alt = "{icon}";
format-icons = [
"󰂃"
"󰁺"
"󰁻"
"󰁼"
"󰁽"
"󰁾"
"󰁾"
"󰁿"
"󰂀"
"󰂁"
"󰂂"
"󰁹"
]; ];
}; # modules-center = [ "hyprland/window" ];
cpu = { modules-right = [
interval = 10; "tray"
format = " {}%"; "cpu"
max-length = 10; "memory"
on-click = ""; "pulseaudio"
}; "network"
memory = { "backlight"
interval = 30; "battery"
format = " {}%"; "clock"
format-alt = " {used:0.1f}G";
max-length = 10;
};
backlight = {
format = "{icon}";
format-icons = [
"󰋙"
"󰫃"
"󰫄"
"󰫅"
"󰫆"
"󰫇"
"󰫈"
]; ];
on-scroll-up = "brightnessctl s 1%-"; "hyprland/window" = {
on-scroll-down = "brightnessctl s +1%"; format = "{}";
};
tray = {
icon-size = 13;
tooltip = false;
spacing = 10;
};
network = {
interval = 1;
format-wifi = "󰖩";
format-ethernet = "󰈀";
format-linked = "󰈁";
format-disconnected = "";
on-click-right = "${pkgs.networkmanagerapplet}/bin/nm-connection-editor";
# tooltip-format = ''
# <big>Network Details</big>
# <tt><small>Interface: {ifname}</small></tt>
# <tt><small>IP: {ipaddr}/{cidr}</small></tt>
# <tt><small>Gateway: {gwaddr}</small></tt>
# <tt><small>󰜷 {bandwidthUpBytes}\n󰜮 {bandwidthDownBytes}</small></tt>'';
tooltip-format = ''
<big>Network Details</big>
<small>
Interface: {ifname}
SSID: {essid}
IP Address: {ipaddr}/{cidr}
Gateway: {gwaddr}
󰜷 {bandwidthUpBytes} / 󰜮 {bandwidthDownBytes}
</small>'';
};
clock = {
format = " {:%Y-%m-%d %H:%M:%S}";
interval = 1;
tooltip-format = ''
<big>{:%Y %B}</big>
<tt><small>{calendar}</small></tt>'';
};
pulseaudio = {
format = "{icon} {volume}%";
tooltip = false;
format-muted = " Muted";
on-click = "pamixer -t";
on-scroll-up = "pamixer -i 5";
on-scroll-down = "pamixer -d 5";
scroll-step = 5;
format-icons = {
headphone = "";
hands-free = "";
headset = "";
phone = "";
portable = "";
car = "";
default = [ "" "" "" ];
}; };
}; "wlr/workspaces" = {
"pulseaudio#microphone" = { on-scroll-up = "hyprctl dispatch workspace e+1";
format = "{format_source}"; on-scroll-down = "hyprctl dispatch workspace e-1";
tooltip = false; all-outputs = true;
format-source = " {volume}%"; on-click = "activate";
format-source-muted = " Muted"; };
on-click = "pamixer --default-source -t"; battery = {
on-scroll-up = "pamixer --default-source -i 5"; states = {
on-scroll-down = "pamixer --default-source -d 5"; warning = 30;
scroll-step = 5; critical = 15;
}; };
}]; format = "{icon}";
format-charging = "󰂄";
format-plugged = "󰂄";
format-alt = "{icon}";
format-icons = [
"󰂃"
"󰁺"
"󰁻"
"󰁼"
"󰁽"
"󰁾"
"󰁾"
"󰁿"
"󰂀"
"󰂁"
"󰂂"
"󰁹"
];
};
cpu = {
interval = 10;
format = " {}%";
max-length = 10;
on-click = "";
};
memory = {
interval = 30;
format = " {}%";
format-alt = " {used:0.1f}G";
max-length = 10;
};
backlight = {
format = "{icon}";
format-icons = [
"󰋙"
"󰫃"
"󰫄"
"󰫅"
"󰫆"
"󰫇"
"󰫈"
];
on-scroll-up = "brightnessctl s 1%-";
on-scroll-down = "brightnessctl s +1%";
};
tray = {
icon-size = 13;
tooltip = false;
spacing = 10;
};
network = {
interval = 1;
format-wifi = "󰖩";
format-ethernet = "󰈀";
format-linked = "󰈁";
format-disconnected = "";
on-click-right = "${pkgs.networkmanagerapplet}/bin/nm-connection-editor";
# tooltip-format = ''
# <big>Network Details</big>
# <tt><small>Interface: {ifname}</small></tt>
# <tt><small>IP: {ipaddr}/{cidr}</small></tt>
# <tt><small>Gateway: {gwaddr}</small></tt>
# <tt><small>󰜷 {bandwidthUpBytes}\n󰜮 {bandwidthDownBytes}</small></tt>'';
tooltip-format = ''
<big>Network Details</big>
<small>
Interface: {ifname}
SSID: {essid}
IP Address: {ipaddr}/{cidr}
Gateway: {gwaddr}
󰜷 {bandwidthUpBytes} / 󰜮 {bandwidthDownBytes}
</small>'';
};
clock = {
format = " {:%Y-%m-%d %H:%M:%S}";
interval = 1;
tooltip-format = ''
<big>{:%Y %B}</big>
<tt><small>{calendar}</small></tt>'';
};
pulseaudio = {
format = "{icon} {volume}%";
tooltip = false;
format-muted = " Muted";
on-click = "pamixer -t";
on-scroll-up = "pamixer -i 5";
on-scroll-down = "pamixer -d 5";
scroll-step = 5;
format-icons = {
headphone = "";
hands-free = "";
headset = "";
phone = "";
portable = "";
car = "";
default = [
""
""
""
];
};
};
"pulseaudio#microphone" = {
format = "{format_source}";
tooltip = false;
format-source = " {volume}%";
format-source-muted = " Muted";
on-click = "pamixer --default-source -t";
on-scroll-up = "pamixer --default-source -i 5";
on-scroll-down = "pamixer --default-source -d 5";
scroll-step = 5;
};
}
];
}; };
home.packages = with pkgs; [ home.packages = with pkgs; [

View File

@@ -10,8 +10,9 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
home.packages = with pkgs; [ home.packages = with pkgs; [
cw aws-sso-util
awscli2 awscli2
cw
ssm-session-manager-plugin ssm-session-manager-plugin
]; ];
}; };

View File

@@ -0,0 +1,3 @@
_scratch
.direnv
.envrc

View File

@@ -0,0 +1,2 @@
.headers on
.mode column

View File

@@ -0,0 +1,99 @@
{ cfg }:
builtins.toJSON (
{
modules = [
{
type = "separator";
string = "";
length = 35;
}
{
type = "title";
format = "Hardware Information";
}
{
type = "cpu";
key = " ";
}
{
type = "memory";
key = " ";
}
{
type = "display";
key = "󰍹 ";
}
{ type = "separator"; }
{
type = "title";
format = "Software Information";
}
{
type = "os";
key = " ";
}
{
type = "kernel";
key = " ";
}
{
type = "terminal";
key = " ";
}
{
type = "packages";
key = "󰏖 ";
}
{
type = "terminalfont";
key = " ";
}
{ type = "separator"; }
{
type = "title";
format = "Network Information";
}
{
type = "publicip";
key = " ";
}
{
type = "localip";
key = " ";
}
{ type = "separator"; }
{
type = "custom";
format = " {#white} {#red} {#green} {#yellow} {#blue} {#magenta} {#cyan} {#white}\n";
}
];
display = {
separator = " ";
key.width = 7;
color = {
keys = "yellow";
title = "blue";
};
};
settings = {
kernelFormat = "minimal";
memoryUnit = "gib";
temperatureUnit = "celsius";
publicIpTimeout = 2000;
publicIpHost = "http://ident.me";
diskUnit = "gib";
showDisks = [ "/" ];
};
}
// (
if cfg.customFastFetchLogo != null then
{
logo = {
source = cfg.customFastFetchLogo;
type = "file";
};
}
else
{ }
)
)

View File

@@ -0,0 +1,85 @@
{ pkgs
, lib
, config
, namespace
, ...
}:
let
inherit (lib.${namespace}) mkOpt;
inherit (lib) mkEnableOption mkIf optionalAttrs;
inherit (pkgs.stdenv) isLinux isDarwin;
cfg = config.${namespace}.programs.terminal.bash;
in
{
options.${namespace}.programs.terminal.bash = with lib.types; {
enable = mkEnableOption "bash";
customFastFetchLogo = mkOpt (nullOr path) null "custom fast fetch logo path";
};
config = mkIf cfg.enable {
programs.bash = {
enable = true;
shellAliases = {
grep = "grep --color";
ssh = "TERM=xterm-256color ssh";
}
// optionalAttrs isLinux {
sync-watch = "watch -d grep -e Dirty: -e Writeback: /proc/meminfo";
}
// optionalAttrs isDarwin {
mosh = "mosh --ssh=\"/usr/bin/ssh\"";
};
profileExtra = ''
export COLORTERM=truecolor
SHELL="$BASH"
PATH=~/.bin:$PATH
bind "set show-mode-in-prompt on"
set -o vi || true
VISUAL=vim
EDITOR="$VISUAL"
if [ -z "$CLAUDE_CODE_ENTRYPOINT" ]; then
fastfetch
fi
[[ -f ~/.bash_custom ]] && . ~/.bash_custom
'';
};
programs.powerline-go = {
enable = true;
settings = {
git-mode = "compact";
theme = "gruvbox";
};
modules = [
"host"
"cwd"
"git"
"docker"
"venv"
];
};
programs.readline = {
enable = true;
extraConfig = ''
# Approximate VIM Dracula Colors
set vi-ins-mode-string \1\e[01;38;5;23;48;5;231m\2 I \1\e[38;5;231;48;5;238m\2\1\e[0m\2
set vi-cmd-mode-string \1\e[01;38;5;22;48;5;148m\2 C \1\e[38;5;148;48;5;238m\2\1\e[0m\2
'';
};
home.packages = with pkgs; [
bashInteractive
fastfetch
mosh
nerd-fonts.meslo-lg
];
home.file.".config/fastfetch/config.jsonc".text = import ./config/fastfetch.nix { inherit cfg; };
home.file.".sqliterc".text = builtins.readFile ./config/.sqliterc;
};
}

View File

@@ -1,4 +1,9 @@
{ lib, config, namespace, ... }: { lib
, pkgs
, config
, namespace
, ...
}:
let let
inherit (lib) mkIf; inherit (lib) mkIf;
cfg = config.${namespace}.programs.terminal.btop; cfg = config.${namespace}.programs.terminal.btop;
@@ -9,10 +14,12 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
programs.btop.enable = true; programs.btop = {
enable = true;
package = pkgs.btop-cuda;
};
home.file.".config/btop/btop.conf".text = home.file.".config/btop/btop.conf".text = builtins.readFile ./config/btop.conf;
builtins.readFile ./config/btop.conf;
home.file.".config/btop/themes/catppuccin_mocha.theme".text = home.file.".config/btop/themes/catppuccin_mocha.theme".text =
builtins.readFile ./config/catppuccin_mocha.theme; builtins.readFile ./config/catppuccin_mocha.theme;
}; };

View File

@@ -0,0 +1,90 @@
{ lib
, pkgs
, config
, namespace
, ...
}:
let
inherit (lib) mkIf;
cfg = config.${namespace}.programs.terminal.claude-code;
in
{
options.${namespace}.programs.terminal.claude-code = {
enable = lib.mkEnableOption "enable claude-code";
};
config = mkIf cfg.enable {
programs.claude-code = {
enable = true;
package = pkgs.reichard.claude-code;
mcpServers = {
gopls = {
type = "stdio";
command = "gopls";
args = [ "mcp" ];
};
};
};
programs.bash = lib.mkIf config.programs.bash.enable {
shellAliases = {
claude-custom = "default_claude_custom";
};
initExtra =
let
baseUrl = "https://llm-api.va.reichard.io";
authToken = "placeholder";
in
''
default_claude_custom() {
local model_id=""
while [[ $# -gt 0 ]]; do
case $1 in
-m|--model)
model_id="$2"
shift 2
;;
*)
shift
;;
esac
done
if [ -z "$model_id" ]; then
echo "Error: Model ID is required. Usage: claude --model <model-id>"
return 1
fi
ANTHROPIC_BASE_URL="${baseUrl}" \
ANTHROPIC_AUTH_TOKEN="${authToken}" \
ANTHROPIC_MODEL="$model_id" \
ANTHROPIC_SMALL_FAST_MODEL="$model_id" \
${lib.getExe pkgs.claude-code}
}
# Completion Function
_complete_claude_custom() {
local cur=''${COMP_WORDS[COMP_CWORD]}
local prev=''${COMP_WORDS[COMP_CWORD-1]}
if [[ "$prev" == "-m" || "$prev" == "--model" ]]; then
local models=( $(${pkgs.curl}/bin/curl -s -H "Authorization: Bearer ${authToken}" "${baseUrl}/v1/models" | ${pkgs.jq}/bin/jq -r '
.data[] |
select(
(try (.meta.llamaswap.type[] | contains("coding")) catch false) or
(.name | startswith("synthetic:"))
) |
.id
' 2>/dev/null) )
COMPREPLY=( $(compgen -W "''${models[*]}" -- "$cur") )
fi
}
# Register Completion
complete -F _complete_claude_custom claude-custom
'';
};
};
}

View File

@@ -1,4 +1,9 @@
{ pkgs, lib, config, namespace, ... }: { pkgs
, lib
, config
, namespace
, ...
}:
let let
inherit (lib) mkIf; inherit (lib) mkIf;
cfg = config.${namespace}.programs.terminal.git; cfg = config.${namespace}.programs.terminal.git;
@@ -11,22 +16,12 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
programs.git = { programs.git = {
enable = true; enable = true;
userName = "Evan Reichard"; settings = {
aliases = { aliases = {
lg = "log --graph --abbrev-commit --decorate --date=relative --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all -n 15"; lg = "log --graph --abbrev-commit --decorate --date=relative --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all -n 15";
}; };
includes = [
{
path = "~/.config/git/work";
condition = "gitdir:~/Development/git/work/";
}
{
path = "~/.config/git/personal";
condition = "gitdir:~/Development/git/personal/";
}
];
extraConfig = {
user = { user = {
name = "Evan Reichard";
email = "evan@reichard.io"; email = "evan@reichard.io";
}; };
core = { core = {
@@ -41,6 +36,7 @@ in
prune = true; prune = true;
pruneTags = true; pruneTags = true;
all = true; all = true;
forceUpdateTags = true;
}; };
help = { help = {
autocorrect = true; autocorrect = true;
@@ -73,6 +69,16 @@ in
autoSetupRemote = true; autoSetupRemote = true;
}; };
}; };
includes = [
{
path = "~/.config/git/work";
condition = "gitdir:~/Development/git/work/";
}
{
path = "~/.config/git/personal";
condition = "gitdir:~/Development/git/personal/";
}
];
}; };
programs.gh = { programs.gh = {
@@ -82,10 +88,7 @@ in
}; };
}; };
home.packages = with pkgs; [ home.packages = with pkgs; [ gh ];
gitAndTools.gh
pre-commit
];
# Copy Configuration # Copy Configuration
xdg.configFile = { xdg.configFile = {

View File

@@ -1,8 +0,0 @@
require('aerial').setup({
on_attach = function(bufnr)
vim.keymap.set('n', '{', '<cmd>AerialPrev<CR>', {buffer = bufnr})
vim.keymap.set('n', '}', '<cmd>AerialNext<CR>', {buffer = bufnr})
end
})
vim.keymap.set('n', '<leader>a', '<cmd>AerialToggle!<CR>')

View File

@@ -5,6 +5,9 @@
-- vim.cmd('colorscheme melange') -- vim.cmd('colorscheme melange')
vim.cmd("colorscheme catppuccin-mocha") vim.cmd("colorscheme catppuccin-mocha")
-- Set User Shell
vim.o.shell = require("nix-vars").bash
-- Set Leader -- Set Leader
vim.keymap.set("n", "<Space>", "<Nop>", { silent = true }) vim.keymap.set("n", "<Space>", "<Nop>", { silent = true })
vim.g.mapleader = " " vim.g.mapleader = " "
@@ -20,7 +23,7 @@ vim.g.loaded_netrwPlugin = 1
vim.opt.termguicolors = true vim.opt.termguicolors = true
-- Synchronize with system clipboard -- Synchronize with system clipboard
vim.opt.clipboard = "unnamed" vim.opt.clipboard:append("unnamedplus")
-- Always show the signcolumn -- Always show the signcolumn
vim.opt.signcolumn = "yes" vim.opt.signcolumn = "yes"
@@ -35,35 +38,3 @@ vim.opt.shiftwidth = 2
vim.opt.foldmethod = "indent" vim.opt.foldmethod = "indent"
vim.opt.foldnestmax = 10 vim.opt.foldnestmax = 10
vim.opt.foldlevel = 2 vim.opt.foldlevel = 2
-- Diagnostics Mappings
local diagnostics_active = true
local toggle_diagnostics = function()
diagnostics_active = not diagnostics_active
if diagnostics_active then
vim.diagnostic.enable()
else
vim.diagnostic.disable()
end
end
local diagnostics_loclist_active = false
local toggle_diagnostics_loclist = function()
diagnostics_loclist_active = not diagnostics_loclist_active
if diagnostics_loclist_active then
vim.diagnostic.setloclist()
else
vim.cmd("lclose")
end
end
local opts = { noremap = true, silent = true }
vim.keymap.set("n", "<leader>qt", toggle_diagnostics, opts)
vim.keymap.set("n", "<leader>qN", function()
vim.diagnostic.goto_prev({ float = false })
end, opts)
vim.keymap.set("n", "<leader>qn", function()
vim.diagnostic.goto_next({ float = false })
end, opts)
vim.keymap.set("n", "<leader>qq", toggle_diagnostics_loclist, opts)
vim.keymap.set("n", "<leader>qe", vim.diagnostic.open_float, opts)

View File

@@ -3,67 +3,67 @@ require("luasnip.loaders.from_vscode").lazy_load()
-- Check Tab Completion -- Check Tab Completion
local has_words_before = function() local has_words_before = function()
local line, col = unpack(vim.api.nvim_win_get_cursor(0)) local line, col = unpack(vim.api.nvim_win_get_cursor(0))
return col ~= 0 and return col ~= 0 and
vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col,
col) col)
:match("%s") == nil :match("%s") == nil
end end
cmp.setup({ cmp.setup({
snippet = { snippet = {
expand = function(args) require'luasnip'.lsp_expand(args.body) end expand = function(args) require 'luasnip'.lsp_expand(args.body) end
}, },
mapping = cmp.mapping.preset.insert({ mapping = cmp.mapping.preset.insert({
-- Tab Completion -- Tab Completion
["<Tab>"] = cmp.mapping(function(fallback) ["<Tab>"] = cmp.mapping(function(fallback)
if cmp.visible() then if cmp.visible() then
cmp.select_next_item() cmp.select_next_item()
elseif has_words_before() then elseif has_words_before() then
cmp.complete() cmp.complete()
else else
fallback() fallback()
end end
end, {"i", "s"}), end, { "i", "s" }),
-- Reverse Tab Completion -- Reverse Tab Completion
["<S-Tab>"] = cmp.mapping(function(fallback) ["<S-Tab>"] = cmp.mapping(function(fallback)
if cmp.visible() then if cmp.visible() then
cmp.select_prev_item() cmp.select_prev_item()
else else
fallback() fallback()
end end
end, {"i", "s"}), end, { "i", "s" }),
-- Misc Mappings -- Misc Mappings
['<C-b>'] = cmp.mapping.scroll_docs(-4), ['<C-b>'] = cmp.mapping.scroll_docs(-4),
['<C-f>'] = cmp.mapping.scroll_docs(4), ['<C-f>'] = cmp.mapping.scroll_docs(4),
['<C-Space>'] = cmp.mapping.complete(), ['<C-Space>'] = cmp.mapping.complete(),
['<C-e>'] = cmp.mapping.abort(), ['<C-e>'] = cmp.mapping.abort(),
['<CR>'] = cmp.mapping.confirm({select = true}) ['<CR>'] = cmp.mapping.confirm({ select = true })
}), }),
-- Default Sources -- Default Sources
sources = cmp.config.sources({ sources = cmp.config.sources({
{name = 'nvim_lsp'}, {name = 'luasnip'}, {name = 'path'}, { name = 'nvim_lsp' }, { name = 'luasnip' }, { name = 'path' },
{name = 'buffer'} { name = 'buffer' }
}) })
}) })
-- Completion - `/` and `?` -- Completion - `/` and `?`
cmp.setup.cmdline({'/', '?'}, { cmp.setup.cmdline({ '/', '?' }, {
mapping = cmp.mapping.preset.cmdline(), mapping = cmp.mapping.preset.cmdline(),
sources = {{name = 'buffer'}} sources = { { name = 'buffer' } }
}) })
-- Completion = `:` -- Completion = `:`
cmp.setup.cmdline(':', { cmp.setup.cmdline(':', {
mapping = cmp.mapping.preset.cmdline(), mapping = cmp.mapping.preset.cmdline(),
sources = cmp.config.sources({{name = 'path'}, {name = 'cmdline'}}) sources = cmp.config.sources({ { name = 'path' }, { name = 'cmdline' } })
}) })
-- Autopairs -- Autopairs

View File

@@ -3,48 +3,48 @@ local dapui = require("dapui")
local dapgo = require("dap-go") local dapgo = require("dap-go")
dapui.setup({ dapui.setup({
controls = { controls = {
element = "repl", element = "repl",
enabled = true, enabled = true,
icons = { icons = {
disconnect = "", disconnect = "",
pause = "", pause = "",
play = "", play = "",
run_last = "", run_last = "",
step_back = "", step_back = "",
step_into = "", step_into = "",
step_out = "", step_out = "",
step_over = "", step_over = "",
terminate = "" terminate = ""
} }
}, },
element_mappings = {}, element_mappings = {},
expand_lines = false, expand_lines = false,
floating = {border = "single", mappings = {close = {"q", "<Esc>"}}}, floating = { border = "single", mappings = { close = { "q", "<Esc>" } } },
force_buffers = true, force_buffers = true,
icons = {collapsed = "", current_frame = "", expanded = ""}, icons = { collapsed = "", current_frame = "", expanded = "" },
layouts = { layouts = {
{ {
elements = {{id = "repl", size = 0.5}, {id = "scopes", size = 0.5}}, elements = { { id = "repl", size = 0.5 }, { id = "scopes", size = 0.5 } },
position = "bottom", position = "bottom",
size = 10 size = 10
}, { }, {
elements = { elements = {
{id = "breakpoints", size = 0.5}, {id = "stacks", size = 0.5} { id = "breakpoints", size = 0.5 }, { id = "stacks", size = 0.5 }
}, },
position = "left", position = "left",
size = 40 size = 40
} }
}, },
mappings = { mappings = {
edit = "e", edit = "e",
expand = {"<CR>", "<2-LeftMouse>"}, expand = { "<CR>", "<2-LeftMouse>" },
open = "o", open = "o",
remove = "d", remove = "d",
repl = "r", repl = "r",
toggle = "t" toggle = "t"
}, },
render = {indent = 1, max_value_lines = 100} render = { indent = 1, max_value_lines = 100 }
}) })
dapgo.setup() dapgo.setup()
@@ -54,17 +54,17 @@ dap.listeners.before.launch.dapui_config = function() dapui.open() end
-- Continue Hotkey ("c") -- Continue Hotkey ("c")
vim.api.nvim_create_autocmd("FileType", { vim.api.nvim_create_autocmd("FileType", {
pattern = "dap-repl", pattern = "dap-repl",
callback = function() callback = function()
vim.api.nvim_buf_set_keymap(0, 'n', 'c', vim.api.nvim_buf_set_keymap(0, 'n', 'c',
"<cmd>lua require'dap'.continue()<CR>", "<cmd>lua require'dap'.continue()<CR>",
{noremap = true, silent = true}) { noremap = true, silent = true })
end end
}) })
-- Leader Keys -- Create KeyMaps
local opts = {noremap = true, silent = true} local opts = { noremap = true, silent = true }
vim.keymap.set('n', '<leader>db', dap.toggle_breakpoint, opts) vim.keymap.set('n', '<leader>db', dap.toggle_breakpoint, vim.tbl_extend("force", { desc = "Toggle Breakpoint" }, opts))
vim.keymap.set('n', '<leader>du', dapui.toggle, opts) vim.keymap.set('n', '<leader>dc', dap.continue, vim.tbl_extend("force", { desc = "Continue" }, opts))
vim.keymap.set('n', '<leader>dc', dap.continue, opts) vim.keymap.set('n', '<leader>dt', dapgo.debug_test, vim.tbl_extend("force", { desc = "Run Test" }, opts))
vim.keymap.set('n', '<leader>dt', dapgo.debug_test, opts) vim.keymap.set('n', '<leader>du', dapui.toggle, vim.tbl_extend("force", { desc = "Toggle UI" }, opts))

View File

@@ -0,0 +1,35 @@
-- Diagnostics Mappings
local diagnostics_active = true
local toggle_diagnostics = function()
diagnostics_active = not diagnostics_active
if diagnostics_active then
vim.diagnostic.enable()
else
vim.diagnostic.disable()
end
end
local diagnostics_loclist_active = false
local toggle_diagnostics_loclist = function()
diagnostics_loclist_active = not diagnostics_loclist_active
if diagnostics_loclist_active then
vim.diagnostic.setloclist()
else
vim.cmd("lclose")
end
end
-- Create KeyMaps
local opts = { noremap = true, silent = true }
vim.keymap.set("n", "<leader>qN", function()
vim.diagnostic.goto_prev({ float = false })
end, vim.tbl_extend("force", { desc = "Previous Diagnostic" }, opts))
vim.keymap.set("n", "<leader>qe", vim.diagnostic.open_float,
vim.tbl_extend("force", { desc = "Open Diagnostics" }, opts))
vim.keymap.set("n", "<leader>qt", toggle_diagnostics,
vim.tbl_extend("force", { desc = "Toggle Inline Diagnostics" }, opts))
vim.keymap.set("n", "<leader>qn", function()
vim.diagnostic.goto_next({ float = false })
end, vim.tbl_extend("force", { desc = "Next Diagnostic" }, opts))
vim.keymap.set("n", "<leader>qq", toggle_diagnostics_loclist,
vim.tbl_extend("force", { desc = "Toggle Diagnostic List" }, opts))

View File

@@ -1,6 +0,0 @@
vim.keymap.set('n', '<leader>go', '<cmd>DiffviewOpen<CR>')
vim.keymap.set('n', '<leader>gO', '<cmd>DiffviewOpen origin/main...HEAD<CR>')
vim.keymap.set('n', '<leader>gh', '<cmd>DiffviewFileHistory<CR>')
vim.keymap.set('n', '<leader>gH',
'<cmd>DiffviewFileHistory --range=origin..HEAD<CR>')
vim.keymap.set('n', '<leader>gc', '<cmd>DiffviewClose<CR>')

View File

@@ -0,0 +1,69 @@
require("gitsigns").setup({
current_line_blame = true,
current_line_blame_opts = { delay = 0 },
on_attach = function(bufnr)
local gitsigns = require("gitsigns")
local function map(mode, l, r, opts)
opts = opts or {}
opts.buffer = bufnr
vim.keymap.set(mode, l, r, opts)
end
map("n", "<leader>gb", gitsigns.toggle_current_line_blame, { desc = "Git Blame Line" })
map("n", "<leader>gB", function()
gitsigns.blame_line({ full = true })
end, { desc = "Git Blame Full" })
end,
})
local function get_git_info()
local abs_path = vim.fn.expand("%:p")
local git_root = vim.fn.systemlist(
"git -C " .. vim.fn.escape(vim.fn.fnamemodify(abs_path, ":h"), " ") .. " rev-parse --show-toplevel"
)[1]
if vim.v.shell_error ~= 0 then
return
end
local git_repo = vim.fn.system("git remote get-url origin"):match("([^/:]+/[^/.]+)%.?[^/]*$"):gsub("\n", "")
local git_branch = vim.fn.system("git rev-parse --abbrev-ref HEAD"):gsub("\n", "")
return {
file = vim.fn.fnamemodify(abs_path, ":s?" .. git_root .. "/??"),
branch = git_branch,
repo = git_repo,
}
end
local function copy_git_link()
local git_info = get_git_info()
if git_info == nil then
vim.notify("Failed to get git info", vim.log.levels.ERROR)
return
end
local start_line = vim.fn.line("v")
local end_line = vim.fn.line(".")
local message = string.format(
"https://github.com/%s/blob/%s/%s#L%d-L%d",
git_info.repo,
git_info.branch,
git_info.file,
start_line,
end_line
)
vim.fn.setreg("+", message)
vim.notify("Copied:\n\t" .. message, vim.log.levels.INFO)
end
-- Create KeyMaps
vim.keymap.set("v", "<Leader>gy", function() copy_git_link() end, { desc = "Copy GitHub Link" })
vim.keymap.set('n', '<leader>go', '<cmd>DiffviewOpen<CR>', { desc = "Open Diff - Current" })
vim.keymap.set('n', '<leader>gO', '<cmd>DiffviewOpen origin/main...HEAD<CR>', { desc = "Open Diff - Main" })
vim.keymap.set('n', '<leader>gh', '<cmd>DiffviewFileHistory<CR>', { desc = "Diff History" })
vim.keymap.set('n', '<leader>gH', '<cmd>DiffviewFileHistory --range=origin..HEAD<CR>', { desc = "Diff History - Main" })
vim.keymap.set('n', '<leader>gc', '<cmd>DiffviewClose<CR>', { desc = "Close Diff" })

View File

@@ -1,41 +0,0 @@
function get_git_info()
local abs_path = vim.fn.expand("%:p")
local git_root = vim.fn.systemlist(
"git -C " .. vim.fn.escape(vim.fn.fnamemodify(abs_path, ":h"), " ") .. " rev-parse --show-toplevel"
)[1]
if vim.v.shell_error ~= 0 then
return
end
local git_repo = vim.fn.system("git remote get-url origin"):match("([^/:]+/[^/.]+)%.?[^/]*$"):gsub("\n", "")
local git_branch = vim.fn.system("git rev-parse --abbrev-ref HEAD"):gsub("\n", "")
return {
file = vim.fn.fnamemodify(abs_path, ":s?" .. git_root .. "/??"),
branch = git_branch,
repo = git_repo,
}
end
vim.keymap.set("v", "<Leader>gy", function()
local git_info = get_git_info()
if git_info == nil then
vim.notify("Failed to get git info", vim.log.levels.ERROR)
return
end
local start_line = vim.fn.line("v")
local end_line = vim.fn.line(".")
local message = string.format(
"https://github.com/%s/blob/%s/%s#L%d-L%d",
git_info.repo,
git_info.branch,
git_info.file,
start_line,
end_line
)
vim.fn.setreg("+", message)
vim.notify("Copied:\n\t" .. message, vim.log.levels.INFO)
end, { noremap = true, silent = true, desc = "Copy GitHub Link" })

View File

@@ -1,16 +0,0 @@
require('gitsigns').setup {
on_attach = function(bufnr)
local gitsigns = require('gitsigns')
local function map(mode, l, r, opts)
opts = opts or {}
opts.buffer = bufnr
vim.keymap.set(mode, l, r, opts)
end
map('n', '<leader>gb', gitsigns.toggle_current_line_blame)
map('n', '<leader>gB', function()
gitsigns.blame_line {full = true}
end)
end
}

View File

@@ -1,23 +1,19 @@
require("base") require("base")
require("aerial-config")
require("autopairs-config") require("autopairs-config")
require("cmp-config") require("cmp-config")
require("comment-config") require("comment-config")
require("dap-config") require("dap-config")
require("diffview-config") require("diagnostics-config")
require("git-ref") require("git-config")
require("git-signs")
require("llm")
require("leap-config") require("leap-config")
require("llm-config")
require("lsp-config") require("lsp-config")
require("lsp-lines-config")
require("lualine-config") require("lualine-config")
require("neotree-config")
require("noice-config") require("noice-config")
require("numb-config") require("numb-config")
require("silicon-config") require("octo-config")
require("telescope-config") require("snacks-config")
require("toggleterm-config") require("toggleterm-config")
require("ts-config") require("ts-config")
require("which-key-config")
require("weird-chars") require("weird-chars")
require("which-key-config")

View File

@@ -0,0 +1,87 @@
local llm_endpoint = "https://llm-api.va.reichard.io"
local llm_assistant_model = "qwen3-coder-next-80b-instruct"
local llm_infill_model = llm_assistant_model
local current_fim = "copilot"
-- Copilot Configuration
vim.g.copilot_no_tab_map = true
vim.g.copilot_filetypes = { ["*"] = true }
-- LLama LLM FIM
vim.g.llama_config = {
endpoint = llm_endpoint .. "/infill",
model = llm_infill_model,
n_predict = 2048,
ring_n_chunks = 32,
enable_at_startup = (current_fim == "llama"), -- enable based on default
}
-- Toggle function for manual switching
local function switch_llm_fim_provider(switch_to)
if switch_to == "llama" then
vim.cmd("Copilot disable")
vim.cmd("LlamaEnable")
current_fim = "llama"
vim.notify("Llama FIM enabled", vim.log.levels.INFO)
else
vim.cmd("Copilot enable")
vim.cmd("LlamaDisable")
current_fim = "copilot"
vim.notify("Copilot FIM enabled", vim.log.levels.INFO)
end
end
-- Configure Code Companion
require("plugins.codecompanion.fidget-spinner"):init()
local codecompanion = require("codecompanion")
codecompanion.setup({
display = {
chat = {
show_token_count = true,
window = {
layout = "float",
width = 0.6,
}
}
},
adapters = {
http = {
opts = { show_defaults = false, },
copilot = "copilot",
llamaswap = function()
return require("codecompanion.adapters").extend("openai_compatible", {
formatted_name = "LlamaSwap",
name = "llamaswap",
schema = { model = { default = llm_assistant_model } },
env = { url = llm_endpoint },
})
end,
},
},
strategies = {
chat = { adapter = "llamaswap" },
inline = { adapter = "llamaswap" },
cmd = { adapter = "llamaswap" },
},
chat = { dispay = "telescope" },
memory = { opts = { chat = { enabled = true } } },
})
-- Create KeyMaps for Code Companion
vim.keymap.set("n", "<leader>aa", codecompanion.actions, { desc = "Actions" })
vim.keymap.set("n", "<leader>af", function()
if current_fim == "llama" then
switch_llm_fim_provider("copilot")
else
switch_llm_fim_provider("llama")
end
end, { desc = "Toggle FIM (Llama / Copilot)" })
vim.keymap.set("n", "<leader>ao", function() require("snacks.terminal").toggle("opencode") end,
{ desc = "Toggle OpenCode" })
vim.keymap.set("v", "<leader>ai", ":CodeCompanion<cr>", { desc = "Inline Prompt" })
vim.keymap.set({ "n", "v" }, "<leader>an", codecompanion.chat, { desc = "New Chat" })
vim.keymap.set({ "n", "t" }, "<leader>at", codecompanion.toggle, { desc = "Toggle Chat" })
vim.keymap.set('i', '<C-J>', 'copilot#Accept("\\<CR>")', {
expr = true,
replace_keycodes = false
})

View File

@@ -1,20 +0,0 @@
-- Configure LLama LLM
vim.g.llama_config = {
endpoint = "http://10.0.50.120:8080/infill",
api_key = "",
n_prefix = 256,
n_suffix = 64,
n_predict = 256,
t_max_prompt_ms = 500,
t_max_predict_ms = 500,
show_info = 2,
auto_fim = true,
max_line_suffix = 8,
max_cache_keys = 256,
ring_n_chunks = 8,
ring_chunk_size = 32,
ring_scope = 512,
ring_update_ms = 1000,
}
-- require("gen").setup({ model = "codegemma" })

View File

@@ -8,22 +8,35 @@ vim.api.nvim_create_autocmd("FileType", {
end, end,
}) })
vim.filetype.add({ require('render-markdown').setup({
extension = { completions = { lsp = { enabled = true } },
templ = "templ", file_types = { 'markdown', 'codecompanion' },
html = {
-- CodeCompanion Markdown Tweaks
tag = {
file = { icon = '󰨸 ', highlight = 'Normal' },
buf = { icon = '󰂥 ', highlight = 'Normal' },
},
}, },
}) })
------------------------------------------------------
---------------------- LSP Lines ---------------------
------------------------------------------------------
require("lsp_lines").setup()
vim.diagnostic.config({
virtual_text = false,
virtual_lines = true,
})
------------------------------------------------------ ------------------------------------------------------
-------------------- Built-in LSP -------------------- -------------------- Built-in LSP --------------------
------------------------------------------------------ ------------------------------------------------------
local nix_vars = require("nix-vars") local nix_vars = require("nix-vars")
local nvim_lsp = require("lspconfig")
local augroup = vim.api.nvim_create_augroup("LspFormatting", { clear = false })
local on_attach = function(client, bufnr) local on_attach = function(client, bufnr)
local bufopts = { noremap = true, silent = true, buffer = bufnr } if client:supports_method("textDocument/formatting") then
if client.supports_method("textDocument/formatting") then
vim.api.nvim_clear_autocmds({ group = augroup, buffer = bufnr }) vim.api.nvim_clear_autocmds({ group = augroup, buffer = bufnr })
vim.api.nvim_create_autocmd("BufWritePre", { vim.api.nvim_create_autocmd("BufWritePre", {
group = augroup, group = augroup,
@@ -34,17 +47,25 @@ local on_attach = function(client, bufnr)
}) })
end end
vim.keymap.set("n", "K", vim.lsp.buf.hover, bufopts) -- Create KeyMaps
vim.keymap.set("n", "<C-k>", vim.lsp.buf.signature_help, bufopts) local bufopts = { noremap = true, silent = true, buffer = bufnr }
vim.keymap.set("n", "<leader>lD", vim.lsp.buf.declaration, bufopts) vim.keymap.set("n", "K", vim.lsp.buf.hover, vim.tbl_extend("force", { desc = 'Hover documentation' }, bufopts))
vim.keymap.set("n", "<leader>ld", vim.lsp.buf.definition, bufopts) vim.keymap.set("n", "<C-k>", vim.lsp.buf.signature_help,
vim.keymap.set("n", "<leader>li", vim.lsp.buf.implementation, bufopts) vim.tbl_extend("force", { desc = "Show signature help" }, bufopts))
vim.keymap.set("n", "<leader>ln", vim.lsp.buf.rename, bufopts) vim.keymap.set("n", "<leader>lD", vim.lsp.buf.declaration,
vim.keymap.set("n", "<leader>lr", vim.lsp.buf.references, bufopts) vim.tbl_extend("force", { desc = "Go to declaration" }, bufopts))
vim.keymap.set("n", "<leader>lt", vim.lsp.buf.type_definition, bufopts) vim.keymap.set("n", "<leader>ld", vim.lsp.buf.definition,
vim.tbl_extend("force", { desc = "Go to definition" }, bufopts))
vim.keymap.set("n", "<leader>li", vim.lsp.buf.implementation,
vim.tbl_extend("force", { desc = "Go to implementation" }, bufopts))
vim.keymap.set("n", "<leader>ln", vim.lsp.buf.rename, vim.tbl_extend("force", { desc = "Rename symbol" }, bufopts))
vim.keymap.set("n", "<leader>lr", vim.lsp.buf.references,
vim.tbl_extend("force", { desc = "Show references" }, bufopts))
vim.keymap.set("n", "<leader>lt", vim.lsp.buf.type_definition,
vim.tbl_extend("force", { desc = "Go to type definition" }, bufopts))
vim.keymap.set("n", "<leader>lf", function() vim.keymap.set("n", "<leader>lf", function()
vim.lsp.buf.format({ async = true, timeout_ms = 2000 }) vim.lsp.buf.format({ async = true, timeout_ms = 2000 })
end, bufopts) end, vim.tbl_extend("force", { desc = "Format file" }, bufopts))
end end
local on_attach_no_formatting = function(client, bufnr) local on_attach_no_formatting = function(client, bufnr)
@@ -71,81 +92,95 @@ local organize_go_imports = function()
end end
end end
-- Define LSP Flags & Capabilities local default_config = {
local lsp_flags = { debounce_text_changes = 150 } flags = { debounce_text_changes = 150 },
local capabilities = require("cmp_nvim_lsp").default_capabilities() capabilities = require("cmp_nvim_lsp").default_capabilities(),
on_attach = on_attach,
}
local setup_lsp = function(name, config)
local final_config = vim.tbl_deep_extend("force", default_config, config or {})
vim.lsp.config(name, final_config)
vim.lsp.enable(name)
end
-- Python LSP Configuration -- Python LSP Configuration
nvim_lsp.pyright.setup({ setup_lsp("pyright", {
on_attach = on_attach, filetypes = { "starlark", "python" },
flags = lsp_flags,
capabilities = capabilities,
}) })
-- HTML LSP Configuration -- HTML LSP Configuration
nvim_lsp.html.setup({ setup_lsp("html", {
on_attach = on_attach_no_formatting, on_attach = on_attach_no_formatting,
flags = lsp_flags,
capabilities = capabilities,
cmd = { nix_vars.vscls .. "/bin/vscode-html-language-server", "--stdio" }, cmd = { nix_vars.vscls .. "/bin/vscode-html-language-server", "--stdio" },
filetypes = { "htm", "html" },
}) })
-- JSON LSP Configuration -- JSON LSP Configuration
nvim_lsp.jsonls.setup({ setup_lsp("jsonls", {
on_attach = on_attach_no_formatting, on_attach = on_attach_no_formatting,
flags = lsp_flags,
capabilities = capabilities,
cmd = { nix_vars.vscls .. "/bin/vscode-html-language-server", "--stdio" }, cmd = { nix_vars.vscls .. "/bin/vscode-html-language-server", "--stdio" },
filetypes = { "json", "jsonc", "jsonl" },
}) })
-- CSS LSP Configuration -- CSS LSP Configuration
nvim_lsp.cssls.setup({ setup_lsp("cssls", {
on_attach = on_attach_no_formatting, on_attach = on_attach_no_formatting,
flags = lsp_flags,
capabilities = capabilities,
cmd = { nix_vars.vscls .. "/bin/vscode-html-language-server", "--stdio" }, cmd = { nix_vars.vscls .. "/bin/vscode-html-language-server", "--stdio" },
filetypes = { "css" },
}) })
-- Typescript / Javascript LSP Configuration -- Typescript / Javascript LSP Configuration
nvim_lsp.ts_ls.setup({ setup_lsp("ts_ls", {
on_attach = on_attach_no_formatting, on_attach = on_attach_no_formatting,
flags = lsp_flags,
capabilities = capabilities,
cmd = { nix_vars.tsls, "--stdio" }, cmd = { nix_vars.tsls, "--stdio" },
filetypes = { "typescript", "typescriptreact", "javascript" },
}) })
-- Svelte LSP Configuration -- ESLint LSP
nvim_lsp.svelte.setup({ setup_lsp("eslint", {
on_attach = on_attach_no_formatting, on_attach = on_attach_no_formatting,
flags = lsp_flags, cmd = { nix_vars.vscls .. "/bin/vscode-eslint-language-server", "--stdio" },
capabilities = capabilities, })
cmd = { nix_vars.sveltels, "--stdio" },
-- C LSP Configuration
setup_lsp("clangd", {
cmd = { nix_vars.clangd },
filetypes = { "c", "cpp", "objc", "objcpp", "cuda" },
}) })
-- Lua LSP Configuration -- Lua LSP Configuration
nvim_lsp.lua_ls.setup({ setup_lsp("lua_ls", {
on_attach = on_attach_no_formatting,
flags = lsp_flags,
capabilities = capabilities,
cmd = { nix_vars.luals }, cmd = { nix_vars.luals },
filetypes = { "lua" },
}) })
-- Templ LSP Configuration -- Unison LSP Configuration
nvim_lsp.templ.setup({ setup_lsp("unison")
on_attach = on_attach,
flags = lsp_flags, -- Lua LSP Configuration
capabilities = capabilities, setup_lsp("sqls", {
cmd = { nix_vars.sqls },
}) })
-- Nix LSP Configuration -- Nix LSP Configuration
nvim_lsp.nil_ls.setup({ setup_lsp("nil_ls", {
on_attach = on_attach, filetypes = { "nix" },
flags = lsp_flags,
capabilities = capabilities,
}) })
-- Omnisharp LSP Configuration
-- NOTE: https://github.com/NixOS/nixpkgs/issues/479348
-- setup_lsp("omnisharp", {
-- enable_roslyn_analyzers = true,
-- enable_import_completion = true,
-- organize_imports_on_format = true,
-- enable_decompilation_support = true,
-- filetypes = { "cs", "vb", "csproj", "sln", "slnx", "props", "csx", "targets", "tproj", "slngen", "fproj" },
-- cmd = { nix_vars.omnisharp, "--languageserver", "--hostPID", tostring(vim.fn.getpid()) },
-- })
-- Go LSP Configuration -- Go LSP Configuration
nvim_lsp.gopls.setup({ setup_lsp("gopls", {
on_attach = function(client, bufnr) on_attach = function(client, bufnr)
on_attach(client, bufnr) on_attach(client, bufnr)
vim.api.nvim_create_autocmd("BufWritePre", { vim.api.nvim_create_autocmd("BufWritePre", {
@@ -154,9 +189,8 @@ nvim_lsp.gopls.setup({
callback = organize_go_imports, callback = organize_go_imports,
}) })
end, end,
flags = lsp_flags,
capabilities = capabilities,
cmd = { nix_vars.gopls }, cmd = { nix_vars.gopls },
filetypes = { "go" },
settings = { settings = {
gopls = { gopls = {
buildFlags = { "-tags=e2e" }, buildFlags = { "-tags=e2e" },
@@ -165,11 +199,10 @@ nvim_lsp.gopls.setup({
}) })
-- Go LSP Linting -- Go LSP Linting
nvim_lsp.golangci_lint_ls.setup({ setup_lsp("golangci_lint_ls", {
on_attach = on_attach_no_formatting, on_attach = on_attach_no_formatting,
flags = lsp_flags,
capabilities = capabilities,
cmd = { nix_vars.golintls }, cmd = { nix_vars.golintls },
filetypes = { "go" },
init_options = { init_options = {
command = { command = {
"golangci-lint", "golangci-lint",
@@ -183,48 +216,26 @@ nvim_lsp.golangci_lint_ls.setup({
}) })
------------------------------------------------------ ------------------------------------------------------
--------------------- Null-LS LSP -------------------- --------------------- None-LS LSP --------------------
------------------------------------------------------ ------------------------------------------------------
local null_ls = require("null-ls") local none_ls = require("null-ls")
local eslintFiles = { none_ls.setup({
".eslintrc",
".eslintrc.js",
".eslintrc.cjs",
".eslintrc.yaml",
".eslintrc.yml",
".eslintrc.json",
"eslint.config.js",
"eslint.config.mjs",
"eslint.config.cjs",
"eslint.config.ts",
"eslint.config.mts",
"eslint.config.cts",
}
has_eslint_in_parents = function(fname)
root_file = nvim_lsp.util.insert_package_json(eslintFiles, "eslintConfig", fname)
return nvim_lsp.util.root_pattern(unpack(root_file))(fname)
end
null_ls.setup({
sources = { sources = {
-- Prettier Formatting -- Formatting
null_ls.builtins.formatting.prettier, none_ls.builtins.formatting.prettier,
null_ls.builtins.formatting.prettier.with({ filetypes = { "template" } }), none_ls.builtins.formatting.prettier.with({ filetypes = { "template" } }),
require("none-ls.diagnostics.eslint_d").with({ none_ls.builtins.formatting.nixpkgs_fmt, -- TODO: nixd native LSP?
condition = function(utils) require("none-ls.formatting.autopep8").with({
return has_eslint_in_parents(vim.fn.getcwd()) filetypes = { "starlark", "python" },
end, extra_args = { "--max-line-length", "100" },
}), }),
null_ls.builtins.completion.spell,
null_ls.builtins.formatting.nixpkgs_fmt, -- Completion
null_ls.builtins.formatting.stylua, none_ls.builtins.completion.spell,
null_ls.builtins.diagnostics.sqlfluff,
null_ls.builtins.formatting.sqlfluff,
}, },
on_attach = function(client, bufnr) on_attach = function(client, bufnr)
if client.supports_method("textDocument/formatting") then if client:supports_method("textDocument/formatting") then
vim.api.nvim_clear_autocmds({ group = augroup, buffer = bufnr }) vim.api.nvim_clear_autocmds({ group = augroup, buffer = bufnr })
vim.api.nvim_create_autocmd("BufWritePre", { vim.api.nvim_create_autocmd("BufWritePre", {
group = augroup, group = augroup,

View File

@@ -1,2 +0,0 @@
require("lsp_lines").setup()
vim.diagnostic.config({virtual_text = false})

View File

@@ -3,23 +3,28 @@ local cached_pr_status = ""
-- Read process output -- Read process output
local function read_output(err, data) local function read_output(err, data)
if err then return end if err then
if not data then return end return
cached_pr_status = data end
if not data then
return
end
cached_pr_status = data
end end
-- Spawn process -- Spawn process
local function execute_command() local function execute_command()
local stdout = vim.loop.new_pipe(false) local stdout = vim.loop.new_pipe(false)
local spawn_opts = { local spawn_opts = {
detached = true, detached = true,
stdio = {nil, stdout, nil}, stdio = { nil, stdout, nil },
args = {"-c", "gh pr checks | awk -F'\t' '{ print $2 }'"} args = { "-c", "gh pr checks | awk -F'\t' '{ print $2 }'" },
} }
vim.loop.spawn("bash", spawn_opts, vim.loop.spawn("bash", spawn_opts, function()
function() stdout:read_start(read_output) end) stdout:read_start(read_output)
end)
end end
-- Spawn & schedule process -- Spawn & schedule process
@@ -27,23 +32,26 @@ execute_command()
vim.fn.timer_start(300000, execute_command) vim.fn.timer_start(300000, execute_command)
-- Return status from cache -- Return status from cache
function pr_status() local function pr_status()
--    --   
--     --    
-- --
-- PENDING COLOR - #d29922 -- PENDING COLOR - #d29922
-- PASS COLOR - #3fb950 -- PASS COLOR - #3fb950
-- FAIL COLOR - #f85149 -- FAIL COLOR - #f85149
return cached_pr_status:gsub("\n", ""):gsub("fail", ""):gsub("pass", return cached_pr_status
"") :gsub("\n", "")
:gsub("pending", " "):gsub("skipping", ""):sub(1, -2) :gsub("fail", " ")
:gsub("pass", "")
:gsub("pending", "")
:gsub("skipping", "")
:sub(1, -2)
end end
require('lualine').setup({ require("lualine").setup({
options = { options = { theme = "catppuccin" },
theme = "gruvbox_dark" sections = {
-- theme = "nord" lualine_c = { { pr_status } },
-- theme = "OceanicNext", -- lualine_z = { require("opencode").statusline }
}, },
sections = {lualine_c = {{pr_status}}}
}) })

View File

@@ -1,2 +0,0 @@
require("neo-tree").setup({ window = { mappings = { ["<space>"] = "none" } } })
vim.keymap.set("n", "<leader>t", ":Neotree toggle<CR>", { silent = true })

View File

@@ -1,26 +1,14 @@
-- Noice Doc Scrolling
vim.keymap.set("n", "<c-f>", function()
if not require("noice.lsp").scroll(4) then return "<c-f>" end
end, {silent = true, expr = true})
vim.keymap.set("n", "<c-b>", function()
if not require("noice.lsp").scroll(-4) then return "<c-b>" end
end, {silent = true, expr = true})
-- Noice Setup -- Noice Setup
require("noice").setup({ require("noice").setup({
lsp = { -- Ignore (Snacks Priority)
override = { routes = {
["vim.lsp.util.convert_input_to_markdown_lines"] = true, {
["vim.lsp.util.stylize_markdown"] = true, filter = { event = "ui", kind = "input", },
["cmp.entry.get_documentation"] = false opts = { skip = true },
}, },
signature = {enabled = false} {
}, filter = { event = "ui", kind = "select", },
presets = { opts = { skip = true },
command_palette = true, -- position the cmdline and popupmenu together },
long_message_to_split = true, -- long messages will be sent to a split },
inc_rename = false, -- enables an input dialog for inc-rename.nvim
lsp_doc_border = false -- add a border to hover docs and signature help
}
}) })

View File

@@ -0,0 +1,13 @@
require("octo").setup()
-- Create KeyMaps
vim.keymap.set("n", "<leader>rs", "<cmd>Octo review start<cr>")
vim.keymap.set("n", "<leader>rd", "<cmd>Octo review discard<cr>")
vim.keymap.set("n", "<leader>rr", "<cmd>Octo review resume<cr>")
vim.keymap.set("n", "<leader>re", "<cmd>Octo review submit<cr>")
vim.keymap.set("n", "<leader>rca", "<cmd>Octo review comments<cr>")
vim.keymap.set("n", "<leader>rcs", "<cmd>Octo comment suggest<cr>")
vim.keymap.set("n", "<leader>rcc", "<cmd>Octo comment add<cr>")
vim.keymap.set("n", "<leader>rcr", "<cmd>Octo comment reply<cr>")
vim.keymap.set("n", "<leader>pd", "<cmd>Octo pr diff<cr>")
vim.keymap.set("n", "<leader>pc", "<cmd>Octo pr changes<cr>")

View File

@@ -0,0 +1,71 @@
local progress = require("fidget.progress")
local M = {}
function M:init()
local group = vim.api.nvim_create_augroup("CodeCompanionFidgetHooks", {})
vim.api.nvim_create_autocmd({ "User" }, {
pattern = "CodeCompanionRequestStarted",
group = group,
callback = function(request)
local handle = M:create_progress_handle(request)
M:store_progress_handle(request.data.id, handle)
end,
})
vim.api.nvim_create_autocmd({ "User" }, {
pattern = "CodeCompanionRequestFinished",
group = group,
callback = function(request)
local handle = M:pop_progress_handle(request.data.id)
if handle then
M:report_exit_status(handle, request)
handle:finish()
end
end,
})
end
M.handles = {}
function M:store_progress_handle(id, handle)
M.handles[id] = handle
end
function M:pop_progress_handle(id)
local handle = M.handles[id]
M.handles[id] = nil
return handle
end
function M:create_progress_handle(request)
return progress.handle.create({
title = " Requesting assistance (" .. request.data.adapter.formatted_name .. ")",
message = "In progress...",
lsp_client = {
name = M:llm_role_title(request.data.adapter),
},
})
end
function M:llm_role_title(adapter)
local parts = {}
table.insert(parts, adapter.formatted_name)
if adapter.model and adapter.model ~= "" then
table.insert(parts, "(" .. adapter.model .. ")")
end
return table.concat(parts, " ")
end
function M:report_exit_status(handle, request)
if request.data.status == "success" then
handle.message = "Completed"
elseif request.data.status == "error" then
handle.message = " Error"
else
handle.message = "󰜺 Cancelled"
end
end
return M

View File

@@ -1,10 +0,0 @@
local silicon = require('silicon')
silicon.setup({})
vim.keymap.set('v', '<Leader>ss', function() silicon.visualise_api({}) end)
vim.keymap.set('v', '<Leader>sb',
function() silicon.visualise_api({show_buf = true}) end)
vim.keymap.set('n', '<Leader>sv',
function() silicon.visualise_api({visible = true}) end)
vim.keymap.set('n', '<Leader>sb',
function() silicon.visualise_api({show_buf = true}) end)

View File

@@ -0,0 +1,23 @@
-- Snacks Setup
local snacks = require("snacks")
snacks.setup({
input = { enabled = true, style = "popup" },
select = { enabled = true, style = "popup" },
})
-- Create KeyMaps
vim.keymap.set("n", "<leader>fb", snacks.picker.buffers, { desc = "Buffers" })
vim.keymap.set("n", "<leader>fd", snacks.picker.diagnostics, { desc = "Diagnostics" })
vim.keymap.set("n", "<leader>ff", snacks.picker.files, { desc = "Find Files" })
vim.keymap.set("n", "<leader>fg", snacks.picker.grep, { desc = "Grep Files" })
vim.keymap.set("n", "<leader>fh", snacks.picker.help, { desc = "Help Tags" })
vim.keymap.set("n", "<leader>fj", snacks.picker.jumps, { desc = "Jump List" })
vim.keymap.set("n", "<leader>fl", function() snacks.terminal("lazygit") end, { desc = "LazyGit" })
vim.keymap.set("n", "<leader>fp", snacks.picker.gh_pr, { desc = "GitHub Pull Requests" })
vim.keymap.set("n", "<leader>fs", snacks.picker.lsp_symbols, { desc = "Symbols" })
vim.keymap.set("n", "<leader>fu", snacks.picker.undo, { desc = "Undo History" })
vim.keymap.set("n", "gI", snacks.picker.lsp_implementations, { desc = "LSP Implementations" })
vim.keymap.set("n", "gi", snacks.picker.lsp_incoming_calls, { desc = "LSP Incoming Calls" })
vim.keymap.set("n", "go", snacks.picker.lsp_outgoing_calls, { desc = "LSP Outgoing Calls" })
vim.keymap.set("n", "gr", snacks.picker.lsp_references, { desc = "LSP References" })
vim.keymap.set("n", [[<c-\>]], function() snacks.terminal() end, { desc = "Toggle Terminal" })

View File

@@ -1,20 +0,0 @@
require('telescope').setup {
extensions = {
fzf = {
fuzzy = true,
override_generic_sorter = true,
override_file_sorter = true,
case_mode = "smart_case"
}
}
}
require('telescope').load_extension('fzf')
require("telescope").load_extension("ui-select")
local builtin = require('telescope.builtin')
vim.keymap.set('n', '<leader>ff', builtin.find_files, {})
vim.keymap.set('n', '<leader>fg', builtin.live_grep, {})
vim.keymap.set('n', '<leader>fb', builtin.buffers, {})
vim.keymap.set('n', '<leader>fh', builtin.help_tags, {})
vim.keymap.set('n', '<leader>fj', builtin.jumplist, {})

View File

@@ -1,20 +1,20 @@
require("toggleterm").setup({open_mapping = [[<c-\>]]}) -- require("toggleterm").setup({open_mapping = [[<c-\>]]})
--
-- Get PR status on terminal load -- -- Get PR status on terminal load
-- require("toggleterm").setup({ -- -- require("toggleterm").setup({
-- open_mapping = [[<c-\>]], -- -- open_mapping = [[<c-\>]],
-- on_create = function(term) -- -- on_create = function(term)
-- vim.cmd("startinsert") -- -- vim.cmd("startinsert")
-- term:send("gh pr checks") -- -- term:send("gh pr checks")
-- end -- -- end
-- }) -- -- })
--
-- Duplicate C-w & Esc Behavior -- -- Duplicate C-w & Esc Behavior
function _G.set_terminal_keymaps() -- function _G.set_terminal_keymaps()
local opts = {buffer = 0} -- local opts = {buffer = 0}
vim.opt.signcolumn = "no" -- vim.opt.signcolumn = "no"
vim.keymap.set('t', '<esc>', [[<C-\><C-n>]], opts) -- vim.keymap.set('t', '<esc>', [[<C-\><C-n>]], opts)
vim.keymap.set('t', '<C-w>', [[<C-\><C-n><C-w>]], opts) -- vim.keymap.set('t', '<C-w>', [[<C-\><C-n><C-w>]], opts)
end -- end
--
vim.cmd('autocmd! TermOpen term://* lua set_terminal_keymaps()') -- vim.cmd('autocmd! TermOpen term://* lua set_terminal_keymaps()')

View File

@@ -1,3 +1,4 @@
require'nvim-treesitter.configs'.setup { require("nvim-treesitter.configs").setup({
highlight = {enable = true, additional_vim_regex_highlighting = false} highlight = { enable = true, additional_vim_regex_highlighting = false },
} })
vim.treesitter.language.register("markdown", "octo")

View File

@@ -1,47 +1,9 @@
local wk = require("which-key") local wk = require("which-key")
wk.setup({})
wk.add({ wk.add({
{ "<C-k>", desc = "Signature Help" }, { "<leader>a", group = "LLM" }, -- llm-config.lua
{ "<leader>a", desc = "Aerial" }, { "<leader>f", group = "Find" }, -- snacks-config.lua
{ "<leader>d", group = "Debug" }, { "<leader>l", group = "LSP" }, -- lsp-config.lua
{ "<leader>db", desc = "Toggle Breakpoint" }, { "<leader>g", group = "Git" }, -- git-config.lua
{ "<leader>dc", desc = "Continue" }, { "<leader>q", group = "Diagnostics" }, -- diagnostics-config.lua
{ "<leader>dt", desc = "Run Test" }, { "<leader>d", group = "Debug" }, -- dap-config.lua
{ "<leader>du", desc = "Toggle UI" },
{ "<leader>f", group = "Find - Telescope" },
{ "<leader>fb", "<cmd>Telescope buffers<cr>", desc = "Find Buffer" },
{ "<leader>ff", "<cmd>Telescope find_files<cr>", desc = "Find File" },
{ "<leader>fg", "<cmd>Telescope live_grep<cr>", desc = "Live Grep" },
{ "<leader>fh", "<cmd>Telescope help_tags<cr>", desc = "Help Tags" },
{ "<leader>fj", "<cmd>Telescope jumplist<cr>", desc = "Jump List" },
{ "<leader>g", group = "DiffView" },
{ "<leader>gB", desc = "Git Blame Full" },
{ "<leader>gH", "<cmd>DiffviewFileHistory --range=origin..HEAD<cr>", desc = "Diff History - Main" },
{ "<leader>gO", "<cmd>DiffviewOpen origin/main...HEAD<cr>", desc = "Open Diff - Main" },
{ "<leader>gb", desc = "Git Blame Line" },
{ "<leader>gc", "<cmd>DiffviewClose<cr>", desc = "Close Diff" },
{ "<leader>gh", "<cmd>DiffviewFileHistory<cr>", desc = "Diff History" },
{ "<leader>go", "<cmd>DiffviewOpen<cr>", desc = "Open Diff - Current" },
{ "<leader>l", group = "LSP" },
{ "<leader>lD", desc = "Declaration" },
{ "<leader>ld", desc = "Definition" },
{ "<leader>lf", desc = "Format" },
{ "<leader>li", desc = "Implementation" },
{ "<leader>ln", desc = "Rename" },
{ "<leader>lr", desc = "References" },
{ "<leader>lt", desc = "Type Definition" },
{ "<leader>q", group = "Diagnostics" },
{ "<leader>qN", desc = "Previous Diagnostic" },
{ "<leader>qe", desc = "Open Diagnostic Float" },
{ "<leader>qn", desc = "Next Diagnostic" },
{ "<leader>qq", desc = "Toggle Diagnostic List" },
{ "<leader>qt", desc = "Toggle Inline Diagnostics" },
{ "<leader>sv", desc = "Visual Screenshot" },
{ "<leader>t", desc = "NeoTree" },
{ "K", desc = "Definition Hover" },
{ "<leader>ss", desc = "Selected Screenshot", mode = "v" },
{ "<leader>s", group = "Screenshot", mode = { "n", "v" } },
{ "<leader>sb", desc = "Buffer Screenshot", mode = { "n", "v" } },
}) })

View File

@@ -1,4 +1,9 @@
{ pkgs, lib, config, namespace, ... }: { pkgs
, lib
, config
, namespace
, ...
}:
let let
inherit (lib) mkIf; inherit (lib) mkIf;
cfg = config.${namespace}.programs.terminal.nvim; cfg = config.${namespace}.programs.terminal.nvim;
@@ -34,31 +39,29 @@ in
# ------------------- # -------------------
# ----- Helpers ----- # ----- Helpers -----
# ------------------- # -------------------
aerial-nvim # Code Outline
comment-nvim # Code Comments comment-nvim # Code Comments
copilot-vim # GitHub Copilot
diffview-nvim # Diff View diffview-nvim # Diff View
fidget-nvim # Notification Helper
gitsigns-nvim # Git Blame gitsigns-nvim # Git Blame
leap-nvim # Quick Movement leap-nvim # Quick Movement
markdown-preview-nvim # Markdown Preview markdown-preview-nvim # Markdown Preview
neo-tree-nvim # File Explorer
none-ls-nvim # Formatters none-ls-nvim # Formatters
numb-nvim # Peek / Jump to Lines numb-nvim # Peek / Jump to Lines
nvim-autopairs # Automatically Close Pairs (),[],{} nvim-autopairs # Automatically Close Pairs (),[],{}
telescope-fzf-native-nvim # Faster Telescope octo-nvim # Git Octo
render-markdown-nvim # Markdown Renderer
snacks-nvim # Snacks
telescope-nvim # Fuzzy Finder telescope-nvim # Fuzzy Finder
telescope-ui-select-nvim # UI
toggleterm-nvim # Terminal Helper
vim-nix # Nix Helpers vim-nix # Nix Helpers
which-key-nvim # Shortcut Helper which-key-nvim # Shortcut Helper
# ------------------ # ------------------
# --- Theme / UI --- # --- Theme / UI ---
# ------------------ # ------------------
catppuccin-nvim # Theme
lualine-nvim # Bottom Line lualine-nvim # Bottom Line
noice-nvim # UI Tweaks noice-nvim # UI Tweaks
# nord-nvim # Theme
# melange-nvim # Theme
catppuccin-nvim # Theme
nvim-notify # Noice Dependency nvim-notify # Noice Dependency
nvim-web-devicons # Dev Icons nvim-web-devicons # Dev Icons
@@ -75,83 +78,58 @@ in
nvim-dap-go nvim-dap-go
nvim-dap-ui nvim-dap-ui
# --------------------
# -- CODE COMPANION --
# --------------------
(pkgs.vimUtils.buildVimPlugin {
pname = "codecompanion.nvim";
version = "2025-12-20";
src = pkgs.fetchFromGitHub {
owner = "olimorris";
repo = "codecompanion.nvim";
rev = "a226ca071ebc1d8b5ae1f70800fa9cf4a06a2101";
sha256 = "sha256-F1nI7q98SPpDjlwPvGy/qFuHvlT1FrbQPcjWrBwLaHU=";
};
doCheck = false;
meta.homepage = "https://github.com/olimorris/codecompanion.nvim/";
meta.hydraPlatforms = [ ];
})
# -------------------- # --------------------
# -- NONE-LS EXTRAS -- # -- NONE-LS EXTRAS --
# -------------------- # --------------------
( (pkgs.vimUtils.buildVimPlugin {
pkgs.vimUtils.buildVimPlugin { pname = "none-ls-extras.nvim";
pname = "none-ls-extras.nvim"; version = "2025-10-28";
version = "2024-06-11"; src = pkgs.fetchFromGitHub {
src = pkgs.fetchFromGitHub { owner = "nvimtools";
owner = "nvimtools"; repo = "none-ls-extras.nvim";
repo = "none-ls-extras.nvim"; rev = "402c6b5c29f0ab57fac924b863709f37f55dc298";
rev = "336e84b9e43c0effb735b08798ffac382920053b"; sha256 = "sha256-4s/xQNWNA4dgb5gZR4Xqn6zDDWrSJNtmHOmmjmYnN/8=";
sha256 = "sha256-UtU4oWSRTKdEoMz3w8Pk95sROuo3LEwxSDAm169wxwk="; };
}; doCheck = false;
meta.homepage = "https://github.com/nvimtools/none-ls-extras.nvim/"; meta.homepage = "https://github.com/nvimtools/none-ls-extras.nvim/";
} })
)
# -------------------
# ----- Silicon -----
# -------------------
(
pkgs.vimUtils.buildVimPlugin {
pname = "silicon.lua";
version = "2022-12-03";
src = pkgs.fetchFromGitHub {
owner = "mhanberg";
repo = "silicon.lua";
rev = "5ca462bee0a39b058786bc7fbeb5d16ea49f3a23";
sha256 = "0vlp645d5mmii513v72jca931miyrhkvhwb9bfzhix1199zx7vi2";
};
meta.homepage = "https://github.com/mhanberg/silicon.lua/";
}
)
# -------------------
# ------- LLM -------
# -------------------
(
pkgs.vimUtils.buildVimPlugin {
pname = "llm.nvim";
version = "2024-05-25";
src = pkgs.fetchFromGitHub {
owner = "David-Kunz";
repo = "gen.nvim";
rev = "bd19cf584b5b82123de977b44105e855e61e5f39";
sha256 = "sha256-0AEB6im8Jz5foYzmL6KEGSAYo48g1bkFpjlCSWT6JeE=";
};
meta.homepage = "https://github.com/David-Kunz/gen.nvim/";
}
)
# ------------------- # -------------------
# ---- LLAMA.VIM ---- # ---- LLAMA.VIM ----
# ------------------- # -------------------
( (pkgs.vimUtils.buildVimPlugin {
pkgs.vimUtils.buildVimPlugin { pname = "llama.vim";
pname = "llama.vim"; version = "2025-10-28";
version = "2025-01-23"; src = pkgs.fetchFromGitHub {
src = pkgs.fetchFromGitHub { owner = "ggml-org";
owner = "ggml-org"; repo = "llama.vim";
repo = "llama.vim"; rev = "ade8966eff57dcbe4a359dd26fb1ea97378ea03c";
rev = "143fe910b8d47a054ed464c38d8b7c17d5354468"; sha256 = "sha256-uPqOZLWKVMimhc9eG7yM5OmhJy3mTRgKsiqKhstWs4Y=";
sha256 = "sha256-PW0HKzhSxcZiWzpDOuy98rl/X0o2nE7tMjZjwwh0qLE="; };
}; meta.homepage = "https://github.com/ggml-org/llama.vim/";
meta.homepage = "https://github.com/ggml-org/llama.vim/"; })
}
)
]; ];
extraPackages = with pkgs; [ extraPackages = with pkgs; [
# Telescope Dependencies # LSP
fd eslint_d
ripgrep
tree-sitter
# LSP Dependencies
go go
golangci-lint golangci-lint
golangci-lint-langserver golangci-lint-langserver
@@ -164,17 +142,19 @@ in
nodePackages.typescript-language-server nodePackages.typescript-language-server
nodePackages.vscode-langservers-extracted nodePackages.vscode-langservers-extracted
pyright pyright
eslint_d python312Packages.autopep8
# Formatters # Formatters
luaformatter luaformatter
nixpkgs-fmt nixpkgs-fmt
nodePackages.prettier nodePackages.prettier
sqlfluff
stylua stylua
# Silicon # Tools
silicon ripgrep
lazygit
git
gh
]; ];
extraConfig = ":luafile ~/.config/nvim/lua/init.lua"; extraConfig = ":luafile ~/.config/nvim/lua/init.lua";
@@ -188,14 +168,20 @@ in
}; };
# Generate Nix Vars # Generate Nix Vars
# NOTE: https://github.com/NixOS/nixpkgs/issues/479348
# omnisharp = "${pkgs.omnisharp-roslyn}/bin/OmniSharp",
"nvim/lua/nix-vars.lua".text = '' "nvim/lua/nix-vars.lua".text = ''
local nix_vars = { local nix_vars = {
bash = "${pkgs.bashInteractive}/bin/bash",
clangd = "${pkgs.clang-tools}/bin/clangd",
golintls = "${pkgs.golangci-lint-langserver}/bin/golangci-lint-langserver",
gopls = "${pkgs.gopls}/bin/gopls", gopls = "${pkgs.gopls}/bin/gopls",
luals = "${pkgs.lua-language-server}/bin/lua-language-server", luals = "${pkgs.lua-language-server}/bin/lua-language-server",
sveltels = "${pkgs.nodePackages.svelte-language-server}/bin/svelteserver", sveltels = "${pkgs.nodePackages.svelte-language-server}/bin/svelteserver",
tsls = "${pkgs.nodePackages.typescript-language-server}/bin/typescript-language-server", tsls = "${pkgs.nodePackages.typescript-language-server}/bin/typescript-language-server",
golintls = "${pkgs.golangci-lint-langserver}/bin/golangci-lint-langserver",
vscls = "${pkgs.nodePackages.vscode-langservers-extracted}", vscls = "${pkgs.nodePackages.vscode-langservers-extracted}",
sqls = "${pkgs.sqls}/bin/sqls",
} }
return nix_vars return nix_vars
''; '';

View File

@@ -0,0 +1,65 @@
---
description: Creates and configures new OpenCode agents based on requirements
mode: subagent
temperature: 0.3
permission:
write: allow
---
You help users create custom OpenCode agents. When asked to create an agent:
1. **Understand the need**: Ask clarifying questions about:
- What tasks should this agent handle?
- Should it be primary or subagent?
- What tools does it need access to?
- Any special permissions or restrictions?
- Should it use a specific model?
2. **Generate the config**: Create a markdown file in the appropriate location:
- Global: `~/.config/opencode/agent/`
- Project: `.opencode/agent/`
3. **Available config options**:
- `description` (required): Brief description of agent purpose
- `mode`: "primary", "subagent", or "all" (defaults to "all")
- `temperature`: 0.0-1.0 (lower = focused, higher = creative)
- `maxSteps`: Limit agentic iterations
- `disable`: Set to true to disable agent
- `tools`: Control tool access (write, edit, bash, etc.)
- `permission`: Set to "ask", "allow", or "deny" for edit/bash/webfetch
- Additional provider-specific options pass through to the model
4. **Tools configuration**:
- Set individual tools: `write: true`, `bash: false`
- Use wildcards: `mymcp_*: false`
- Inherits from global config, agent config overrides
5. **Permissions** (for edit, bash, webfetch):
- `ask`: Prompt before running
- `allow`: Run without approval
- `deny`: Disable completely
- Can set per-command for bash: `"git push": "ask"`
6. **Keep it simple**: Start minimal, users can extend later.
7. **Explain usage**: Tell them how to invoke with `@agent-name`.
Example structure:
```markdown
---
description: [one-line purpose]
mode: subagent
model: anthropic/claude-sonnet-4-20250514
temperature: 0.2
tools:
write: false
bash: false
permission:
edit: deny
---
[Clear instructions for the agent's behavior]
```
Be conversational. Ask questions before generating.

View File

@@ -0,0 +1,51 @@
---
description: Implements code from plans and review feedback
mode: subagent
temperature: 0.3
permission:
"*": deny
bash: allow
context7_*: allow
edit: allow
glob: allow
grep: allow
list: allow
lsp: allow
read: allow
todoread: allow
todowrite: allow
---
You implement code. You're the only agent that modifies files.
**Input:**
- Plan file path from @planner
- Optional: Review feedback from @reviewer
**Workflow:**
1. Read the plan file
2. Read the specific files/lines mentioned in context maps
3. Read incrementally if needed (imports, function definitions, etc.)
4. Implement changes and accompanying tests
5. Commit:
```bash
git add -A
git commit -m "type: description"
```
Types: `feat`, `fix`, `refactor`, `docs`, `test`, `chore`
**Testing Requirements:**
- All tests must pass before committing
- Never ignore or skip failing tests
- If tests fail: either fix the code or fix the test
- Run tests after implementation to verify
**Rules:**
- Trust the plan - don't re-analyze or re-plan
- Start with context map locations, expand only as needed
- Fix all critical/regular findings, use judgment on nits
- Stop reading once you understand the change

View File

@@ -0,0 +1,37 @@
---
description: Orchestrates development by delegating to subagents
mode: primary
temperature: 0.2
maxSteps: 50
permission:
"*": deny
task:
"*": deny
planner: allow
developer: allow
reviewer: allow
---
You orchestrate development by delegating to subagents. Never code yourself.
**Subagents:**
- **@planner** - Creates implementation plans in `./plans/`
- **@developer** - Implements from plan files
- **@reviewer** - Reviews implementations
**Workflow:**
1. **Plan**: Call @planner with requirements
2. **Review Plan**: Show user the plan path, ask for approval
3. **Develop**: Call @developer with plan file path
4. **Review Code**: Call @reviewer with implementation
5. **Iterate**: If NEEDS_WORK, call @developer with plan + feedback
6. **Done**: When APPROVED or APPROVED_WITH_NITS
**Rules:**
- Always pass plan file path to @developer (not plan content)
- Include review feedback on iterations
- Nits are optional - ask user if they want them fixed
- Keep user informed of current step

View File

@@ -0,0 +1,100 @@
---
description: Explores codebase and breaks features into ordered implementation tasks. Writes plans to ./plans/
mode: subagent
temperature: 0.3
permission:
"*": deny
context7_*: allow
edit: allow
glob: allow
grep: allow
list: allow
lsp: allow
read: allow
---
# Code Task Planner Agent
You are a code analysis agent that breaks down feature requests into implementable, independent tasks.
## Your Task
1. **Analyze the codebase** using available tools (grep, lsp, read, etc.)
2. **Identify dependencies** between components
3. **Create ordered tasks** where each task can be implemented independently
4. **Generate context maps** showing exact files and line numbers that need changes
5. **Write the plan** to `./plans/<PLAN_NAME>.md`
## Task Requirements
- **Independent**: Each task should be implementable without future tasks
- **Hierarchical**: Dependencies must come before dependents
- **Specific**: Include exact file paths and line numbers
- **Contextual**: Explain WHY each file matters (1-2 lines max)
## Output Format
Write to `./plans/<PLAN_NAME>.md` with this structure:
```markdown
# Plan: <PLAN_NAME>
## Feature Overview
<feature summary>
## Implementation Tasks
### Task 1: <Descriptive Title>
**Context Map:**
- `<file_path>:<line_number>` - <why it's relevant or what changes>
- `<file_path>:<line_number>` - <why it's relevant or what changes>
---
### Task 2: <Descriptive Title>
**Context Map:**
- `<file_path>:<line_number>` - <why it's relevant or what changes>
---
```
## Analysis Strategy
1. **Start with interfaces/contracts** - these are foundational
2. **Then implementations** - concrete types that satisfy interfaces
3. **Then handlers/controllers** - code that uses the implementations
4. **Finally integrations** - wiring everything together
## Context Map Guidelines
- Use exact line numbers from actual code analysis
- Be specific: "Add AddChat method" not "modify file"
- Include both new additions AND modifications to existing code
- If a file doesn't exist yet, use line 0 and note "new file"
## Example
```markdown
### Task 1: Add Store Interface Methods
**Context Map:**
- `./internal/store/interface.go:15` - Add Conversation struct definition
- `./internal/store/interface.go:28` - Add AddConversation method to Store interface
- `./internal/store/interface.go:32` - Add AddMessage method to Store interface
```
Remember: The context map is what developers see FIRST, so make it count!
## Completion
After writing the plan file, respond with:
**Plan created:** `<PLAN_NAME>`
**Path:** `./plans/<PLAN_NAME>.md`
**Tasks:** <number of tasks>

View File

@@ -0,0 +1,54 @@
---
description: Reviews implementations and provides structured feedback
mode: subagent
temperature: 0.2
permission:
"*": deny
bash:
"*": deny
"git diff *": allow
"git log *": allow
"git show *": allow
"git show": allow
"git status *": allow
"git status": allow
glob: allow
grep: allow
list: allow
lsp: allow
read: allow
---
You review code implementations.
**Process:**
1. Check `git status` - if uncommitted changes, stop and tell @developer to commit
2. Review latest commit with `git show`
3. Read full files only if needed for context
4. Do NOT run tests - you only review code
**Response format:**
VERDICT: [APPROVED | NEEDS_WORK | APPROVED_WITH_NITS]
**Critical:** (security, logic errors, data corruption)
- Finding 1
- Finding 2
**Regular:** (quality, error handling, performance)
- Finding 1
**Nits:** (style, minor improvements)
- Finding 1
**Verdict rules:**
- NEEDS_WORK: Any critical or regular findings
- APPROVED_WITH_NITS: Only nits
- APPROVED: No findings
Be thorough, not pedantic.

View File

@@ -0,0 +1,42 @@
---
description: Create a conventional commit from git changes
agent: build
---
Run git commands to ensure all changes are staged, then generate a conventional commit message based on the diff and create the commit.
Steps:
1. Add all files (including untracked) using `git add -A`
2. Show the current diff with `git diff --cached` and `git diff --staged`
3. Analyze the changes and create a conventional commit message following the format:
- Type (feat, fix, docs, style, refactor, test, chore, etc.)
- Scope (optional, e.g., "runtime", "functions")
- Subject (brief description, imperative mood)
- Body (detailed explanation, optional)
4. Execute `git commit -m "message"` with the generated message
5. Show the commit result with `git log -1 --stat`
Conventional commit format:
```
<type>(<scope>): <subject>
<body>
<footer>
```
Common types:
- feat: New feature
- fix: Bug fix
- docs: Documentation changes
- style: Code style changes (formatting, semicolons, etc.)
- refactor: Code refactoring (neither bug fix nor feature)
- test: Adding or updating tests
- chore: Maintenance tasks
- perf: Performance improvements
- ci: CI/CD changes
- build: Build system or dependencies
- revert: Revert a previous commit

View File

@@ -0,0 +1,83 @@
{ lib
, pkgs
, config
, namespace
, ...
}:
let
inherit (lib) mkIf;
helpers = import ./lib.nix { inherit lib; };
llamaSwapConfig = import ./../../../../nixos/services/llama-swap/config.nix { inherit pkgs; };
cfg = config.${namespace}.programs.terminal.opencode;
in
{
options.${namespace}.programs.terminal.opencode = {
enable = lib.mkEnableOption "enable opencode";
};
config = mkIf cfg.enable {
# Enable OpenCode
programs.opencode = {
enable = true;
package = pkgs.reichard.opencode;
enableMcpIntegration = true;
agents = {
orchestrator = ./config/agents/orchestrator.md;
planner = ./config/agents/planner.md;
developer = ./config/agents/developer.md;
reviewer = ./config/agents/reviewer.md;
agent-creator = ./config/agents/agent-creator.md;
};
commands = {
commit = ./config/commands/commit.md;
};
};
# Define OpenCode Configuration
sops = {
secrets.context7_apikey = {
sopsFile = lib.snowfall.fs.get-file "secrets/common/evanreichard.yaml";
};
templates."opencode.json" = {
path = "${config.home.homeDirectory}/.config/opencode/opencode.json";
content = builtins.toJSON {
"$schema" = "https://opencode.ai/config.json";
theme = "catppuccin";
provider = {
"llama-swap" = {
npm = "@ai-sdk/openai-compatible";
options = {
baseURL = "https://llm-api.va.reichard.io/v1";
};
models = helpers.toOpencodeModels llamaSwapConfig;
};
};
lsp = {
biome = {
disabled = true;
};
starlark = {
command = [
"${pkgs.pyright}/bin/pyright-langserver"
"--stdio"
];
extensions = [ ".star" ];
};
};
mcp = {
context7 = {
type = "remote";
url = "https://mcp.context7.com/mcp";
headers = {
CONTEXT7_API_KEY = "${config.sops.placeholder.context7_apikey}";
};
enabled = true;
};
};
};
};
};
};
}

View File

@@ -0,0 +1,51 @@
{ lib }:
let
inherit (lib)
mapAttrs
filterAttrs
any
flatten
listToAttrs
nameValuePair
;
in
{
# Convert llama-swap models to opencode format
toOpencodeModels =
llamaSwapConfig:
let
textGenModels = filterAttrs (name: model: any (t: t == "coding") (model.metadata.type or [ ])) (
llamaSwapConfig.models or { }
);
localModels = mapAttrs
(
name: model:
{
inherit (model) name;
}
// (
if model.macros.ctx or null != null then
{
limit = {
context = lib.toInt model.macros.ctx;
input = lib.toInt model.macros.ctx;
output = lib.toInt model.macros.ctx;
};
}
else
{ }
)
)
textGenModels;
peerModels = listToAttrs (
flatten (
map (peer: map (modelName: nameValuePair modelName { name = modelName; }) peer.models) (
builtins.attrValues (llamaSwapConfig.peers or { })
)
)
);
in
localModels // peerModels;
}

View File

@@ -0,0 +1,33 @@
# AI Agent Guidelines
## Important Rules
1. **Timeout for bash tool**: The `bash` tool MUST have a timeout specified. Without a timeout, the tool will hang indefinitely and cause the task to fail.
2. **File writing**: Do NOT use `cat` with heredocs to write files. Use the `write` tool instead (or `edit` for modifications).
## Example of Correct Usage
### Incorrect (will hang):
```bash
bash(command="some long-running command")
```
### Correct (with timeout):
```bash
bash(command="some command", timeout=30)
```
### Incorrect (file writing):
```bash
bash(command="cat > file.txt << 'EOF'\ncontent\nEOF")
```
### Correct (file writing):
```bash
write(path="file.txt", content="content")
```

View File

@@ -0,0 +1,34 @@
---
description: Review staged git changes
---
**Process:**
1. Review staged changes with `git diff --cached`
2. Read full files only if needed for context
3. Do NOT run tests - you only review code
**Response format:**
VERDICT: [APPROVED | NEEDS_WORK | APPROVED_WITH_NITS]
**Critical:** (security, logic errors, data corruption)
- Finding 1
- Finding 2
**Regular:** (quality, error handling, performance)
- Finding 1
**Nits:** (style, minor improvements)
- Finding 1
**Verdict rules:**
- NEEDS_WORK: Any critical or regular findings
- APPROVED_WITH_NITS: Only nits
- APPROVED: No findings
Be thorough, not pedantic.

View File

@@ -0,0 +1,122 @@
---
name: git-commit
description: 'Execute git commit with conventional commit message analysis, intelligent staging, and message generation. Use when user asks to commit changes, create a git commit, or mentions "/commit". Supports: (1) Auto-detecting type and scope from changes, (2) Generating conventional commit messages from diff, (3) Interactive commit with optional type/scope/description overrides, (4) Intelligent file staging for logical grouping'
---
# Git Commit with Conventional Commits
## Overview
Create standardized, semantic git commits using the Conventional Commits specification. Analyze the actual diff to determine appropriate type, scope, and message.
## Conventional Commit Format
```
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
```
## Commit Types
| Type | Purpose |
| ---------- | ------------------------------ |
| `feat` | New feature |
| `fix` | Bug fix |
| `docs` | Documentation only |
| `style` | Formatting/style (no logic) |
| `refactor` | Code refactor (no feature/fix) |
| `perf` | Performance improvement |
| `test` | Add/update tests |
| `build` | Build system/dependencies |
| `ci` | CI/config changes |
| `chore` | Maintenance/misc |
| `revert` | Revert commit |
## Breaking Changes
```
# Exclamation mark after type/scope
feat!: remove deprecated endpoint
# BREAKING CHANGE footer
feat: allow config to extend other configs
BREAKING CHANGE: `extends` key behavior changed
```
## Workflow
### 1. Analyze Diff
```bash
# If files are staged, use staged diff
git diff --staged
# If nothing staged, use working tree diff
git diff
# Also check status
git status --porcelain
```
### 2. Stage Files (if needed)
If nothing is staged or you want to group changes differently:
```bash
# Stage specific files
git add path/to/file1 path/to/file2
# Stage by pattern
git add *.test.*
git add src/components/*
# Interactive staging
git add -p
```
**Never commit secrets** (.env, credentials.json, private keys).
### 3. Generate Commit Message
Analyze the diff to determine:
- **Type**: What kind of change is this?
- **Scope**: What area/module is affected?
- **Description**: One-line summary of what changed (present tense, imperative mood, <72 chars)
### 4. Execute Commit
```bash
# Single line
git commit -m "<type>[scope]: <description>"
# Multi-line with body/footer
git commit -m "$(cat <<'EOF'
<type>[scope]: <description>
<optional body>
<optional footer>
EOF
)"
```
## Best Practices
- One logical change per commit
- Present tense: "add" not "added"
- Imperative mood: "fix bug" not "fixes bug"
- Reference issues: `Closes #123`, `Refs #456`
- Keep description under 72 characters
## Git Safety Protocol
- NEVER update git config
- NEVER run destructive commands (--force, hard reset) without explicit request
- NEVER skip hooks (--no-verify) unless user asks
- NEVER force push to main/master
- If commit fails due to hooks, fix and create NEW commit (don't amend)

View File

@@ -0,0 +1,53 @@
{ lib
, pkgs
, config
, namespace
, ...
}:
let
inherit (lib) mkIf;
helpers = import ./lib.nix { inherit lib; };
llamaSwapConfig = import ./../../../../nixos/services/llama-swap/config.nix { inherit pkgs; };
cfg = config.${namespace}.programs.terminal.pi;
in
{
options.${namespace}.programs.terminal.pi = {
enable = lib.mkEnableOption "enable pi";
};
config = mkIf cfg.enable {
# Add Pi Coding Agent to Home Packages
home.packages = with pkgs; [
reichard.pi-coding-agent
];
# Define Pi Configuration
home.file = {
".pi/agent/models.json" = {
text = builtins.toJSON {
providers = {
"llama-swap" = {
baseUrl = "https://llm-api.va.reichard.io/v1";
api = "openai-completions";
apiKey = "none";
models = helpers.toPiModels llamaSwapConfig;
};
};
};
};
".pi/agent/AGENTS.md" = {
source = ./config/AGENTS.md;
};
".pi/agent/skills" = {
source = ./config/skills;
recursive = true;
};
".pi/agent/prompts" = {
source = ./config/prompts;
recursive = true;
};
};
};
}

View File

@@ -0,0 +1,58 @@
{ lib }:
let
inherit (lib)
mapAttrs
filterAttrs
any
flatten
listToAttrs
nameValuePair
;
in
{
toPiModels =
llamaSwapConfig:
let
textGenModels = filterAttrs (name: model: any (t: t == "coding") (model.metadata.type or [ ])) (
llamaSwapConfig.models or { }
);
localModels = mapAttrs
(
name: model:
{
id = name;
inherit (model) name;
}
// (
if model.macros.ctx or null != null then
{
contextWindow = lib.toInt model.macros.ctx;
}
else
{ }
)
)
textGenModels;
peerModels = listToAttrs (
flatten (
map
(
peer:
map
(
modelName:
nameValuePair modelName {
id = modelName;
name = modelName;
}
)
peer.models
)
(builtins.attrValues (llamaSwapConfig.peers or { }))
)
);
in
builtins.attrValues (localModels // peerModels);
}

View File

@@ -0,0 +1,67 @@
{ lib
, pkgs
, config
, namespace
, ...
}:
let
inherit (lib) mkIf;
cfg = config.${namespace}.programs.terminal.tmux;
in
{
options.${namespace}.programs.terminal.tmux = {
enable = lib.mkEnableOption "tmux";
};
config = mkIf cfg.enable {
programs.tmux = {
enable = true;
clock24 = true;
plugins = with pkgs.tmuxPlugins; [
{
plugin = catppuccin;
extraConfig = ''
set -g @catppuccin_flavor "mocha"
set -g @catppuccin_status_background "none"
# Style & Separators
set -g @catppuccin_window_status_style "basic"
set -g @catppuccin_status_left_separator ""
set -g @catppuccin_status_middle_separator ""
set -g @catppuccin_status_right_separator ""
# Window Titles
set -g @catppuccin_window_text " #W"
set -g @catppuccin_window_current_text " #W"
'';
}
cpu
yank
];
extraConfig = ''
# Misc Settings
set -g status-position top
set -g mouse on
setw -g mode-keys vi
set -ag terminal-overrides ",xterm-256color:Tc:Ms=\\E]52;c%p1%.0s;%p2%s\\7"
# Start Index 1
set -g base-index 1
setw -g pane-base-index 1
set -g renumber-windows on
# Maintain Directory
bind '"' split-window -c "#{pane_current_path}"
bind % split-window -h -c "#{pane_current_path}"
bind c new-window -c "#{pane_current_path}"
# Theme
set -g status-left ""
set -g status-right ""
set -ag status-right "#{E:@catppuccin_status_host}"
'';
};
};
}

View File

@@ -0,0 +1,37 @@
{ config
, lib
, namespace
, pkgs
, ...
}:
let
inherit (lib) mkIf mkEnableOption types;
inherit (lib.${namespace}) mkOpt;
getFile = lib.snowfall.fs.get-file;
cfg = config.${namespace}.security.sops;
in
{
options.${namespace}.security.sops = with types; {
enable = mkEnableOption "Enable sops";
defaultSopsFile = mkOpt str "secrets/common/evanreichard.yaml" "Default sops file.";
sshKeyPaths = mkOpt (listOf path) [ ] "Additional SSH key paths to use.";
};
config = mkIf cfg.enable {
home.packages = with pkgs; [
age
sops
ssh-to-age
];
sops = {
defaultSopsFile = getFile cfg.defaultSopsFile;
age = {
keyFile = "${config.home.homeDirectory}/.config/sops/age/keys.txt";
sshKeyPaths = [ "${config.home.homeDirectory}/.ssh/id_ed25519" ] ++ cfg.sshKeyPaths;
};
};
};
}

View File

@@ -0,0 +1,17 @@
{ config, lib, namespace, ... }:
let
inherit (lib) mkIf;
cfg = config.${namespace}.services.poweralertd;
in
{
options.${namespace}.services.poweralertd = {
enable = lib.mkEnableOption "poweralertd";
};
config = mkIf cfg.enable {
services.poweralertd = {
enable = true;
};
};
}

View File

@@ -1,41 +0,0 @@
{ config, lib, namespace, pkgs, ... }:
let
inherit (lib) mkIf types;
inherit (lib.${namespace}) mkOpt;
cfg = config.${namespace}.services.sops;
in
{
options.${namespace}.services.sops = with types; {
enable = lib.mkEnableOption "sops";
defaultSopsFile = mkOpt path null "Default sops file.";
sshKeyPaths = mkOpt (listOf path) [ ] "SSH Key paths to use.";
};
config = mkIf cfg.enable {
home.packages = with pkgs; [
age
sops
ssh-to-age
];
sops = {
inherit (cfg) defaultSopsFile;
defaultSopsFormat = "yaml";
age = {
generateKey = true;
keyFile = "${config.home.homeDirectory}/.config/sops/age/keys.txt";
sshKeyPaths = [ "${config.home.homeDirectory}/.ssh/id_ed25519" ] ++ cfg.sshKeyPaths;
};
# TODO
# secrets = {
# nix = {
# sopsFile = lib.snowfall.fs.get-file "secrets/default.yaml";
# path = "${config.home.homeDirectory}/.config/nix/nix.conf";
# };
# };
};
};
}

View File

@@ -1,4 +1,9 @@
{ config, lib, pkgs, namespace, ... }: { config
, lib
, pkgs
, namespace
, ...
}:
let let
cfg = config.${namespace}.services.swww; cfg = config.${namespace}.services.swww;
in in

View File

@@ -0,0 +1,6 @@
{ pkgs, ... }:
{
environment.systemPackages = with pkgs; [
wget
];
}

View File

@@ -1,4 +1,9 @@
{ config, lib, pkgs, namespace, ... }: { config
, lib
, pkgs
, namespace
, ...
}:
let let
inherit (lib) mkIf types; inherit (lib) mkIf types;
inherit (lib.${namespace}) mkOpt; inherit (lib.${namespace}) mkOpt;
@@ -17,7 +22,7 @@ in
sddm = { sddm = {
inherit (cfg) enable; inherit (cfg) enable;
package = pkgs.kdePackages.sddm; package = pkgs.kdePackages.sddm;
theme = "catppuccin-mocha"; theme = "catppuccin-mocha-mauve";
wayland.enable = true; wayland.enable = true;
}; };
}; };

View File

@@ -1,7 +1,7 @@
{ config, lib, inputs, namespace, ... }: { config, lib, inputs, namespace, ... }:
let let
inherit (lib) types optionalAttrs; inherit (lib) types optionalAttrs;
inherit (lib.${namespace}) mkOpt mkBoolOpt; inherit (lib.${namespace}) mkOpt;
cfg = config.${namespace}.hardware.asahi; cfg = config.${namespace}.hardware.asahi;
in in
@@ -12,7 +12,6 @@ in
options.${namespace}.hardware.asahi = { options.${namespace}.hardware.asahi = {
enable = lib.mkEnableOption "support for asahi linux"; enable = lib.mkEnableOption "support for asahi linux";
enableGPU = mkBoolOpt false "enable gpu driver";
firmwareDirectory = mkOpt types.path null "firmware directory"; firmwareDirectory = mkOpt types.path null "firmware directory";
}; };
@@ -21,7 +20,6 @@ in
enable = cfg.enable; enable = cfg.enable;
} // optionalAttrs cfg.enable { } // optionalAttrs cfg.enable {
peripheralFirmwareDirectory = cfg.firmwareDirectory; peripheralFirmwareDirectory = cfg.firmwareDirectory;
useExperimentalGPUDriver = cfg.enableGPU;
}; };
}; };
} }

View File

@@ -0,0 +1,15 @@
{ config, lib, namespace, ... }:
let
inherit (lib) mkIf;
cfg = config.${namespace}.hardware.battery.upower;
in
{
options.${namespace}.hardware.battery.upower = {
enable = lib.mkEnableOption "enable upower";
};
config = mkIf cfg.enable {
services.upower.enable = true;
};
}

View File

@@ -1,4 +1,9 @@
{ config, lib, pkgs, namespace, ... }: { config
, lib
, pkgs
, namespace
, ...
}:
let let
inherit (lib) mkIf mkForce; inherit (lib) mkIf mkForce;
inherit (lib.${namespace}) mkBoolOpt; inherit (lib.${namespace}) mkBoolOpt;
@@ -14,14 +19,25 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
environment.systemPackages = with pkgs; [ services.xserver.videoDrivers = mkIf cfg.enableNvidia [ "nvidia" ];
libva-utils
vdpauinfo environment.systemPackages =
] ++ lib.optionals cfg.enableNvidia [ with pkgs;
nvtopPackages.full [
] ++ lib.optionals cfg.enableIntel [ libva-utils
intel-gpu-tools vdpauinfo
]; ]
++ lib.optional cfg.enableNvidia nvtopPackages.nvidia
++ lib.optional cfg.enableIntel nvtopPackages.intel;
# Enable Nvidia Hardware
hardware.nvidia = mkIf cfg.enableNvidia {
package = config.boot.kernelPackages.nvidiaPackages.stable;
modesetting.enable = true;
powerManagement.enable = true;
open = false;
nvidiaSettings = true;
};
# Add Intel Arc / Nvidia Drivers # Add Intel Arc / Nvidia Drivers
hardware.enableRedistributableFirmware = mkIf cfg.enableIntel (mkForce true); hardware.enableRedistributableFirmware = mkIf cfg.enableIntel (mkForce true);
@@ -29,14 +45,16 @@ in
enable = true; enable = true;
enable32Bit = cfg.enable32Bit; enable32Bit = cfg.enable32Bit;
extraPackages = with pkgs; extraPackages =
with pkgs;
lib.optionals cfg.enableIntel [ lib.optionals cfg.enableIntel [
libvdpau-va-gl libvdpau-va-gl
intel-vaapi-driver intel-vaapi-driver
intel-media-driver intel-media-driver
intel-compute-runtime intel-compute-runtime
intel-ocl intel-ocl
] ++ lib.optionals cfg.enableNvidia [ ]
++ lib.optionals cfg.enableNvidia [
cudatoolkit cudatoolkit
]; ];
}; };

View File

@@ -1,4 +1,4 @@
{ config, lib, namespace, ... }: { config, pkgs, lib, namespace, ... }:
let let
inherit (lib) mkIf; inherit (lib) mkIf;
@@ -17,6 +17,10 @@ in
}; };
}; };
environment.systemPackages = with pkgs; [
wl-clipboard
];
reichard = { reichard = {
display-managers = { display-managers = {
sddm = { sddm = {

View File

@@ -1,31 +1,39 @@
{ config, lib, namespace, ... }: { config
, lib
, namespace
, ...
}:
let let
inherit (lib) mkIf mkEnableOption types;
inherit (lib.${namespace}) mkOpt; inherit (lib.${namespace}) mkOpt;
getFile = lib.snowfall.fs.get-file;
user = config.users.users.${config.${namespace}.user.name};
cfg = config.${namespace}.security.sops; cfg = config.${namespace}.security.sops;
in in
{ {
options.${namespace}.security.sops = { options.${namespace}.security.sops = with types; {
enable = lib.mkEnableOption "sops"; enable = mkEnableOption "Enable sops";
defaultSopsFile = mkOpt lib.types.path null "Default sops file."; defaultSopsFile = mkOpt str "secrets/systems/${config.system.name}.yaml" "Default sops file.";
sshKeyPaths = mkOpt (with lib.types; listOf path) [ sshKeyPaths = mkOpt (listOf path) [ ] "Additional SSH key paths to use.";
# "/etc/ssh/ssh_host_ed25519_key"
] "SSH Key paths to use.";
}; };
config = lib.mkIf cfg.enable { config = mkIf cfg.enable {
sops = { sops = {
inherit (cfg) defaultSopsFile; defaultSopsFile = getFile cfg.defaultSopsFile;
age = { age = {
inherit (cfg) sshKeyPaths; keyFile = "${user.home}/.config/sops/age/keys.txt";
sshKeyPaths = [
keyFile = "${config.users.users.${config.${namespace}.user.name}.home}/.config/sops/age/keys.txt"; "/etc/ssh/ssh_host_ed25519_key"
"${user.home}/.ssh/id_ed25519"
]
++ cfg.sshKeyPaths;
}; };
}; };
sops.secrets.builder_ssh_key = { sops.secrets.builder_ssh_key = {
sopsFile = lib.snowfall.fs.get-file "secrets/default.yaml"; sopsFile = getFile "secrets/common/systems.yaml";
}; };
}; };
} }

View File

@@ -0,0 +1,51 @@
{ config, lib, namespace, ... }:
let
inherit (lib) mkIf mkEnableOption;
cfg = config.${namespace}.services.headscale;
inherit (lib.${namespace}) mkBoolOpt;
in
{
options.${namespace}.services.headscale = {
enable = mkEnableOption "enable headscale service";
openFirewall = mkBoolOpt false "Open firewall";
};
options.services.headscale.settings.dns.nameservers.split = lib.mkOption {
type = lib.types.attrsOf (lib.types.listOf lib.types.str);
default = { };
description = ''
Split DNS configuration mapping domains to specific nameservers.
Each key is a domain suffix, and the value is a list of nameservers
to use for that domain.
'';
example = {
"internal.company.com" = [ "10.0.0.1" "10.0.0.2" ];
"dev.local" = [ "192.168.1.1" ];
};
};
config = mkIf cfg.enable {
services.headscale = {
enable = true;
address = "0.0.0.0";
settings = {
server_url = "https://headscale.reichard.io";
dns = {
base_domain = "reichard.dev";
nameservers = {
global = [
"9.9.9.9"
];
split = {
"va.reichard.io" = [ "10.0.20.20" ];
};
};
};
};
};
networking.firewall = mkIf cfg.openFirewall {
allowedTCPPorts = [ 8080 ];
};
};
}

View File

@@ -0,0 +1,463 @@
{ pkgs }:
let
llama-cpp = pkgs.reichard.llama-cpp;
stable-diffusion-cpp = pkgs.reichard.stable-diffusion-cpp.override {
cudaSupport = true;
};
in
{
models = {
# https://huggingface.co/unsloth/GLM-4.7-Flash-GGUF/tree/main
"glm-4.7-flash" = {
name = "GLM 4.7 Flash (30B) - Thinking";
macros.ctx = "131072";
cmd = ''
${llama-cpp}/bin/llama-server \
--port ''${PORT} \
-m /mnt/ssd/Models/GLM/GLM-4.7-Flash-UD-Q6_K_XL.gguf \
-c ''${ctx} \
--temp 0.7 \
--top-p 1.0 \
--min-p 0.01 \
--repeat-penalty 1.0 \
-fit off \
-ts 70,30
'';
metadata = {
type = [
"text-generation"
"coding"
];
};
};
# https://huggingface.co/unsloth/Devstral-Small-2-24B-Instruct-2512-GGUF/tree/main
"devstral-small-2-instruct" = {
name = "Devstral Small 2 (24B) - Instruct";
macros.ctx = "131072";
cmd = ''
${llama-cpp}/bin/llama-server \
--port ''${PORT} \
-m /mnt/ssd/Models/Devstral/Devstral-Small-2-24B-Instruct-2512-UD-Q6_K_XL.gguf \
--temp 0.15 \
-c ''${ctx} \
-ctk q8_0 \
-ctv q8_0 \
-fit off \
-ts 75,25
'';
metadata = {
type = [
"text-generation"
"coding"
];
};
};
# https://huggingface.co/unsloth/GLM-4-32B-0414-GGUF/tree/main
"glm-4-32b-instruct" = {
name = "GLM 4 (32B) - Instruct";
macros.ctx = "32768";
cmd = ''
${llama-cpp}/bin/llama-server \
--port ''${PORT} \
-m /mnt/ssd/Models/GLM/GLM-4-32B-0414-Q4_K_M.gguf \
-c ''${ctx} \
--temp 0.6 \
--top-k 40 \
--top-p 0.95 \
--min-p 0.0 \
-fit off \
-dev CUDA0
'';
metadata = {
type = [ "text-generation" ];
};
};
# https://huggingface.co/mradermacher/gpt-oss-20b-heretic-v2-i1-GGUF/tree/main
"gpt-oss-20b-thinking" = {
name = "GPT OSS (20B) - Thinking";
macros.ctx = "131072";
cmd = ''
${llama-cpp}/bin/llama-server \
--port ''${PORT} \
-m /mnt/ssd/Models/GPT-OSS/gpt-oss-20b-heretic-v2.i1-MXFP4_MOE.gguf \
-c ''${ctx} \
--temp 1.0 \
--top-p 1.0 \
--top-k 40 \
-dev CUDA0
'';
metadata = {
type = [ "text-generation" ];
};
};
# https://huggingface.co/mradermacher/GPT-OSS-Cybersecurity-20B-Merged-i1-GGUF/tree/main
"gpt-oss-csec-20b-thinking" = {
name = "GPT OSS CSEC (20B) - Thinking";
macros.ctx = "131072";
cmd = ''
${llama-cpp}/bin/llama-server \
--port ''${PORT} \
-m /mnt/ssd/Models/GPT-OSS/GPT-OSS-Cybersecurity-20B-Merged.i1-MXFP4_MOE.gguf \
-c ''${ctx} \
--temp 1.0 \
--top-p 1.0 \
--top-k 40 \
-dev CUDA0
'';
metadata = {
type = [ "text-generation" ];
};
};
# https://huggingface.co/unsloth/Qwen3-Next-80B-A3B-Instruct-GGUF/tree/main
"qwen3-next-80b-instruct" = {
name = "Qwen3 Next (80B) - Instruct";
macros.ctx = "262144";
cmd = ''
${llama-cpp}/bin/llama-server \
--port ''${PORT} \
-m /mnt/ssd/Models/Qwen3/Qwen3-Next-80B-A3B-Instruct-UD-Q2_K_XL.gguf \
-c ''${ctx} \
--temp 0.7 \
--min-p 0.0 \
--top-p 0.8 \
--top-k 20 \
--repeat-penalty 1.05 \
-ctk q8_0 \
-ctv q8_0 \
-fit off
'';
metadata = {
type = [
"text-generation"
"coding"
];
};
};
# https://huggingface.co/unsloth/Qwen3-Coder-Next-GGUF/tree/main
"qwen3-coder-next-80b-instruct" = {
name = "Qwen3 Coder Next (80B) - Instruct";
macros.ctx = "131072";
cmd = ''
${llama-cpp}/bin/llama-server \
--port ''${PORT} \
-m /mnt/ssd/Models/Qwen3/Qwen3-Coder-Next-UD-Q4_K_XL.gguf \
-c ''${ctx} \
--temp 1.0 \
--top-p 0.95 \
--min-p 0.01 \
--top-k 40 \
-fit off \
-ncmoe 18 \
-ts 78,22
'';
metadata = {
type = [
"text-generation"
"coding"
];
};
};
# https://huggingface.co/AesSedai/Qwen3.5-35B-A3B-GGUF/tree/main
"qwen3.5-35b-thinking" = {
name = "Qwen3.5 (35B) - Thinking";
macros.ctx = "262144";
cmd = ''
${llama-cpp}/bin/llama-server \
--port ''${PORT} \
-m /mnt/ssd/Models/Qwen3.5/Qwen3.5-35B-A3B-IQ4_XS-00001-of-00002.gguf \
-c ''${ctx} \
--temp 0.6 \
--top-p 0.95 \
--top-k 20 \
--min-p 0.00 \
-dev CUDA0 \
-fit off
'';
# --chat-template-kwargs "{\"enable_thinking\": false}"
metadata = {
type = [
"text-generation"
"coding"
];
};
};
# https://huggingface.co/unsloth/Qwen3.5-27B-GGUF/tree/main
"qwen3.5-27b-thinking" = {
name = "Qwen3.5 (27B) - Thinking";
macros.ctx = "131072";
cmd = ''
${llama-cpp}/bin/llama-server \
--port ''${PORT} \
-m /mnt/ssd/Models/Qwen3.5/Qwen3.5-27B-UD-Q4_K_XL.gguf \
-c ''${ctx} \
--temp 0.6 \
--top-p 0.95 \
--top-k 20 \
--min-p 0.00 \
-fit off
'';
# --chat-template-kwargs "{\"enable_thinking\": false}"
metadata = {
type = [
"text-generation"
"coding"
];
};
};
# https://huggingface.co/unsloth/Qwen3-30B-A3B-Instruct-2507-GGUF/tree/main
"qwen3-30b-2507-instruct" = {
name = "Qwen3 2507 (30B) - Instruct";
macros.ctx = "262144";
cmd = ''
${llama-cpp}/bin/llama-server \
--port ''${PORT} \
-m /mnt/ssd/Models/Qwen3/Qwen3-30B-A3B-Instruct-2507-Q4_K_M.gguf \
-c ''${ctx} \
--temp 0.7 \
--min-p 0.0 \
--top-p 0.8 \
--top-k 20 \
--presence-penalty 1.0 \
--repeat-penalty 1.0 \
-ctk q8_0 \
-ctv q8_0 \
-ts 70,30 \
-fit off
'';
metadata = {
type = [ "text-generation" ];
};
};
# https://huggingface.co/unsloth/Qwen3-Coder-30B-A3B-Instruct-GGUF/tree/main
"qwen3-coder-30b-instruct" = {
name = "Qwen3 Coder (30B) - Instruct";
macros.ctx = "131072";
cmd = ''
${llama-cpp}/bin/llama-server \
--port ''${PORT} \
-m /mnt/ssd/Models/Qwen3/Qwen3-Coder-30B-A3B-Instruct-UD-Q6_K_XL.gguf \
-c ''${ctx} \
--temp 0.7 \
--min-p 0.0 \
--top-p 0.8 \
--top-k 20 \
--repeat-penalty 1.05 \
-ctk q8_0 \
-ctv q8_0 \
-ts 70,30 \
-fit off
'';
metadata = {
type = [
"text-generation"
"coding"
];
};
};
# https://huggingface.co/unsloth/Qwen3-30B-A3B-Thinking-2507-GGUF/tree/main
"qwen3-30b-2507-thinking" = {
name = "Qwen3 2507 (30B) - Thinking";
macros.ctx = "262144";
cmd = ''
${llama-cpp}/bin/llama-server \
--port ''${PORT} \
-m /mnt/ssd/Models/Qwen3/Qwen3-30B-A3B-Thinking-2507-UD-Q4_K_XL.gguf \
-c ''${ctx} \
--temp 0.6 \
--min-p 0.0 \
--top-p 0.95 \
--top-k 20 \
--presence-penalty 1.0 \
--repeat-penalty 1.0 \
-ctk q8_0 \
-ctv q8_0 \
-ts 70,30 \
-fit off
'';
metadata = {
type = [ "text-generation" ];
};
};
# https://huggingface.co/unsloth/Nemotron-3-Nano-30B-A3B-GGUF/tree/main
"nemotron-3-nano-30b-thinking" = {
name = "Nemotron 3 Nano (30B) - Thinking";
macros.ctx = "1048576";
cmd = ''
${llama-cpp}/bin/llama-server \
--port ''${PORT} \
-m /mnt/ssd/Models/Nemotron/Nemotron-3-Nano-30B-A3B-UD-Q4_K_XL.gguf \
-c ''${ctx} \
--temp 1.1 \
--top-p 0.95 \
-fit off
'';
metadata = {
type = [
"text-generation"
"coding"
];
};
};
# https://huggingface.co/unsloth/Qwen3-VL-8B-Instruct-GGUF/tree/main
"qwen3-8b-vision" = {
name = "Qwen3 Vision (8B) - Thinking";
macros.ctx = "65536";
cmd = ''
${llama-cpp}/bin/llama-server \
--port ''${PORT} \
-m /mnt/ssd/Models/Qwen3/Qwen3-VL-8B-Instruct-UD-Q4_K_XL.gguf \
--mmproj /mnt/ssd/Models/Qwen3/Qwen3-VL-8B-Instruct-UD-Q4_K_XL_mmproj-F16.gguf \
-c ''${ctx} \
--temp 0.7 \
--min-p 0.0 \
--top-p 0.8 \
--top-k 20 \
-ctk q8_0 \
-ctv q8_0 \
-fit off \
-dev CUDA1
'';
metadata = {
type = [ "text-generation" ];
};
};
# https://huggingface.co/unsloth/Qwen3-4B-Instruct-2507-GGUF/tree/main
"qwen3-4b-2507-instruct" = {
name = "Qwen3 2507 (4B) - Instruct";
macros.ctx = "98304";
cmd = ''
${llama-cpp}/bin/llama-server \
--port ''${PORT} \
-m /mnt/ssd/Models/Qwen3/Qwen3-4B-Instruct-2507-Q4_K_M.gguf \
-c ''${ctx} \
-fit off \
-ctk q8_0 \
-ctv q8_0 \
-dev CUDA1
'';
metadata = {
type = [ "text-generation" ];
};
};
# ---------------------------------------
# ---------- Stable Diffussion ----------
# ---------------------------------------
"z-image-turbo" = {
name = "Z-Image-Turbo";
checkEndpoint = "/";
cmd = ''
${stable-diffusion-cpp}/bin/sd-server \
--listen-port ''${PORT} \
--diffusion-fa \
--diffusion-model /mnt/ssd/StableDiffusion/ZImageTurbo/z-image-turbo-Q8_0.gguf \
--vae /mnt/ssd/StableDiffusion/ZImageTurbo/ae.safetensors \
--llm /mnt/ssd/Models/Qwen3/Qwen3-4B-Instruct-2507-Q4_K_M.gguf \
--cfg-scale 1.0 \
--steps 8 \
--rng cuda
'';
metadata = {
type = [ "image-generation" ];
};
};
"qwen-image-edit-2511" = {
name = "Qwen Image Edit 2511";
checkEndpoint = "/";
cmd = ''
${stable-diffusion-cpp}/bin/sd-server \
--listen-port ''${PORT} \
--diffusion-fa \
--qwen-image-zero-cond-t \
--diffusion-model /mnt/ssd/StableDiffusion/QwenImage/qwen-image-edit-2511-Q5_K_M.gguf \
--vae /mnt/ssd/StableDiffusion/QwenImage/qwen_image_vae.safetensors \
--llm /mnt/ssd/Models/Qwen2.5/Qwen2.5-VL-7B-Instruct.Q4_K_M.gguf \
--lora-model-dir /mnt/ssd/StableDiffusion/QwenImage/Loras \
--cfg-scale 2.5 \
--sampling-method euler \
--flow-shift 3 \
--steps 20 \
--rng cuda
'';
metadata = {
type = [
"image-edit"
"image-generation"
];
};
};
"qwen-image-2512" = {
name = "Qwen Image 2512";
checkEndpoint = "/";
cmd = ''
${stable-diffusion-cpp}/bin/sd-server \
--listen-port ''${PORT} \
--diffusion-fa \
--diffusion-model /mnt/ssd/StableDiffusion/QwenImage/qwen-image-2512-Q5_K_M.gguf \
--vae /mnt/ssd/StableDiffusion/QwenImage/qwen_image_vae.safetensors \
--llm /mnt/ssd/Models/Qwen2.5/Qwen2.5-VL-7B-Instruct.Q4_K_M.gguf \
--lora-model-dir /mnt/ssd/StableDiffusion/QwenImage/Loras \
--cfg-scale 2.5 \
--sampling-method euler \
--flow-shift 3 \
--steps 20 \
--rng cuda
'';
metadata = {
type = [ "image-generation" ];
};
};
"chroma-radiance" = {
name = "Chroma Radiance";
checkEndpoint = "/";
cmd = ''
${stable-diffusion-cpp}/bin/sd-server \
--listen-port ''${PORT} \
--diffusion-fa --chroma-disable-dit-mask \
--diffusion-model /mnt/ssd/StableDiffusion/Chroma/chroma_radiance_x0_q8.gguf \
--t5xxl /mnt/ssd/StableDiffusion/Chroma/t5xxl_fp16.safetensors \
--cfg-scale 4.0 \
--sampling-method euler \
--rng cuda
'';
metadata = {
type = [ "image-generation" ];
};
};
};
peers = {
synthetic = {
proxy = "https://api.synthetic.new/openai/";
models = [
"hf:MiniMaxAI/MiniMax-M2.1"
"hf:MiniMaxAI/MiniMax-M2.5"
"hf:moonshotai/Kimi-K2.5"
"hf:moonshotai/Kimi-K2-Instruct-0905"
"hf:moonshotai/Kimi-K2-Thinking"
"hf:openai/gpt-oss-120b"
"hf:Qwen/Qwen3.5-397B-A17B"
"hf:zai-org/GLM-4.7"
];
};
};
}

View File

@@ -0,0 +1,107 @@
{ config
, lib
, pkgs
, namespace
, ...
}:
let
inherit (lib) mkIf mkEnableOption recursiveUpdate;
cfg = config.${namespace}.services.llama-swap;
llama-swap = pkgs.reichard.llama-swap;
in
{
options.${namespace}.services.llama-swap = {
enable = mkEnableOption "enable llama-swap service";
config = lib.mkOption {
type = lib.types.unspecified;
default = import ./config.nix { inherit pkgs; };
readOnly = true;
description = "The llama-swap configuration data";
};
};
config = mkIf cfg.enable {
# Create User
users.groups.llama-swap = { };
users.users.llama-swap = {
isSystemUser = true;
group = "llama-swap";
};
# Create Service
systemd.services.llama-swap = {
description = "Model swapping for LLaMA C++ Server (or any local OpenAPI compatible server)";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "exec";
ExecStart = "${lib.getExe llama-swap} --listen :8080 --config ${
config.sops.templates."llama-swap.json".path
}";
Restart = "on-failure";
RestartSec = 3;
# for GPU acceleration
PrivateDevices = false;
# hardening
User = "llama-swap";
Group = "llama-swap";
CapabilityBoundingSet = "";
RestrictAddressFamilies = [
"AF_INET"
"AF_INET6"
"AF_UNIX"
];
NoNewPrivileges = true;
PrivateMounts = true;
PrivateTmp = true;
PrivateUsers = true;
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectSystem = "strict";
MemoryDenyWriteExecute = true;
LimitMEMLOCK = "infinity";
LockPersonality = true;
RemoveIPC = true;
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
SystemCallArchitectures = "native";
SystemCallFilter = [
"@system-service"
"~@privileged"
];
SystemCallErrorNumber = "EPERM";
ProtectProc = "invisible";
ProtectHostname = true;
ProcSubset = "pid";
};
};
# Create Config
sops = {
secrets.synthetic_apikey = {
sopsFile = lib.snowfall.fs.get-file "secrets/common/systems.yaml";
};
templates."llama-swap.json" = {
owner = "llama-swap";
group = "llama-swap";
mode = "0400";
content = builtins.toJSON (
recursiveUpdate cfg.config {
peers.synthetic.apiKey = config.sops.placeholder.synthetic_apikey;
}
);
};
};
networking.firewall.allowedTCPPorts = [ 8080 ];
};
}

View File

@@ -0,0 +1,18 @@
{ config, lib, namespace, ... }:
let
inherit (lib) mkIf;
cfg = config.${namespace}.services.mosh;
in
{
options.${namespace}.services.mosh = {
enable = lib.mkEnableOption "mosh support";
};
config = mkIf cfg.enable {
programs.mosh = {
enable = true;
openFirewall = true;
};
};
}

View File

@@ -0,0 +1,79 @@
{ config
, pkgs
, lib
, namespace
, ...
}:
let
inherit (lib) mkIf types mkEnableOption;
inherit (lib.${namespace}) mkOpt;
settingsFormat = pkgs.formats.yaml { };
cfg = config.${namespace}.services.octoprint;
in
{
options.${namespace}.services.octoprint = {
enable = mkEnableOption "Enable OctoPrint service";
openFirewall = mkEnableOption "Open firewall";
port = mkOpt types.port 5000 "Port to listen on";
settings = lib.mkOption {
type = lib.types.submodule { freeformType = settingsFormat.type; };
default = { };
description = ''
OctoPrint configuration. Refer to the [OctoPrint example configuration](https://docs.octoprint.org/en/main/configuration/config_yaml.html)
for details on supported values.
'';
};
};
config = mkIf cfg.enable {
# Create User
users.groups.octoprint = { };
users.users.octoprint = {
isSystemUser = true;
group = "octoprint";
extraGroups = [ "dialout" ];
};
# Create Service
systemd.services.octoprint =
let
# Merge Port
finalSettings = lib.recursiveUpdate cfg.settings {
server.port = cfg.port;
};
# Create Config
configFile = settingsFormat.generate "config.yaml" finalSettings;
in
{
description = "OctoPrint 3D Printing Service";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "exec";
ExecStartPre = pkgs.writeShellScript "setup-octoprint-config" ''
if [ ! -f /var/lib/octoprint/config.yaml ]; then
${pkgs.coreutils}/bin/cp ${configFile} /var/lib/octoprint/config.yaml
fi
'';
ExecStart = "${lib.getExe pkgs.octoprint} serve -b /var/lib/octoprint";
Restart = "on-failure";
RestartSec = 3;
StateDirectory = "octoprint";
WorkingDirectory = "/var/lib/octoprint";
Environment = "HOME=/var/lib/octoprint";
User = "octoprint";
Group = "octoprint";
SupplementaryGroups = [ "dialout" ];
PrivateDevices = false;
};
};
networking.firewall = lib.mkIf cfg.openFirewall { allowedTCPPorts = [ cfg.port ]; };
};
}

View File

@@ -1,4 +1,8 @@
{ config, lib, namespace, ... }: { config
, lib
, namespace
, ...
}:
let let
inherit (lib) inherit (lib)
types types
@@ -9,17 +13,18 @@ let
cfg = config.${namespace}.services.openssh; cfg = config.${namespace}.services.openssh;
authorizedKeys = [ globalKeys = [
# evanreichard@lin-va-mbp-personal "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILJJoyXQOv9cAjGUHrUcvsW7vY9W0PmuPMQSI9AMZvNY evanreichard@lin-va-mbp-personal"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILJJoyXQOv9cAjGUHrUcvsW7vY9W0PmuPMQSI9AMZvNY" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMWj6rd6uDtHj/gGozgIEgxho/vBKebgN5Kce/N6vQWV evanreichard@mac-va-mbp-personal"
# evanreichard@lin-va-thinkpad "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAq5JQr/6WJMIHhR434nK95FrDmf2ApW2Ahd2+cBKwDz evanreichard@lin-va-thinkpad"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAq5JQr/6WJMIHhR434nK95FrDmf2ApW2Ahd2+cBKwDz" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM5e6Cty+7rX5BjIEHBTU6GnzfOxPJiHpSqin/BnsypO evanreichard@lin-va-terminal"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIARTNbl4lgQsp7SJEng7vprL0+ChC9e6iR7o/PiC4Jme evanreichard@mobile"
]; ];
in in
{ {
options.${namespace}.services.openssh = with types; { options.${namespace}.services.openssh = with types; {
enable = lib.mkEnableOption "OpenSSH support"; enable = lib.mkEnableOption "OpenSSH support";
authorizedKeys = mkOpt (listOf str) authorizedKeys "The public keys to apply."; authorizedKeys = mkOpt (listOf str) [ ] "The public keys to apply.";
extraConfig = mkOpt str "" "Extra configuration to apply."; extraConfig = mkOpt str "" "Extra configuration to apply.";
}; };
@@ -62,6 +67,7 @@ in
"hmac-sha2-512-etm@openssh.com" "hmac-sha2-512-etm@openssh.com"
"hmac-sha2-256-etm@openssh.com" "hmac-sha2-256-etm@openssh.com"
"umac-128-etm@openssh.com" "umac-128-etm@openssh.com"
"hmac-sha2-512"
]; ];
}; };
@@ -74,7 +80,7 @@ in
}; };
reichard = { reichard = {
user.extraOptions.openssh.authorizedKeys.keys = cfg.authorizedKeys; user.extraOptions.openssh.authorizedKeys.keys = cfg.authorizedKeys ++ globalKeys;
}; };
}; };
} }

View File

@@ -0,0 +1,215 @@
*PPD-Adobe: "4.3"
*% PPD created by ipp2ppd (v2:Jun 6 2020)
*FormatVersion: "4.3"
*FileVersion: "2.0"
*LanguageVersion: English
*LanguageEncoding: ISOLatin1
*PSVersion: "(3010.000) 0"
*LanguageLevel: "3"
*FileSystem: False
*cupsVersion: 2.0
*cupsModelNumber: 0
*cupsSNMPSupplies: False
*APAirPrint: True
*APAirPrintVersion: 1.3
*APURFVersion: 1.3
*% WARNING missing printer-firmware-name and/or printer-firmware-string-version.
*cupsLanguages: "en"
*cupsIdentifyActions: "flash"
*APAcceptsMixedURF: True
*PCFileName: "APCANONI.PPD"
*ModelName: "Canon PIXMA iX6820"
*Product: (Canon PIXMA iX6820)
*ShortNickName: "Canon PIXMA iX6820"
*Manufacturer: "Canon"
*NickName: "Canon PIXMA iX6820-AirPrint"
*Throughput: 12
*APSupplies: "http://10.0.60.45/index.html?PAGE_AAP"
*cupsSingleFile: True
*cupsFilter2: "image/jpeg image/jpeg 0 maxsize(12582912) -"
*cupsFilter: "image/jpeg 0 -"
*cupsFilter2: "image/urf image/urf 10 -"
*cupsFilter: "image/urf 10 -"
*cupsMaxCopies: 99
*ColorDevice: True
*APColorSpaces: true
*DefaultColorSpace: RGB
*OpenUI *ColorModel/Color Mode: PickOne
*OrderDependency: 10 AnySetup *ColorModel
*DefaultColorModel: RGB
*ColorModel Gray/Grayscale: "<</cupsColorSpace 18/cupsBitsPerColor 8/cupsColorOrder 0/cupsCompression 0>>setpagedevice"
*ColorModel RGB/Color: "<</cupsColorSpace 19/cupsBitsPerColor 8/cupsColorOrder 0/cupsCompression 0>>setpagedevice"
*CloseUI: *ColorModel
*LandscapeOrientation: Minus90
*DefaultResolution: 600x600dpi
*OpenUI *cupsPrintQuality/Quality: PickOne
*OrderDependency: 10 AnySetup *cupsPrintQuality
*DefaultcupsPrintQuality: Normal
*cupsPrintQuality Normal: "<</cupsInteger1 4 /HWResolution[600 600]>>setpagedevice"
*cupsPrintQuality High: "<</cupsInteger1 5 /HWResolution[600 600]>>setpagedevice"
*CloseUI: *cupsPrintQuality
*cupsBackSide: Normal
*DefaultOutputOrder: Reverse
*OpenUI *PageSize/Media Size: PickOne
*OrderDependency: 10 AnySetup *PageSize
*DefaultPageSize: Letter.Fullbleed
*PageSize 3.5x5: "<</PageSize[252.0000 360.0000]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageSize 3.5x5.Fullbleed: "<</PageSize[252.0000 360.0000]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageSize 4x6: "<</PageSize[288.0000 432.0000]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageSize 4x6.Fullbleed: "<</PageSize[288.0000 432.0000]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageSize 5x7: "<</PageSize[360.0000 504.0000]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageSize 5x7.Fullbleed: "<</PageSize[360.0000 504.0000]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageSize 8x10: "<</PageSize[576.0000 720.0000]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageSize 8x10.Fullbleed: "<</PageSize[576.0000 720.0000]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageSize A3: "<</PageSize[841.8898 1190.5512]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageSize A3.Fullbleed: "<</PageSize[841.8898 1190.5512]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageSize A4: "<</PageSize[595.2756 841.8898]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageSize A4.Fullbleed: "<</PageSize[595.2756 841.8898]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageSize A5: "<</PageSize[419.5276 595.2756]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageSize B4: "<</PageSize[728.5039 1031.8110]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageSize B5: "<</PageSize[515.9055 728.5039]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageSize Env10: "<</PageSize[296.9858 684.0000]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageSize EnvDL: "<</PageSize[311.8110 623.6220]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageSize Legal: "<</PageSize[612.0000 1008.0000]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageSize Letter: "<</PageSize[612.0000 792.0000]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageSize Letter.Fullbleed: "<</PageSize[612.0000 792.0000]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageSize Postcard: "<</PageSize[283.4646 419.5276]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageSize Postcard.Fullbleed: "<</PageSize[283.4646 419.5276]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageSize Tabloid: "<</PageSize[792.0000 1224.0000]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageSize Tabloid.Fullbleed: "<</PageSize[792.0000 1224.0000]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageSize 13x19: "<</PageSize[936.0000 1368.0000]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageSize 13x19.Fullbleed: "<</PageSize[936.0000 1368.0000]/ImagingBBox null/Orientation 0>>setpagedevice"
*CloseUI: *PageSize
*OpenUI *PageRegion/Media Size: PickOne
*OrderDependency: 10 AnySetup *PageRegion
*DefaultPageRegion: Letter.Fullbleed
*PageRegion 3.5x5: "<</PageSize[252.0000 360.0000]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageRegion 3.5x5.Fullbleed: "<</PageSize[252.0000 360.0000]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageRegion 4x6: "<</PageSize[288.0000 432.0000]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageRegion 4x6.Fullbleed: "<</PageSize[288.0000 432.0000]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageRegion 5x7: "<</PageSize[360.0000 504.0000]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageRegion 5x7.Fullbleed: "<</PageSize[360.0000 504.0000]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageRegion 8x10: "<</PageSize[576.0000 720.0000]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageRegion 8x10.Fullbleed: "<</PageSize[576.0000 720.0000]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageRegion A3: "<</PageSize[841.8898 1190.5512]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageRegion A3.Fullbleed: "<</PageSize[841.8898 1190.5512]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageRegion A4: "<</PageSize[595.2756 841.8898]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageRegion A4.Fullbleed: "<</PageSize[595.2756 841.8898]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageRegion A5: "<</PageSize[419.5276 595.2756]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageRegion B4: "<</PageSize[728.5039 1031.8110]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageRegion B5: "<</PageSize[515.9055 728.5039]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageRegion Env10: "<</PageSize[296.9858 684.0000]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageRegion EnvDL: "<</PageSize[311.8110 623.6220]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageRegion Legal: "<</PageSize[612.0000 1008.0000]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageRegion Letter: "<</PageSize[612.0000 792.0000]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageRegion Letter.Fullbleed: "<</PageSize[612.0000 792.0000]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageRegion Postcard: "<</PageSize[283.4646 419.5276]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageRegion Postcard.Fullbleed: "<</PageSize[283.4646 419.5276]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageRegion Tabloid: "<</PageSize[792.0000 1224.0000]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageRegion Tabloid.Fullbleed: "<</PageSize[792.0000 1224.0000]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageRegion 13x19: "<</PageSize[936.0000 1368.0000]/ImagingBBox null/Orientation 0>>setpagedevice"
*PageRegion 13x19.Fullbleed: "<</PageSize[936.0000 1368.0000]/ImagingBBox null/Orientation 0>>setpagedevice"
*CloseUI: *PageRegion
*DefaultImageableArea: Letter.Fullbleed
*DefaultPaperDimension: Letter.Fullbleed
*PaperDimension 3.5x5: "252.0000 360.0000"
*ImageableArea 3.5x5: "9.6378 14.1732 242.3622 345.8268"
*PaperDimension 3.5x5.Fullbleed: "252.0000 360.0000"
*ImageableArea 3.5x5.Fullbleed: "0.0000 0.0000 252.0000 360.0000"
*PaperDimension 4x6: "288.0000 432.0000"
*ImageableArea 4x6: "9.6378 14.1732 278.3622 417.8268"
*PaperDimension 4x6.Fullbleed: "288.0000 432.0000"
*ImageableArea 4x6.Fullbleed: "0.0000 0.0000 288.0000 432.0000"
*PaperDimension 5x7: "360.0000 504.0000"
*ImageableArea 5x7: "9.6378 14.1732 350.3622 489.8268"
*PaperDimension 5x7.Fullbleed: "360.0000 504.0000"
*ImageableArea 5x7.Fullbleed: "0.0000 0.0000 360.0000 504.0000"
*PaperDimension 8x10: "576.0000 720.0000"
*ImageableArea 8x10: "9.6378 14.1732 566.3622 705.8268"
*PaperDimension 8x10.Fullbleed: "576.0000 720.0000"
*ImageableArea 8x10.Fullbleed: "0.0000 0.0000 576.0000 720.0000"
*PaperDimension A3: "841.8898 1190.5512"
*ImageableArea A3: "9.6378 14.1732 832.2520 1176.3780"
*PaperDimension A3.Fullbleed: "841.8898 1190.5512"
*ImageableArea A3.Fullbleed: "0.0000 0.0000 841.8898 1190.5512"
*PaperDimension A4: "595.2756 841.8898"
*ImageableArea A4: "9.6378 14.1732 585.6378 827.7165"
*PaperDimension A4.Fullbleed: "595.2756 841.8898"
*ImageableArea A4.Fullbleed: "0.0000 0.0000 595.2756 841.8898"
*PaperDimension A5: "419.5276 595.2756"
*ImageableArea A5: "9.6378 14.1732 409.8898 581.1024"
*PaperDimension B4: "728.5039 1031.8110"
*ImageableArea B4: "9.6378 14.1732 718.8661 1017.6378"
*PaperDimension B5: "515.9055 728.5039"
*ImageableArea B5: "9.6378 14.1732 506.2677 714.3307"
*PaperDimension Env10: "296.9858 684.0000"
*ImageableArea Env10: "15.8740 106.0157 281.1118 661.3228"
*PaperDimension EnvDL: "311.8110 623.6220"
*ImageableArea EnvDL: "15.8740 106.0157 295.9370 600.9449"
*PaperDimension Legal: "612.0000 1008.0000"
*ImageableArea Legal: "18.1417 14.1732 593.8583 993.8268"
*PaperDimension Letter: "612.0000 792.0000"
*ImageableArea Letter: "18.1417 14.1732 593.8583 777.8268"
*PaperDimension Letter.Fullbleed: "612.0000 792.0000"
*ImageableArea Letter.Fullbleed: "0.0000 0.0000 612.0000 792.0000"
*PaperDimension Postcard: "283.4646 419.5276"
*ImageableArea Postcard: "9.6378 14.1732 273.8268 405.3543"
*PaperDimension Postcard.Fullbleed: "283.4646 419.5276"
*ImageableArea Postcard.Fullbleed: "0.0000 0.0000 283.4646 419.5276"
*PaperDimension Tabloid: "792.0000 1224.0000"
*ImageableArea Tabloid: "9.6378 14.1732 782.3622 1209.8268"
*PaperDimension Tabloid.Fullbleed: "792.0000 1224.0000"
*ImageableArea Tabloid.Fullbleed: "0.0000 0.0000 792.0000 1224.0000"
*PaperDimension 13x19: "792.0000 1224.0000"
*ImageableArea 13x19: "9.6378 14.1732 926.3622 1353.8268"
*PaperDimension 13x19.Fullbleed: "936.0000 1368.0000"
*ImageableArea 13x19.Fullbleed: "0.0000 0.0000 936.0000 1368.0000"
*ParamCustomPageSize Width: 1 points 156 933
*ParamCustomPageSize Height: 2 points 258 1916
*ParamCustomPageSize WidthOffset: 3 points 0 0
*ParamCustomPageSize HeightOffset: 4 points 0 0
*ParamCustomPageSize Orientation: 5 int 0 3
*CustomPageSize True: ""
*OpenUI *MediaType/MediaType: PickOne
*OrderDependency: 10 AnySetup *MediaType
*MediaType stationery/Stationery: ""
*MediaType photographic/Photo: ""
*MediaType envelope/Envelope: ""
*MediaType any/Any: ""
*DefaultMediaType: any
*CloseUI: *MediaType
*APPrinterPreset Gray_with_Paper_Auto-Detect/Black and White: "
*cupsPrintQuality Normal
*ColorModel Gray
com.apple.print.preset.graphicsType General
com.apple.print.preset.quality mid
com.apple.print.preset.media-front-coating autodetect
com.apple.print.preset.output-mode monochrome"
*End
*APPrinterPreset Color_with_Paper_Auto-Detect/Color: "
*cupsPrintQuality Normal
*ColorModel RGB
com.apple.print.preset.graphicsType General
com.apple.print.preset.quality mid
com.apple.print.preset.media-front-coating autodetect"
*End
*APPrinterPreset Photo_on_Plain_Paper/Photo on Plain Paper: "
*cupsPrintQuality High
*Duplex None
*ColorModel RGB
*MediaType stationery
com.apple.print.preset.graphicsType Photo
com.apple.print.preset.quality high
com.apple.print.preset.media-front-coating none
"
*End
*APPrinterPreset Photo_on_Photo_Paper/Photo on Photo Paper: "
*cupsPrintQuality High
*Duplex None
*ColorModel RGB
*MediaType photographic
com.apple.print.preset.graphicsType Photo
com.apple.print.preset.quality high
com.apple.print.preset.media-front-coating photo
"
*End

View File

@@ -0,0 +1,23 @@
# Printing Service Module
This module configures a Canon PIXMA iX6820 printer for fullbleed/borderless printing on NixOS.
## PPD File
The `Canon_PIXMA_iX6820_AirPrint.ppd` file is essential for enabling fullbleed (borderless) printing on the Canon PIXMA iX6820.
The default IPP/PPD driver included with Linux claims to support borderless printing, but it never works in practice. This custom PPD was generated via macOS and manually converted to work with Linux/CUPS to actually enable fullbleed printing functionality. It provides CUPS with the necessary printer capabilities and configuration options, including the `4x6.Fullbleed` page size and media type options.
## Nix Module
The module (`default.nix`) provides a NixOS service that:
- Enables CUPS printing service
- Installs the custom PPD driver for the Canon PIXMA iX6820
- Configures the printer via `hardware.printers.ensurePrinters`
- Sets default print options for high-quality borderless photo printing:
- Page size: 4x6 Fullbleed
- Color model: RGB
- Print quality: High
- Media type: Photographic
- Sets the printer as the default system printer

View File

@@ -0,0 +1,63 @@
{
config,
lib,
pkgs,
namespace,
...
}:
let
inherit (lib) mkIf mkEnableOption;
inherit (pkgs) writeTextDir;
cfg = config.${namespace}.services.printing;
in
{
options.${namespace}.services.printing = {
enable = mkEnableOption "enable printing service";
};
config = mkIf cfg.enable {
hardware.printers = {
ensurePrinters = [
{
name = "Canon_PIXMA_iX6820";
location = "Home";
deviceUri = "ipp://10.0.60.45:631/ipp/print";
model = "Canon_PIXMA_iX6820.ppd";
ppdOptions = {
PageSize = "4x6.Fullbleed";
ColorModel = "RGB";
cupsPrintQuality = "High";
MediaType = "photographic";
};
}
{
name = "Brother_HL-2270DW";
location = "Home";
deviceUri = "dnssd://Brother%20HL-2270DW%20series._pdl-datastream._tcp.local/";
model = "drv:///brlaser.drv/br2270d.ppd";
ppdOptions = {
PageSize = "Letter";
Resolution = "600dpi";
InputSlot = "Auto";
MediaType = "PLAIN";
Duplex = "DuplexNoTumble";
brlaserEconomode = "False";
brlaserDensityAdjust = "100";
};
}
];
ensureDefaultPrinter = "Canon_PIXMA_iX6820";
};
services.printing = {
enable = true;
drivers = [
pkgs.brlaser
(writeTextDir "share/cups/model/Canon_PIXMA_iX6820.ppd" (
builtins.readFile ./Canon_PIXMA_iX6820_AirPrint.ppd
))
];
};
};
}

View File

@@ -1,4 +1,9 @@
{ config, pkgs, lib, namespace, ... }: { config
, pkgs
, lib
, namespace
, ...
}:
let let
inherit (lib) types mkIf; inherit (lib) types mkIf;
inherit (lib.${namespace}) mkOpt mkBoolOpt; inherit (lib.${namespace}) mkOpt mkBoolOpt;
@@ -9,15 +14,25 @@ in
options.${namespace}.services.rke2 = with types; { options.${namespace}.services.rke2 = with types; {
enable = lib.mkEnableOption "Enable RKE2"; enable = lib.mkEnableOption "Enable RKE2";
disable = mkOpt (listOf str) [ ] "Disable services"; disable = mkOpt (listOf str) [ ] "Disable services";
openFirewall = mkBoolOpt true "Open firewall"; openFirewall = mkBoolOpt false "Open firewall";
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
boot.kernel.sysctl = {
"fs.inotify.max_user_watches" = 1048576;
"fs.inotify.max_user_instances" = 8192;
"fs.file-max" = 2097152;
};
services.rke2 = { services.rke2 = {
enable = true; enable = true;
disable = cfg.disable; disable = cfg.disable;
}; };
# NOTE: Tailscale & K8s Calico conflict due to FWMask. You need to update the DaemonSet Env with:
# - name: FELIX_IPTABLESMARKMASK
# value: "0xff00ff00"
networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [
# RKE2 Ports - https://docs.rke2.io/install/requirements#networking # RKE2 Ports - https://docs.rke2.io/install/requirements#networking
6443 # Kubernetes API 6443 # Kubernetes API
@@ -32,8 +47,6 @@ in
7946 # memberlist 7946 # memberlist
]; ];
environment.systemPackages = with pkgs; [ nfs-utils ];
networking.firewall.allowedUDPPorts = mkIf cfg.openFirewall [ networking.firewall.allowedUDPPorts = mkIf cfg.openFirewall [
# RKE2 Ports - https://docs.rke2.io/install/requirements#networking # RKE2 Ports - https://docs.rke2.io/install/requirements#networking
8472 # Canal CNI with VXLAN 8472 # Canal CNI with VXLAN
@@ -49,5 +62,11 @@ in
after = [ "cloud-final.service" ]; after = [ "cloud-final.service" ];
requires = [ "cloud-final.service" ]; requires = [ "cloud-final.service" ];
}; };
environment.systemPackages = with pkgs; [
k9s
kubectl
nfs-utils
];
}; };
} }

View File

@@ -0,0 +1,32 @@
{ config, pkgs, lib, namespace, ... }:
let
inherit (lib) mkIf mkEnableOption;
inherit (lib.${namespace}) mkBoolOpt;
cfg = config.${namespace}.services.rtl-tcp;
in
{
options.${namespace}.services.rtl-tcp = {
enable = mkEnableOption "RTL-TCP support";
openFirewall = mkBoolOpt true "Open firewall";
};
config = mkIf cfg.enable {
hardware.rtl-sdr.enable = true;
networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ 1234 ];
# RTL-SDR TCP Server Service
systemd.services.rtl-tcp = {
description = "RTL-SDR TCP Server";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStart = "${pkgs.rtl-sdr}/bin/rtl_tcp -a 0.0.0.0 -f 1090000000 -s 2400000";
Restart = "on-failure";
RestartSec = "10s";
User = "root";
Group = "root";
};
};
};
}

View File

@@ -0,0 +1,20 @@
{ config, lib, namespace, ... }:
let
inherit (lib) mkIf mkEnableOption;
inherit (lib.${namespace}) mkBoolOpt;
cfg = config.${namespace}.services.sunshine;
in
{
options.${namespace}.services.sunshine = {
enable = mkEnableOption "enable sunshine service";
openFirewall = mkBoolOpt true "open firewall";
};
config = mkIf cfg.enable {
services.sunshine = {
enable = true;
openFirewall = cfg.openFirewall;
};
};
}

Some files were not shown because too many files have changed in this diff Show More