Compare commits

8 Commits

Author SHA1 Message Date
559ef8c17d remove ff sponsored 2025-04-19 21:12:13 -04:00
036f162264 fix sops 2025-04-19 21:08:21 -04:00
00070837c2 fix bindings 2025-04-19 20:37:58 -04:00
e84f6e7cb4 again 2025-04-19 20:35:52 -04:00
914f8e8d30 more 2025-04-19 20:35:22 -04:00
fb1b69153b thinkpad conf 2025-04-19 20:09:49 -04:00
cf82afea4b utility 2025-04-10 20:01:05 -04:00
4d04f2600f snowfall migration 2025-04-10 17:40:56 -04:00
156 changed files with 1546 additions and 7276 deletions

1
.envrc
View File

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

2
.gitignore vendored
View File

@@ -1,6 +1,4 @@
.codexis
.DS_Store .DS_Store
_scratch _scratch
result result
._* ._*
.direnv

View File

@@ -1,70 +0,0 @@
---
name: update-package-hashes
description: Update a package in packages/ to a new version and refresh its hashes (src, vendorHash, npmDepsHash, cargoHash, etc.) WITHOUT compiling the package. Use when the user asks to bump, update, or upgrade a specific package under packages/. Requires package name and target version/rev.
---
# Update Package Hashes (Without Building)
Require the user to supply the **package name** and **target version/rev/tag**. Ask if missing.
## Hard Rules — Read First
1. **Never run `nix build .#<pkg>`** or `.#packages.<system>.<pkg>`. That compiles the package. Only realise **FOD sub-attributes** (`.src`, `.goModules`, `.npmDeps`, `.cargoDeps`) — those are pure downloads, not builds.
2. **Never** use `nix-prefetch-git`, `nix-prefetch-url`, `nix hash path`, `git clone` + manual hashing, `builtins.fetchGit`, or any other ad-hoc method to compute hashes. They produce hashes in formats that don't match what `fetchgit`/`fetchFromGitHub`/etc. expect, and you will waste time chasing mismatches.
3. There are exactly **two** correct ways to get a hash, both listed below. If neither fits, stop and ask the user — don't improvise.
## The Only Two Methods
### Method A — `nurl` (preferred for `src` on any git forge)
`nurl` works for **any git URL**, not just GitHub: `gitea.va.reichard.io`, `gitlab`, `codeberg`, `sourcehut`, plain `https://...git`, all fine. It downloads the source and prints a complete fetcher expression with the correct hash.
```bash
nix run nixpkgs#nurl -- <git-url> <rev-or-tag>
```
Examples:
```bash
nix run nixpkgs#nurl -- https://github.com/owner/repo v1.2.3
nix run nixpkgs#nurl -- https://gitea.va.reichard.io/evan/slack-cli.git 0a9484257a2adc414aa4cdab4fb9539a37e04d1f
```
Copy the `hash = "sha256-..."` line into the package's `src` block.
### Method B — FOD mismatch trick (for everything else)
For `vendorHash`, `npmDepsHash`, `cargoHash`, `cargoLock.outputHashes.<crate>`, or any `src` using a custom fetcher (`leaveDotGit`, `postFetch`, `fetchSubmodules`, etc. — applies to `llama-cpp` and `llama-swap`), realise the **specific FOD sub-attribute** and read the `got:` line from the error.
```bash
nix build .#<name>.src --no-link 2>&1 | tee /tmp/hash.log # for src
nix build .#<name>.goModules --no-link 2>&1 | tee /tmp/hash.log # for vendorHash
nix build .#<name>.npmDeps --no-link 2>&1 | tee /tmp/hash.log # for npmDepsHash
nix build .#<name>.cargoDeps --no-link 2>&1 | tee /tmp/hash.log # for cargoHash
grep -E '^[[:space:]]*got:' /tmp/hash.log | tail -1 | awk '{print $2}'
```
Setting the hash to `sha256-AAAA...` (44 A's) or leaving the old one in place both work — the build will fail at the FOD with `got: sha256-...` which is the correct value.
**Note:** `.src`, `.goModules`, etc. are sub-attributes of the derivation. They download but do not compile. `nix build .#<name>` (without the `.src` suffix) compiles — never do that.
## Flow
1. Edit `packages/<name>/default.nix` — bump `version` / `rev` / `tag`. Check for sibling `.nix` files (e.g. `ui.nix`) that may also need bumping.
2. Get the new `src` hash with **Method A** (`nurl`). If the package uses a custom fetcher, use **Method B** on `.src` instead.
3. For each dependency hash (`vendorHash` / `npmDepsHash` / `cargoHash` / etc.), use **Method B** on the matching sub-attribute.
4. **Opaque `outputHash` FODs** (e.g. opencode's `node_modules` which runs `bun install`) — do NOT attempt locally. Leave as-is and flag for CI in the summary.
5. Show `git diff -- packages/<name>/` and list any hashes left for CI.
## Resolving Tags Without Cloning
```bash
git ls-remote <url> refs/tags/<tag>
```
## Don't Touch What Didn't Change
Skip pinned sub-dependencies whose inputs didn't change — e.g. `slack-cli`'s `python-snappy` / `zstd-python` PyPI tarballs are pinned by the upstream `dfindexeddb`, not by the slack-cli rev.
## Optional Shortcut
`nix-update --flake <name> --version <v>` sometimes handles everything for simple packages. Try it first; fall back to the methods above if it fails.

View File

@@ -1,35 +1,15 @@
keys: keys:
# Global Admin # Admin - Age Native
- &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/common/systems.yaml - path_regex: secrets/lin-va-mbp-personal/evanreichard/[^/]+\.(yaml|json|env|ini)$
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

119
AGENTS.md
View File

@@ -1,119 +0,0 @@
# NixOS Configuration — Agent Guide
This is a multi-host NixOS/nix-darwin configuration managed with [Snowfall Lib](https://github.com/snowfallorg/lib). It declaratively configures NixOS (Linux), nix-darwin (macOS), and Home Manager across many machines from a single flake.
## Snowfall Lib Conventions
Snowfall Lib auto-discovers everything by directory convention — there is no manual wiring. The namespace is `reichard`, so all custom options live under `reichard.*` (e.g. `reichard.services.tailscale`, `reichard.programs.terminal.nvim`). Modules use `lib.reichard.enabled` / `lib.reichard.disabled` helpers from `lib/module/default.nix`.
**Important:** Files must be tracked by git (`git add`) for the flake to see them.
## Layout
### `flake.nix`
Entrypoint. Defines inputs (nixpkgs, home-manager, sops-nix, disko, apple-silicon, snowfall-lib, etc.) and calls `snowfall-lib.mkFlake`. All system and home modules are auto-discovered from the directory structure below.
### `systems/`
System-level NixOS and nix-darwin configurations, organized by architecture:
- `systems/aarch64-linux/` — ARM Linux hosts (e.g. Asahi MacBook, Oracle Cloud nodes, headscale)
- `systems/x86_64-linux/` — x86 Linux hosts (desktop, thinkpad, utility servers, Kubernetes nodes)
- `systems/aarch64-darwin/` — macOS hosts (work and personal MacBooks)
- `systems/aarch64-raw-efi/` — Raw EFI image builds (terminal image via nixos-generators)
- `systems/x86_64-vmware/` — VMware images (RKE2 node)
Each host is a directory with a `default.nix` that composes modules via the `reichard.*` option namespace (e.g. `reichard.services.tailscale = enabled;`). Some hosts include `hardware-configuration.nix` or firmware directories.
### `homes/`
Home Manager configurations, organized by `<arch>/<user>@<host>/default.nix`. Each home config enables per-host programs and services (e.g. Neovim, Firefox, Hyprland, git, tmux) via the `reichard.*` namespace, same as system modules.
### `modules/`
Reusable NixOS, Home Manager, and Darwin modules. This is where most of the configuration logic lives.
- **`modules/nixos/`** — NixOS system modules:
- `common/` — Packages applied to all NixOS systems
- `home/` — Home Manager integration (useGlobalPkgs, useUserPackages)
- `nix/` — Nix daemon settings, registries, binary caches, distributed builds
- `user/` — User account creation
- `security/sops/` — sops-nix secret decryption (age-based)
- `system/` — Boot, networking, NetworkManager, disko disk partitioning
- `services/` — Headscale, Tailscale, llama-swap (LLM model server), OpenSSH, RKE2, printing, Avahi, cloud-init, Sunshine, etc.
- `hardware/` — OpenGL, Asahi (Apple Silicon), battery/UPower
- `programs/graphical/wms/hyprland/` — System-level Hyprland WM setup
- `display-managers/sddm/` — SDDM display manager
- `virtualisation/` — Podman, libvirtd
- **`modules/home/`** — Home Manager modules:
- `common/` — Packages applied to all home configs (sqlite, jq, ripgrep, ncdu, jnv)
- `user/` — Home Manager user identity
- `security/sops/` — Per-user secret decryption
- `services/` — Fusuma (touchpad gestures), swww (wallpaper), SSH agent, poweralertd
- `programs/terminal/` — CLI tools: bash, tmux, btop, git, k9s, zk, aws, Neovim, opencode, claude-code, pi
- `programs/graphical/` — GUI apps: Firefox (with extensions overlay), Ghostty, Hyprland (home-level), Remmina, GIMP, Wireshark, Ghidra, Strawberry
- **`modules/darwin/`** — nix-darwin modules: user, OpenSSH, sops
### `modules/home/programs/terminal/nvim/` — Neovim Configuration
This is the full Neovim setup, frequently modified. The `default.nix` declares:
- All plugins (via nixpkgs vimPlugins + custom `buildVimPlugin` for codecompanion.nvim, none-ls-extras, llama.vim)
- LSP servers and formatters as `extraPackages`
- A generated `nix-vars.lua` that injects Nix store paths for LSP binaries
The actual Neovim Lua configuration lives in `config/lua/`:
- `init.lua` — Main loader
- `base.lua` — Core Vim settings and keymaps
- `lsp-config.lua` — LSP server setup (uses paths from `nix-vars.lua`)
- `cmp-config.lua` — nvim-cmp completion
- `llm-config.lua` — LLM integration (codecompanion, llama.vim)
- `snacks-config.lua` — Snacks.nvim dashboard/picker
- `dap-config.lua` — Debug Adapter Protocol (Go, etc.)
- `diagnostics-config.lua`, `ts-config.lua`, `lualine-config.lua`, `noice-config.lua`, `git-config.lua`, `which-key-config.lua`, etc.
When editing the Neovim config, note that **plugin declarations** happen in `default.nix` (Nix), while **plugin configuration** happens in the Lua files under `config/lua/`. LSP binary paths are bridged via the auto-generated `nix-vars.lua`.
### `packages/`
Custom package derivations, auto-discovered by Snowfall Lib and available as `pkgs.reichard.<name>`:
- `codexis/` — Go: code indexer using tree-sitter (built from gitea via `fetchgit`)
- `llama-cpp/` — LLaMA C++ inference engine
- `llama-swap/` — Go: LLM model swap proxy (with UI sub-derivation)
- `opencode/` — Go: terminal coding tool
- `pi-coding-agent/` — Node.js: coding agent CLI
- `qwen-code/` — Qwen code assistant
- `stable-diffusion-cpp/` — Stable Diffusion C++ inference
### `overlays/`
Nixpkgs overlays. Currently just `firefox-addons/` which imports the rycee Firefox addons repository.
### `secrets/`
sops-encrypted secrets (age keys). Managed via `.sops.yaml` which defines per-host and per-user key groups:
- `keys.yaml` — Master key definitions
- `common/evanreichard.yaml` — User-level secrets (shared across personal machines)
- `common/systems.yaml` — System-level secrets (e.g. builder SSH keys)
### `shells/`
Dev shell definitions. `shells/default/` provides the default `nix develop` environment for working on this repo.
### `lib/`
Shared library helpers. `lib/module/default.nix` exports `mkOpt`, `mkBoolOpt`, `enabled`, and `disabled` — used throughout all modules for consistent option declarations.
## Common Tasks
- **Adding a new system:** Create `systems/<arch>/<hostname>/default.nix` and optionally `homes/<arch>/<user>@<hostname>/default.nix`. Compose existing modules via `reichard.*` options.
- **Adding a new module:** Create `modules/{nixos,home,darwin}/<category>/<name>/default.nix` with an `enable` option under the `reichard` namespace. It will be auto-discovered.
- **Adding a new package:** Create `packages/<name>/default.nix`. Run `git add` so the flake sees it. Reference it in modules as `pkgs.reichard.<name>`.
- **Editing Neovim plugins:** Modify `modules/home/programs/terminal/nvim/default.nix` (plugin list, extraPackages, nix-vars).
- **Editing Neovim config (Lua):** Modify files under `modules/home/programs/terminal/nvim/config/lua/`.
- **Managing secrets:** Edit `.sops.yaml` for key groups, use `sops` CLI to encrypt/decrypt files in `secrets/`.
- **Building/testing:** `nix build .#packages.<arch>.<name>` for packages, `nix build .#nixosConfigurations.<host>.config.system.build.toplevel` for full system builds.
- **Bumping a package version / refreshing hashes:** Use the `update-package-hashes` skill at `.pi/skills/update-package-hashes/`.

110
README.md
View File

@@ -2,101 +2,65 @@
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).
```bash ### NixOS
# 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
``` ```
## Nix Darwin ### NixOS Generators
```bash ```bash
# Install Nix Without Determinate nix build .#vmwareConfigurations.rke2-node
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
``` ```
## Clean Garbage ### Home Manager
NOTE: This will remove previous generations
```bash ```bash
sudo nix-collect-garbage --delete-old home-manager switch --flake .#evanreichard@MBP-Personal
nix-collect-garbage --delete-old
``` ```
## Home Manager ### NixOS Hosts
#### Copy Config
```bash ```bash
# Update System Channels rsync -av --exclude='.git' . root@HOST:/etc/nixos
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
``` ```
### OS Update #### Partition Drives
`/etc/bashrc` may get overridden. To properly load Nix, prepend the following:
```bash ```bash
# Nix # Validate Disk
if [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then ls -l /dev/disk/by-id
. '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'
fi # Partition Disk
# End Nix # WARNING: This will destroy all data on the disk(s)
sudo nix \
--experimental-features "nix-command flakes" \
run github:nix-community/disko -- \
--mode disko \
--flake /etc/nixos#HOST_CONFIG
``` ```
#### SOPS #### Install NixOS
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
# Convert SSH to Age # Install
mkdir -p ~/.config/sops/age sudo nixos-install --flake /etc/nixos#HOST_CONFIG
ssh-to-age -private-key -i $HOME/.ssh/id_ed25519 -o ~/.config/sops/age/keys.txt
# Get Public Key # Reboot
age-keygen -y ~/.config/sops/age/keys.txt sudo reboot
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
# NOTE: You can specify key with - `SOPS_AGE_KEY_FILE=~/.config/sops/age/other.txt` ```bash
sops secrets/lin-va-thinkpad/evanreichard/default.yaml rsync -av --exclude='.git' . root@HOST:/etc/nixos
```
#### 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 \
".#vmwareConfigurations" \ ".#qcowConfigurations" \
--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=(".#vmwareConfigurations.$name") build_args=(".#qcowConfigurations.$name")
if [ "$remote" = true ]; then if [ "$remote" = true ]; then
build_args+=("-j0") build_args+=("-j0")
fi fi
@@ -51,9 +51,8 @@ function cmd_image() {
} }
function cmd_install() { function cmd_install() {
local usage="Usage: $0 install --name <system-name> [--remote <user@remote-host>]" local usage="Usage: $0 install --name <system-name>"
local name="" local name=""
local remote=""
while [[ $# -gt 0 ]]; do while [[ $# -gt 0 ]]; do
case "$1" in case "$1" in
@@ -61,10 +60,6 @@ function cmd_install() {
name="$2" name="$2"
shift 2 shift 2
;; ;;
--remote)
remote="$2"
shift 2
;;
*) *)
echo "$usage" echo "$usage"
exit 1 exit 1
@@ -92,18 +87,6 @@ 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"
@@ -150,27 +133,6 @@ function cmd_install_local(){
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

373
flake.lock generated
View File

@@ -5,111 +5,34 @@
"flake-compat": "flake-compat", "flake-compat": "flake-compat",
"nixpkgs": [ "nixpkgs": [
"nixpkgs" "nixpkgs"
] ],
"rust-overlay": "rust-overlay"
}, },
"locked": { "locked": {
"lastModified": 1776147994, "lastModified": 1738646032,
"narHash": "sha256-c5F8jYiB0fjWsP4j/yeszqszA3laflzDj6/pmoJTeG4=", "narHash": "sha256-57BdBE9anNpIpf48EiTVLGxg4mOQ04XjHCEP0gLTsFA=",
"owner": "nix-community", "owner": "tpwrules",
"repo": "nixos-apple-silicon", "repo": "nixos-apple-silicon",
"rev": "81439a7fb8067ab43641efd79c84607701da1ccd", "rev": "e77031211944723a38bebc043e48847c36e43668",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "nix-community", "owner": "tpwrules",
"ref": "releasep2-2024-12-25",
"repo": "nixos-apple-silicon", "repo": "nixos-apple-silicon",
"type": "github" "type": "github"
} }
}, },
"darwin": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1772129556,
"narHash": "sha256-Utk0zd8STPsUJPyjabhzPc5BpPodLTXrwkpXBHYnpeg=",
"owner": "nix-darwin",
"repo": "nix-darwin",
"rev": "ebec37af18215214173c98cf6356d0aca24a2585",
"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": 1775584659,
"narHash": "sha256-NA5oZRunqxD+4LNdU7ZKJHqwuazKyAmBjO4OHXL14X4=",
"owner": "determinatesystems",
"repo": "determinate",
"rev": "21dcaa011d3d35cf42a04e988eaac9b28c97a707",
"type": "github"
},
"original": {
"owner": "determinatesystems",
"repo": "determinate",
"type": "github"
}
},
"determinate-nixd-aarch64-darwin": {
"flake": false,
"locked": {
"narHash": "sha256-qLWfYk9qkb21wKCDWnhMfqBFjcdBBJkNUKBlvdHSLgA=",
"type": "file",
"url": "https://install.determinate.systems/determinate-nixd/tag/v3.17.3/macOS"
},
"original": {
"type": "file",
"url": "https://install.determinate.systems/determinate-nixd/tag/v3.17.3/macOS"
}
},
"determinate-nixd-aarch64-linux": {
"flake": false,
"locked": {
"narHash": "sha256-0BmprPIRTopvJ2QdImOMP+TujAPVgRdl0bUL3vhqGIY=",
"type": "file",
"url": "https://install.determinate.systems/determinate-nixd/tag/v3.17.3/aarch64-linux"
},
"original": {
"type": "file",
"url": "https://install.determinate.systems/determinate-nixd/tag/v3.17.3/aarch64-linux"
}
},
"determinate-nixd-x86_64-linux": {
"flake": false,
"locked": {
"narHash": "sha256-+Q85cySxr0FB/cr97hk/WWYgeJY+iC4OH+FjGYygIbU=",
"type": "file",
"url": "https://install.determinate.systems/determinate-nixd/tag/v3.17.3/x86_64-linux"
},
"original": {
"type": "file",
"url": "https://install.determinate.systems/determinate-nixd/tag/v3.17.3/x86_64-linux"
}
},
"disko": { "disko": {
"inputs": { "inputs": {
"nixpkgs": "nixpkgs_3" "nixpkgs": "nixpkgs"
}, },
"locked": { "locked": {
"lastModified": 1773889306, "lastModified": 1743598667,
"narHash": "sha256-PAqwnsBSI9SVC2QugvQ3xeYCB0otOwCacB1ueQj2tgw=", "narHash": "sha256-ViE7NoFWytYO2uJONTAX35eGsvTYXNHjWALeHAg8OQY=",
"owner": "nix-community", "owner": "nix-community",
"repo": "disko", "repo": "disko",
"rev": "5ad85c82cc52264f4beddc934ba57f3789f28347", "rev": "329d3d7e8bc63dd30c39e14e6076db590a6eabe6",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -120,17 +43,18 @@
}, },
"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": 1776199335, "lastModified": 1743861198,
"narHash": "sha256-ImihxU7ReZZuNdrASq8qzOmmO/UQtkuqQ9V9KKb1dD0=", "narHash": "sha256-PzbPHoSI5U1juWd01Spf3ST7ylR9mQ84v5p7NksBplY=",
"owner": "rycee", "owner": "rycee",
"repo": "nur-expressions", "repo": "nur-expressions",
"rev": "95066e56aaa948f170747f57a20c99511a953eed", "rev": "7408ed5bbc9009741094f4dd4cc1abec79e79e7e",
"type": "gitlab" "type": "gitlab"
}, },
"original": { "original": {
@@ -142,11 +66,11 @@
}, },
"flake-compat": { "flake-compat": {
"locked": { "locked": {
"lastModified": 1761640442, "lastModified": 1688025799,
"narHash": "sha256-AtrEP6Jmdvrqiv4x2xa5mrtaIp3OEe8uBYCDZDS+hu8=", "narHash": "sha256-ktpB4dRtnksm9F5WawoIkEneh1nrEvuxb5lJFt1iOyw=",
"owner": "nix-community", "owner": "nix-community",
"repo": "flake-compat", "repo": "flake-compat",
"rev": "4a56054d8ffc173222d09dad23adf4ba946c8884", "rev": "8bf105319d44f6b9f0d764efa4fdef9f1cc9ba1c",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -156,22 +80,6 @@
} }
}, },
"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,
@@ -187,28 +95,41 @@
"type": "github" "type": "github"
} }
}, },
"flake-parts": { "flake-utils": {
"inputs": {
"nixpkgs-lib": [
"determinate",
"nix",
"nixpkgs"
]
},
"locked": { "locked": {
"lastModified": 1748821116, "lastModified": 1629284811,
"narHash": "sha256-F82+gS044J1APL0n4hH50GYdPRv/5JWm34oCJYmVKdE=", "narHash": "sha256-JHgasjPR0/J1J3DRm4KxM4zTyAj4IOJY8vIl75v/kPI=",
"rev": "49f0870db23e8c1ca0b5259734a02cd9e1e371a1", "owner": "numtide",
"revCount": 377, "repo": "flake-utils",
"type": "tarball", "rev": "c5d161cc0af116a2e17f54316f0bf43f0819785c",
"url": "https://api.flakehub.com/f/pinned/hercules-ci/flake-parts/0.1.377%2Brev-49f0870db23e8c1ca0b5259734a02cd9e1e371a1/01972f28-554a-73f8-91f4-d488cc502f08/source.tar.gz" "type": "github"
}, },
"original": { "original": {
"type": "tarball", "owner": "numtide",
"url": "https://flakehub.com/f/hercules-ci/flake-parts/0.1" "repo": "flake-utils",
"type": "github"
} }
}, },
"flake-utils": { "flake-utils-plus": {
"inputs": {
"flake-utils": "flake-utils_2"
},
"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"
}
},
"flake-utils_2": {
"inputs": { "inputs": {
"systems": "systems" "systems": "systems"
}, },
@@ -226,51 +147,6 @@
"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": [
@@ -278,41 +154,20 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1775425411, "lastModified": 1743808813,
"narHash": "sha256-KY6HsebJHEe5nHOWP7ur09mb0drGxYSzE3rQxy62rJo=", "narHash": "sha256-2lDQBOmlz9ggPxcS7/GvcVdzXMIiT+PpMao6FbLJSr0=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "0d02ec1d0a05f88ef9e74b516842900c41f0f2fe", "rev": "a9f8b3db211b4609ddd83683f9db89796c7f6ac6",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "nix-community", "owner": "nix-community",
"ref": "release-25.11", "ref": "release-24.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": 1775583600,
"narHash": "sha256-/shs/3GA4R3rxhhqpPbEMnDZKbCvf3VpwnHB75nkTcI=",
"rev": "e9b4735be7b90cf49767faf5c36f770ac1bdc586",
"revCount": 24880,
"type": "tarball",
"url": "https://api.flakehub.com/f/pinned/DeterminateSystems/nix-src/3.17.3/019d6913-e8c2-7128-ba76-3dc4f6b58158/source.tar.gz"
},
"original": {
"type": "tarball",
"url": "https://flakehub.com/f/DeterminateSystems/nix-src/%2A"
}
},
"nixlib": { "nixlib": {
"locked": { "locked": {
"lastModified": 1736643958, "lastModified": 1736643958,
@@ -336,11 +191,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1769813415, "lastModified": 1742568034,
"narHash": "sha256-nnVmNNKBi1YiBNPhKclNYDORoHkuKipoz7EtVnXO50A=", "narHash": "sha256-QaMEhcnscfF2MqB7flZr+sLJMMYZPnvqO4NYf9B4G38=",
"owner": "nix-community", "owner": "nix-community",
"repo": "nixos-generators", "repo": "nixos-generators",
"rev": "8946737ff703382fda7623b9fab071d037e897d5", "rev": "42ee229088490e3777ed7d1162cb9e9d8c3dbb11",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -351,57 +206,27 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1761597516, "lastModified": 1743259260,
"narHash": "sha256-wxX7u6D2rpkJLWkZ2E932SIvDJW8+ON/0Yy8+a5vsDU=", "narHash": "sha256-ArWLUgRm1tKHiqlhnymyVqi5kLNCK5ghvm06mfCl4QY=",
"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": "a62e6edd6d5e1fa0329b8653c801147986f8d446", "rev": "eb0e0f21f15c559d2ac7633dc81d079d1caf5f5f",
"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": 1775710090, "lastModified": 1744098102,
"narHash": "sha256-ar3rofg+awPB8QXDaFJhJ2jJhu+KqN/PRCXeyuXR76E=", "narHash": "sha256-tzCdyIJj9AjysC3OuKA+tMD/kDEDAF9mICPDU7ix0JA=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "4c1018dae018162ec878d42fec712642d214fdfa", "rev": "c8cd81426f45942bb2906d5ed2fe21d2f19d95b7",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -413,46 +238,16 @@
}, },
"nixpkgs_2": { "nixpkgs_2": {
"locked": { "locked": {
"lastModified": 1775464765, "lastModified": 1743813633,
"narHash": "sha256-nex6TL2x1/sVHCyDWcvl1t/dbTedb9bAGC4DLf/pmYk=", "narHash": "sha256-BgkBz4NpV6Kg8XF7cmHDHRVGZYnKbvG0Y4p+jElwxaM=",
"rev": "83e29f2b8791f6dec20804382fcd9a666d744c07",
"revCount": 975711,
"type": "tarball",
"url": "https://api.flakehub.com/f/pinned/DeterminateSystems/nixpkgs-weekly/0.1.975711%2Brev-83e29f2b8791f6dec20804382fcd9a666d744c07/019d6689-cde2-7061-b044-e0ef61ade488/source.tar.gz"
},
"original": {
"type": "tarball",
"url": "https://flakehub.com/f/DeterminateSystems/nixpkgs-weekly/0.1"
}
},
"nixpkgs_3": {
"locked": {
"lastModified": 1773628058,
"narHash": "sha256-hpXH0z3K9xv0fHaje136KY872VT2T5uwxtezlAskQgY=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "f8573b9c935cfaa162dd62cc9e75ae2db86f85df", "rev": "7819a0d29d1dd2bc331bec4b327f0776359b1fa6",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"ref": "nixpkgs-unstable", "ref": "nixos-24.11",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_4": {
"locked": {
"lastModified": 1776067740,
"narHash": "sha256-B35lpsqnSZwn1Lmz06BpwF7atPgFmUgw1l8KAV3zpVQ=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "7e495b747b51f95ae15e74377c5ce1fe69c1765f",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-25.11",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }
@@ -460,32 +255,46 @@
"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_4", "nixpkgs": "nixpkgs_2",
"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_3", "flake-compat": "flake-compat_2",
"flake-utils-plus": "flake-utils-plus", "flake-utils-plus": "flake-utils-plus",
"nixpkgs": [ "nixpkgs": [
"nixpkgs" "nixpkgs"
] ]
}, },
"locked": { "locked": {
"lastModified": 1765361626, "lastModified": 1736130495,
"narHash": "sha256-kX0Dp/kYSRbQ+yd9e3lmmUWdNbipufvKfL2IzbrSpnY=", "narHash": "sha256-4i9nAJEZFv7vZMmrE0YG55I3Ggrtfo5/T07JEpEZ/RM=",
"owner": "snowfallorg", "owner": "snowfallorg",
"repo": "lib", "repo": "lib",
"rev": "c566ad8b7352c30ec3763435de7c8f1c46ebb357", "rev": "02d941739f98a09e81f3d2d9b3ab08918958beac",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -501,11 +310,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1776119890, "lastModified": 1743910657,
"narHash": "sha256-Zm6bxLNnEOYuS/SzrAGsYuXSwk3cbkRQZY0fJnk8a5M=", "narHash": "sha256-zr2jmWeWyhCD8WmO2aWov2g0WPPuZfcJDKzMJZYGq3Y=",
"owner": "Mic92", "owner": "Mic92",
"repo": "sops-nix", "repo": "sops-nix",
"rev": "d4971dd58c6627bfee52a1ad4237637c0a2fb0cd", "rev": "523f58a4faff6c67f5f685bed33a7721e984c304",
"type": "github" "type": "github"
}, },
"original": { "original": {

View File

@@ -2,20 +2,19 @@
description = "NixOS Hosts"; description = "NixOS Hosts";
inputs = { inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11"; nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.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-25.11"; url = "github:nix-community/home-manager/release-24.11";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
apple-silicon = { apple-silicon = {
url = "github:nix-community/nixos-apple-silicon"; url = "github:tpwrules/nixos-apple-silicon/releasep2-2024-12-25";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
nixos-generators = { nixos-generators = {
@@ -30,14 +29,9 @@
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 = outputs = inputs:
inputs:
inputs.snowfall-lib.mkFlake { inputs.snowfall-lib.mkFlake {
inherit inputs; inherit inputs;
src = ./.; src = ./.;
@@ -57,27 +51,14 @@
]; ];
}; };
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
./modules/home/common
]; ];
systems.modules = { systems.modules = {
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,13 +1,9 @@
{ lib { lib, config, namespace, ... }:
, config
, namespace
, ...
}:
let let
inherit (lib.${namespace}) enabled; inherit (lib.${namespace}) enabled;
in in
{ {
home.stateVersion = "25.11"; home.stateVersion = "24.11";
reichard = { reichard = {
user = { user = {
@@ -15,6 +11,15 @@ 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;
@@ -27,12 +32,26 @@ in
git = enabled; git = enabled;
k9s = enabled; k9s = enabled;
nvim = enabled; nvim = enabled;
opencode = enabled; };
}; };
}; };
security = { # Global Packages
sops = enabled; # 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,14 +1,9 @@
{ pkgs { pkgs, lib, config, namespace, ... }:
, lib
, config
, namespace
, ...
}:
let let
inherit (lib.${namespace}) enabled; inherit (lib.${namespace}) enabled;
in in
{ {
home.stateVersion = "25.11"; home.stateVersion = "24.11";
reichard = { reichard = {
user = { user = {
@@ -16,48 +11,47 @@ 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;
customProfile = builtins.readFile ./vm-init.sh;
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;
opencode = enabled; aws = enabled;
pi = enabled;
zk = enabled;
}; };
}; };
services = {
# nunc = enabled;
sketchybar = 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; [
# colima android-tools
docker imagemagick
keycastr mosh
reichard.slack-cli python311
_1password-cli texliveSmall # Pandoc PDF Dep
google-cloud-sdk
tldr
]; ];
# SQLite Configuration
home.file.".sqliterc".text = ''
.headers on
.mode column
'';
} }

View File

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

View File

@@ -1,39 +0,0 @@
echo "
██████╗██████╗ ██████╗ ██╗ ██╗██████╗ ███████╗████████╗██████╗ ██╗██╗ ██╗███████╗
██╔════╝██╔══██╗██╔═══██╗██║ ██║██╔══██╗██╔════╝╚══██╔══╝██╔══██╗██║██║ ██╔╝██╔════╝
██║ ██████╔╝██║ ██║██║ █╗ ██║██║ ██║███████╗ ██║ ██████╔╝██║█████╔╝ █████╗
██║ ██╔══██╗██║ ██║██║███╗██║██║ ██║╚════██║ ██║ ██╔══██╗██║██╔═██╗ ██╔══╝
╚██████╗██║ ██║╚██████╔╝╚███╔███╔╝██████╔╝███████║ ██║ ██║ ██║██║██║ ██╗███████╗
╚═════╝╚═╝ ╚═╝ ╚═════╝ ╚══╝╚══╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═╝╚══════╝
EVASION SYSTEM - Because IT can't handle Nix 
"
# Start VM
utmctl=/Applications/UTM.app/Contents/MacOS/utmctl
vm="lin-va-mbp-work-vm"
if ! "$utmctl" status "$vm" | grep -q "started"; then
echo " [*] CrowdStrike Evasion VM Starting..."
"$utmctl" start "$vm"
fi
# Wait for VM & Start Tunnel
if ! pgrep -f "ssh -N -D 1080 adios-cs" > /dev/null; then
echo " [*] VM Starting..."
until nc -z -w 2 192.168.64.3 22 &> /dev/null; do
sleep 2
done
echo " [✓] VM Started"
echo " [*] VM SOCKS Proxy Starting..."
ssh -N -D 1080 adios-cs &> /dev/null &
disown
echo " [✓] VM SOCKS Proxy Started"
else
echo " [✓] VM SOCKS Proxy Already Running"
fi
echo -e " [*] Connecting..."
# Connect to VM
mosh --ssh="ssh -q" adios-cs -- tmux new-session -A -s main

View File

@@ -1,15 +1,9 @@
{ pkgs { pkgs, lib, config, namespace, osConfig, ... }:
, lib
, config
, namespace
, osConfig
, ...
}:
let let
inherit (lib.${namespace}) enabled; inherit (lib.${namespace}) enabled;
in in
{ {
home.stateVersion = "25.11"; home.stateVersion = "24.11";
reichard = { reichard = {
user = { user = {
@@ -21,22 +15,23 @@ 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";
sshKeyPaths = [ "${config.home.homeDirectory}/.ssh/id_ed25519" ];
}; };
security = {
sops = enabled;
}; };
programs = { programs = {
graphical = { graphical = {
wms.hyprland = { wms.hyprland = {
enable = true; enable = true;
mainMod = "ALT"; monitors = [
monitors = [ ",highres,auto,2" ]; # Alternatively - 1.68 ",highres,auto,2" # Optional - 1.68
];
}; };
ghostty = enabled; ghostty = enabled;
ghidra = enabled; ghidra = enabled;
gimp = enabled;
browsers.firefox = { browsers.firefox = {
enable = true; enable = true;
gpuAcceleration = true; gpuAcceleration = true;
@@ -50,15 +45,13 @@ 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; [
orca-slicer # catppuccin-gtk
]; # ];
dconf = { dconf = {
settings = { settings = {
@@ -66,10 +59,15 @@ 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";
@@ -80,7 +78,26 @@ 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/lin-va-kube"; path = "${config.home.homeDirectory}/.kube/rke2";
}; };
}; };
# 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,39 +0,0 @@
{ 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 = {
enable = true;
customFastFetchLogo = ./prophet.txt;
};
btop = enabled;
claude-code = enabled;
direnv = enabled;
git = enabled;
k9s = enabled;
nvim = enabled;
pi = enabled;
tmux = enabled;
};
};
};
}

View File

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

View File

@@ -1,29 +0,0 @@
{ 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

@@ -1,31 +0,0 @@
{ 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

@@ -1,40 +0,0 @@
{ 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,15 +1,9 @@
{ pkgs { pkgs, lib, config, namespace, osConfig, ... }:
, lib
, config
, namespace
, osConfig
, ...
}:
let let
inherit (lib.${namespace}) enabled; inherit (lib.${namespace}) enabled;
in in
{ {
home.stateVersion = "25.11"; home.stateVersion = "24.11";
reichard = { reichard = {
user = { user = {
@@ -21,22 +15,18 @@ in
ssh-agent = enabled; ssh-agent = enabled;
fusuma = enabled; fusuma = enabled;
swww = enabled; swww = enabled;
poweralertd = enabled; sops = {
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;
@@ -50,21 +40,29 @@ 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";
@@ -75,7 +73,13 @@ 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/lin-va-kube"; path = "${config.home.homeDirectory}/.kube/rke2";
}; };
}; };
# SQLite Configuration
home.file.".sqliterc".text = ''
.headers on
.mode column
'';
} }

View File

@@ -1,15 +1,9 @@
{ pkgs { pkgs, lib, config, namespace, osConfig, ... }:
, lib
, config
, namespace
, osConfig
, ...
}:
let let
inherit (lib.${namespace}) enabled; inherit (lib.${namespace}) enabled;
in in
{ {
home.stateVersion = "25.05"; home.stateVersion = "24.11";
reichard = { reichard = {
user = { user = {
@@ -21,10 +15,11 @@ 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";
sshKeyPaths = [ "${config.home.homeDirectory}/.ssh/id_ed25519" ];
}; };
security = {
sops = enabled;
}; };
programs = { programs = {
@@ -49,16 +44,25 @@ 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";
@@ -69,7 +73,26 @@ 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/lin-va-kube"; path = "${config.home.homeDirectory}/.kube/rke2";
}; };
}; };
# 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 +0,0 @@
{
config = {
nix.enable = false;
home-manager = {
useGlobalPkgs = true;
useUserPackages = true;
};
};
}

View File

@@ -1,35 +0,0 @@
{ 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

@@ -1,20 +0,0 @@
{ 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

@@ -1,23 +0,0 @@
{ 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

@@ -1,12 +0,0 @@
{ pkgs, ... }:
{
home.packages = with pkgs; [
sqlite-interactive
jnv
jq
ncdu
ripgrep
reichard.codexis
];
}

View File

@@ -38,12 +38,6 @@ 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";
@@ -59,7 +53,7 @@ in
settings = mkOpt attrs { } "Settings to apply to the profile."; settings = mkOpt attrs { } "Settings to apply to the profile.";
extensions.packages = mkOpt (with lib.types; listOf package) extensions = mkOpt (with lib.types; listOf package)
(with pkgs.firefox-addons; [ (with pkgs.firefox-addons; [
bitwarden bitwarden
darkreader darkreader

View File

@@ -0,0 +1,93 @@
{
"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,14 +10,62 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
# Enable Bash programs.bash = {
${namespace}.programs.terminal.bash.enable = true; 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
VISUAL=vim
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 # Pending Darwin @ https://github.com/NixOS/nixpkgs/pull/369788
home.packages = with pkgs; optionals isLinux [
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

@@ -1,24 +0,0 @@
{ 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

@@ -1,17 +0,0 @@
{ 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

@@ -1,17 +0,0 @@
{ 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

@@ -1,17 +0,0 @@
{ 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,6 +44,7 @@ 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 :)
@@ -126,7 +127,11 @@ input {
} }
# https://wiki.hyprland.org/Configuring/Variables/#gestures # https://wiki.hyprland.org/Configuring/Variables/#gestures
gesture = 4, horizontal, workspace, invert gestures {
workspace_swipe = true
workspace_swipe_fingers = 4
workspace_swipe_invert = true
}
# Thinkpad Trackpoint # Thinkpad Trackpoint
device { device {

View File

@@ -1,10 +1,4 @@
{ { 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;
@@ -14,9 +8,10 @@ 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" "main modifier key"; mainMod = mkOpt types.str "SUPER" "Hyprland main modifier key";
menuMod = mkOpt types.str "SUPER" "menu modifier key (i.e. menuMod + space)"; monitors = mkOpt (with types; listOf str) [
monitors = mkOpt (with types; listOf str) [ ", preferred, auto, 1" ] "monitor configuration"; ", preferred, auto, 1"
] "Hyprland monitor configuration";
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
@@ -27,26 +22,25 @@ 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 = [
# Menu Mod Bindings (macOS Transition - Spotlight & Screenshots) # Super Bindings (macOS Transition)
"$menuMod, SPACE, exec, $menu" "ALT_SHIFT, 1, exec, hyprshot -m output"
"$menuMod SHIFT, 1, exec, hyprshot -m output" "ALT_SHIFT, 2, exec, hyprshot -m window"
"$menuMod SHIFT, 2, exec, hyprshot -m window" "ALT_SHIFT, 3, exec, hyprshot -m region"
"$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, pin" "$mainMod, P, pseudo" # dwindle
"$mainMod, J, togglesplit" "$mainMod, J, togglesplit" # dwindle
"$mainMod, S, togglespecialworkspace, magic" "$mainMod, S, togglespecialworkspace, magic"
"$mainMod SHIFT, S, movetoworkspace, special:magic" "$mainMod SHIFT, S, movetoworkspace, special:magic"
@@ -93,12 +87,12 @@ in
",XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-" ",XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"
",XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle" ",XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"
",XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle" ",XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"
",XF86MonBrightnessUp, exec, brightnessctl s 4%+" ",XF86MonBrightnessUp, exec, brightnessctl s 10%+"
",XF86MonBrightnessDown, exec, brightnessctl s 5%-" ",XF86MonBrightnessDown, exec, brightnessctl s 10%-"
# macOS Keyboard Brightness # macOS Keyboard Brightness
"$menuMod, XF86MonBrightnessUp, exec, brightnessctl -d kbd_backlight s 10%+" "ALT, XF86MonBrightnessUp, exec, brightnessctl -d kbd_backlight s 10%+"
"$menuMod, XF86MonBrightnessDown, exec, brightnessctl -d kbd_backlight s 10%-" "ALT, XF86MonBrightnessDown, exec, brightnessctl -d kbd_backlight s 10%-"
]; ];
bindl = [ bindl = [
# Player Controls # Player Controls
@@ -113,8 +107,7 @@ 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"; layer = "top";
position = "top"; position = "top";
mod = "dock"; mod = "dock";
@@ -137,9 +130,7 @@ in
"battery" "battery"
"clock" "clock"
]; ];
"hyprland/window" = { "hyprland/window" = { format = "{}"; };
format = "{}";
};
"wlr/workspaces" = { "wlr/workspaces" = {
on-scroll-up = "hyprctl dispatch workspace e+1"; on-scroll-up = "hyprctl dispatch workspace e+1";
on-scroll-down = "hyprctl dispatch workspace e-1"; on-scroll-down = "hyprctl dispatch workspace e-1";
@@ -249,11 +240,7 @@ in
phone = ""; phone = "";
portable = ""; portable = "";
car = ""; car = "";
default = [ default = [ "" "" "" ];
""
""
""
];
}; };
}; };
"pulseaudio#microphone" = { "pulseaudio#microphone" = {
@@ -266,8 +253,7 @@ in
on-scroll-down = "pamixer --default-source -d 5"; on-scroll-down = "pamixer --default-source -d 5";
scroll-step = 5; scroll-step = 5;
}; };
} }];
];
}; };
home.packages = with pkgs; [ home.packages = with pkgs; [

View File

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

View File

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

View File

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

View File

@@ -1,99 +0,0 @@
{ 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

@@ -1,75 +0,0 @@
#!/usr/bin/env bash
MODEL="qwen3-coder-next-80b-instruct"
SYSTEM_PROMPT="You are a shell command expert. Given a natural language query, generate a single shell command that accomplishes the task."
# Colors
CYAN='\033[0;36m'
YELLOW='\033[1;33m'
GREEN='\033[0;32m'
RESET='\033[0m'
hey-intern() {
local query="$*"
# Help
if [ -z "$query" ]; then
echo "Usage: hey-intern \"your query here\"" >&2
return 1
fi
# Execute LLM Request
response=$(curl -s -X POST "https://llm-api.va.reichard.io/v1/chat/completions" \
-H "Content-Type: application/json" \
-d "$(jq -n \
--arg model "$MODEL" \
--arg system "$SYSTEM_PROMPT" \
--arg user "$query" \
'{
model: $model,
temperature: 0.2,
messages: [
{role: "system", content: $system},
{role: "user", content: $user}
],
tools: [{
type: "function",
function: {
name: "generate_shell_command",
description: "Generate a shell command to answer a query",
parameters: {
type: "object",
properties: {
command: {type: "string", description: "The shell command to execute"}
},
required: ["command"]
}
}
}]
}')" | jq -r '.choices[0].message.tool_calls[0].function.arguments // empty')
# Extract Command
local command=$(echo "$response" | jq -r '.command // empty')
if [ -n "$command" ]; then
echo -e "\n ${CYAN}${command}${RESET}\n"
read -p "$(echo -e "${YELLOW}Would you like to run this command? [y/N]${RESET} ")" -n 1 -r
echo ""
if [[ $REPLY =~ ^[Yy]$ ]]; then
echo -e "${GREEN}Running...${RESET}\n"
history -s "$command"
eval "$command"
fi
else
echo "Failed to generate a valid command from the response." >&2
echo "Raw response: $response" >&2
return 1
fi
}
# Export Script
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
hey-intern "$@"
fi

View File

@@ -1,93 +0,0 @@
{ 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";
customProfile = mkOpt str "" "custom profile";
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
source <(fzf --bash)
VISUAL=vim
EDITOR="$VISUAL"
if [ -z "$CLAUDE_CODE_ENTRYPOINT" ]; then
fastfetch
fi
[[ -f ~/.bash_custom ]] && . ~/.bash_custom
source ${./config/hey-intern.sh}
''
+ cfg.customProfile;
};
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
'';
};
programs.fzf.enable = true;
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,9 +1,4 @@
{ lib { lib, config, namespace, ... }:
, pkgs
, config
, namespace
, ...
}:
let let
inherit (lib) mkIf; inherit (lib) mkIf;
cfg = config.${namespace}.programs.terminal.btop; cfg = config.${namespace}.programs.terminal.btop;
@@ -14,12 +9,10 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
programs.btop = { programs.btop.enable = true;
enable = true;
package = pkgs.btop-cuda;
};
home.file.".config/btop/btop.conf".text = builtins.readFile ./config/btop.conf; home.file.".config/btop/btop.conf".text =
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

@@ -1,89 +0,0 @@
{ 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;
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,9 +1,4 @@
{ pkgs { pkgs, lib, config, namespace, ... }:
, lib
, config
, namespace
, ...
}:
let let
inherit (lib) mkIf; inherit (lib) mkIf;
cfg = config.${namespace}.programs.terminal.git; cfg = config.${namespace}.programs.terminal.git;
@@ -16,12 +11,22 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
programs.git = { programs.git = {
enable = true; enable = true;
settings = { userName = "Evan Reichard";
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 = {
@@ -36,7 +41,6 @@ in
prune = true; prune = true;
pruneTags = true; pruneTags = true;
all = true; all = true;
forceUpdateTags = true;
}; };
help = { help = {
autocorrect = true; autocorrect = true;
@@ -69,16 +73,6 @@ 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 = {
@@ -88,7 +82,10 @@ in
}; };
}; };
home.packages = with pkgs; [ gh ]; home.packages = with pkgs; [
gitAndTools.gh
pre-commit
];
# Copy Configuration # Copy Configuration
xdg.configFile = { xdg.configFile = {

View File

@@ -0,0 +1,8 @@
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,9 +5,6 @@
-- 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 = " "
@@ -23,7 +20,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:append("unnamedplus") vim.opt.clipboard = "unnamed"
-- Always show the signcolumn -- Always show the signcolumn
vim.opt.signcolumn = "yes" vim.opt.signcolumn = "yes"
@@ -38,3 +35,35 @@ 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

@@ -12,7 +12,7 @@ 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({
@@ -26,7 +26,7 @@ cmp.setup({
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)
@@ -35,35 +35,35 @@ cmp.setup({
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

@@ -20,17 +20,17 @@ dapui.setup({
}, },
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
@@ -38,13 +38,13 @@ dapui.setup({
}, },
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()
@@ -58,13 +58,13 @@ vim.api.nvim_create_autocmd("FileType", {
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
}) })
-- Create KeyMaps -- Leader Keys
local opts = { noremap = true, silent = true } local opts = {noremap = true, silent = true}
vim.keymap.set('n', '<leader>db', dap.toggle_breakpoint, vim.tbl_extend("force", { desc = "Toggle Breakpoint" }, opts)) vim.keymap.set('n', '<leader>db', dap.toggle_breakpoint, opts)
vim.keymap.set('n', '<leader>dc', dap.continue, vim.tbl_extend("force", { desc = "Continue" }, opts)) vim.keymap.set('n', '<leader>du', dapui.toggle, opts)
vim.keymap.set('n', '<leader>dt', dapgo.debug_test, vim.tbl_extend("force", { desc = "Run Test" }, opts)) vim.keymap.set('n', '<leader>dc', dap.continue, opts)
vim.keymap.set('n', '<leader>du', dapui.toggle, vim.tbl_extend("force", { desc = "Toggle UI" }, opts)) vim.keymap.set('n', '<leader>dt', dapgo.debug_test, opts)

View File

@@ -1,35 +0,0 @@
-- 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

@@ -0,0 +1,6 @@
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

@@ -1,126 +0,0 @@
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 git_cmd(dir, cmd)
return vim.fn.system("git -C " .. vim.fn.escape(dir, " ") .. " " .. cmd)
end
local function git_cmd_list(dir, cmd)
return vim.fn.systemlist("git -C " .. vim.fn.escape(dir, " ") .. " " .. cmd)
end
local function yank(message)
vim.fn.setreg("+", message)
vim.notify("Copied:\n\t" .. message, vim.log.levels.INFO)
end
local function get_git_info()
local abs_path = vim.fn.expand("%:p")
local file_dir = vim.fn.fnamemodify(abs_path, ":h")
local git_root = git_cmd_list(file_dir, "rev-parse --show-toplevel")[1]
if vim.v.shell_error ~= 0 then
vim.notify("Failed to get git info", vim.log.levels.ERROR)
return
end
local git_repo = git_cmd(file_dir, "remote get-url origin"):match("([^/:]+/[^/.]+)%.?[^/]*$"):gsub("\n", "")
local git_branch = git_cmd(file_dir, "rev-parse --abbrev-ref HEAD"):gsub("\n", "")
return {
abs_path = abs_path,
file_dir = file_dir,
file = vim.fn.fnamemodify(abs_path, ":s?" .. git_root .. "/??"),
branch = git_branch,
repo = git_repo,
}
end
local function get_blame_info(file_dir, abs_path, line_num)
local blame_output = git_cmd_list(
file_dir,
"blame -L " .. line_num .. "," .. line_num .. " --porcelain " .. vim.fn.escape(abs_path, " ")
)
if vim.v.shell_error ~= 0 then
vim.notify("Failed to get git blame", vim.log.levels.ERROR)
return
end
local commit_hash = blame_output[1]:match("^(%S+)")
local original_line = blame_output[1]:match("^%S+ (%d+)")
local commit_file = nil
for _, line in ipairs(blame_output) do
local f = line:match("^filename (.+)$")
if f then
commit_file = f
break
end
end
if not commit_hash or not commit_file then
vim.notify("Failed to extract commit info", vim.log.levels.ERROR)
return
end
return {
hash = commit_hash,
line = tonumber(original_line),
file = commit_file,
file_hash = vim.fn.system("echo -n " .. vim.fn.shellescape(commit_file) .. " | sha256sum | cut -d' ' -f1"):gsub("\n",
""),
}
end
local function copy_git_link()
local git_info = get_git_info()
if not git_info then return end
local start_line = vim.fn.line("v")
local end_line = vim.fn.line(".")
yank(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
))
end
local function copy_commit_url()
local git_info = get_git_info()
if not git_info then return end
local blame = get_blame_info(git_info.file_dir, git_info.abs_path, vim.fn.line("."))
if not blame then return end
yank(string.format(
"https://github.com/%s/commit/%s#diff-%sR%d",
git_info.repo, blame.hash, blame.file_hash, blame.line
))
end
-- Keymaps
vim.keymap.set("v", "<Leader>gy", copy_git_link, { desc = "Copy GitHub Link" })
vim.keymap.set("n", "<Leader>gC", copy_commit_url, { desc = "Copy Commit URL" })
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

@@ -0,0 +1,41 @@
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

@@ -0,0 +1,16 @@
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,19 +1,23 @@
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("diagnostics-config") require("diffview-config")
require("git-config") require("git-ref")
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("octo-config") require("silicon-config")
require("snacks-config") require("telescope-config")
require("toggleterm-config") require("toggleterm-config")
require("ts-config") require("ts-config")
require("weird-chars")
require("which-key-config") require("which-key-config")
require("weird-chars")

View File

@@ -1,87 +0,0 @@
local llm_endpoint = "https://llm-api.va.reichard.io"
local llm_assistant_model = "qwen3.5-27b-thinking"
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 = { display = "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

@@ -0,0 +1,20 @@
-- 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,35 +8,22 @@ vim.api.nvim_create_autocmd("FileType", {
end, end,
}) })
require('render-markdown').setup({ vim.filetype.add({
completions = { lsp = { enabled = true } }, extension = {
file_types = { 'markdown', 'codecompanion' }, templ = "templ",
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)
if client:supports_method("textDocument/formatting") then local bufopts = { noremap = true, silent = true, buffer = bufnr }
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,
@@ -47,25 +34,17 @@ local on_attach = function(client, bufnr)
}) })
end end
-- Create KeyMaps vim.keymap.set("n", "K", vim.lsp.buf.hover, bufopts)
local bufopts = { noremap = true, silent = true, buffer = bufnr } vim.keymap.set("n", "<C-k>", vim.lsp.buf.signature_help, 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.declaration, bufopts)
vim.keymap.set("n", "<C-k>", vim.lsp.buf.signature_help, vim.keymap.set("n", "<leader>ld", vim.lsp.buf.definition, bufopts)
vim.tbl_extend("force", { desc = "Show signature help" }, bufopts)) vim.keymap.set("n", "<leader>li", vim.lsp.buf.implementation, bufopts)
vim.keymap.set("n", "<leader>lD", vim.lsp.buf.declaration, vim.keymap.set("n", "<leader>ln", vim.lsp.buf.rename, bufopts)
vim.tbl_extend("force", { desc = "Go to declaration" }, bufopts)) vim.keymap.set("n", "<leader>lr", vim.lsp.buf.references, bufopts)
vim.keymap.set("n", "<leader>ld", vim.lsp.buf.definition, vim.keymap.set("n", "<leader>lt", vim.lsp.buf.type_definition, bufopts)
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, vim.tbl_extend("force", { desc = "Format file" }, bufopts)) end, bufopts)
end end
local on_attach_no_formatting = function(client, bufnr) local on_attach_no_formatting = function(client, bufnr)
@@ -92,113 +71,81 @@ local organize_go_imports = function()
end end
end end
local default_config = { -- Define LSP Flags & Capabilities
flags = { debounce_text_changes = 150 }, local lsp_flags = { debounce_text_changes = 150 }
capabilities = require("cmp_nvim_lsp").default_capabilities(), local 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
setup_lsp("pyright", { nvim_lsp.pyright.setup({
filetypes = { "starlark", "python" }, on_attach = on_attach,
flags = lsp_flags,
capabilities = capabilities,
}) })
-- HTML LSP Configuration -- HTML LSP Configuration
setup_lsp("html", { nvim_lsp.html.setup({
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
setup_lsp("jsonls", { nvim_lsp.jsonls.setup({
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
setup_lsp("cssls", { nvim_lsp.cssls.setup({
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
setup_lsp("ts_ls", { nvim_lsp.ts_ls.setup({
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" },
}) })
-- ESLint LSP -- Svelte LSP Configuration
setup_lsp("eslint", { nvim_lsp.svelte.setup({
on_attach = on_attach_no_formatting, on_attach = on_attach_no_formatting,
cmd = { nix_vars.vscls .. "/bin/vscode-eslint-language-server", "--stdio" }, flags = lsp_flags,
}) 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
setup_lsp("lua_ls", { nvim_lsp.lua_ls.setup({
on_attach = on_attach_no_formatting,
flags = lsp_flags,
capabilities = capabilities,
cmd = { nix_vars.luals }, cmd = { nix_vars.luals },
filetypes = { "lua" },
}) })
-- Unison LSP Configuration -- Templ LSP Configuration
setup_lsp("unison") nvim_lsp.templ.setup({
on_attach = on_attach,
-- SQL Configuration flags = lsp_flags,
-- NOTE: root_markers resolves root_dir but Neovim does NOT use root_dir as capabilities = capabilities,
-- the process cwd (cmd_cwd defaults to Neovim's cwd). We use cmd as a
-- function so we can read root_dir from the resolved config and build an
-- absolute path to .sqls.yml.
setup_lsp("sqls", {
on_attach = on_attach_no_formatting,
root_markers = { ".sqls.yml", ".git" },
cmd = function(dispatchers, config)
local cmd = { nix_vars.sqls }
if config.root_dir then
local config_file = config.root_dir .. "/.sqls.yml"
if vim.fn.filereadable(config_file) == 1 then
cmd = { nix_vars.sqls, "-config", config_file }
end
end
return vim.lsp.rpc.start(cmd, dispatchers, {
cwd = config.root_dir,
})
end,
}) })
-- Nix LSP Configuration -- Nix LSP Configuration
setup_lsp("nil_ls", { nvim_lsp.nil_ls.setup({
filetypes = { "nix" }, on_attach = on_attach,
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
setup_lsp("gopls", { nvim_lsp.gopls.setup({
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", {
@@ -207,8 +154,9 @@ setup_lsp("gopls", {
callback = organize_go_imports, callback = organize_go_imports,
}) })
end, end,
filetypes = { "go" }, flags = lsp_flags,
cmd = { "gopls", "-remote=auto" }, capabilities = capabilities,
cmd = { nix_vars.gopls },
settings = { settings = {
gopls = { gopls = {
buildFlags = { "-tags=e2e" }, buildFlags = { "-tags=e2e" },
@@ -217,10 +165,11 @@ setup_lsp("gopls", {
}) })
-- Go LSP Linting -- Go LSP Linting
setup_lsp("golangci_lint_ls", { nvim_lsp.golangci_lint_ls.setup({
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",
@@ -234,32 +183,48 @@ setup_lsp("golangci_lint_ls", {
}) })
------------------------------------------------------ ------------------------------------------------------
--------------------- None-LS LSP -------------------- --------------------- Null-LS LSP --------------------
------------------------------------------------------ ------------------------------------------------------
local none_ls = require("null-ls") local null_ls = require("null-ls")
none_ls.setup({ local eslintFiles = {
".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 = {
-- Formatting -- Prettier Formatting
none_ls.builtins.formatting.prettier, null_ls.builtins.formatting.prettier,
none_ls.builtins.formatting.prettier.with({ filetypes = { "template" } }), null_ls.builtins.formatting.prettier.with({ filetypes = { "template" } }),
none_ls.builtins.formatting.nixpkgs_fmt, -- TODO: nixd native LSP? require("none-ls.diagnostics.eslint_d").with({
none_ls.builtins.formatting.sql_formatter.with({ condition = function(utils)
extra_args = { return has_eslint_in_parents(vim.fn.getcwd())
"--config", end,
'{"tabWidth":4,"keywordCase":"upper","language":"sql"}',
}
}), }),
require("none-ls.formatting.autopep8").with({ null_ls.builtins.completion.spell,
filetypes = { "starlark", "python" }, null_ls.builtins.formatting.nixpkgs_fmt,
extra_args = { "--max-line-length", "100" }, null_ls.builtins.formatting.stylua,
}), null_ls.builtins.diagnostics.sqlfluff,
null_ls.builtins.formatting.sqlfluff,
-- Completion
none_ls.builtins.completion.spell,
}, },
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

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

View File

@@ -3,12 +3,8 @@ 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 if err then return end
return if not data then return end
end
if not data then
return
end
cached_pr_status = data cached_pr_status = data
end end
@@ -18,13 +14,12 @@ local function execute_command()
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, function() vim.loop.spawn("bash", spawn_opts,
stdout:read_start(read_output) function() stdout:read_start(read_output) end)
end)
end end
-- Spawn & schedule process -- Spawn & schedule process
@@ -32,26 +27,23 @@ execute_command()
vim.fn.timer_start(300000, execute_command) vim.fn.timer_start(300000, execute_command)
-- Return status from cache -- Return status from cache
local function pr_status() 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 return cached_pr_status:gsub("\n", ""):gsub("fail", ""):gsub("pass",
:gsub("\n", "") "")
:gsub("fail", " ") :gsub("pending", ""):gsub("skipping", " "):sub(1, -2)
:gsub("pass", "")
:gsub("pending", "")
:gsub("skipping", "")
:sub(1, -2)
end end
require("lualine").setup({ require('lualine').setup({
options = { theme = "catppuccin" }, options = {
sections = { theme = "gruvbox_dark"
lualine_c = { { pr_status } }, -- theme = "nord"
-- lualine_z = { require("opencode").statusline } -- theme = "OceanicNext",
}, },
sections = {lualine_c = {{pr_status}}}
}) })

View File

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

View File

@@ -1,14 +1,26 @@
-- 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({
-- Ignore (Snacks Priority) lsp = {
routes = { override = {
{ ["vim.lsp.util.convert_input_to_markdown_lines"] = true,
filter = { event = "ui", kind = "input", }, ["vim.lsp.util.stylize_markdown"] = true,
opts = { skip = true }, ["cmp.entry.get_documentation"] = false
},
{
filter = { event = "ui", kind = "select", },
opts = { skip = true },
}, },
signature = {enabled = false}
}, },
presets = {
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

@@ -1,13 +0,0 @@
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

@@ -1,71 +0,0 @@
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

@@ -0,0 +1,10 @@
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

@@ -1,23 +0,0 @@
-- 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

@@ -0,0 +1,20 @@
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
-- -- })
--
-- -- Duplicate C-w & Esc Behavior
-- function _G.set_terminal_keymaps()
-- local opts = {buffer = 0}
-- vim.opt.signcolumn = "no"
-- vim.keymap.set('t', '<esc>', [[<C-\><C-n>]], opts)
-- vim.keymap.set('t', '<C-w>', [[<C-\><C-n><C-w>]], opts)
-- end -- end
-- -- })
-- vim.cmd('autocmd! TermOpen term://* lua set_terminal_keymaps()')
-- Duplicate C-w & Esc Behavior
function _G.set_terminal_keymaps()
local opts = {buffer = 0}
vim.opt.signcolumn = "no"
vim.keymap.set('t', '<esc>', [[<C-\><C-n>]], opts)
vim.keymap.set('t', '<C-w>', [[<C-\><C-n><C-w>]], opts)
end
vim.cmd('autocmd! TermOpen term://* lua set_terminal_keymaps()')

View File

@@ -1,4 +1,3 @@
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,9 +1,47 @@
local wk = require("which-key") local wk = require("which-key")
wk.setup({})
wk.add({ wk.add({
{ "<leader>a", group = "LLM" }, -- llm-config.lua { "<C-k>", desc = "Signature Help" },
{ "<leader>f", group = "Find" }, -- snacks-config.lua { "<leader>a", desc = "Aerial" },
{ "<leader>l", group = "LSP" }, -- lsp-config.lua { "<leader>d", group = "Debug" },
{ "<leader>g", group = "Git" }, -- git-config.lua { "<leader>db", desc = "Toggle Breakpoint" },
{ "<leader>q", group = "Diagnostics" }, -- diagnostics-config.lua { "<leader>dc", desc = "Continue" },
{ "<leader>d", group = "Debug" }, -- dap-config.lua { "<leader>dt", desc = "Run Test" },
{ "<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,9 +1,4 @@
{ pkgs { pkgs, lib, config, namespace, ... }:
, lib
, config
, namespace
, ...
}:
let let
inherit (lib) mkIf; inherit (lib) mkIf;
cfg = config.${namespace}.programs.terminal.nvim; cfg = config.${namespace}.programs.terminal.nvim;
@@ -39,29 +34,31 @@ 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 (),[],{}
octo-nvim # Git Octo telescope-fzf-native-nvim # Faster Telescope
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
@@ -78,61 +75,87 @@ 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; [
# LSP # Telescope Dependencies
eslint_d fd
ripgrep
tree-sitter
# LSP Dependencies
go go
golangci-lint golangci-lint
golangci-lint-langserver golangci-lint-langserver
gopls
lua-language-server lua-language-server
nil nil
nodePackages.eslint nodePackages.eslint
@@ -141,20 +164,17 @@ in
nodePackages.typescript-language-server nodePackages.typescript-language-server
nodePackages.vscode-langservers-extracted nodePackages.vscode-langservers-extracted
pyright pyright
python312Packages.autopep8 eslint_d
# Formatters # Formatters
luaformatter luaformatter
nixpkgs-fmt nixpkgs-fmt
nodePackages.prettier nodePackages.prettier
sqlfluff
stylua stylua
sql-formatter
# Tools # Silicon
ripgrep silicon
lazygit
git
gh
]; ];
extraConfig = ":luafile ~/.config/nvim/lua/init.lua"; extraConfig = ":luafile ~/.config/nvim/lua/init.lua";
@@ -168,19 +188,14 @@ 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", gopls = "${pkgs.gopls}/bin/gopls",
clangd = "${pkgs.clang-tools}/bin/clangd",
golintls = "${pkgs.golangci-lint-langserver}/bin/golangci-lint-langserver",
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

@@ -1,65 +0,0 @@
---
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

@@ -1,51 +0,0 @@
---
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

@@ -1,37 +0,0 @@
---
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

@@ -1,100 +0,0 @@
---
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

@@ -1,54 +0,0 @@
---
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

@@ -1,42 +0,0 @@
---
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

@@ -1,83 +0,0 @@
{ 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

@@ -1,51 +0,0 @@
{ 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

@@ -1,63 +0,0 @@
# 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")
```
## Principles
1. **KISS / YAGNI** - Keep solutions simple and straightforward. Don't introduce abstractions, generics, or indirection unless there is a concrete, immediate need. Prefer obvious code over clever code.
2. **Maintain AGENTS.md** - If the project has an `AGENTS.md`, keep it up to date as conventions or architecture evolve. However, follow the **BLUF** (Bottom Line Up Front) principle: keep it concise, actionable, and context-size conscious. Don't overload it with information that belongs in code comments or external docs.
## Style
### Comment Style
A logical "block" of code (doesn't have to be a scope, but a cohesive group of statements responsible for something) should have a comment above it with a short "title". The title must be in **Title Case**. For example:
```go
// Map Component Results
for _, comp := range components {
results[comp.Name] = comp.Result
}
```
If the block is more complicated or non-obvious, explain _why_ it does what it does after the title:
```go
// Map Component Results - This is needed because downstream consumers
// expect a name-keyed lookup. Without it, the renderer would fall back
// to O(n) scans on every frame.
for _, comp := range components {
results[comp.Name] = comp.Result
}
```

View File

@@ -1,19 +0,0 @@
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
export default function replacePiWithClaudeCodeExtension(pi: ExtensionAPI) {
pi.on("before_agent_start", async (event) => {
// Replace "pi" With "claude code" - Exclude Literal ".pi" (e.g. Paths)
const transformedSystemPrompt = event.systemPrompt.replace(
/(?<!\.)pi/gi,
"claude code",
);
if (transformedSystemPrompt === event.systemPrompt) {
return undefined;
}
return {
systemPrompt: transformedSystemPrompt,
};
});
}

View File

@@ -1,34 +0,0 @@
---
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

@@ -1,64 +0,0 @@
---
name: address-gh-review
description: 'Fetch and address unresolved GitHub PR review comments. Use when user asks to handle PR reviews, address review feedback, mentions "/address-gh-review", or wants to see what reviewers requested. Fetches unresolved threads, presents an actionable summary, and lets the user select which items to address.'
---
# GitHub PR Review
## Overview
Fetch unresolved review threads from the current PR, consolidate them into actionable items, and address selected items — each as a separate commit.
## Prerequisites
- `gh` CLI authenticated and in a repo with an open PR on the current branch
- The `git-commit` skill available for committing changes
## Workflow
### 1. Fetch Review Comments
Run the bundled script to get unresolved threads:
```bash
bash gh_review.sh
```
If the script fails (no PR, not authenticated, etc.), report the error and stop.
### 2. Consolidate into Actionable Items
Parse the output and group into actionable items. Combine threads that ask for the same change (e.g. multiple reviewers commenting on the same function about the same concern). Keep items separate when they require distinct code changes.
Present a numbered list to the user:
```
## Unresolved Review Items
1. **src/auth/login.ts:42** — Add rate limiting to prevent brute force attacks (alice-dev)
2. **src/utils/validators.ts:89** — Use stricter type checking for email validation (bob-coder)
3. **src/api/users.ts:156** — Add error handling for null responses (alice-dev, charlie-reviewer)
```
### 3. Ask User for Selection
**Always ask before proceeding.** Prompt the user to select which items to address:
```
Which items would you like me to address? (e.g. "1,3", "all", or "none")
```
**Do not proceed until the user responds.** Respect "none" — just stop.
### 4. Address Each Item
For each selected item, in order:
1. Read the relevant file and understand the context around the referenced line
2. Implement the requested change
3. Run relevant linting/tests if applicable (e.g. `quicklint`)
4. Commit using the `git-commit` skill — **one commit per item**
### 5. Summary
After all selected items are addressed, print a brief summary of what was done.

View File

@@ -1,71 +0,0 @@
#!/usr/bin/env bash
# Fetch unresolved PR review threads, formatted for LLM consumption.
# Omits diff hunks (the LLM can read files from the repo directly).
# Groups comments into threads so conversation context is preserved.
set -euo pipefail
err() { echo "error: $1" >&2; exit 1; }
# Verify gh CLI is installed
command -v gh >/dev/null 2>&1 || err "'gh' CLI not found. Install it from https://cli.github.com"
# Verify we're inside a git repository
git rev-parse --is-inside-work-tree >/dev/null 2>&1 || err "not inside a git repository"
# Verify the remote is a GitHub repo
gh repo view --json name -q .name >/dev/null 2>&1 || err "this repo does not appear to be hosted on GitHub"
# Verify we're on a PR branch
PR_NUM=$(gh pr view --json number -q .number 2>/dev/null) || err "no pull request found for the current branch"
# Fetch current user, repo owner, and repo name
ME=$(gh api user -q .login 2>/dev/null) || err "failed to fetch GitHub user - are you authenticated? Run 'gh auth login'"
OWNER=$(gh repo view --json owner -q .owner.login 2>/dev/null) || err "failed to determine repository owner"
REPO=$(gh repo view --json name -q .name 2>/dev/null) || err "failed to determine repository name"
# Fetch unresolved review threads via GraphQL
OUTPUT=$(gh api graphql -f query='
query {
repository(owner: "'"$OWNER"'", name: "'"$REPO"'") {
pullRequest(number: '"$PR_NUM"') {
reviewThreads(first: 100) {
nodes {
isResolved
comments(first: 100) {
nodes {
author { login }
body
path
line
}
}
}
}
}
}
}' --jq '
[
.data.repository.pullRequest.reviewThreads.nodes[]
| select(.isResolved == false)
| {
file: .comments.nodes[0].path,
line: .comments.nodes[0].line,
comments: [
.comments.nodes[]
| select(.author.login != "'"$ME"'")
| {author: .author.login, body: .body}
]
}
| select(.comments | length > 0)
]
| .[]
| "## \(.file):\(.line)\n\(.comments | map("- **\(.author)**: \(.body)") | join("\n"))\n"
' 2>/dev/null) || err "GraphQL query failed - check your permissions and token scopes"
# Format output
if [[ -z "$OUTPUT" ]]; then
echo "No unresolved review comments found."
else
echo "$OUTPUT" | sed 's/\\n/\n/g'
fi

View File

@@ -1,136 +0,0 @@
---
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, mentions "/commit", or simply says "do it". Automatically commits without confirmation. Supports: (1) Auto-detecting type and scope from changes, (2) Generating conventional commit messages from diff, (3) 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.
## Automatic Execution — CRITICAL
**When this skill is invoked, EXECUTE THE COMMIT IMMEDIATELY. Do NOT ask for confirmation. Do NOT say "I'm ready" or "let me know when you want to proceed." Do NOT wait for further input. Do NOT acknowledge and then wait.**
The skill is invoked when the user says "commit", "do it", "/commit", "make a commit", "create a commit", or any similar phrase. The moment you recognize this intent, analyze the diff and run `git commit`. That's it.
**Zero prompts. Zero confirmation requests. Zero hand-holding.**
Only skip the commit if:
- Nothing is staged or modified (say "Nothing to commit" and stop)
- Secrets appear to be about to be committed (refuse and stop)
For everything else — just commit.
## 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

@@ -1,57 +0,0 @@
{ 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;
};
".pi/agent/extensions" = {
source = ./config/extensions;
recursive = true;
};
};
};
}

View File

@@ -1,58 +0,0 @@
{ 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

@@ -1,71 +0,0 @@
{ 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 -g default-terminal "tmux-256color"
set -ag terminal-overrides ",xterm-256color:Tc:Ms=\\E]52;c%p1%.0s;%p2%s\\7"
set -g extended-keys-format csi-u
set -g extended-keys on
set -sg escape-time 0
# Start Index 1
set -g base-index 1
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

@@ -1,22 +0,0 @@
{ lib
, config
, namespace
, ...
}:
let
inherit (lib) mkIf;
cfg = config.${namespace}.programs.terminal.zk;
in
{
options.${namespace}.programs.terminal.zk = {
enable = lib.mkEnableOption "enable zk";
};
config = mkIf cfg.enable {
programs.zk = {
enable = true;
};
programs.fzf.enable = true;
};
}

View File

@@ -1,37 +0,0 @@
{ 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

@@ -1,109 +0,0 @@
{ config
, lib
, pkgs
, namespace
, ...
}:
let
cfg = config.${namespace}.services.nunc;
in
{
options.${namespace}.services.nunc = {
enable = lib.mkEnableOption "nunc floating clock overlay";
settings = lib.mkOption {
type = lib.types.submodule {
options = {
fontSize = lib.mkOption {
type = lib.types.number;
default = 12;
description = "Font size for the clock display.";
};
verticalPadding = lib.mkOption {
type = lib.types.number;
default = 9;
description = "Vertical padding around the clock text.";
};
horizontalPadding = lib.mkOption {
type = lib.types.number;
default = 20;
description = "Horizontal padding around the clock text.";
};
position = lib.mkOption {
type = lib.types.enum [
"top_left"
"top_center"
"top_right"
"bottom_left"
"bottom_center"
"bottom_right"
];
default = "top_right";
description = "Position of the clock overlay on screen.";
};
offsetX = lib.mkOption {
type = lib.types.number;
default = -12;
description = "Horizontal offset from the base position.";
};
offsetY = lib.mkOption {
type = lib.types.number;
default = 4;
description = "Vertical offset from the base position.";
};
dateFormat = lib.mkOption {
type = lib.types.str;
default = "EEE MMM d HH:mm:ss";
description = "Date format string (NSDateFormatter / Unicode TR35 format).";
};
};
};
default = { };
description = "Nunc configuration. Written to ~/.config/nunc/config.json.";
};
};
config = lib.mkIf cfg.enable {
assertions = [
{
assertion = pkgs.stdenv.isDarwin;
message = "reichard.services.nunc is only supported on macOS (Darwin).";
}
];
home.packages = [ pkgs.reichard.nunc ];
home.file.".config/nunc/config.json" = {
text = builtins.toJSON {
inherit (cfg.settings)
fontSize
verticalPadding
horizontalPadding
position
offsetX
offsetY
dateFormat
;
};
};
launchd.agents.nunc = {
enable = true;
config = {
Label = "io.reichard.nunc";
Program = "${pkgs.reichard.nunc}/bin/nunc";
RunAtLoad = true;
KeepAlive = true;
ProcessType = "Interactive";
StandardOutPath = "${config.home.homeDirectory}/Library/Logs/nunc/nunc.out.log";
StandardErrorPath = "${config.home.homeDirectory}/Library/Logs/nunc/nunc.err.log";
};
};
};
}

View File

@@ -1,17 +0,0 @@
{ 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,178 +0,0 @@
{ config
, lib
, pkgs
, namespace
, ...
}:
let
cfg = config.${namespace}.services.sketchybar;
colors = {
white = "0xddffffff";
white_dim = "0x99ffffff";
bg = "0x1a808080";
transparent = "0x00000000";
green = "0xff8ceb34";
yellow = "0xffe8d44d";
red = "0xffed4f51";
};
sketchybarConfig = ''
#!/usr/bin/env bash
COLOR_BG="${colors.bg}"
COLOR_WHITE="${colors.white}"
COLOR_WHITE_DIM="${colors.white_dim}"
COLOR_GREEN="${colors.green}"
COLOR_YELLOW="${colors.yellow}"
COLOR_RED="${colors.red}"
COLOR_TRANSPARENT="${colors.transparent}"
FONT_FACE="SF Pro"
NERD_FONT="Symbols Nerd Font Mono:Regular:16.0"
PADDING=6
# Bar - transparent, top
sketchybar --bar \
height=36 \
position=top \
color=$COLOR_TRANSPARENT \
shadow=off \
sticky=on \
topmost=off \
padding_left=0 \
padding_right=12 \
y_offset=3
# Defaults
sketchybar --default \
icon.font="$NERD_FONT" \
icon.color=$COLOR_WHITE \
icon.padding_left=$(($PADDING + 2)) \
icon.padding_right=2 \
label.font="$FONT_FACE:Medium:13.0" \
label.color=$COLOR_WHITE \
label.padding_left=2 \
label.padding_right=$(($PADDING + 2)) \
background.color=$COLOR_BG \
background.corner_radius=6 \
background.clip=0.5 \
background.height=32 \
background.padding_left=4 \
blur_radius=30 \
background.padding_right=4
# Right side items (rightmost leftmost)
# Clock
sketchybar --add item clock right \
--set clock \
icon=󰃰 \
icon.color=$COLOR_WHITE_DIM \
update_freq=1 \
script="${pkgs.writeShellScript "sketchybar-clock" ''
sketchybar --set $NAME label="$(date '+%a %b %-d %H:%M:%S')"
''}"
# Battery
sketchybar --add item battery right \
--set battery \
update_freq=30 \
script="${pkgs.writeShellScript "sketchybar-battery" ''
PERCENTAGE="$(pmset -g batt | grep -Eo "\d+%" | head -1)"
CHARGING="$(pmset -g batt | grep -c "AC Power")"
PCT="''${PERCENTAGE//\%/}"
if [ "$CHARGING" -gt 0 ]; then
ICON="󰂄"
COLOR="${colors.green}"
elif [ "$PCT" -ge 80 ]; then
ICON="󰁹"
COLOR="${colors.green}"
elif [ "$PCT" -ge 60 ]; then
ICON="󰂀"
COLOR="${colors.green}"
elif [ "$PCT" -ge 40 ]; then
ICON="󰁾"
COLOR="${colors.yellow}"
elif [ "$PCT" -ge 20 ]; then
ICON="󰁼"
COLOR="${colors.yellow}"
else
ICON="󰁺"
COLOR="${colors.red}"
fi
sketchybar --set $NAME icon="$ICON" icon.color="$COLOR" label="$PERCENTAGE"
''}" \
--subscribe battery power_source_change system_woke
# Volume
sketchybar --add item volume right \
--set volume \
script="${pkgs.writeShellScript "sketchybar-volume" ''
VOL="$(osascript -e 'output volume of (get volume settings)')"
MUTED="$(osascript -e 'output muted of (get volume settings)')"
if [ "$MUTED" = "true" ]; then
ICON="󰖁"
elif [ "$VOL" -ge 60 ]; then
ICON="󰕾"
elif [ "$VOL" -ge 30 ]; then
ICON="󰖀"
elif [ "$VOL" -gt 0 ]; then
ICON="󰕿"
else
ICON="󰖁"
fi
sketchybar --set $NAME icon="$ICON" label="''${VOL}%"
''}" \
--subscribe volume volume_change
# Wi-Fi
sketchybar --add item wifi right \
--set wifi \
icon=󰖩 \
icon.color=$COLOR_WHITE_DIM \
update_freq=10 \
script="${pkgs.writeShellScript "sketchybar-wifi" ''
EN="$(networksetup -listallhardwareports | awk '/Wi-Fi|AirPort/{getline; print $NF}')"
if ipconfig getsummary "$EN" | grep -Fxq " Active : FALSE"; then
sketchybar --set $NAME icon=󰖪 label="Off"
else
SSID="$(networksetup -listpreferredwirelessnetworks "$EN" | sed -n '2s/^\t//p')"
if [ -n "$SSID" ]; then
sketchybar --set $NAME icon=󰖩 label="$SSID"
else
sketchybar --set $NAME icon=󰖪 label="Off"
fi
fi
''}"
sketchybar --update
'';
in
{
options.${namespace}.services.sketchybar = {
enable = lib.mkEnableOption "sketchybar status bar";
};
config = lib.mkIf cfg.enable {
assertions = [
{
assertion = pkgs.stdenv.isDarwin;
message = "reichard.services.sketchybar is only supported on macOS (Darwin).";
}
];
programs.sketchybar = {
enable = true;
extraPackages = [
pkgs.sketchybar-app-font
];
config = sketchybarConfig;
service.enable = true;
};
};
}

View File

@@ -0,0 +1,41 @@
{ 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,9 +1,4 @@
{ config { config, lib, pkgs, namespace, ... }:
, lib
, pkgs
, namespace
, ...
}:
let let
cfg = config.${namespace}.services.swww; cfg = config.${namespace}.services.swww;
in in

View File

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

View File

@@ -1,9 +1,4 @@
{ config { config, lib, pkgs, namespace, ... }:
, lib
, pkgs
, namespace
, ...
}:
let let
inherit (lib) mkIf types; inherit (lib) mkIf types;
inherit (lib.${namespace}) mkOpt; inherit (lib.${namespace}) mkOpt;
@@ -22,7 +17,7 @@ in
sddm = { sddm = {
inherit (cfg) enable; inherit (cfg) enable;
package = pkgs.kdePackages.sddm; package = pkgs.kdePackages.sddm;
theme = "catppuccin-mocha-mauve"; theme = "catppuccin-mocha";
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; inherit (lib.${namespace}) mkOpt mkBoolOpt;
cfg = config.${namespace}.hardware.asahi; cfg = config.${namespace}.hardware.asahi;
in in
@@ -12,6 +12,7 @@ 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";
}; };
@@ -20,6 +21,7 @@ in
enable = cfg.enable; enable = cfg.enable;
} // optionalAttrs cfg.enable { } // optionalAttrs cfg.enable {
peripheralFirmwareDirectory = cfg.firmwareDirectory; peripheralFirmwareDirectory = cfg.firmwareDirectory;
useExperimentalGPUDriver = cfg.enableGPU;
}; };
}; };
} }

View File

@@ -1,15 +0,0 @@
{ 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,9 +1,4 @@
{ config { config, lib, pkgs, namespace, ... }:
, lib
, pkgs
, namespace
, ...
}:
let let
inherit (lib) mkIf mkForce; inherit (lib) mkIf mkForce;
inherit (lib.${namespace}) mkBoolOpt; inherit (lib.${namespace}) mkBoolOpt;
@@ -19,25 +14,14 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
services.xserver.videoDrivers = mkIf cfg.enableNvidia [ "nvidia" ]; environment.systemPackages = with pkgs; [
environment.systemPackages =
with pkgs;
[
libva-utils libva-utils
vdpauinfo vdpauinfo
] ] ++ lib.optionals cfg.enableNvidia [
++ lib.optional cfg.enableNvidia nvtopPackages.nvidia nvtopPackages.full
++ lib.optional cfg.enableIntel nvtopPackages.intel; ] ++ lib.optionals cfg.enableIntel [
intel-gpu-tools
# 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);
@@ -45,16 +29,14 @@ in
enable = true; enable = true;
enable32Bit = cfg.enable32Bit; enable32Bit = cfg.enable32Bit;
extraPackages = extraPackages = with pkgs;
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,9 +1,4 @@
{ config { config, lib, namespace, ... }:
, pkgs
, lib
, namespace
, ...
}:
let let
inherit (lib) mkIf; inherit (lib) mkIf;
@@ -22,10 +17,6 @@ in
}; };
}; };
environment.systemPackages = with pkgs; [
wl-clipboard
];
reichard = { reichard = {
display-managers = { display-managers = {
sddm = { sddm = {

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