All checks were successful
Check / eval (push) Successful in 3m10s
The "Battery Limit" entry was a raw number prompt; make it a proper toggle picker — Off / 80% (recommended) / 90% / 60% / Custom… — writing settings.power.batteryChargeLimit. Kept in the control-center, where the baked rebuild-valued System Toggles live (the rofi nomarchy-menu is the instant surface; the CC holds config values), and reachable from the menu via System › Control Center. Base machinery (the sysfs oneshot + AC-replug udev in power.nix) is unchanged, so it lands on the next sys-rebuild like its siblings. Instant-effect (no rebuild) is refiled in BACKLOG § PROPOSED as [blocked:hw]: it needs a udev-writable threshold node, confirmable only on a laptop with the control. Verified: V0 (bash -n; nix flake check --no-build, green) + V1 (nomarchy-control-center package builds — the writeShellApplication shellcheck gate passes). Session spot-check queued in HARDWARE-QUEUE. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
257 lines
10 KiB
Bash
257 lines
10 KiB
Bash
#!/usr/bin/env bash
|
||
set -euo pipefail
|
||
|
||
# Nomarchy Control Center — TUI frontend over nomarchy-theme-sync and tools
|
||
# Uses charmbracelet/gum for rendering.
|
||
|
||
trap 'exit 0' SIGINT
|
||
|
||
function get_state() {
|
||
nomarchy-theme-sync get "$1" 2>/dev/null || echo ""
|
||
}
|
||
|
||
function set_state() {
|
||
nomarchy-theme-sync --quiet set "$1" "$2" --no-switch
|
||
}
|
||
|
||
function first_boot() {
|
||
gum style --border normal --margin "1" --padding "1 2" --border-foreground 212 "Welcome to Nomarchy!"
|
||
|
||
echo "Pick a Theme Preset:"
|
||
themes=$(nomarchy-theme-sync list)
|
||
chosen_theme=$(printf "%s" "$themes" | gum choose)
|
||
if [ -n "$chosen_theme" ]; then
|
||
echo "Applying theme $chosen_theme..."
|
||
nomarchy-theme-sync apply "$chosen_theme"
|
||
fi
|
||
|
||
if gum confirm "Enable auto-commit for settings?"; then
|
||
set_state "settings.autoCommit" "true"
|
||
else
|
||
set_state "settings.autoCommit" "false"
|
||
fi
|
||
|
||
if command -v nomarchy-autotimezone >/dev/null 2>&1; then
|
||
if gum confirm "Enable automatic timezone detection?"; then
|
||
set_state "settings.autoTimezone" "true"
|
||
else
|
||
set_state "settings.autoTimezone" "false"
|
||
fi
|
||
fi
|
||
|
||
gum style --foreground 212 "First boot configuration complete!"
|
||
echo "You can always change these later in the Control Center."
|
||
read -r -n 1 -s -p "Press any key to exit..."
|
||
echo
|
||
}
|
||
|
||
function main_menu() {
|
||
while true; do
|
||
choice=$(gum choose "Appearance" "System Toggles" "Health (Doctor)" "Rollback" "Exit")
|
||
case "$choice" in
|
||
"Appearance") appearance_menu ;;
|
||
"System Toggles") toggles_menu ;;
|
||
"Health (Doctor)")
|
||
if command -v nomarchy-doctor >/dev/null 2>&1; then
|
||
nomarchy-doctor || true
|
||
else
|
||
echo "nomarchy-doctor not found."
|
||
fi
|
||
echo
|
||
read -r -n 1 -s -p "Press any key to return..."
|
||
echo
|
||
;;
|
||
"Rollback")
|
||
gens=$(home-manager generations 2>/dev/null | head -10)
|
||
if [ -z "$gens" ]; then
|
||
echo "No Home Manager generations found."
|
||
else
|
||
printf "%s\n" "$gens" | awk '{ printf "Desktop gen %s — %s %s%s\n", $5, $1, $2, (NR==1 ? " (current)" : "") }' > /tmp/nomarchy-gens
|
||
sel=$(gum choose < /tmp/nomarchy-gens || true)
|
||
if [ -n "$sel" ]; then
|
||
num=${sel#Desktop gen }
|
||
num=${num%% *}
|
||
path=$(printf "%s\n" "$gens" | awk -v n="$num" '$5 == n { print $7 }')
|
||
if [ -x "$path/activate" ]; then
|
||
echo "Activating Home Manager generation $num..."
|
||
"$path/activate"
|
||
echo "Desktop rolled back to generation $num."
|
||
else
|
||
echo "Generation $num not found."
|
||
fi
|
||
fi
|
||
fi
|
||
echo
|
||
read -r -n 1 -s -p "Press any key to return..."
|
||
echo
|
||
;;
|
||
"Exit"|*) break ;;
|
||
esac
|
||
done
|
||
}
|
||
|
||
function appearance_menu() {
|
||
while true; do
|
||
choice=$(gum choose "Pick Theme" "Toggle Blur" "Set Gaps" "Back")
|
||
case "$choice" in
|
||
"Pick Theme")
|
||
themes=$(nomarchy-theme-sync list)
|
||
chosen=$(printf "%s" "$themes" | gum choose)
|
||
if [ -n "$chosen" ]; then
|
||
nomarchy-theme-sync apply "$chosen"
|
||
fi
|
||
;;
|
||
"Toggle Blur")
|
||
blur=$(get_state "ui.blur")
|
||
if [ "$blur" = "true" ]; then
|
||
set_state "ui.blur" "false"
|
||
else
|
||
set_state "ui.blur" "true"
|
||
fi
|
||
;;
|
||
"Set Gaps")
|
||
gaps=$(gum input --prompt "Enter gaps in pixels: " --placeholder "$(get_state ui.gapsOut)")
|
||
if [ -n "$gaps" ]; then
|
||
set_state "ui.gapsOut" "$gaps"
|
||
fi
|
||
;;
|
||
"Back"|*) break ;;
|
||
esac
|
||
done
|
||
}
|
||
|
||
function toggles_menu() {
|
||
while true; do
|
||
choice=$(gum choose "Auto-commit" "Auto-timezone" "Night Light" "Updates" "Battery Limit" "Bluetooth" "Printing" "Terminal" "Keyboard Layout" "Auto-Login" "Back")
|
||
case "$choice" in
|
||
"Auto-commit")
|
||
cur=$(get_state "settings.autoCommit")
|
||
if [ "$cur" = "true" ]; then
|
||
set_state "settings.autoCommit" "false"
|
||
echo "Auto-commit disabled."
|
||
else
|
||
set_state "settings.autoCommit" "true"
|
||
echo "Auto-commit enabled."
|
||
fi
|
||
sleep 1
|
||
;;
|
||
"Auto-timezone")
|
||
cur=$(get_state "settings.autoTimezone")
|
||
if [ "$cur" = "true" ]; then
|
||
set_state "settings.autoTimezone" "false"
|
||
echo "Auto-timezone disabled."
|
||
else
|
||
set_state "settings.autoTimezone" "true"
|
||
echo "Auto-timezone enabled."
|
||
fi
|
||
sleep 1
|
||
;;
|
||
"Night Light")
|
||
if command -v nomarchy-nightlight >/dev/null 2>&1; then
|
||
nomarchy-nightlight toggle
|
||
sleep 1
|
||
else
|
||
echo "nomarchy-nightlight not found."
|
||
sleep 1
|
||
fi
|
||
;;
|
||
"Updates")
|
||
cur=$(get_state "settings.updates.enable")
|
||
if [ "$cur" = "true" ]; then
|
||
set_state "settings.updates.enable" "false"
|
||
echo "Updates checker disabled (requires rebuild)."
|
||
else
|
||
set_state "settings.updates.enable" "true"
|
||
echo "Updates checker enabled (requires rebuild)."
|
||
fi
|
||
sleep 1
|
||
;;
|
||
"Battery Limit")
|
||
# Conservation-mode toggle: cap charging to spare the battery,
|
||
# or Off to charge full. A preset picker (not a raw number) with
|
||
# a Custom escape hatch. This is a baked NixOS system option
|
||
# (settings.power.batteryChargeLimit → the sysfs oneshot in
|
||
# power.nix), so it lands on the next sys-rebuild like the other
|
||
# System Toggles.
|
||
cur=$(get_state settings.power.batteryChargeLimit)
|
||
sel=$(gum choose --header "Battery charge limit (now: ${cur:-default})" \
|
||
"80% (recommended)" "90%" "60%" "Off (charge to 100%)" "Custom…" "Cancel")
|
||
case "$sel" in
|
||
"80%"*) set_state "settings.power.batteryChargeLimit" "80"
|
||
echo "Charge limit set to 80% (requires rebuild)." ;;
|
||
"90%") set_state "settings.power.batteryChargeLimit" "90"
|
||
echo "Charge limit set to 90% (requires rebuild)." ;;
|
||
"60%") set_state "settings.power.batteryChargeLimit" "60"
|
||
echo "Charge limit set to 60% (requires rebuild)." ;;
|
||
"Off"*) set_state "settings.power.batteryChargeLimit" "null"
|
||
echo "Charge limit off — charges to 100% (requires rebuild)." ;;
|
||
"Custom…")
|
||
limit=$(gum input --prompt "Charge limit % (50–100): " --placeholder "$cur")
|
||
if [ -n "$limit" ]; then
|
||
set_state "settings.power.batteryChargeLimit" "$limit"
|
||
echo "Charge limit set to $limit% (requires rebuild)."
|
||
fi ;;
|
||
*) : ;;
|
||
esac
|
||
sleep 1
|
||
;;
|
||
"Bluetooth")
|
||
cur=$(get_state "settings.bluetooth.enable")
|
||
if [ "$cur" = "true" ]; then
|
||
set_state "settings.bluetooth.enable" "false"
|
||
echo "Bluetooth disabled (requires rebuild)."
|
||
else
|
||
set_state "settings.bluetooth.enable" "true"
|
||
echo "Bluetooth enabled (requires rebuild)."
|
||
fi
|
||
sleep 1
|
||
;;
|
||
"Printing")
|
||
cur=$(get_state "settings.printing.enable")
|
||
if [ "$cur" = "true" ]; then
|
||
set_state "settings.printing.enable" "false"
|
||
echo "Printing services disabled (requires rebuild)."
|
||
else
|
||
set_state "settings.printing.enable" "true"
|
||
echo "Printing services enabled (requires rebuild)."
|
||
fi
|
||
sleep 1
|
||
;;
|
||
"Terminal")
|
||
term=$(gum choose "ghostty" "kitty" "alacritty" "wezterm" "foot")
|
||
if [ -n "$term" ]; then
|
||
set_state "settings.terminal" "\"$term\""
|
||
echo "Terminal set to $term (requires rebuild)."
|
||
fi
|
||
sleep 1
|
||
;;
|
||
"Keyboard Layout")
|
||
layout=$(gum input --prompt "Enter keyboard layout (e.g. us, de, es): " --placeholder "$(get_state settings.keyboard.layout | tr -d '"')")
|
||
if [ -n "$layout" ]; then
|
||
set_state "settings.keyboard.layout" "\"$layout\""
|
||
echo "Keyboard layout set to $layout (requires rebuild)."
|
||
fi
|
||
sleep 1
|
||
;;
|
||
"Auto-Login")
|
||
user=$(gum input --prompt "Enter auto-login username (or empty to disable): " --placeholder "$(get_state settings.greeter.autoLogin | tr -d '"')")
|
||
if [ -n "$user" ]; then
|
||
set_state "settings.greeter.autoLogin" "\"$user\""
|
||
echo "Auto-login set to $user (requires rebuild)."
|
||
else
|
||
set_state "settings.greeter.autoLogin" "null"
|
||
echo "Auto-login disabled (requires rebuild)."
|
||
fi
|
||
sleep 1
|
||
;;
|
||
"Back"|*) break ;;
|
||
esac
|
||
done
|
||
}
|
||
|
||
if [ "${1:-}" = "--first-boot" ]; then
|
||
first_boot
|
||
else
|
||
main_menu
|
||
fi
|