common: add agents configuration for Claude/Gemini
This commit is contained in:
parent
b96b20b51d
commit
883b91d822
5 changed files with 232 additions and 7 deletions
56
AGENTS.md
Normal file
56
AGENTS.md
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
# Agent Guide for NixOS System Configuration
|
||||
|
||||
This repository contains NixOS and macOS (nix-darwin) configurations managed with Nix Flakes.
|
||||
|
||||
## Project Structure
|
||||
|
||||
- **`flake.nix`**: Entry point for all system configurations.
|
||||
- **`systems/`**: Configuration for specific hosts.
|
||||
- `zw`, `jellybee`, `homebee`: NixOS systems.
|
||||
- `greenhouse` (hostname `JJTH7GH17J`): macOS system.
|
||||
- `pi`, `homepi`: Likely Raspberry Pi or similar ARM systems (some may be inactive in `flake.nix`).
|
||||
- **`common/`**: Shared configurations, overlays, and Home Manager modules.
|
||||
- **`images/`**: Configuration for generating system images.
|
||||
|
||||
## Key Commands
|
||||
|
||||
### Deployment
|
||||
- **Install NixOS**: `nixos-install --flake .#<hostname>`
|
||||
- **Rebuild NixOS**: `nixos-rebuild switch --flake .#<hostname>`
|
||||
- **Rebuild macOS**: `darwin-rebuild switch --flake .#<hostname>`
|
||||
- **Update Flakes**: `nix flake update`
|
||||
|
||||
### Provisioning
|
||||
- **ZFS Setup**: Use `systems/<hostname>/nixos-zfs-setup.sh` (e.g., for `zw`) to partition disks and create ZFS pools before installation.
|
||||
- **Warning**: This script wipes disks. Read carefully before running.
|
||||
|
||||
## Configuration Patterns
|
||||
|
||||
### Modules & Options
|
||||
- Custom Home Manager modules are defined in `common/home-manager` (e.g., `code`, `jira`).
|
||||
- Modules often use `mkOption` to define enabling flags (e.g., `code.jujutsu.enable`).
|
||||
- Shared system configuration is often imported via `imports` in host-specific `configuration.nix`.
|
||||
|
||||
### Secret Management
|
||||
- **Tool**: `agenix` is used for encryption.
|
||||
- **Files**: Secrets are stored as `.age` files in `systems/<hostname>/secrets/`.
|
||||
- **Key**: Secrets are typically decrypted using SSH keys or dedicated key files.
|
||||
- **Integration**: `homeage` is used for user-level secret management in Home Manager.
|
||||
|
||||
### Version Control
|
||||
- **Jujutsu (jj)**: The user heavily utilizes `jj` alongside `git`.
|
||||
- **Aliases**: `jj` aliases are configured in `common/home-manager/code/default.nix`.
|
||||
|
||||
## Gotchas
|
||||
|
||||
- **Empty Directories**: Some directories might seem empty but serve as mount points or future placeholders.
|
||||
- **Hardware Specifics**:
|
||||
- `zw`: ThinkPad (x86_64)
|
||||
- `greenhouse`: MacBook Pro (M-series, aarch64)
|
||||
- **Private Modules**: The flake inputs reference a private `greenhouse-nix-modules` repo. If you cannot access it, some evaluations might fail.
|
||||
- **Impermanence**: Some systems use "impermanence" setup (root rollback on boot), configured in `nixos-zfs-setup.sh` and Nix modules.
|
||||
|
||||
## Development
|
||||
|
||||
- **Formatting**: No global formatter is enforced in `flake.nix` (only `nixpkgs-fmt` or `alejandra` are common in Nix, but check if installed).
|
||||
- **Linter**: `statix` or `deadnix` are common but not explicitly seen in the root.
|
||||
91
common/home-manager/ai-agents/crush.nix
Normal file
91
common/home-manager/ai-agents/crush.nix
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
cfg = config.ai-agents.crush;
|
||||
in {
|
||||
options.ai-agents.crush.enable = lib.mkEnableOption "Charmbracelet's Crush";
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
home.packages = [
|
||||
(pkgs.buildGo125Module rec {
|
||||
name = "crush";
|
||||
version = "0.32.0";
|
||||
vendorHash = "sha256-HauqqSrdpJFKV60BA2/2ZFaMz/wFwRf0+Te4zX34NsU=";
|
||||
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "charmbracelet";
|
||||
repo = name;
|
||||
tag = "v${version}";
|
||||
hash = "sha256-EXHyYpIUGew2AwRqN7CU/A3YXF3HLGkkCgK2jYhSNnA=";
|
||||
};
|
||||
|
||||
checkFlags = let
|
||||
# these tests fail in the sandbox
|
||||
skippedTests = [
|
||||
"TestCoderAgent"
|
||||
"TestOpenAIClientStreamChoices"
|
||||
"TestGrepWithIgnoreFiles"
|
||||
"TestSearchImplementations"
|
||||
];
|
||||
in ["-skip=^${builtins.concatStringsSep "$|^" skippedTests}$"];
|
||||
})
|
||||
];
|
||||
|
||||
programs = {
|
||||
git.ignores = [".crush"];
|
||||
fish.loginShellInit =
|
||||
#fish
|
||||
''
|
||||
eval "$(crush completion fish)"
|
||||
'';
|
||||
};
|
||||
|
||||
xdg.configFile."crush/crush.json".source = (pkgs.formats.json {}).generate "crush-config" {
|
||||
"$schema" = "https://charm.land/crush.json";
|
||||
|
||||
lsp = {
|
||||
go.command = lib.getExe pkgs.gopls;
|
||||
nix.command = lib.getExe pkgs.nil;
|
||||
ruby = {
|
||||
command = lib.getExe pkgs.solargraph;
|
||||
args = ["stdio"];
|
||||
env = {
|
||||
RUBYOPT = "-W0";
|
||||
};
|
||||
};
|
||||
typescript = {
|
||||
args = ["--stdio"];
|
||||
command = lib.getExe pkgs.typescript-language-server;
|
||||
};
|
||||
};
|
||||
|
||||
mcp = let
|
||||
transformMcpServer = name: server: {
|
||||
name = name;
|
||||
value =
|
||||
{
|
||||
disabled = false;
|
||||
timeout = 120;
|
||||
}
|
||||
// (
|
||||
server
|
||||
// (
|
||||
if server ? url
|
||||
then
|
||||
if ((builtins.match ".*sse.*" server.url) == null)
|
||||
then {type = "http";}
|
||||
else {type = "sse";}
|
||||
else if server ? command
|
||||
then {type = "stdio";}
|
||||
else {}
|
||||
)
|
||||
);
|
||||
};
|
||||
in
|
||||
lib.listToAttrs (lib.mapAttrsToList transformMcpServer config.ai-agents.mcpServers);
|
||||
};
|
||||
};
|
||||
}
|
||||
67
common/home-manager/ai-agents/default.nix
Normal file
67
common/home-manager/ai-agents/default.nix
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
cfg = config.ai-agents;
|
||||
json = pkgs.formats.json {};
|
||||
in {
|
||||
imports = [
|
||||
./crush.nix
|
||||
];
|
||||
|
||||
options.ai-agents = with lib;
|
||||
with types; {
|
||||
enable = mkEnableOption "AI Agents";
|
||||
|
||||
mcpServers = mkOption {
|
||||
description = "MCP Configurations";
|
||||
type = attrs;
|
||||
default = {
|
||||
git = {
|
||||
args = ["mcp-server-git" "--repository" "${config.home.homeDirectory}/proj/nixos-system"];
|
||||
command = "uvx";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
ai-agents.crush.enable = true;
|
||||
|
||||
home = {
|
||||
file.".cursor/mcp.json".source = json.generate "cursor-mcp-config" {inherit (cfg) mcpServers;};
|
||||
|
||||
packages = with pkgs; [
|
||||
nodejs_24 # for npx
|
||||
uv # for uvx
|
||||
];
|
||||
};
|
||||
|
||||
programs = {
|
||||
aider-chat.enable = true;
|
||||
codex.enable = true;
|
||||
|
||||
opencode = {
|
||||
enable = true;
|
||||
enableMcpIntegration = true;
|
||||
};
|
||||
|
||||
mcp = {
|
||||
enable = true;
|
||||
servers = cfg.mcpServers;
|
||||
};
|
||||
|
||||
claude-code = {
|
||||
inherit (cfg) mcpServers;
|
||||
enable = true;
|
||||
};
|
||||
|
||||
fabric-ai = {
|
||||
enable = true;
|
||||
enableZshIntegration = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -511,14 +511,11 @@
|
|||
},
|
||||
"nixpkgs_5": {
|
||||
"locked": {
|
||||
"lastModified": 1767892417,
|
||||
"narHash": "sha256-dhhvQY67aboBk8b0/u0XB6vwHdgbROZT3fJAjyNh5Ww=",
|
||||
"lastModified": 1766309749,
|
||||
"narHash": "sha256-3xY8CZ4rSnQ0NqGhMKAy5vgC+2IVK0NoVEzDoOh4DA4=",
|
||||
"lastModified": 1768127708,
|
||||
"narHash": "sha256-1Sm77VfZh3mU0F5OqKABNLWxOuDeHIlcFjsXeeiPazs=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "3497aa5c9457a9d88d71fa93a4a8368816fbeeba",
|
||||
"rev": "a6531044f6d0bef691ea18d4d4ce44d0daa6e816",
|
||||
"rev": "ffbc9f8cbaacfb331b6017d5a5abb21a492c9a38",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
|||
|
|
@ -11,9 +11,14 @@
|
|||
../../../common/home-manager/helix
|
||||
../../../common/home-manager/jira
|
||||
../../../common/home-manager/qutebrowser
|
||||
../../../common/home-manager/ai-agents
|
||||
homeage.homeManagerModules.homeage
|
||||
];
|
||||
|
||||
ai-agents = {
|
||||
enable = true;
|
||||
crush.enable = true;
|
||||
};
|
||||
modules.aerospace.enable = true;
|
||||
programs = {
|
||||
aerc = {
|
||||
|
|
@ -96,7 +101,7 @@
|
|||
}
|
||||
];
|
||||
loginShellInit = ''
|
||||
. $HOME/.nix-profile/share/asdf-vm/asdf.fish
|
||||
# . $HOME/.nix-profile/share/asdf-vm/asdf.fish
|
||||
'';
|
||||
};
|
||||
fzf = {
|
||||
|
|
@ -124,6 +129,15 @@
|
|||
active_border_color none
|
||||
font_size 14.0
|
||||
'';
|
||||
environment = {
|
||||
# for gemini
|
||||
"GOOGLE_CLOUD_PROJECT" = "elegant-pipe-468016-d8";
|
||||
"GOOGLE_CLOUD_LOCATION" = "global";
|
||||
# for gemini via crush
|
||||
"VERTEXAI_LOCATION" = "$GOOGLE_CLOUD_LOCATION";
|
||||
"VERTEXAI_PROJECT" = "$GOOGLE_CLOUD_PROJECT";
|
||||
};
|
||||
|
||||
shellIntegration.enableFishIntegration = true;
|
||||
};
|
||||
starship = {
|
||||
|
|
|
|||
Loading…
Reference in a new issue