# Repository Guidelines

## Project Structure & Module Organization
This directory is the Hyprland portion of a chezmoi dotfiles source tree. Key paths:
- `dot_config/` maps to `~/.config/` (e.g., `dot_config/hypr/`, `dot_config/nvim/`, `dot_config/waybar/`).
- `dot_local/` maps to `~/.local/` (scripts, data, and app state).
- `dot_profile.tmpl` renders to `~/.profile`.
- `.chezmoiscripts/` holds chezmoi hooks such as `run_onchange_*`.
- Host-specific variants use `##hostname.<name>` (e.g., `hyprpaper.conf##hostname.owlenlap01`).

Hyprland configuration uses the v0.55+ **Lua** config: entry point `hyprland.lua.tmpl` (rendered to `~/.config/hypr/hyprland.lua`), with modular includes under `hyprland.d.lua/` (`general.lua`, `layout.lua`, `keybinds.lua.tmpl`, etc.) plus the shared `state.lua` module. Related configs: `hypridle.conf.tmpl`, `hyprlock.conf.tmpl`, `hyprsunset.conf.tmpl`. The `.luarc.json` points the Lua LSP at the API stubs in `/usr/share/hypr/stubs`.

## Chezmoi Config (chezmoi.toml)
- Source of truth: `~/.config/chezmoi/chezmoi.toml` (not tracked here).
- Data model: `tags` (booleans: `laptop`, `touchscreen`, `pipewire`, `dev`, `bluetooth` — no `desktop`, use `not laptop`), `compositor` (`"hyprland"`/`"niri"`), `apps` (optional programs, gate with `has "x" .apps`), `data.monitors` (array; each `name` + optional `primary` + `role`), `data.placement` (app-home workspaces), `data.microphones`.
- **Workspace placement is data-driven.** `data.placement[]` entries define the app-home workspaces (`id`, `name`, monitor `role`, `apps` = window classes routed there, `silent`, optional `layout`/`layoutopts`/`on_created_empty`/`requires`/`reassert`). `workspaces.lua.tmpl` turns each into a `workspace_rule` (resolving `role` → monitor name, falling back to the `primary` monitor when that role is absent), and `rules.lua.tmpl` turns each `apps` class into a `window_rule` routing to that workspace. `reassert = true` additionally emits a `window.open` handler that re-applies the assignment by address, for apps (e.g. Joplin) that ignore the map-time silent rule and open on the focused workspace. To move an app or add a new app-home, edit `data.placement` — do **not** hardcode monitor names in the templates.
- Reference structure (current machine):
  ```toml
  [data]
  tags = { laptop = false, touchscreen = false, pipewire = true, dev = true, bluetooth = false }
  compositor = "hyprland"
  apps = ["steam", "spotify", "jellyfin"]

  [[data.placement]]
  id = 2; name = "comms"; role = "right"; silent = true; layout = "scrolling"; layoutopts = ["direction:down"]
  apps = ["info.mumble.Mumble", "discord", "vesktop", "teamspeak-client", "TeamSpeak", "TeamSpeak 3", "teamspeak3"]
  [[data.placement]]
  id = 4; name = "joplin"; role = "left"; apps = ["joplin-app-desktop"]; silent = true

  # --- Monitors (role drives placement; primary = fallback) ---
  [[data.monitors]]
  name = "DP-1"; primary = true; role = "primary"
  workspaces = [{ id = 24, name = "4" }, { id = 25, name = "5" }]
  [[data.monitors]]
  name = "DP-2"; role = "right"
  workspaces = [{ id = 28, name = "8" }, { id = 29, name = "9", layout = "scrolling" }]
  [[data.monitors]]
  name = "HDMI-A-2"; role = "left"
  workspaces = [{ id = 21, name = "1" }]
  ```

## Build, Test, and Development Commands
There is no build system. Validate changes via chezmoi:
- `chezmoi diff` shows pending changes between source and target files.
- `chezmoi apply` renders templates and applies updates to `$HOME`.
- `chezmoi status` summarizes managed file state.

After applying, reload Hyprland (e.g., `hyprctl reload`) or restart related tools to verify behavior.

## Coding Style & Naming Conventions
- Match existing formatting; avoid reflowing unrelated blocks.
- Use chezmoi prefixes: `dot_` for dotfiles, `executable_` for executables, `symlink_` for symlinks, `private_` for restricted files, and `.tmpl` for Go templates.
- Keep templates minimal and use `##hostname.<name>` for host-specific variants.

## Testing Guidelines
No automated tests are defined. Validate by:
- Running `chezmoi diff` and `chezmoi apply`.
- Smoke-testing the affected tool (e.g., reload Hyprland, start Waybar).

## Commit & Pull Request Guidelines
No established Git history. Use concise, imperative commit subjects with optional scope (e.g., `hypr: adjust keybinds`). For PRs, include:
- A clear summary of changes.
- Affected paths (e.g., `dot_config/hypr/hyprland.conf`).
- Screenshots for visible UI changes.

## Agent-Specific Notes

### Lua config (`hyprland.lua.tmpl` + `hyprland.d.lua/`)

The Lua config entry point is `hyprland.lua.tmpl`. It is rendered by chezmoi to `~/.config/hypr/hyprland.lua`, which Hyprland v0.55+ loads in preference to `hyprland.conf`.

`theme.lua.tmpl` reads `.chezmoi.config.data.theme` to select the color palette. This key is **not** in the tracked AGENTS.md reference but must be present in `~/.config/chezmoi/chezmoi.toml`:

```toml
[data]
theme = "apex-neon"   # or "apex-aeon"
```

Valid values: `"apex-neon"` (dark), `"apex-aeon"` (light). If the key is absent, the theme table will be empty and all border/groupbar colors will be unset.
