Compare commits
4
Commits
491340bf93
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f706f512d3
|
||
|
|
911f0d6f05
|
||
|
|
edd232e6be
|
||
|
|
8ebed5d954
|
@@ -0,0 +1,86 @@
|
||||
# AGENTS.md
|
||||
|
||||
Repository of personal dotfiles managed via Nix (home-manager, nix-darwin, NixOS) + GNU Stow for legacy config files.
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
flake.nix — Flake entrypoint: home/darwin/nixos configurations
|
||||
hosts/ — Per-machine config files
|
||||
deimos/ — Linux server (NixOS machine + home-manager user)
|
||||
mars/ — macOS laptop (nix-darwin machine + home-manager user)
|
||||
common/home.nix — Per-user git config shared across hosts
|
||||
modules/ — Reusable exported modules
|
||||
home/*.nix — Shared home-manager modules (common, linux-headless, mac-portable)
|
||||
nixos/*.nix — NixOS modules (linux-headless, linux-lxc, jailed-agy)
|
||||
darwin/*.nix — nix-darwin modules (mac-portable)
|
||||
migrated/ — Raw dotfiles (.zshrc, .vimrc) managed by BOTH stow and home-manager
|
||||
legacy/ — Non-Nix config files managed purely via `stow legacy`
|
||||
```
|
||||
|
||||
## Key Conventions
|
||||
|
||||
### Flake inputs span multiple Nix versions
|
||||
|
||||
The flake uses two nixpkgs sources: `nixpkgs` (nixos-unstable) for Linux, and `nixpkgs-mars` (nixpkgs-26.05-darwin) for macOS. The `darwin`, `home-manager-mars`, and `nix-homebrew` inputs all follow `-mars`. When the darwin-specific inputs are eventually dropped, the flake can be simplified (see comment at `flake.nix:52`).
|
||||
|
||||
### Dual-dotfile management
|
||||
|
||||
The `migrated/` and `legacy/` directories use GNU Stow to symlink files into `$HOME`. Home-manager also sources `migrated/.zshrc` and `migrated/.vimrc` at runtime via path detection — it checks for a local checkout first (`~/dotfiles/migrated/...`) before falling back to the Nix-built path. This allows live editing without rebuilding.
|
||||
|
||||
### Module resolution
|
||||
|
||||
Host-level files import shared modules in a chain rather than flat-merging:
|
||||
|
||||
- `hosts/<name>/home.nix` → imports `hosts/common/home.nix` at minimum
|
||||
- `modules/home/linux-headless.nix` and `mac-portable.nix` both import `modules/home/common.nix`
|
||||
|
||||
### Secrets via `identities` input
|
||||
|
||||
The `fw_nix` input (`futureware-tech/nix`) provides an `identities` module used across all configurations. It exposes:
|
||||
|
||||
- `identities.users.${user}.sign.<keyname>.publicKey` — SSH signing keys
|
||||
- `identities.getAccessKeys { user = ...; }` — authorized_keys for login
|
||||
- `identities.getSigningEntries {}` — git signers file entries
|
||||
|
||||
These are passed via `specialArgs.primaryUser` and the `fw_nix.nixosModules.identities` import. Any host config that touches SSH keys or git signing depends on this.
|
||||
|
||||
### SOPS / AGE encryption
|
||||
|
||||
Secrets are encrypted with AGE using hardware-backed identities (Apple Secure Enclave, Yubikey). The identities file lives at `~/.config/sops/age/keys.txt` (Linux) or `~/Library/Application Support/sops/age/keys.txt` (macOS). Decryption only works on the hardware device; the identity files themselves are not sensitive.
|
||||
|
||||
### Jailed AGY wrapper
|
||||
|
||||
The `jailed-agy.nix` module wraps `antigravity-cli` in a sandbox via `jail.nix`. It's highly custom: sets up local pip/ruby/gem paths, forwards Nix vars, bind-mounts Nix store for `nix-shell`, and blocks root. If you need to add tools or adjust the jail, modify the combinator list there.
|
||||
|
||||
### macOS SSH agent is Secretive
|
||||
|
||||
On Mars (macOS), `SSH_AUTH_SOCK` points to the Secretive app socket manually (not a generic ssh-agent). This was a deliberate tradeoff: `ssh-agent-mux` doesn't work well with Secretive + YubiKey agent together. Commit signing keys use the `key::` SSH URI format (`gpg.format = "ssh"`).
|
||||
|
||||
### stateVersion immutability
|
||||
|
||||
Both `modules/nixos/linux-headless.nix` and `modules/darwin/mac-portable.nix` have `"Never change"` comments next to `system.stateVersion`. Do not modify these.
|
||||
|
||||
## Essential Commands
|
||||
|
||||
| Command | Description |
|
||||
| -------------------------------------------- | ----------------------------------------------------------------- |
|
||||
| `nix flake check` | Run pre-commit hooks (nixfmt, dead code checks via git-hooks.nix) |
|
||||
| `nix develop` | Enter dev shell with pre-commit hook packages available |
|
||||
| `home-manager switch --flake .#artem@deimos` | Apply home-manager config for deimos (Linux) |
|
||||
| `home-manager switch --flake .#artem@mars` | Apply home-manager config for mars (macOS) |
|
||||
| `darwin-rebuild switch --flake .#mars` | Apply nix-darwin config for mars |
|
||||
| `nixos-rebuild switch --flake .#deimos` | Apply NixOS config for deimos |
|
||||
| `stow legacy` | Symlink non-Nix configs from `legacy/` into `$HOME` |
|
||||
|
||||
### Pre-commit exclusions
|
||||
|
||||
The git-hooks.nix pre-commit check explicitly excludes `migrated/` and `legacy/` paths. Formatting tools only run on `.nix` files in `hosts/`, `modules/`, `flake.nix`, etc.
|
||||
|
||||
## Gotchas
|
||||
|
||||
- **Unused `with pkgs`** — `modules/nixos/linux-headless.nix:14` has an unnecessary `with pkgs; [...]` that nixd warns about but is left as-is since the `[` immediately after it makes the block valid. Consider removing when editing that file.
|
||||
- **SSH_AUTH_SOCK in tmux** — The tmux config hardcodes `SSH_AUTH_SOCK=$HOME/.ssh/ssh_auth_sock`. On Linux this is a socket symlinked by home-manager; on macOS Secretive provides it. Changing this path breaks SSH inside tmux.
|
||||
- **Home-assistant sshfs mount** — The deimos home config mounts a remote Home Assistant directory via sshfs. The `umount.fuse.sshfs` wrapper script in `linux-headless.nix` is required because of SUID restrictions on fusermount.
|
||||
- **Direnv + nix-direnv** — Enabled globally; `.envrc` files use `use flake` to enter dev shells automatically.
|
||||
- **Zsh loads from file, not Nix attrSet** — The `.zshrc` is sourced as a raw file path (not via `programs.zsh.initExtra`). Modifications to zsh behavior may need to go in either the Nix config (`initContent`) or the raw `migrated/.zshrc` depending on whether you want persistence outside Nix.
|
||||
Generated
+16
-16
@@ -3,16 +3,16 @@
|
||||
"brew-src": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1785710351,
|
||||
"narHash": "sha256-DTL5T9+HlblsnXCEdxRpEo/2NBHD3t48BS7r+PTf090=",
|
||||
"lastModified": 1786348930,
|
||||
"narHash": "sha256-bCQJkbgsAMDp5HQystZLCq11UHiyEuoWbxKulAPYrh8=",
|
||||
"owner": "Homebrew",
|
||||
"repo": "brew",
|
||||
"rev": "7b0f22a4ab77567edef114c8dfc423fb96e2fbaa",
|
||||
"rev": "3ecc9eff23feebf1bc73846d74e14a122c93b66f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "Homebrew",
|
||||
"ref": "6.0.15",
|
||||
"ref": "6.0.16",
|
||||
"repo": "brew",
|
||||
"type": "github"
|
||||
}
|
||||
@@ -160,11 +160,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1786031233,
|
||||
"narHash": "sha256-TIDlLTLI1/pB7IqgjzcKQjpODQsZE2oII4XGG9B6KjI=",
|
||||
"lastModified": 1786887553,
|
||||
"narHash": "sha256-0J8EwNSJ/2OeyuvXgfG+k5uBT1gkg0ww7VEo+14xl50=",
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"rev": "7834e82588860aaf780cec1366524456a70898d7",
|
||||
"rev": "5bd505963717a894b02a57cdbcc00db28d9b029f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -214,11 +214,11 @@
|
||||
"brew-src": "brew-src"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1786217209,
|
||||
"narHash": "sha256-rusAj5QBnbSwXG6csns6dwxTeCOGRcj08VmlnhUQ6ZY=",
|
||||
"lastModified": 1786686423,
|
||||
"narHash": "sha256-8q3WdB8o3VUI7rOz1OXfioXIaaWbFTAxRJAkWLlfc0s=",
|
||||
"owner": "zhaofengli",
|
||||
"repo": "nix-homebrew",
|
||||
"rev": "486357ea434dc0061ea52121ff99b1d33096c811",
|
||||
"rev": "ccabf79a6b9845eb72b51ea1d9c7ce3446350df3",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -229,11 +229,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1786106723,
|
||||
"narHash": "sha256-zDSUbpoeo/9ZmD2+wXnzxoo1+uhL8vxc0b8yuYMKYq0=",
|
||||
"lastModified": 1786862985,
|
||||
"narHash": "sha256-FBJRXmbGXiSUDvYEbfLYRkckayyZ6SK1UEqhCrIZ2Cs=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "f13ff45afd1bb73e640eaa08a7066dbed07e3238",
|
||||
"rev": "e5bdc4a41d4c072fe1e3787eaa0320a384741d44",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -260,11 +260,11 @@
|
||||
},
|
||||
"nixpkgs-mars": {
|
||||
"locked": {
|
||||
"lastModified": 1785067121,
|
||||
"narHash": "sha256-rdJdWxAcg5fnntU4DjPivPdVEN4F+VJavw+UWpEMeUI=",
|
||||
"lastModified": 1786527240,
|
||||
"narHash": "sha256-OLtJPnSXcRy79Rf7BhYaMeXAVF625FpLcd3+Svq641Y=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "329c3d2af6d1b618705150ea39f72c15eb4e613e",
|
||||
"rev": "e0c84f9d0ad137f076dc957494f5b39885597d4f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
@@ -1,41 +1,52 @@
|
||||
{
|
||||
"$schema": "https://charm.land/crush.json",
|
||||
"experimental": { "openTelemetry": false },
|
||||
"share": "disabled",
|
||||
"autoupdate": false,
|
||||
"disabled_providers": ["crush", "exa"],
|
||||
"options": {
|
||||
"disable_metrics": true
|
||||
},
|
||||
"providers": {
|
||||
"crush": {
|
||||
"disable": true
|
||||
},
|
||||
"exa": {
|
||||
"disable": true
|
||||
},
|
||||
"local-ollama": {
|
||||
"type": "openai-compat",
|
||||
"base_url": "http://ollama.home.arpa:11434/v1",
|
||||
"api_key": "ollama",
|
||||
"model_overrides": {
|
||||
"gemma4-1gpu": {
|
||||
"models": [
|
||||
{
|
||||
"id": "gemma4-1gpu",
|
||||
"name": "gemma4-1gpu",
|
||||
"context_window": 48000,
|
||||
"tools": true
|
||||
"cost_per_1m_in": 0,
|
||||
"cost_per_1m_out": 0,
|
||||
"cost_per_1m_in_cached": 0,
|
||||
"cost_per_1m_out_cached": 0,
|
||||
"default_max_tokens": 8192,
|
||||
"can_reason": true,
|
||||
"supports_attachments": true
|
||||
},
|
||||
"qwen3.6-1gpu": {
|
||||
{
|
||||
"id": "qwen3.6-1gpu",
|
||||
"name": "qwen3.6-1gpu",
|
||||
"context_window": 128000,
|
||||
"tools": true
|
||||
"cost_per_1m_in": 0,
|
||||
"cost_per_1m_out": 0,
|
||||
"cost_per_1m_in_cached": 0,
|
||||
"cost_per_1m_out_cached": 0,
|
||||
"default_max_tokens": 8192,
|
||||
"can_reason": true,
|
||||
"supports_attachments": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"model": "local-ollama/qwen3.6-200k",
|
||||
"compaction": {
|
||||
"auto": true,
|
||||
"prune": true,
|
||||
"threshold": 0.75,
|
||||
"preserve_recent_tokens": 8192,
|
||||
"reserved": 16384
|
||||
},
|
||||
"tool_output": {
|
||||
"max_bytes": 16384,
|
||||
"max_lines": 200
|
||||
},
|
||||
"agent": {
|
||||
"build": {
|
||||
"steps": 1000
|
||||
"models": {
|
||||
"default": {
|
||||
"provider": "local-ollama",
|
||||
"model": "qwen3.6-1gpu",
|
||||
"think": true
|
||||
}
|
||||
},
|
||||
"mcp": {
|
||||
@@ -46,8 +57,7 @@
|
||||
"run",
|
||||
"github:utensils/mcp-nixos",
|
||||
"--"
|
||||
],
|
||||
"enabled": true
|
||||
]
|
||||
},
|
||||
"gitea": {
|
||||
"type": "stdio",
|
||||
@@ -56,8 +66,7 @@
|
||||
"run",
|
||||
"nixpkgs#gitea-mcp-server",
|
||||
"--"
|
||||
],
|
||||
"enabled": false
|
||||
]
|
||||
},
|
||||
"ha": {
|
||||
"type": "stdio",
|
||||
@@ -75,8 +84,7 @@
|
||||
"env": {
|
||||
"UV_PYTHON_DOWNLOADS": "never",
|
||||
"UV_PYTHON_PREFERENCE": "system"
|
||||
},
|
||||
"enabled": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user