main @ 247 LINES
[ HISTORY ] [ UP ]
┌─ NIX ──────────────────────────────────────────────────────────────────────┐
│ { │
│ lib, │
│ ook, │
│ ... │
│ }: let │
│ inherit (lib) mkOption; │
│ inherit (lib.types) int bool str listOf attrsOf submodule; │
│ inherit (ook) color; │
│ mkInt = default: │
│ mkOption { │
│ type = int; │
│ inherit default; │
│ }; │
│ mkColor = default: │
│ mkOption { │
│ type = str; │
│ inherit default; │
│ }; │
│ mkStr = mkColor; │
│ mkBool = default: │
│ mkOption { │
│ type = bool; │
│ inherit default; │
│ }; │
│ service = submodule { │
│ options = { │
│ name = mkStr ""; │
│ http = mkStr ""; # direct: url to GET │
│ bodyContains = mkStr ""; # http only │
│ ssh = mkStr ""; # ssh check: host to curl localhost on (for proxied/vpn'd se │
│ rvices) │
│ port = mkInt 0; # localhost port for the ssh check │
│ path = mkStr ""; # url path, default / │
│ expect = mkInt 0; # expected status, 0 = any 2xx/3xx │
│ degradedMs = mkInt 0; # latency over this -> degraded │
│ }; │
│ }; │
│ in { │
│ options.ooknet.ookshell = { │
│ enable = mkOption { │
│ type = bool; │
│ default = true; │
│ }; │
│ │
│ bar = { │
│ height = mkInt 32; │
│ radius = mkInt 10; │
│ spacing = mkInt 12; # gap between modules in a cluster │
│ padding = mkInt 12; # inner horizontal padding of a cluster │
│ borderWidth = mkInt 2; │
│ margin = { │
│ top = mkInt 10; │
│ left = mkInt 10; │
│ right = mkInt 10; │
│ }; │
│ }; │
│ │
│ workspaces = { │
│ persistent = mkInt 5; # always-shown count, extras appear dynamically │
│ spacing = mkInt 10; │
│ }; │
│ │
│ tray = { │
│ iconSize = mkInt 21; │
│ spacing = mkInt 8; │
│ compact = mkBool true; # collapse to a chevron, reveal icons on hover │
│ menu = { │
│ padding = mkInt 6; │
│ timeout = mkInt 1500; # ms before auto-closing when not hovered │
│ colors = { │
│ background = mkColor "#${color.layout.menu}"; │
│ text = mkColor "#${color.typography.text}"; │
│ disabled = mkColor "#${color.typography.subtext}"; │
│ hover = mkColor "#${color.layout.selection}"; │
│ }; │
│ }; │
│ }; │
│ │
│ monitor = { │
│ width = mkInt 380; # dashboard pane width │
│ services = mkOption { │
│ type = listOf service; │
│ # ookflix stack on ooksmedia is behind traefik/gluetun, so checked via ssh │
│ # (curl localhost on the host) rather than directly │
│ default = [ │
│ { │
│ name = "website"; │
│ http = "https://www.ooknet.org"; │
│ } │
│ { │
│ name = "plex"; │
│ ssh = "ooksmedia"; │
│ port = 32400; │
│ path = "/identity"; │
│ } │
│ { │
│ name = "jellyfin"; │
│ ssh = "ooksmedia"; │
│ port = 8096; │
│ } │
│ { │
│ name = "sonarr"; │
│ ssh = "ooksmedia"; │
│ port = 8989; │
│ } │
│ { │
│ name = "radarr"; │
│ ssh = "ooksmedia"; │
│ port = 7878; │
│ } │
│ { │
│ name = "prowlarr"; │
│ ssh = "ooksmedia"; │
│ port = 9696; │
│ } │
│ { │
│ name = "jellyseerr"; │
│ ssh = "ooksmedia"; │
│ port = 5055; │
│ } │
│ { │
│ name = "tautulli"; │
│ ssh = "ooksmedia"; │
│ port = 8181; │
│ } │
│ { │
│ name = "homepage"; │
│ ssh = "ooksmedia"; │
│ port = 3000; │
│ } │
│ { │
│ name = "qbittorrent"; │
│ ssh = "ooksmedia"; │
│ port = 8081; │
│ } │
│ ]; │
│ }; │
│ qbittorrent = { │
│ enable = mkBool true; │
│ service = mkStr "qbittorrent"; # which service entry to enrich │
│ ssh = mkStr "ooksmedia"; │
│ container = mkStr "qbittorrent"; # podman container (queried via podman ex │
│ ec, no auth) │
│ port = mkInt 8080; # webui port inside the container │
│ }; │
│ }; │
│ │
│ # color roles, defaulting from the active ook scheme. override per-host │
│ colors = { │
│ background = mkColor "#${color.layout.header}"; │
│ border = mkColor "#${color.border.base}"; │
│ text = mkColor "#${color.typography.text}"; │
│ workspaceActive = mkColor "#${color.primary.base}"; │
│ workspaceUrgent = mkColor "#${color.orange.base}"; │
│ record = mkColor "#${color.red.base}"; │
│ battery = { │
│ good = mkColor "#${color.success.base}"; │
│ warning = mkColor "#${color.warning.base}"; │
│ critical = mkColor "#${color.error.base}"; │
│ }; │
│ }; │
│ │
│ # terminal-style notification popups (replaces mako) │
│ notifications = { │
│ columns = mkInt 38; # card width in monospace columns │
│ padding = mkInt 8; # inner px padding between frame and text │
│ # command (as args list) to open a screenshot for editing on click; the │
│ # image path is appended. empty -> default (satty) resolved in default.nix │
│ imageEditor = mkOption { │
│ type = listOf str; │
│ default = []; │
│ }; │
│ maxBodyLines = mkInt 4; │
│ maxVisible = mkInt 5; │
│ spacing = mkInt 8; # gap between stacked cards │
│ margin = { │
│ top = mkInt 10; │
│ right = mkInt 10; │
│ }; │
│ timeout = { │
│ # ms, 0 = sticky (no auto-dismiss) │
│ low = mkInt 3000; │
│ normal = mkInt 3000; │
│ critical = mkInt 0; │
│ }; │
│ glyphs = { │
│ topLeft = mkStr "┌"; │
│ topRight = mkStr "┐"; │
│ bottomLeft = mkStr "└"; │
│ bottomRight = mkStr "┘"; │
│ horizontal = mkStr "─"; │
│ vertical = mkStr "│"; │
│ }; │
│ colors = { │
│ background = mkColor "#${color.layout.menu}"; │
│ title = mkColor "#${color.typography.text}"; │
│ text = mkColor "#${color.typography.text}"; │
│ action = mkColor "#${color.primary.base}"; │
│ # border colors, normal matches hyprland's col.active_border │
│ urgency = { │
│ low = mkColor "#${color.neutrals."650"}"; │
│ normal = mkColor "#${color.neutrals."650"}"; │
│ critical = mkColor "#${color.red.base}"; │
│ }; │
│ }; │
│ │
│ # per-app overrides keyed by appName (lowercased). lets chat apps that ship │
│ # avatars + channel context render with their brand color and a clean layout │
│ apps = mkOption { │
│ type = attrsOf (submodule { │
│ options = { │
│ border = mkColor ""; # border color, empty -> urgency color │
│ titleFromName = mkBool false; # header = sender name parsed from summa │
│ ry │
│ hideImage = mkBool false; # ignore the notification image (avatars) │
│ }; │
│ }); │
│ default = { │
│ vesktop = { │
│ border = "#5865F2"; # discord blurple │
│ titleFromName = true; │
│ hideImage = true; │
│ }; │
│ }; │
│ }; │
│ }; │
│ │
│ # ascii cells on-screen display for volume / brightness / mic │
│ osd = { │
│ cells = mkInt 24; # number of slider cells │
│ timeout = mkInt 1500; # ms visible after a change │
│ padding = mkInt 8; │
│ # marginTop is derived in default.nix: aligned to the bar's bottom edge so │
│ # the osd's top border is inline with where windows start │
│ glyphs = { │
│ filled = mkStr "?"; │
│ empty = mkStr "?"; │
│ }; │
│ colors = { │
│ border = mkColor "#${color.neutrals."650"}"; │
│ title = mkColor "#${color.typography.text}"; │
│ filled = mkColor "#${color.primary.base}"; │
│ empty = mkColor "#${color.neutrals."600"}"; │
│ text = mkColor "#${color.typography.text}"; │
│ muted = mkColor "#${color.red.base}"; │
│ }; │
│ }; │
│ }; │
│ } │
└────────────────────────────────────────────────────────────────────────────────────┘
┌─ NIX ────────────────────────────────┐
│ { │
│ lib, │
│ ook, │
│ ... │
│ }: let │
│ inherit (lib) mkOption; │
│ inherit (lib.types) int bool str listOf at │
│ trsOf submodule; │
│ inherit (ook) color; │
│ mkInt = default: │
│ mkOption { │
│ type = int; │
│ inherit default; │
│ }; │
│ mkColor = default: │
│ mkOption { │
│ type = str; │
│ inherit default; │
│ }; │
│ mkStr = mkColor; │
│ mkBool = default: │
│ mkOption { │
│ type = bool; │
│ inherit default; │
│ }; │
│ service = submodule { │
│ options = { │
│ name = mkStr ""; │
│ http = mkStr ""; # direct: url to GET │
│ bodyContains = mkStr ""; # http only │
│ ssh = mkStr ""; # ssh check: host to c │
│ url localhost on (for proxied/vpn'd services │
│ ) │
│ port = mkInt 0; # localhost port for t │
│ he ssh check │
│ path = mkStr ""; # url path, default / │
│ expect = mkInt 0; # expected status, 0 │
│ = any 2xx/3xx │
│ degradedMs = mkInt 0; # latency over t │
│ his -> degraded │
│ }; │
│ }; │
│ in { │
│ options.ooknet.ookshell = { │
│ enable = mkOption { │
│ type = bool; │
│ default = true; │
│ }; │
│ │
│ bar = { │
│ height = mkInt 32; │
│ radius = mkInt 10; │
│ spacing = mkInt 12; # gap between modu │
│ les in a cluster │
│ padding = mkInt 12; # inner horizontal │
│ padding of a cluster │
│ borderWidth = mkInt 2; │
│ margin = { │
│ top = mkInt 10; │
│ left = mkInt 10; │
│ right = mkInt 10; │
│ }; │
│ }; │
│ │
│ workspaces = { │
│ persistent = mkInt 5; # always-shown c │
│ ount, extras appear dynamically │
│ spacing = mkInt 10; │
│ }; │
│ │
│ tray = { │
│ iconSize = mkInt 21; │
│ spacing = mkInt 8; │
│ compact = mkBool true; # collapse to a │
│ chevron, reveal icons on hover │
│ menu = { │
│ padding = mkInt 6; │
│ timeout = mkInt 1500; # ms before au │
│ to-closing when not hovered │
│ colors = { │
│ background = mkColor "#${color.lay │
│ out.menu}"; │
│ text = mkColor "#${color.typograph │
│ y.text}"; │
│ disabled = mkColor "#${color.typog │
│ raphy.subtext}"; │
│ hover = mkColor "#${color.layout.s │
│ election}"; │
│ }; │
│ }; │
│ }; │
│ │
│ monitor = { │
│ width = mkInt 380; # dashboard pane wi │
│ dth │
│ services = mkOption { │
│ type = listOf service; │
│ # ookflix stack on ooksmedia is behi │
│ nd traefik/gluetun, so checked via ssh │
│ # (curl localhost on the host) rathe │
│ r than directly │
│ default = [ │
│ { │
│ name = "website"; │
│ http = "https://www.ooknet.org"; │
│ } │
│ { │
│ name = "plex"; │
│ ssh = "ooksmedia"; │
│ port = 32400; │
│ path = "/identity"; │
│ } │
│ { │
│ name = "jellyfin"; │
│ ssh = "ooksmedia"; │
│ port = 8096; │
│ } │
│ { │
│ name = "sonarr"; │
│ ssh = "ooksmedia"; │
│ port = 8989; │
│ } │
│ { │
│ name = "radarr"; │
│ ssh = "ooksmedia"; │
│ port = 7878; │
│ } │
│ { │
│ name = "prowlarr"; │
│ ssh = "ooksmedia"; │
│ port = 9696; │
│ } │
│ { │
│ name = "jellyseerr"; │
│ ssh = "ooksmedia"; │
│ port = 5055; │
│ } │
│ { │
│ name = "tautulli"; │
│ ssh = "ooksmedia"; │
│ port = 8181; │
│ } │
│ { │
│ name = "homepage"; │
│ ssh = "ooksmedia"; │
│ port = 3000; │
│ } │
│ { │
│ name = "qbittorrent"; │
│ ssh = "ooksmedia"; │
│ port = 8081; │
│ } │
│ ]; │
│ }; │
│ qbittorrent = { │
│ enable = mkBool true; │
│ service = mkStr "qbittorrent"; # whi │
│ ch service entry to enrich │
│ ssh = mkStr "ooksmedia"; │
│ container = mkStr "qbittorrent"; # p │
│ odman container (queried via podman exec, no │
│ auth) │
│ port = mkInt 8080; # webui port insi │
│ de the container │
│ }; │
│ }; │
│ │
│ # color roles, defaulting from the activ │
│ e ook scheme. override per-host │
│ colors = { │
│ background = mkColor "#${color.layout. │
│ header}"; │
│ border = mkColor "#${color.border.base │
│ }"; │
│ text = mkColor "#${color.typography.te │
│ xt}"; │
│ workspaceActive = mkColor "#${color.pr │
│ imary.base}"; │
│ workspaceUrgent = mkColor "#${color.or │
│ ange.base}"; │
│ record = mkColor "#${color.red.base}"; │
│ battery = { │
│ good = mkColor "#${color.success.bas │
│ e}"; │
│ warning = mkColor "#${color.warning. │
│ base}"; │
│ critical = mkColor "#${color.error.b │
│ ase}"; │
│ }; │
│ }; │
│ │
│ # terminal-style notification popups (re │
│ places mako) │
│ notifications = { │
│ columns = mkInt 38; # card width in mo │
│ nospace columns │
│ padding = mkInt 8; # inner px padding │
│ between frame and text │
│ # command (as args list) to open a scr │
│ eenshot for editing on click; the │
│ # image path is appended. empty -> def │
│ ault (satty) resolved in default.nix │
│ imageEditor = mkOption { │
│ type = listOf str; │
│ default = []; │
│ }; │
│ maxBodyLines = mkInt 4; │
│ maxVisible = mkInt 5; │
│ spacing = mkInt 8; # gap between stack │
│ ed cards │
│ margin = { │
│ top = mkInt 10; │
│ right = mkInt 10; │
│ }; │
│ timeout = { │
│ # ms, 0 = sticky (no auto-dismiss) │
│ low = mkInt 3000; │
│ normal = mkInt 3000; │
│ critical = mkInt 0; │
│ }; │
│ glyphs = { │
│ topLeft = mkStr "┌"; │
│ topRight = mkStr "┐"; │
│ bottomLeft = mkStr "└"; │
│ bottomRight = mkStr "┘"; │
│ horizontal = mkStr "─"; │
│ vertical = mkStr "│"; │
│ }; │
│ colors = { │
│ background = mkColor "#${color.layou │
│ t.menu}"; │
│ title = mkColor "#${color.typography │
│ .text}"; │
│ text = mkColor "#${color.typography. │
│ text}"; │
│ action = mkColor "#${color.primary.b │
│ ase}"; │
│ # border colors, normal matches hypr │
│ land's col.active_border │
│ urgency = { │
│ low = mkColor "#${color.neutrals." │
│ 650"}"; │
│ normal = mkColor "#${color.neutral │
│ s."650"}"; │
│ critical = mkColor "#${color.red.b │
│ ase}"; │
│ }; │
│ }; │
│ │
│ # per-app overrides keyed by appName ( │
│ lowercased). lets chat apps that ship │
│ # avatars + channel context render wit │
│ h their brand color and a clean layout │
│ apps = mkOption { │
│ type = attrsOf (submodule { │
│ options = { │
│ border = mkColor ""; # border co │
│ lor, empty -> urgency color │
│ titleFromName = mkBool false; # │
│ header = sender name parsed from summary │
│ hideImage = mkBool false; # igno │
│ re the notification image (avatars) │
│ }; │
│ }); │
│ default = { │
│ vesktop = { │
│ border = "#5865F2"; # discord bl │
│ urple │
│ titleFromName = true; │
│ hideImage = true; │
│ }; │
│ }; │
│ }; │
│ }; │
│ │
│ # ascii cells on-screen display for volu │
│ me / brightness / mic │
│ osd = { │
│ cells = mkInt 24; # number of slider c │
│ ells │
│ timeout = mkInt 1500; # ms visible aft │
│ er a change │
│ padding = mkInt 8; │
│ # marginTop is derived in default.nix: │
│ aligned to the bar's bottom edge so │
│ # the osd's top border is inline with │
│ where windows start │
│ glyphs = { │
│ filled = mkStr "?"; │
│ empty = mkStr "?"; │
│ }; │
│ colors = { │
│ border = mkColor "#${color.neutrals. │
│ "650"}"; │
│ title = mkColor "#${color.typography │
│ .text}"; │
│ filled = mkColor "#${color.primary.b │
│ ase}"; │
│ empty = mkColor "#${color.neutrals." │
│ 600"}"; │
│ text = mkColor "#${color.typography. │
│ text}"; │
│ muted = mkColor "#${color.red.base}" │
│ ; │
│ }; │
│ }; │
│ }; │
│ } │
└──────────────────────────────────────────────┘
──────────────────────────────────────────────────────────────────────────────────────
OOKNET
────────────────────────────────────────────────
OOKNET