diff --git a/docs/AGENT.md b/docs/AGENT.md new file mode 100644 index 0000000..9e226bb --- /dev/null +++ b/docs/AGENT.md @@ -0,0 +1,229 @@ +# Agent Instructions for Nomarchy + +You're an AI coding agent picking up the Nomarchy project. This document gives you everything you need to be useful from the first turn: what Nomarchy is, how it's organized, what the rules are, and how to actually pick up the next piece of work. + +If anything below conflicts with what the user just said, the user wins. If anything below conflicts with the existing code, read the code — these notes can rot. + +--- + +## 1. What Nomarchy is + +Nomarchy is a NixOS-based distribution that ships the Omarchy Hyprland desktop on a strictly declarative, flake-based foundation. It targets power users who want the polish of Omarchy without giving up reproducibility. + +Concretely: + +- A flake at the repo root exposes `nixosModules.system` (foundational OS modules) and `nixosModules.home` (apps + desktop), plus three `nixosConfigurations` (`installerIso`, `installerIsoGraphical`, `default`) and standalone `homeConfigurations`. +- Downstream users get the distro by importing `nomarchy.nixosModules.system` and `nomarchy.nixosModules.home` from their own `/etc/nixos/flake.nix`. The Nomarchy installer generates that flake for them; an existing-NixOS user can hand-write it (see `docs/MIGRATION.md`). +- A bash/`gum` TUI installer lives in `installer/install.sh` (~1100 lines). It auto-detects hardware via `installer/hardware-db.sh` (DMI + `lspci` + `BAT*` sysfs), prompts for the rest, and generates `flake.nix`, `system.nix`, `home.nix`, and `hardware-selection.nix` into `/mnt/etc/nixos/`. +- The desktop is Hyprland + waybar + walker + a curated theming engine (`themes/`) with 22 palettes wired through Stylix. + +Read in this order to come up to speed: + +1. `README.md` — public face. +2. `docs/STRUCTURE.md` — directory layout and module logic. +3. `docs/OPTIONS.md` — every `nomarchy.*` option a downstream flake can set. +4. `docs/ROADMAP.md` — what's planned. **This is your work queue.** +5. `docs/SCRIPTS.md` — the script & menu audit table (Pillar 3 of the roadmap). +6. `docs/MIGRATION.md` — how an existing NixOS install becomes Nomarchy. +7. `docs/creating-themes.md` — when palette work comes up. + +--- + +## 2. How the repo is organized + +``` +core/ Foundational OS + user defaults. Don't put apps here. + system/ NixOS modules, all imported via core/default.nix. + options.nix nomarchy.system.* options live here. + hardware.nix nomarchy.hardware.* options + module wiring. + network.nix NetworkManager, DNS, networkmanagerapplet. + impermanence.nix Erase-Your-Darlings root wipe. + scripts/ Low-level system scripts (battery, brightness, hardware). + home/ Home Manager modules. + options.nix Most home-side nomarchy.* options. + behavior.nix nomarchy.behavior.* (deploy-default-config toggles). + overrides.nix File-based overrides from ~/.config/nomarchy/overrides/. + config/ Plain dotfiles symlinked into ~/.config. + +features/ Apps and desktop components. Add new apps here. + apps/ One subdir per app (alacritty, btop, kitty, vscode.nix, …). + desktop/ hyprland, waybar, idle.nix, nightlight.nix, … + scripts/ User-PATH scripts, battery-monitor user service. + utils/ ~68 nomarchy-* user scripts. + default.nix Packages them as nomarchy-system-scripts derivation. + +themes/ Theme engine + 22 palettes. + engine/ Loader, Stylix glue, switcher, scripts (font, theme, wallpaper). + palettes/ One subdir per palette (summer-night, tokyo-night, …). + +hosts/ ISO host configs (installerIso, installerIsoGraphical/live-iso). +installer/ The bash/gum TUI + disko configs + hardware-db.sh. +lib/ Shared Nix helpers (state schema, color resolution, paths). +docs/ All long-form documentation. README.md stays at repo root. +bin/ Convenience wrappers for testing (nomarchy-test-installer, …). +``` + +When you add a new feature: + +- A new app → `features/apps//default.nix` (+ optional `config/`), import it from `features/default.nix`. +- A new system service → `core/system/.nix`, import from `core/default.nix`. +- A new toggle → add to `core/system/options.nix` or `core/home/options.nix`, wire it into the relevant module, document it in `docs/OPTIONS.md`. + +--- + +## 3. Guardrails (non-negotiable unless the user overrides) + +These are inherited from the established Nomarchy conventions. Violating them is a bug. + +1. **Declarative-first.** No imperative state in `core/`. Mutable state goes in `~/.config/nomarchy/state.json` or in NixOS / home-manager options. +2. **Downstream-flake friendly.** Every behavior toggle is a `nomarchy.*` option documented in `docs/OPTIONS.md`. Adding a feature without a corresponding option is a bug. +3. **Opt-in by default.** New features default off (or default to existing behavior). The installer can flip defaults *for the user being installed*, but the option must read sensibly when set by hand. +4. **`lib.mkDefault` everywhere user might override.** If a downstream `system.nix` would reasonably want to change something Nomarchy sets, set it with `lib.mkDefault`. If it must not be overridden, use `lib.mkForce` and explain why in a comment. +5. **Reuse before invent.** ~155 `nomarchy-*` scripts already exist across `core/system/scripts/`, `features/scripts/utils/`, `themes/engine/scripts/`. Grep before writing a new one. +6. **No comments that narrate.** Don't write comments explaining *what* the code does. Only write a comment when the *why* is non-obvious — a hidden constraint, a subtle invariant, a workaround. +7. **No backwards-compat shims.** If you remove a thing, remove it everywhere. No re-exports, no `// removed` markers. + +--- + +## 4. How to find work to do + +The roadmap (`docs/ROADMAP.md`) is the source of truth. It has three columns and seven pillars. + +**Default rule:** prefer items in the **Now** column. Pick whichever matches the user's current ask, or the smallest one if no ask is in flight. + +If the user asked for something not in the roadmap: + +- Do the work. +- After it ships, propose a one-line addition to `docs/ROADMAP.md` so future you doesn't re-discover it. + +If the user asks "what's next?", reply with the Now column items in 2–3 sentences and let them pick. + +### The script & menu audit (Pillar 3) + +This is the **largest single open work item**. Phase A (inventory) hasn't run yet; `docs/SCRIPTS.md` is just scaffolding. The user explicitly flagged this pillar as important. + +To pick it up: + +1. Run the three generator commands at the top of `docs/SCRIPTS.md`. +2. Populate the **Scripts** table with one row per `nomarchy-*` file (location, callers, status `unknown` for now). +3. Populate the **Menu items** table by walking each `show_*_menu` function in `features/scripts/utils/nomarchy-menu`. +4. Tag every row with one of: `kept` / `port-from-omarchy` / `delete-dead` / `stub-with-notify` / `unknown`. Triage live, but leave anything ambiguous as `unknown`. +5. Land it as **one PR** (the inventory PR). Don't start porting in the same change. + +Then Phase B is per-script: one PR per ~10 scripts, branch named `wave/audit-`. Each PR closes specific rows in `docs/SCRIPTS.md`. + +--- + +## 5. Workflow per change + +Steps you should follow for any non-trivial change: + +1. **Understand the current state first.** + - `git status` and `git log -5` so you know what's just landed and what's in flight. + - Read the relevant files. Don't infer. +2. **Plan if it's non-trivial.** Tasks with three or more steps benefit from a TaskCreate list. Tasks that touch the architecture benefit from plan mode. +3. **Reuse existing options and scripts.** Grep `core/system/options.nix`, `core/home/options.nix`, and the three script directories before adding anything. +4. **Touch the docs in the same change.** New option → row in `docs/OPTIONS.md`. New script → row in `docs/SCRIPTS.md`. Roadmap item shipped → move it to the **Shipped** section at the bottom of `docs/ROADMAP.md`. +5. **Verify the change evaluates** (cheap, do this before declaring done): + ```bash + nix --extra-experimental-features 'nix-command flakes' flake check --no-build + bash -n installer/install.sh # if you touched it + ``` + For installer changes, also do a dry-run end-to-end: + ```bash + sudo /etc/install.sh --dry-run # in the live ISO or VM + ``` + For waybar / Hyprland visual changes, the only reliable check is booting the live ISO with `nomarchy-test-live-iso`. If you can't boot it, **say so** rather than claiming success. +6. **Commit narrowly.** One concept per commit. The commit subject is `: ` (`feat:`, `fix:`, `docs:`, `chore:`). The body explains the why. +7. **Push only when the user asks.** Local commits are free; pushing publishes. + +--- + +## 6. Patterns worth knowing + +### Adding a new option + +```nix +# core/system/options.nix (or core/home/options.nix for home-side) +mything.enable = lib.mkEnableOption '' + Concise description that reads well in `nix eval`. Mention any + pre-conditions (groups, kernel modules, hardware needed). +''; +``` + +Then wire it inside a `config = lib.mkIf cfg.mything.enable { ... }` block and document it in `docs/OPTIONS.md`. + +### Filtering modules conditionally + +We do this for waybar (drop `battery` on desktop) in `features/desktop/waybar/default.nix:25-39`. Pattern: + +```nix +let + rawSettings = builtins.fromJSON (builtins.readFile configFile); + laptopOnly = [ "battery" "custom/battery" ]; + filterModules = mods: + if config.nomarchy.formFactor == "laptop" then mods + else builtins.filter (m: !(builtins.elem m laptopOnly)) mods; + settings = rawSettings // { + modules-right = filterModules (rawSettings.modules-right or []); + modules-center = filterModules (rawSettings.modules-center or []); + modules-left = filterModules (rawSettings.modules-left or []); + }; +in { ... } +``` + +### Form-factor (laptop vs desktop) + +`nomarchy.system.formFactor` and `nomarchy.formFactor` are the two halves of the same flag (system + home). Default `"laptop"`. The installer auto-detects via `compgen -G "/sys/class/power_supply/BAT*"` and writes the explicit value into both generated files. Use this option to gate any laptop-only UI / service. + +### State (`state.json`) + +Theme, font, wallpaper, and a few feature toggles live in `~/.config/nomarchy/state.json` so they can change without a rebuild. Schema is in `lib/state-schema.nix`. The Home Manager evaluator reads it via `lib/default.nix`. **Don't add new state without justifying it** — most "state" should be a NixOS option instead. + +### Scripts derivation + +User-PATH scripts ship via `nomarchy-system-scripts` (`core/system/scripts-derivation.nix`) plus the per-category dependencies declared in `features/scripts/default.nix:categoryDeps`. When you add a script: + +1. Drop the file in `features/scripts/utils/` or `core/system/scripts/`. +2. `chmod +x` it (it'll be wrapped with the right deps automatically). +3. Reference the right `categoryDeps` group in `features/scripts/default.nix` if it needs new tools. +4. Test that `which