8.7 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
Omnixient is a declarative NixOS configuration that builds a Hyprland-based desktop environment. It uses Nix flakes, home-manager, and a custom module system with feature flags and presets.
Repository: https://github.com/TheArctesian/omnixy
Relationship to ~/dev and ~/.claude (read first)
This dir configures bohm (the local dev box). It is NOT
~/dev/deploy/server-deploy/ — that's a separate NixOS flake for the
deployed server fleet (host1, host2, host3, host4, host5, host6,
…). When the user says "rebuild" / "deploy" without context, ask
whether they mean local (this dir, omni-rebuild) or remote
(server-deploy + deploy.sh).
Most files here are user-owned (no sudo needed). hardware-configuration.nix
is generated — don't hand-edit.
What this config provides to ~/dev work
The Omnixient config is the source of everything ~/dev expects to be
on this machine:
- Global git pre-commit hook —
modules/dev-env/scripts/git-hooks/pre-commit, wired into every repo viacore.hooksPath. Secret-scanner withpragma: allowlist secretmarkers. See user-global~/.claude/CLAUDE.mdfor the false-positive workflow. - Home-manager systemd user units — declared in
home.nixundersystemd.user.{services,timers}.*. The refs weekly refresh (refs-refresh.timer) lives here. - PATH, env, shell tooling —
modules/dev-env/,home.nixprograms.*, andhome.packages/environment.systemPackages. - SSH host aliases —
home.nixprograms.ssh.matchBlocks(or wherever ssh is declared). - lazyvim-nix — pinned in
flake.nix, configured underprograms.lazyviminhome.nix. User-global CLAUDE.md has the full plugin/config conventions. ~/dev/CLAUDE.md— workspace-level Claude instructions for the aiolabs / AIO stack.~/dev/itself isn't a git repo, so the file lives atfiles/dev-CLAUDE.mdhere and is surfaced as a mutable symlink viahome.file."dev/CLAUDE.md".source = config.lib.file.mkOutOfStoreSymlink ...inhome.nix. Edit at either path; commit from this repo. Usefiles/for any other documents that conceptually belong outside/etc/nixosbut have no other repo to live in.
Cross-references
~/.claude/CLAUDE.md— user-global preferences, including a "Machine config —/etc/nixos" section that mirrors this overview but oriented for sessions started outside this dir. Loaded in every session regardless of cwd.~/dev/CLAUDE.md— workspace orientation for the aiolabs / AIO stack under~/dev/. Loaded when working there.
Key Commands
# Build without switching (validate changes)
nixos-rebuild build --flake .#omni
# Build and switch
sudo nixos-rebuild switch --flake .#omni
# Test in VM
nixos-rebuild build-vm --flake .#omni
# Check flake evaluation
nix flake check
# Format / lint Nix code
nixfmt *.nix modules/*.nix # or: make fmt (find -name '*.nix' | xargs nixfmt)
statix check .
deadnix .
# Build ISO
nix build .#iso
Sandboxed claude sessions
Two scripts launch claude under an allowlist+deny policy, so it can work unattended on a target dir without being able to reach bohm's running system:
scripts/sandbox-claude.sh [<dir>]— generalized form. Targets<dir>if given (any repo path on the machine), else the parent of the script dir. Remaining args pass through to claude. Use this when iterating on a separate repo (e.g. a new public template under development).scripts/refactor-claude.sh— backwards-compatible wrapper for the~/nixos-refactor/worktree of this repo. Equivalent tosandbox-claude.shwith no args.
Both bootstrap <target>/.claude/settings.json fresh from
scripts/sandbox-settings.json on every launch — policy evolves in
the main /etc/nixos checkout and propagates on next launch.
Hand-editing the runtime copy is pointless (overwritten on relaunch);
<target>/.gitignore should list .claude/ (the script warns if not).
Policy (scripts/sandbox-settings.json)
defaultMode=acceptEdits— file edits silent.- allow: narrow Bash set —
nix build|check|eval|run,nixfmt,statix,deadnix, in-worktree git (status/diff/log/add/commit/ checkout/restore/stash/rev-parse/worktree list),find/xargs, and basic inspection (ls,pwd,which,type,env,echo,file,stat,wc,head,tail,cat). - ask:
rm,rmdir,mv,cp,chmod,chown— prompt every time. - deny: sudo,
nixos-rebuild switch|test|boot,omni-rebuild,nh,git push,git remote,git reset --hard, curl, wget, ssh, scp, rsync, nc, systemctl, docker, podman, WebFetch, WebSearch.
deny is hard-reject and cannot be overridden mid-session. To loosen,
edit scripts/sandbox-settings.json in main and relaunch.
Verification signal for an autonomous run
nix flake check -L— all checksnix build .#checks.x86_64-linux.refactor-smoke -L— headless VM boot test scaffold attests/refactor-smoke.nixnixos-rebuild build --flake .#omni— build only, no switch
Merging a passing refactor is a manual step done from the main
/etc/nixos checkout, not from the sandbox.
omni-rebuild itself now wraps nh os switch --hostname omni /etc/nixos (see 60bd3f75); the surface for users is unchanged but
nh is now also a system-wide command via programs.nh.
Architecture
Entry Points
- settings.nix — Single source of truth for user, gitName, gitEmail, hostName, timeZone. Imported by flake.nix and passed via
specialArgsto all modules. - flake.nix — Inputs (nixpkgs, home-manager, hyprland, nix-colors, stylix, neovim-nightly, NUR), outputs. Passes
settingsto NixOS and home-manager modules. - configuration.nix — Thin entry point: imports all modules, sets per-host nix/networking/locale config, and
omni.*options. Receivessettingsvia specialArgs. - home.nix — Home-manager user config. Uses
osConfig.omni.featuresto gate packages by feature flag. Receivessettingsvia extraSpecialArgs. - iso.nix — Live ISO config (overrides user to "nixos").
Module System (modules/)
All modules use config.omni.* options defined in modules/core.nix:
- core.nix — Defines options:
user,theme,preset,features.*,displayManager,colorScheme,wallpaper. Presets auto-enable feature combinations viamkDefault. - lib.nix — Exposes shared helpers via
config.omni.lib:isEnabled,userPath,getColor,withFeature,filterPackages,makeScript,paths,colors. This is the only place helpers are defined — all modules access them throughconfig.omni.lib. - packages.nix — System packages gated by
cfg.features.*andcfg.packages.categories.*. - services.nix — Canonical location for all system services (pipewire, openssh, greetd, fstrim, thermald, avahi, etc.). Also owns polkit and AppArmor config.
- boot.nix — Boot loader, kernel, Plymouth, console config.
- hardware/ — Conditional modules for Intel, AMD, NVIDIA, audio, bluetooth, touchpad.
default.nixis the entry point with common hardware support.
Desktop (modules/desktop/)
- hyprland.nix — Uses home-manager's
wayland.windowManager.hyprland.settingsfor structured, mergeable config. Also configures Waybar. - hyprland/autostart.nix —
exec-once/execlists (themes and feature modules can append). - hyprland/bindings.nix — Keybindings as
bind/binde/bindm/bindllists. - hyprland/idle.nix — Uses HM
services.hypridleandprograms.hyprlockmodules.
Theme System (modules/themes/)
Each theme is a standalone module that merges config into HM settings:
- Hyprland colors via
wayland.windowManager.hyprland.settings.general."col.active_border"etc. - Waybar CSS via
programs.waybar.style - Terminal colors (alacritty, kitty), editor themes (neovim, vscode), starship palette, lazygit, mako notifications, fzf colors, Firefox userChrome, GTK
- Only one theme is imported at a time (selected by
currentThemein configuration.nix) - Use tokyo-night.nix as the template for new themes
Key Patterns
- Feature flags:
config.omni.features.coding, etc. — guarded withlib.mkIforlib.optionals. Both system packages (packages.nix) and user packages (home.nix) respect these. - Helpers access: Always via
config.omni.lib(neverimport ./helpers.nix). - User reference: Always via
config.omni.userin NixOS modules,settings.userin home.nix/flake.nix. - Theme switching: Change
currentThemein configuration.nix, then rebuild. - Structured Hyprland config: Themes merge attrsets into
wayland.windowManager.hyprland.settings— no raw config files in/etc/.