Compare commits

..

1 Commits

Author SHA1 Message Date
a62ffc0089 chore: update llama-swap 2026-04-06 16:08:23 -04:00
31 changed files with 95 additions and 1051 deletions

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.

1
.gitignore vendored
View File

@@ -1,4 +1,3 @@
.codexis
.DS_Store .DS_Store
_scratch _scratch
result result

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/`.

98
flake.lock generated
View File

@@ -8,11 +8,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1776147994, "lastModified": 1770051625,
"narHash": "sha256-c5F8jYiB0fjWsP4j/yeszqszA3laflzDj6/pmoJTeG4=", "narHash": "sha256-TvePW8C3Bh/yC2cjCWBy2kjeCtfLDj/lsB4dLnfOYn0=",
"owner": "nix-community", "owner": "nix-community",
"repo": "nixos-apple-silicon", "repo": "nixos-apple-silicon",
"rev": "81439a7fb8067ab43641efd79c84607701da1ccd", "rev": "7b90aeb40c4eeecc7b53caf23d6acb05d99fcd4f",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -28,11 +28,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1772129556, "lastModified": 1767634391,
"narHash": "sha256-Utk0zd8STPsUJPyjabhzPc5BpPodLTXrwkpXBHYnpeg=", "narHash": "sha256-owcSz2ICqTSvhBbhPP+1eWzi88e54rRZtfCNE5E/wwg=",
"owner": "nix-darwin", "owner": "nix-darwin",
"repo": "nix-darwin", "repo": "nix-darwin",
"rev": "ebec37af18215214173c98cf6356d0aca24a2585", "rev": "08585aacc3d6d6c280a02da195fdbd4b9cf083c2",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -51,11 +51,11 @@
"nixpkgs": "nixpkgs_2" "nixpkgs": "nixpkgs_2"
}, },
"locked": { "locked": {
"lastModified": 1775584659, "lastModified": 1770325739,
"narHash": "sha256-NA5oZRunqxD+4LNdU7ZKJHqwuazKyAmBjO4OHXL14X4=", "narHash": "sha256-TPDWnhzKW/1+FPMiagZ9mZiQN0aKcGC09yYSUBuv8Mo=",
"owner": "determinatesystems", "owner": "determinatesystems",
"repo": "determinate", "repo": "determinate",
"rev": "21dcaa011d3d35cf42a04e988eaac9b28c97a707", "rev": "1b3259b71c81508ffd409114525df6a55c0f337f",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -67,37 +67,37 @@
"determinate-nixd-aarch64-darwin": { "determinate-nixd-aarch64-darwin": {
"flake": false, "flake": false,
"locked": { "locked": {
"narHash": "sha256-qLWfYk9qkb21wKCDWnhMfqBFjcdBBJkNUKBlvdHSLgA=", "narHash": "sha256-zK2dgNHh/p92rk5jN+Y1LOMn0HEdTsS+7XXwb2g52oM=",
"type": "file", "type": "file",
"url": "https://install.determinate.systems/determinate-nixd/tag/v3.17.3/macOS" "url": "https://install.determinate.systems/determinate-nixd/tag/v3.15.2/macOS"
}, },
"original": { "original": {
"type": "file", "type": "file",
"url": "https://install.determinate.systems/determinate-nixd/tag/v3.17.3/macOS" "url": "https://install.determinate.systems/determinate-nixd/tag/v3.15.2/macOS"
} }
}, },
"determinate-nixd-aarch64-linux": { "determinate-nixd-aarch64-linux": {
"flake": false, "flake": false,
"locked": { "locked": {
"narHash": "sha256-0BmprPIRTopvJ2QdImOMP+TujAPVgRdl0bUL3vhqGIY=", "narHash": "sha256-ckvZP0zFcbzLXWYOJUqYXkKBt0b2IZcQEr7YjEVtwOI=",
"type": "file", "type": "file",
"url": "https://install.determinate.systems/determinate-nixd/tag/v3.17.3/aarch64-linux" "url": "https://install.determinate.systems/determinate-nixd/tag/v3.15.2/aarch64-linux"
}, },
"original": { "original": {
"type": "file", "type": "file",
"url": "https://install.determinate.systems/determinate-nixd/tag/v3.17.3/aarch64-linux" "url": "https://install.determinate.systems/determinate-nixd/tag/v3.15.2/aarch64-linux"
} }
}, },
"determinate-nixd-x86_64-linux": { "determinate-nixd-x86_64-linux": {
"flake": false, "flake": false,
"locked": { "locked": {
"narHash": "sha256-+Q85cySxr0FB/cr97hk/WWYgeJY+iC4OH+FjGYygIbU=", "narHash": "sha256-8dLtm8FJrpyBmrNpspJj30/6I5HGEfjjXuFqURcZ8pk=",
"type": "file", "type": "file",
"url": "https://install.determinate.systems/determinate-nixd/tag/v3.17.3/x86_64-linux" "url": "https://install.determinate.systems/determinate-nixd/tag/v3.15.2/x86_64-linux"
}, },
"original": { "original": {
"type": "file", "type": "file",
"url": "https://install.determinate.systems/determinate-nixd/tag/v3.17.3/x86_64-linux" "url": "https://install.determinate.systems/determinate-nixd/tag/v3.15.2/x86_64-linux"
} }
}, },
"disko": { "disko": {
@@ -105,11 +105,11 @@
"nixpkgs": "nixpkgs_3" "nixpkgs": "nixpkgs_3"
}, },
"locked": { "locked": {
"lastModified": 1773889306, "lastModified": 1769524058,
"narHash": "sha256-PAqwnsBSI9SVC2QugvQ3xeYCB0otOwCacB1ueQj2tgw=", "narHash": "sha256-zygdD6X1PcVNR2PsyK4ptzrVEiAdbMqLos7utrMDEWE=",
"owner": "nix-community", "owner": "nix-community",
"repo": "disko", "repo": "disko",
"rev": "5ad85c82cc52264f4beddc934ba57f3789f28347", "rev": "71a3fc97d80881e91710fe721f1158d3b96ae14d",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -126,11 +126,11 @@
}, },
"locked": { "locked": {
"dir": "pkgs/firefox-addons", "dir": "pkgs/firefox-addons",
"lastModified": 1776199335, "lastModified": 1770091431,
"narHash": "sha256-ImihxU7ReZZuNdrASq8qzOmmO/UQtkuqQ9V9KKb1dD0=", "narHash": "sha256-9Sqq/hxq8ZDLRSzu+edn0OfWG+FAPWFpwMKaJobeLec=",
"owner": "rycee", "owner": "rycee",
"repo": "nur-expressions", "repo": "nur-expressions",
"rev": "95066e56aaa948f170747f57a20c99511a953eed", "rev": "4f827ff035c6ddc58d04c45abe5b777d356b926a",
"type": "gitlab" "type": "gitlab"
}, },
"original": { "original": {
@@ -278,11 +278,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1775425411, "lastModified": 1769580047,
"narHash": "sha256-KY6HsebJHEe5nHOWP7ur09mb0drGxYSzE3rQxy62rJo=", "narHash": "sha256-tNqCP/+2+peAXXQ2V8RwsBkenlfWMERb+Uy6xmevyhM=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "0d02ec1d0a05f88ef9e74b516842900c41f0f2fe", "rev": "366d78c2856de6ab3411c15c1cb4fb4c2bf5c826",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -301,12 +301,12 @@
"nixpkgs-regression": "nixpkgs-regression" "nixpkgs-regression": "nixpkgs-regression"
}, },
"locked": { "locked": {
"lastModified": 1775583600, "lastModified": 1768960381,
"narHash": "sha256-/shs/3GA4R3rxhhqpPbEMnDZKbCvf3VpwnHB75nkTcI=", "narHash": "sha256-32oMe1y+kwvIJNiJsIvozTuSmDxcwST06i+0ak+L4AU=",
"rev": "e9b4735be7b90cf49767faf5c36f770ac1bdc586", "rev": "45ce621408cb8c9a724193d5fe858eb839662db8",
"revCount": 24880, "revCount": 24453,
"type": "tarball", "type": "tarball",
"url": "https://api.flakehub.com/f/pinned/DeterminateSystems/nix-src/3.17.3/019d6913-e8c2-7128-ba76-3dc4f6b58158/source.tar.gz" "url": "https://api.flakehub.com/f/pinned/DeterminateSystems/nix-src/3.15.2/019bde75-b4ee-74b2-a812-28dc2ee83d58/source.tar.gz"
}, },
"original": { "original": {
"type": "tarball", "type": "tarball",
@@ -397,11 +397,11 @@
}, },
"nixpkgs-unstable": { "nixpkgs-unstable": {
"locked": { "locked": {
"lastModified": 1775710090, "lastModified": 1770115704,
"narHash": "sha256-ar3rofg+awPB8QXDaFJhJ2jJhu+KqN/PRCXeyuXR76E=", "narHash": "sha256-KHFT9UWOF2yRPlAnSXQJh6uVcgNcWlFqqiAZ7OVlHNc=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "4c1018dae018162ec878d42fec712642d214fdfa", "rev": "e6eae2ee2110f3d31110d5c222cd395303343b08",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -413,12 +413,12 @@
}, },
"nixpkgs_2": { "nixpkgs_2": {
"locked": { "locked": {
"lastModified": 1775464765, "lastModified": 1768783163,
"narHash": "sha256-nex6TL2x1/sVHCyDWcvl1t/dbTedb9bAGC4DLf/pmYk=", "narHash": "sha256-tLj4KcRDLakrlpvboTJDKsrp6z2XLwyQ4Zmo+w8KsY4=",
"rev": "83e29f2b8791f6dec20804382fcd9a666d744c07", "rev": "bde09022887110deb780067364a0818e89258968",
"revCount": 975711, "revCount": 930106,
"type": "tarball", "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" "url": "https://api.flakehub.com/f/pinned/DeterminateSystems/nixpkgs-weekly/0.1.930106%2Brev-bde09022887110deb780067364a0818e89258968/019bd9ed-5f0b-7074-afb0-8bb5e13a7598/source.tar.gz"
}, },
"original": { "original": {
"type": "tarball", "type": "tarball",
@@ -427,11 +427,11 @@
}, },
"nixpkgs_3": { "nixpkgs_3": {
"locked": { "locked": {
"lastModified": 1773628058, "lastModified": 1769330179,
"narHash": "sha256-hpXH0z3K9xv0fHaje136KY872VT2T5uwxtezlAskQgY=", "narHash": "sha256-yxgb4AmkVHY5OOBrC79Vv6EVd4QZEotqv+6jcvA212M=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "f8573b9c935cfaa162dd62cc9e75ae2db86f85df", "rev": "48698d12cc10555a4f3e3222d9c669b884a49dfe",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -443,11 +443,11 @@
}, },
"nixpkgs_4": { "nixpkgs_4": {
"locked": { "locked": {
"lastModified": 1776067740, "lastModified": 1770056022,
"narHash": "sha256-B35lpsqnSZwn1Lmz06BpwF7atPgFmUgw1l8KAV3zpVQ=", "narHash": "sha256-yvCz+Qmci1bVucXEyac3TdoSPMtjqVJmVy5wro6j/70=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "7e495b747b51f95ae15e74377c5ce1fe69c1765f", "rev": "d04d8548aed39902419f14a8537006426dc1e4fa",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -501,11 +501,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1776119890, "lastModified": 1770110318,
"narHash": "sha256-Zm6bxLNnEOYuS/SzrAGsYuXSwk3cbkRQZY0fJnk8a5M=", "narHash": "sha256-NUVGVtYBTC96WhPh4Y3SVM7vf0o1z5W4uqRBn9v1pfo=",
"owner": "Mic92", "owner": "Mic92",
"repo": "sops-nix", "repo": "sops-nix",
"rev": "d4971dd58c6627bfee52a1ad4237637c0a2fb0cd", "rev": "f990b0a334e96d3ef9ca09d4bd92778b42fd84f9",
"type": "github" "type": "github"
}, },
"original": { "original": {

View File

@@ -24,7 +24,6 @@ in
terminal = { terminal = {
bash = { bash = {
enable = true; enable = true;
customProfile = builtins.readFile ./vm-init.sh;
customFastFetchLogo = ./prophet.txt; customFastFetchLogo = ./prophet.txt;
}; };
aws = enabled; aws = enabled;
@@ -40,11 +39,6 @@ in
}; };
}; };
services = {
# nunc = enabled;
sketchybar = enabled;
};
security = { security = {
sops = enabled; sops = enabled;
}; };
@@ -54,10 +48,9 @@ in
programs.jq = enabled; programs.jq = enabled;
programs.pandoc = enabled; programs.pandoc = enabled;
home.packages = with pkgs; [ home.packages = with pkgs; [
# colima colima
docker docker
keycastr keycastr
reichard.slack-cli
_1password-cli _1password-cli
]; ];
} }

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

@@ -2,11 +2,9 @@
{ {
home.packages = with pkgs; [ home.packages = with pkgs; [
sqlite-interactive
jnv jnv
jq jq
ncdu ncdu
ripgrep ripgrep
reichard.codexis
]; ];
} }

View File

@@ -14,7 +14,6 @@ in
{ {
options.${namespace}.programs.terminal.bash = with lib.types; { options.${namespace}.programs.terminal.bash = with lib.types; {
enable = mkEnableOption "bash"; enable = mkEnableOption "bash";
customProfile = mkOpt str "" "custom profile";
customFastFetchLogo = mkOpt (nullOr path) null "custom fast fetch logo path"; customFastFetchLogo = mkOpt (nullOr path) null "custom fast fetch logo path";
}; };
@@ -50,8 +49,7 @@ in
[[ -f ~/.bash_custom ]] && . ~/.bash_custom [[ -f ~/.bash_custom ]] && . ~/.bash_custom
source ${./config/hey-intern.sh} source ${./config/hey-intern.sh}
'' '';
+ cfg.customProfile;
}; };
programs.powerline-go = { programs.powerline-go = {

View File

@@ -1,4 +1,3 @@
_scratch _scratch
.direnv .direnv
.envrc .envrc
.agents

View File

@@ -138,23 +138,10 @@ setup_lsp("ts_ls", {
filetypes = { "typescript", "typescriptreact", "javascript" }, filetypes = { "typescript", "typescriptreact", "javascript" },
}) })
-- Oxlint - Prefer a project-local oxlint from node_modules so the LSP -- ESLint LSP
-- version matches the project's pinned dependency; fall back to PATH. setup_lsp("eslint", {
setup_lsp("oxlint", {
on_attach = on_attach_no_formatting, on_attach = on_attach_no_formatting,
root_markers = { ".oxlintrc.json", "oxlint.config.json", "package.json", ".git" }, cmd = { nix_vars.vscls .. "/bin/vscode-eslint-language-server", "--stdio" },
cmd = function(dispatchers, config)
local bin = "oxlint"
if config.root_dir then
local local_bin = config.root_dir .. "/node_modules/.bin/oxlint"
if vim.fn.executable(local_bin) == 1 then
bin = local_bin
end
end
return vim.lsp.rpc.start({ bin, "--lsp" }, dispatchers, {
cwd = config.root_dir,
})
end,
}) })
-- C LSP Configuration -- C LSP Configuration
@@ -221,7 +208,6 @@ setup_lsp("gopls", {
}) })
end, end,
filetypes = { "go" }, filetypes = { "go" },
cmd = { "gopls", "-remote=auto" },
settings = { settings = {
gopls = { gopls = {
buildFlags = { "-tags=e2e" }, buildFlags = { "-tags=e2e" },

View File

@@ -31,33 +31,3 @@ bash(command="cat > file.txt << 'EOF'\ncontent\nEOF")
```bash ```bash
write(path="file.txt", content="content") 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,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,6 +1,6 @@
--- ---
name: git-commit 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' description: 'Execute git commit with conventional commit message analysis, intelligent staging, and message generation. Use when user asks to commit changes, create a git commit, or mentions "/commit". Supports: (1) Auto-detecting type and scope from changes, (2) Generating conventional commit messages from diff, (3) Interactive commit with optional type/scope/description overrides, (4) Intelligent file staging for logical grouping'
--- ---
# Git Commit with Conventional Commits # Git Commit with Conventional Commits
@@ -9,20 +9,6 @@ description: 'Execute git commit with conventional commit message analysis, inte
Create standardized, semantic git commits using the Conventional Commits specification. Analyze the actual diff to determine appropriate type, scope, and message. 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 ## Conventional Commit Format
``` ```

View File

@@ -48,10 +48,6 @@ in
source = ./config/prompts; source = ./config/prompts;
recursive = true; recursive = true;
}; };
".pi/agent/extensions" = {
source = ./config/extensions;
recursive = true;
};
}; };
}; };
} }

View File

@@ -45,11 +45,9 @@ in
set -g status-position top set -g status-position top
set -g mouse on set -g mouse on
setw -g mode-keys vi 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 -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-format csi-u
set -g extended-keys on set -g extended-keys on
set -sg escape-time 0
# Start Index 1 # Start Index 1
set -g base-index 1 set -g base-index 1

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,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

@@ -124,32 +124,6 @@ in
}; };
}; };
# https://huggingface.co/unsloth/Qwen3.6-35B-A3B-GGUF/tree/main
"qwen3.6-35b-thinking" = {
name = "Qwen3.6 (35B) - Thinking";
macros.ctx = "262144";
cmd = ''
${llama-cpp}/bin/llama-server \
--port ''${PORT} \
-m /mnt/ssd/Models/Qwen3.6/Qwen3.6-35B-A3B-UD-IQ4_XS.gguf \
-c ''${ctx} \
--temp 0.6 \
--top-p 0.95 \
--top-k 20 \
--min-p 0.0 \
--presence-penalty 0.0 \
--repeat-penalty 1.0 \
-dev CUDA0 \
-fit off
'';
metadata = {
type = [
"text-generation"
"coding"
];
};
};
# https://huggingface.co/bartowski/Qwen_Qwen3.5-27B-GGUF/tree/main # https://huggingface.co/bartowski/Qwen_Qwen3.5-27B-GGUF/tree/main
"qwen3.5-27b-thinking" = { "qwen3.5-27b-thinking" = {
name = "Qwen3.5 (27B) - Thinking"; name = "Qwen3.5 (27B) - Thinking";

View File

@@ -1,4 +1,8 @@
{ inputs, ... }: { inputs, ... }:
final: _prev: { final: _prev: {
firefox-addons = inputs.firefox-addons.packages.${final.system}; firefox-addons = import inputs.firefox-addons {
inherit (final) fetchurl;
inherit (final) lib;
inherit (final) stdenv;
};
} }

View File

@@ -1,12 +0,0 @@
# Workaround for aarch64-darwin codesigning bug (nixpkgs#208951 / #507531):
# fish binaries from the binary cache occasionally have invalid ad-hoc
# signatures on Apple Silicon. Forcing a local rebuild ensures codesigning
# is applied on this machine with a valid signature.
{ inputs, ... }:
final: prev: {
fish = prev.fish.overrideAttrs (_old: {
# Bust the cache key so fish is always built locally rather than
# substituted from the binary cache where the signature may be stale.
NIX_FORCE_LOCAL_REBUILD = "darwin-codesign-fix";
});
}

View File

@@ -1,27 +0,0 @@
{ lib
, buildGoModule
, fetchgit
}:
buildGoModule rec {
pname = "codexis";
version = "unstable-2026-04-10";
src = fetchgit {
url = "https://gitea.va.reichard.io/evan/codexis.git";
rev = "39fcfc296857f52b962388e454f8161ff0442d23";
hash = "sha256-B1VKY82tBxkd/L71Lq8Hh+1whQ03DzddkTcR82a+YXk=";
};
vendorHash = "sha256-8B1utE6bicIn1YO0qIcZhF7RaIK5cOu1/vm41EG+yyQ=";
subPackages = [ "." ];
meta = {
description = "Code index database tool using tree-sitter";
homepage = "https://gitea.va.reichard.io/evan/codexis";
license = lib.licenses.mit;
maintainers = with lib.maintainers; [ evanreichard ];
mainProgram = "codexis";
};
}

View File

@@ -7,12 +7,12 @@
vulkanSupport = true; vulkanSupport = true;
}).overrideAttrs }).overrideAttrs
(oldAttrs: rec { (oldAttrs: rec {
version = "8815"; version = "8680";
src = pkgs.fetchFromGitHub { src = pkgs.fetchFromGitHub {
owner = "ggml-org"; owner = "ggml-org";
repo = "llama.cpp"; repo = "llama.cpp";
tag = "b${version}"; tag = "b${version}";
hash = "sha256-QJsGBHLdvFfMXZJSk9D76b7v6DP06NaTYztHv41o/CA="; hash = "sha256-tJCA19BQs0vZc0VjPnbIrh3CJFxyPL6Ne4oIG4gfozw=";
leaveDotGit = true; leaveDotGit = true;
postFetch = '' postFetch = ''
git -C "$out" rev-parse --short HEAD > $out/COMMIT git -C "$out" rev-parse --short HEAD > $out/COMMIT
@@ -20,11 +20,6 @@
''; '';
}; };
# Add SPIR-V Headers for Vulkan Backend
# Newer llama.cpp requires spirv/unified1/spirv.hpp which isn't
# pulled in by vulkan-headers alone.
buildInputs = (oldAttrs.buildInputs or [ ]) ++ [ pkgs.spirv-headers ];
# Auto CPU Optimizations # Auto CPU Optimizations
cmakeFlags = (oldAttrs.cmakeFlags or [ ]) ++ [ cmakeFlags = (oldAttrs.cmakeFlags or [ ]) ++ [
"-DGGML_CUDA_ENABLE_UNIFIED_MEMORY=1" "-DGGML_CUDA_ENABLE_UNIFIED_MEMORY=1"

View File

@@ -5,6 +5,7 @@
, versionCheckHook , versionCheckHook
, callPackage , callPackage
, nixosTests , nixosTests
, nix-update-script
, ,
}: }:
@@ -13,13 +14,18 @@ let
in in
buildGoModule (finalAttrs: { buildGoModule (finalAttrs: {
pname = "llama-swap"; pname = "llama-swap";
version = "197"; version = "199";
outputs = [
"out"
"wol" # wake on lan proxy
];
src = fetchFromGitHub { src = fetchFromGitHub {
owner = "mostlygeek"; owner = "mostlygeek";
repo = "llama-swap"; repo = "llama-swap";
tag = "v${finalAttrs.version}"; tag = "v${finalAttrs.version}";
hash = "sha256-EXgyYmpbN/zzr6KeSpvFEB+FS7gDIZFinNMv70v5boY="; hash = "sha256-tAWXhfOWPLBuEgd+32CbuIkn1hN+4VI4xkyx7E2a81I=";
# populate values that require us to use git. By doing this in postFetch we # populate values that require us to use git. By doing this in postFetch we
# can delete .git afterwards and maintain better reproducibility of the src. # can delete .git afterwards and maintain better reproducibility of the src.
leaveDotGit = true; leaveDotGit = true;
@@ -35,7 +41,6 @@ buildGoModule (finalAttrs: {
vendorHash = "sha256-XiDYlw/byu8CWvg4KSPC7m8PGCZXtp08Y1velx4BR8U="; vendorHash = "sha256-XiDYlw/byu8CWvg4KSPC7m8PGCZXtp08Y1velx4BR8U=";
passthru.ui = callPackage ./ui.nix { llama-swap = finalAttrs.finalPackage; }; passthru.ui = callPackage ./ui.nix { llama-swap = finalAttrs.finalPackage; };
passthru.npmDepsHash = "sha256-Fs7+JKE8YBp2Xj8bVBlwmT+UwuD642VeUHiPx+fv94c=";
nativeBuildInputs = [ nativeBuildInputs = [
versionCheckHook versionCheckHook
@@ -73,8 +78,8 @@ buildGoModule (finalAttrs: {
checkFlags = checkFlags =
let let
skippedTests = lib.optionals (stdenv.isDarwin && stdenv.isx86_64) [ skippedTests = lib.optionals (stdenv.isDarwin) [
# Fail only on x86_64-darwin intermittently # Fail only on *-darwin intermittently
# https://github.com/mostlygeek/llama-swap/issues/320 # https://github.com/mostlygeek/llama-swap/issues/320
"TestProcess_AutomaticallyStartsUpstream" "TestProcess_AutomaticallyStartsUpstream"
"TestProcess_WaitOnMultipleStarts" "TestProcess_WaitOnMultipleStarts"
@@ -90,6 +95,7 @@ buildGoModule (finalAttrs: {
"TestProcess_ForceStopWithKill" "TestProcess_ForceStopWithKill"
"TestProcess_StopCmd" "TestProcess_StopCmd"
"TestProcess_EnvironmentSetCorrectly" "TestProcess_EnvironmentSetCorrectly"
"TestProcess_ReverseProxyPanicIsHandled"
]; ];
in in
[ "-skip=^${builtins.concatStringsSep "$|^" skippedTests}$" ]; [ "-skip=^${builtins.concatStringsSep "$|^" skippedTests}$" ];
@@ -105,14 +111,22 @@ buildGoModule (finalAttrs: {
rm "$GOPATH/bin/simple-responder" rm "$GOPATH/bin/simple-responder"
''; '';
preInstall = '' postInstall = ''
install -Dm444 -t "$out/share/llama-swap" config.example.yaml install -Dm444 -t "$out/share/llama-swap" config.example.yaml
mkdir -p "$wol/bin"
mv "$out/bin/wol-proxy" "$wol/bin/"
''; '';
doInstallCheck = true; doInstallCheck = true;
versionCheckProgramArg = "-version"; versionCheckProgramArg = "-version";
passthru.tests.nixos = nixosTests.llama-swap; passthru.tests.nixos = nixosTests.llama-swap;
passthru.updateScript = nix-update-script {
extraArgs = [
"--subpackage"
"ui"
];
};
meta = { meta = {
homepage = "https://github.com/mostlygeek/llama-swap"; homepage = "https://github.com/mostlygeek/llama-swap";

View File

@@ -5,7 +5,8 @@
buildNpmPackage (finalAttrs: { buildNpmPackage (finalAttrs: {
pname = "${llama-swap.pname}-ui"; pname = "${llama-swap.pname}-ui";
inherit (llama-swap) version src npmDepsHash; inherit (llama-swap) version src;
npmDepsHash = "sha256-gTDsuWPLCWsPltioziygFmSQFdLqjkZpmmVWIWoZwoc=";
postPatch = '' postPatch = ''
substituteInPlace vite.config.ts \ substituteInPlace vite.config.ts \

View File

@@ -1,48 +0,0 @@
{ lib
, swiftPackages
, fetchgit
,
}:
swiftPackages.stdenv.mkDerivation rec {
pname = "nunc";
version = "unstable-2026-04-15";
src = fetchgit {
url = "https://gitea.va.reichard.io/evan/Nunc.git";
rev = "95d95840aa0bc7b595293c6c5c9f53d120a90cca";
hash = "sha256-UXBKcEuNnVO7WzuvmVqXMiJH7uvjLkcWiqBO0BhynsU=";
};
nativeBuildInputs = [
swiftPackages.swift
swiftPackages.swiftpm
];
buildInputs = [
swiftPackages.Foundation
swiftPackages.XCTest
];
buildPhase = ''
runHook preBuild
swift build -c release
runHook postBuild
'';
installPhase = ''
runHook preInstall
mkdir -p $out/bin
cp .build/release/Nunc $out/bin/nunc
runHook postInstall
'';
meta = {
description = "Minimal floating clock overlay for macOS";
homepage = "https://gitea.va.reichard.io/evan/Nunc";
license = lib.licenses.mit;
maintainers = with lib.maintainers; [ evanreichard ];
mainProgram = "nunc";
platforms = lib.platforms.darwin;
};
}

View File

@@ -14,16 +14,16 @@
buildNpmPackage rec { buildNpmPackage rec {
pname = "pi-coding-agent"; pname = "pi-coding-agent";
version = "0.67.5"; version = "0.65.2";
src = fetchFromGitHub { src = fetchFromGitHub {
owner = "badlogic"; owner = "badlogic";
repo = "pi-mono"; repo = "pi-mono";
rev = "v${version}"; rev = "v${version}";
hash = "sha256-Pw2f/6rKGWzmSdswungerrGrR6i9tUVFNiA4xaNygsQ="; hash = "sha256-nHCQboyRT8k2t7dD0knmQSaUciQua17518CG/3jC7Rg=";
}; };
npmDepsHash = "sha256-L53UEVQNsLoSkmP9L9AZQ74iThdMFBgtnLaXqZHqBRw="; npmDepsHash = "sha256-ZFrOh2P2kkKz4kwD153ltPX852sS1JcTCvSLYwZbyoo=";
nativeBuildInputs = [ pkg-config ]; nativeBuildInputs = [ pkg-config ];

View File

@@ -1,90 +0,0 @@
{ lib
, fetchgit
, fetchurl
, python312
, snappy
,
}:
let
pythonPackages = python312.pkgs;
# ── Python Dependency Overrides ──────────────────────────────
#
# dfindexeddb pins python-snappy==0.6.1 and zstd==1.5.5.1.
# nixpkgs ships newer versions, so we build the exact pins
# from PyPI source tarballs.
python-snappy = pythonPackages.buildPythonPackage rec {
pname = "python-snappy";
version = "0.6.1";
format = "setuptools";
src = fetchurl {
url = "https://files.pythonhosted.org/packages/98/7a/44a24bad98335b2c72e4cadcdecf79f50197d1bab9f22f863a274f104b96/python-snappy-0.6.1.tar.gz";
hash = "sha256-tqEHqwYgasxTWdTFYyvZsi1EhwKnmzFpsMYuD7gIuyo=";
};
buildInputs = [ snappy ];
doCheck = false;
};
zstd-python = pythonPackages.buildPythonPackage rec {
pname = "zstd";
version = "1.5.5.1";
format = "setuptools";
src = fetchurl {
url = "https://files.pythonhosted.org/packages/source/z/zstd/zstd-1.5.5.1.tar.gz";
hash = "sha256-HvmAq/Dh4HKwKNLXbvlbR2YyZRyWIlzzC2Gcbu9iVnI=";
};
doCheck = false;
};
dfindexeddb = pythonPackages.buildPythonPackage rec {
pname = "dfindexeddb";
version = "20260210";
format = "setuptools";
src = fetchurl {
url = "https://files.pythonhosted.org/packages/source/d/dfindexeddb/dfindexeddb-20260210.tar.gz";
hash = "sha256-4ahEe4Lpoh0oqGR6kI7J1HEGfvKVEzu3qQ+3ykgFd/Y=";
};
propagatedBuildInputs = [
python-snappy
zstd-python
];
doCheck = false;
};
in
pythonPackages.buildPythonApplication {
pname = "slack-cli";
version = "0.1.0";
format = "pyproject";
src = fetchgit {
url = "https://gitea.va.reichard.io/evan/slack-cli.git";
rev = "0a9484257a2adc414aa4cdab4fb9539a37e04d1f";
hash = "sha256-FbzE1yRdVIhmhqrxtT3C/Pomqv8iAjI9ydQGBZr+UgY=";
};
build-system = [ pythonPackages.setuptools ];
dependencies = [ dfindexeddb ];
doCheck = false;
meta = {
description = "Read Slack messages from local Chromium IndexedDB cache";
homepage = "https://gitea.va.reichard.io/evan/slack-cli";
license = lib.licenses.mit;
maintainers = with lib.maintainers; [ evanreichard ];
mainProgram = "slack-cli";
platforms = lib.platforms.darwin;
};
}

View File

@@ -28,21 +28,12 @@
KeyRepeat = 2; KeyRepeat = 2;
NSWindowShouldDragOnGesture = true; NSWindowShouldDragOnGesture = true;
AppleICUForce24HourTime = true; AppleICUForce24HourTime = true;
_HIHideMenuBar = true;
}; };
WindowManager = { WindowManager = {
HideDesktop = true; HideDesktop = true;
StandardHideDesktopIcons = true;
};
finder = {
CreateDesktop = false;
}; };
}; };
system.activationScripts.postActivation.text = ''
sudo defaults write /Library/Preferences/com.apple.iokit.AmbientLightSensor "Automatic Display Enabled" -bool false
'';
security.pam.services.sudo_local.touchIdAuth = true; security.pam.services.sudo_local.touchIdAuth = true;
reichard = { }; reichard = { };

View File

@@ -14,6 +14,7 @@ in
system.stateVersion = "25.11"; system.stateVersion = "25.11";
time.timeZone = "America/New_York"; time.timeZone = "America/New_York";
networking.firewall.trustedInterfaces = [ "enp0s1" ];
programs.nix-ld.enable = true; programs.nix-ld.enable = true;
# System Config # System Config
@@ -52,29 +53,16 @@ in
}; };
}; };
# Trust Interface & NAT All Ports
networking = {
firewall.trustedInterfaces = [ "enp0s1" ];
nftables.enable = true;
nftables.ruleset = ''
table ip nat {
chain prerouting {
type nat hook prerouting priority dstnat; policy accept;
iifname "enp0s1" meta l4proto tcp dnat ip to 127.0.0.1
iifname "enp0s1" meta l4proto udp dnat ip to 127.0.0.1
}
}
'';
};
# Allow NAT
boot.kernel.sysctl = {
"net.ipv4.conf.all.route_localnet" = 1;
};
fileSystems."/mnt/host-share" = { fileSystems."/mnt/host-share" = {
device = "share"; device = "share";
fsType = "virtiofs"; fsType = "virtiofs";
options = [ "defaults" ]; options = [ "defaults" ];
}; };
# fileSystems."/home/evanreichard/Development" = {
# device = "/mnt/host-share/Development";
# fsType = "none";
# options = [ "bind" ];
# depends = [ "/mnt/host-share" ];
# };
} }