feat(first-boot): post-install hardware hints — one self-gated toast, once
All checks were successful
Check / eval (push) Successful in 3m39s
All checks were successful
Check / eval (push) Successful in 3m39s
After the #81 "you're set" card, at most one additional "Hardware tips" toast: a Firmware line when fwupdmgr is on PATH, a Fingerprint line when fprintd-list is (VISION § B). One-shot marker settings.hardwareHintsShown, in-checkout like firstBootShown. When no tooling matches, the marker is deliberately left unset — the re-check costs a command -v per session, and a later-enabled fwupd or newly-added reader still gets its hint once. Never a permanent nag; live-ISO gate covers the new stage too. Lives inside nomarchy-first-boot: the card's semantics are unchanged (retry loop, exit 1 so a failed notify retries next login, marker only after success); hints run only once the card has landed. Docs: README option row, HARDWARE.md hint paragraphs, VISION § B checked off. Verification: V2 — shellcheck clean, nix flake check --no-build green, nix build .#checks.x86_64-linux.first-boot green (bare node silent → fwupdmgr appears → fires once → silent again → live-ISO still skips). Real toast rendering is the same session surface as the proven #81 card. Implementation by a Sonnet subagent; design and review on Fable. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,53 +1,117 @@
|
||||
# nomarchy-first-boot — one-shot "you're set" toast on the first session.
|
||||
# Marker is settings.firstBootShown in the flake's state.json
|
||||
# (in-checkout state; never ~/.local/state). notify-send and
|
||||
# nomarchy-state-sync come from PATH so the VM check can shim them.
|
||||
# nomarchy-first-boot — one-shot "you're set" toast on the first session,
|
||||
# plus a second self-gated toast (hardware hints, VISION § B) pointing at
|
||||
# hardware-specific menu items when the matching tooling is on PATH.
|
||||
# Markers are settings.firstBootShown / settings.hardwareHintsShown in the
|
||||
# flake's state.json (in-checkout state; never ~/.local/state). notify-send
|
||||
# and nomarchy-state-sync come from PATH so the VM check can shim them.
|
||||
|
||||
# Live ISO already has its own welcome (hosts/live.nix); skip there so
|
||||
# users aren't double-toasted and the live seed doesn't get a sticky
|
||||
# firstBootShown write every boot.
|
||||
# firstBootShown write every boot. This also covers the hints stage below.
|
||||
# uname -n is coreutils; avoid depending on a separate hostname package.
|
||||
hn=$(uname -n 2>/dev/null || true)
|
||||
if [ "$hn" = nomarchy-live ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Already shown → silent. Missing key / no checkout → treat as not shown
|
||||
# (state-sync get exits non-zero when the key is absent).
|
||||
# Already shown → skip straight to the hardware-hints stage below. Missing
|
||||
# key / no checkout → treat as not shown (state-sync get exits non-zero
|
||||
# when the key is absent).
|
||||
shown=$(nomarchy-state-sync get settings.firstBootShown 2>/dev/null || true)
|
||||
just_shown=
|
||||
case "$shown" in
|
||||
true|1|yes) exit 0 ;;
|
||||
esac
|
||||
|
||||
# Wait for the notification daemon (swaync). On first login the unit can
|
||||
# race graphical-session and get "Timeout was reached" from D-Bus — then
|
||||
# either no toast, or a toast that never lands while we still write the
|
||||
# marker. Retry notify-send; only persist the marker after a success.
|
||||
body="SUPER+M menu · SUPER+T themes · SUPER+? keys
|
||||
true|1|yes) : ;;
|
||||
*)
|
||||
# Wait for the notification daemon (swaync). On first login the unit
|
||||
# can race graphical-session and get "Timeout was reached" from
|
||||
# D-Bus — then either no toast, or a toast that never lands while we
|
||||
# still write the marker. Retry notify-send; only persist the marker
|
||||
# after a success.
|
||||
body="SUPER+M menu · SUPER+T themes · SUPER+? keys
|
||||
Wi‑Fi: System › Network (or the bar tray)
|
||||
Anything off? System › Doctor"
|
||||
|
||||
ok=
|
||||
ok=
|
||||
i=0
|
||||
while [ "$i" -lt 8 ]; do
|
||||
if notify-send -a Nomarchy -u normal -t 0 \
|
||||
"You're set" \
|
||||
"$body"; then
|
||||
ok=1
|
||||
break
|
||||
fi
|
||||
i=$((i + 1))
|
||||
sleep 2
|
||||
done
|
||||
|
||||
if [ -z "$ok" ]; then
|
||||
# Leave firstBootShown alone so the next login can try again. Don't
|
||||
# attempt hardware hints either — they're gated on the card landing.
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Persist in the checkout so re-login is silent. --no-switch: marker
|
||||
# only.
|
||||
if ! nomarchy-state-sync --quiet set settings.firstBootShown true --no-switch; then
|
||||
# No writable flake checkout (or tool missing) — still showed the
|
||||
# toast; without a marker it may reappear next login. Don't fail
|
||||
# the unit, and skip hints too (state-sync isn't writable anyway).
|
||||
exit 0
|
||||
fi
|
||||
just_shown=1
|
||||
;;
|
||||
esac
|
||||
|
||||
# --- hardware hints (post-install hints, VISION § B) ----------------------
|
||||
# At most one additional self-gated toast, once per machine, pointing at
|
||||
# hardware-specific menu items when the matching tooling is on PATH.
|
||||
hints_shown=$(nomarchy-state-sync get settings.hardwareHintsShown 2>/dev/null || true)
|
||||
case "$hints_shown" in
|
||||
true|1|yes) exit 0 ;;
|
||||
esac
|
||||
|
||||
hint_lines=()
|
||||
if command -v fwupdmgr >/dev/null 2>&1; then
|
||||
hint_lines+=("SUPER+M → System › Firmware to check LVFS updates")
|
||||
fi
|
||||
if command -v fprintd-list >/dev/null 2>&1; then
|
||||
hint_lines+=("SUPER+M → System › Fingerprint to enroll a finger")
|
||||
fi
|
||||
|
||||
# No matching hardware/tooling: stay quiet and deliberately don't set the
|
||||
# marker — this re-check is cheap each session, and if the tooling shows
|
||||
# up later (fwupd enabled, a reader added) the hint still fires once.
|
||||
if [ "${#hint_lines[@]}" -eq 0 ]; then
|
||||
exit 0
|
||||
fi
|
||||
hints=$(printf '%s\n' "${hint_lines[@]}")
|
||||
|
||||
# Just showed the welcome card in this run: give swaync a moment so the
|
||||
# two toasts don't collide.
|
||||
if [ -n "$just_shown" ]; then
|
||||
sleep 3
|
||||
fi
|
||||
|
||||
hok=
|
||||
i=0
|
||||
while [ "$i" -lt 8 ]; do
|
||||
if notify-send -a Nomarchy -u normal -t 0 \
|
||||
"You're set" \
|
||||
"$body"; then
|
||||
ok=1
|
||||
"Hardware tips" \
|
||||
"$hints"; then
|
||||
hok=1
|
||||
break
|
||||
fi
|
||||
i=$((i + 1))
|
||||
sleep 2
|
||||
done
|
||||
|
||||
if [ -z "$ok" ]; then
|
||||
# Leave firstBootShown alone so the next login can try again.
|
||||
if [ -z "$hok" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Persist in the checkout so re-login is silent. --no-switch: marker only.
|
||||
if ! nomarchy-state-sync --quiet set settings.firstBootShown true --no-switch; then
|
||||
# No writable flake checkout (or tool missing) — still showed the toast;
|
||||
# without a marker it may reappear next login. Don't fail the unit.
|
||||
if ! nomarchy-state-sync --quiet set settings.hardwareHintsShown true --no-switch; then
|
||||
# No writable flake checkout — still showed the toast; without a marker
|
||||
# it may reappear next login. Don't fail the unit.
|
||||
exit 0
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user