summaryrefslogtreecommitdiffstatshomepage
Commit message (Collapse)AuthorAgeFilesLines
* feat(sway): auto-lock on idle and before suspendsommerfeld2026-05-133-1/+66
| | | | | | | | | | | - logind: IdleAction=lock, IdleActionSec=5min. systemd emits a lock signal at 5min idle (session becomes locked from logind PoV; swayidle listens and invokes swaylock). - swayidle: lock at 5min, blank display at 6min, lock before sleep. Closes the gap where lid-close or manual suspend would wake to an unlocked session. - swaylock: add -i (--ignore-empty-password) to ignore accidental Enter. - meta/wayland: add swayidle.
* refactor(etc): keep mkinitcpio.conf closer to Arch pristinesommerfeld2026-05-131-1/+1
| | | | | | Arch already ships systemd-based HOOKS as default; only add sd-encrypt. keymap is redundant with sd-vconsole but harmless, and keeping it minimizes diff from upstream (one word changed).
* feat(boot): switch to systemd initramfs + rd.luks.name cmdlinesommerfeld2026-05-132-2/+2
| | | | | | | | | Prerequisite for TPM2 LUKS unlock. systemd-cryptenroll stores TPM hints in LUKS2 token metadata, so no cmdline options are needed beyond rd.luks.name (sd-encrypt auto-discovers enrolled tokens). After chezmoi apply: sudo mkinitcpio -P && sudo sbctl verify, then reboot. Passphrase still works; TPM enrollment is a separate step.
* refactor(etc): drop marginal UPower percentage overridessommerfeld2026-05-131-3/+3
| | | | | | Only CriticalPowerAction=PowerOff is a behaviorally meaningful change vs pristine. Percentage tweaks (15/7/3 vs 20/5/2) are not worth the drift.
* refactor(etc): re-sync reflector.conf against pristine; VPN-aware countriessommerfeld2026-05-131-3/+26
| | | | | | | - Drop ES/PT from country list (always-on VPN exits in Zurich; Iberian mirrors are slow through that path). - Replace --latest 5 + --sort age with --age 12 + --fastest 10 + --threads 5 (real throughput benchmark over 5 parallel probes).
* refactor(etc): re-sync UPower.conf against pristinesommerfeld2026-05-131-4/+107
| | | | | No behavior change; only the four overrides (PercentageLow/Critical/ Action, CriticalPowerAction=PowerOff) differ from upstream defaults.
* feat(etc): relax faillock (deny=50, unlock_time=30)sommerfeld2026-05-131-0/+64
| | | | | | Single-user laptop behind FDE with key-only SSH means local brute force is not a realistic threat. Tight defaults (3 attempts, 10min lock) mainly punish typos.
* feat(etc): cap user systemd stop timeout at 10ssommerfeld2026-05-131-0/+3
| | | | | | User scopes (e.g. ghostty surface containing zellij) inherit timeouts from the user manager, not /etc/systemd/system.conf.d. Without this, zellij sessions stall reboot for 90s before SIGKILL.
* fix(just): unit-status handles template instances and static unitssommerfeld2026-05-133-2/+12
| | | | | | | | - use systemctl is-enabled per curated unit (list-unit-files does not show instantiated template units like btrfs-scrub@-.timer) - accept static/indirect/generated/alias states in addition to enabled - drop pkgstats.timer from curated (no [Install] section) - ignore systemd-oomd.socket (distro default)
* chore(meta): add fwupd, smartmontools; enable oomd, smartd, btrfs-scrub, ↵sommerfeld2026-05-132-1/+6
| | | | fwupd-refresh; drop fstrim.timer
* fix(nvim): use print() in update.lua to satisfy selenesommerfeld2026-05-131-8/+3
| | | | | selene's neovim stdlib doesn't expose io.stdout:write/:flush. print() goes to the same place in headless mode and is already allowed.
* feat(just): add 'update' recipe — system + nvim plugins + masonsommerfeld2026-05-132-0/+62
| | | | | | | | | | | | | | | New recipes (new 'Updates' section after 'Day-to-day'): - update: pkg-update nvim-update - pkg-update: paru -Syu - nvim-update: nvim --headless +'lua require("config.update").run()' New dot_config/nvim/lua/config/update.lua drives the headless session: clean orphan plugins, vim.pack.update with force=true (skips the confirm buffer since this is unattended; changes still go to nvim-pack.log), then :MasonToolsUpdateSync — the blocking variant intended for headless Interactive :PackSync stays unchanged (confirm buffer remains visible for reviewed updates).
* refactor(nvim): keep PackUpdate confirm buffer visiblesommerfeld2026-05-131-11/+4
| | | | | | Auto-writing it defeated the purpose — no feedback on what changed. Now :PackUpdate and :PackSync show the confirm buffer; user reviews and :w to apply or :q to cancel. Matches vim.pack's intended UX.
* refactor(nvim): drop refactoring.nvimsommerfeld2026-05-133-36/+0
| | | | | | | | | Upstream broke itself today by adding require('async') without shipping lua/async.lua. I never use these mappings anyway. Removed the plugin spec, setup call, <leader>r* keymaps, and the which-key group entry. plenary.nvim stays — neogit still depends on it. Run :PackClean afterwards to prune the on-disk plugin.
* chore(nvim): stop tracking pack lockfilesommerfeld2026-05-132-222/+1
| | | | | | | | The seeded lockfile offered little value for a single-user setup: fresh bootstraps will resolve version specs at install time, and any meaningful pinning is already expressed in init.lua's vim.pack.add() specs. Added an explicit .chezmoiignore entry so the runtime file doesn't show up as drift.
* chore(nvim): seed pack lockfile with create_ prefixsommerfeld2026-05-131-0/+0
| | | | | | | The file is owned by vim.pack at runtime — tracking it causes constant chezmoi drift on every plugin update. The create_ prefix writes it once on fresh machines and leaves it alone after. Manually chezmoi re-add when you want to snapshot a known-good revision set.
* refactor(nvim): simplify PackUpdate — vim.pack.update is effectively syncsommerfeld2026-05-131-13/+3
| | | | | | | It drives its async git ops with internal vim.wait and makes the confirm buffer current before returning. No need for a FileType autocmd: just write the buffer if the filetype matches (guards the 'Nothing to update' case where no buffer is created).
* fix(nvim): auto-confirm PackUpdate preview buffer instead of forcingsommerfeld2026-05-131-2/+15
| | | | | | Using force=true hid all feedback. Now we let vim.pack.update open its confirmation buffer (showing pending changes) and auto-:write it via a one-shot FileType=nvim-pack autocmd. User sees what updated.
* feat(nvim): add :PackList to show managed plugins with rev and versionsommerfeld2026-05-131-0/+36
| | | | | Uses vim.pack.get() and prints one line per plugin: ● (active) or ○ (orphan), name, short rev, version spec.
* feat(nvim): add :PackClean, :PackUpdate, :PackSync user commandssommerfeld2026-05-132-0/+42
| | | | | | | | | | Wraps vim.pack for a more ergonomic workflow: - :PackClean - delete plugins no longer declared in vim.pack.add() (computed from vim.pack.get() where active == false) - :PackUpdate - run vim.pack.update(nil, { force = true }); skips the confirmation buffer - :PackSync - :PackClean followed by :PackUpdate
* style: silence SC1003 in bootstrap.sh efibootmgr hint; shfmt wifi-status.shsommerfeld2026-04-212-9/+10
| | | | | | | | - bootstrap.sh: the trailing backslash in the efibootmgr example is literal text shown to the user, not shell line continuation. Disable SC1003 with an inline directive and switch back to single quotes so the backslash renders as-is. - wifi-status.sh: reformat with shfmt -i 2 -ci -s.
* ci: fix taplo download URL (upstream dropped -full suffix)sommerfeld2026-04-211-1/+1
| | | | | taplo 0.10.0 renamed the release asset from taplo-full-linux-x86_64.gz to taplo-linux-x86_64.gz.
* refactor(firefox): auto-enumerate files like etc/ deploy scriptsommerfeld2026-04-212-15/+16
| | | | | | | Drop the per-file include hashes and explicit cp calls; walk firefox/ with find(1) and mirror the tree into the LibreWolf profile. Drop-in new files (e.g. user.js, chrome/userContent.css) now deploy without touching the script. Same pattern already in use for etc/.
* chore: prune stale/redundant chezmoi configsommerfeld2026-04-212-12/+1
| | | | | | | | | | | | .chezmoiignore: - remove create-efi.sh (deleted in UKI migration) - remove dot-prefixed entries (.editorconfig, .github/, .worktrees/, .githooks/, .stylua.toml, .prettierrc.json, .ruff_cache); chezmoi already ignores source paths beginning with '.' by default (reserved chezmoi names aside) .chezmoi.toml.tmpl: - drop unused data.hostname (not referenced by any template)
* chore: ignore bootstrap.sh in chezmoi, mask xdg-user-dirs-updatesommerfeld2026-04-212-0/+2
| | | | | | | | | bootstrap.sh is host-only bootstrapping and should not deploy into $HOME. The xdg-user-dirs-update.service user unit (shipped enabled by the xdg-user-dirs package) rewrites ~/.config/user-dirs.dirs on login, clobbering the tracked short-path variant (docs/dl/pics/vids). Mask it by symlinking to /dev/null.
* waybar: use iwd D-Bus + /proc for wifi instead of scraping iwctlsommerfeld2026-04-211-18/+35
| | | | | | | Replace iwctl ANSI-stripping with busctl calls against net.connman.iwd (a formally stable, documented D-Bus API) to get state and SSID, and read signal strength directly from /proc/net/wireless. No more parser fragility if iwctl's human-readable layout changes.
* sway: manage mako, poweralertd, display-watcher via systemd user unitssommerfeld2026-04-214-3/+25
| | | | | | | Replace sway exec launches with a sway-session.target that BindsTo graphical-session.target and Wants mako, poweralertd, and a new display-watcher.service. Services now get restart-on-failure, journal integration, and clean shutdown when sway exits.
* efistub -> UKI migrationsommerfeld2026-04-216-66/+16
| | | | | | | Track /etc/kernel/cmdline and enable default_uki/fallback_uki in linux.preset. Remove create-efi helper (UKI is self-contained; only needed once at install time). Update bootstrap to print the one-off efibootmgr command instead of launching create-efi.
* system: add zram swap via zram-generatorsommerfeld2026-04-213-0/+9
| | | | | Cap at 8 GiB, zstd compression. Tune VM for RAM-backed swap: high swappiness, no read-ahead clustering.
* sway: auto-toggle display layout on external plug/unplugsommerfeld2026-04-212-0/+21
|
* sway: display-toggle re-enables laptop screen when no external presentsommerfeld2026-04-211-0/+6
|
* UPower: PowerOff critical action (no swap, no hibernate)sommerfeld2026-04-212-4/+7
|
* hibernate: add resume mkinitcpio hook, UPower critical actionsommerfeld2026-04-212-1/+9
|
* sway: add poweralertd for battery notifications via makosommerfeld2026-04-212-0/+2
|
* waybar: add disk module, heat-colour VOL, move window title to leftsommerfeld2026-04-212-2/+37
|
* waybar: heat-colour CPU/memory/wifi %/temperature values via pangosommerfeld2026-04-213-4/+60
|
* waybar: use iwctl (from iwd) instead of iw for wifi statussommerfeld2026-04-212-9/+16
|
* waybar: custom/wifi via iw for bond-slaved wlan; drop wg; shorter memorysommerfeld2026-04-215-35/+29
|
* waybar: wifi interface is wlan0 on this hostsommerfeld2026-04-211-1/+1
|
* waybar: split network into wifi/bond/wg, reorder, add gruvbox accentssommerfeld2026-04-213-9/+78
|
* waybar: add free% to memory, slow network updates to 10ssommerfeld2026-04-212-6/+7
|
* waybar: show memory used/free and wifi SSID + signal + throughputsommerfeld2026-04-211-5/+7
|
* docs: add high-level overview of stack and principlessommerfeld2026-04-211-0/+34
|
* revert(zprofile): drop DISPLAY=:0 hack now that xorg-xwayland is installedsommerfeld2026-04-211-4/+0
| | | | | | | | Sway sets DISPLAY in its own environment at compositor startup when xwayland support is enabled and the Xwayland binary is available, so all children (terminals, scripts) inherit it automatically. The zprofile override was only needed as a workaround while xorg-xwayland was missing.
* fix(justfile): strip inline '# ...' comments in meta/ and systemd-units/ parsingsommerfeld2026-04-211-10/+10
| | | | | | | | | | The grep-based filter only dropped lines starting with '#' and blank lines, so 'xorg-xwayland # note' got passed to paru verbatim and failed with 'could not find all required packages'. Replace all 11 call sites with a single sed that strips trailing '# ...' comments AND blank lines, so both full-line and inline comments are supported consistently across pkg-apply, pkg-add, pkg-forget, pkg-status, pkg-list, and unit-apply / unit-list / unit-status.
* pkg(wayland): add xorg-xwayland for zbarcam previewsommerfeld2026-04-211-0/+1
| | | | | | | zbarcam opens an X11 preview window and bails with "unable to open X display" on a pure-Wayland sway without an X server. xorg-xwayland is ~2MB and demand-spawned by sway, so the runtime cost when not scanning is zero.
* fix(zprofile): export DISPLAY=:0 for XWayland before exec swaysommerfeld2026-04-212-4/+4
| | | | | | | | | | | | | | Sway's XWayland is lazy — DISPLAY isn't set in sway's env until the first X client connects, which means systemctl/dbus import-environment runs too early and nothing downstream sees DISPLAY. Setting DISPLAY=:0 in zprofile before 'exec sway' ensures sway itself inherits it, and therefore so do all its child processes (terminals, scripts, systemd user services via import-environment). XWayland will spawn on demand when a client actually connects to :0. Also drop the redundant fallback from rqr now that the session-wide export covers it.
* fix(rqr): restore zbarcam preview and propagate DISPLAY to XWaylandsommerfeld2026-04-212-3/+7
| | | | | | | | | | | zbarcam needs an X11 display for the live camera preview, which sway provides via XWayland. Two changes to make that reliable: - sway/config: add DISPLAY to the systemd/dbus user-environment imports, so anything launched through those paths (not just direct sway execs) can reach XWayland. - rqr: default DISPLAY to :0 (sway's default XWayland socket) when unset, as a belt-and-suspenders fallback.
* fix(rqr): use --nodisplay to avoid X11 dependency on Waylandsommerfeld2026-04-211-1/+1
| | | | | | | zbarcam defaults to opening an X11 preview window, which fails on Sway without XWayland ("unable to open X display"). --nodisplay runs the scanner headlessly; we don't need the preview since -1 exits on the first barcode anyway.
* docs: update recipe vocabulary in README and copilot-instructionssommerfeld2026-04-212-31/+37
| | | | | Reflect the new DOMAIN-VERB scheme and shape dispatchers introduced in the justfile refactor.