omnixient/CLAUDE.md
Padreug a8f1045518 chore: Claude/agent guidance and workspace files
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 10:00:14 +02:00

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 hookmodules/dev-env/scripts/git-hooks/pre-commit, wired into every repo via core.hooksPath. Secret-scanner with pragma: allowlist secret markers. See user-global ~/.claude/CLAUDE.md for the false-positive workflow.
  • Home-manager systemd user units — declared in home.nix under systemd.user.{services,timers}.*. The refs weekly refresh (refs-refresh.timer) lives here.
  • PATH, env, shell toolingmodules/dev-env/, home.nix programs.*, and home.packages / environment.systemPackages.
  • SSH host aliaseshome.nix programs.ssh.matchBlocks (or wherever ssh is declared).
  • lazyvim-nix — pinned in flake.nix, configured under programs.lazyvim in home.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 at files/dev-CLAUDE.md here and is surfaced as a mutable symlink via home.file."dev/CLAUDE.md".source = config.lib.file.mkOutOfStoreSymlink ... in home.nix. Edit at either path; commit from this repo. Use files/ for any other documents that conceptually belong outside /etc/nixos but 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 to sandbox-claude.sh with 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 checks
  • nix build .#checks.x86_64-linux.refactor-smoke -L — headless VM boot test scaffold at tests/refactor-smoke.nix
  • nixos-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 specialArgs to all modules.
  • flake.nix — Inputs (nixpkgs, home-manager, hyprland, nix-colors, stylix, neovim-nightly, NUR), outputs. Passes settings to NixOS and home-manager modules.
  • configuration.nix — Thin entry point: imports all modules, sets per-host nix/networking/locale config, and omni.* options. Receives settings via specialArgs.
  • home.nix — Home-manager user config. Uses osConfig.omni.features to gate packages by feature flag. Receives settings via 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 via mkDefault.
  • 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 through config.omni.lib.
  • packages.nix — System packages gated by cfg.features.* and cfg.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.nix is the entry point with common hardware support.

Desktop (modules/desktop/)

  • hyprland.nix — Uses home-manager's wayland.windowManager.hyprland.settings for structured, mergeable config. Also configures Waybar.
  • hyprland/autostart.nixexec-once/exec lists (themes and feature modules can append).
  • hyprland/bindings.nix — Keybindings as bind/binde/bindm/bindl lists.
  • hyprland/idle.nix — Uses HM services.hypridle and programs.hyprlock modules.

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 currentTheme in configuration.nix)
  • Use tokyo-night.nix as the template for new themes

Key Patterns

  • Feature flags: config.omni.features.coding, etc. — guarded with lib.mkIf or lib.optionals. Both system packages (packages.nix) and user packages (home.nix) respect these.
  • Helpers access: Always via config.omni.lib (never import ./helpers.nix).
  • User reference: Always via config.omni.user in NixOS modules, settings.user in home.nix/flake.nix.
  • Theme switching: Change currentTheme in configuration.nix, then rebuild.
  • Structured Hyprland config: Themes merge attrsets into wayland.windowManager.hyprland.settings — no raw config files in /etc/.