aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/dot_config
Commit message (Collapse)AuthorAgeFilesLines
...
* feat(git): pre-push also rejects commits with foreign committerLibravatar sommerfeld2026-05-131-8/+34
| | | | | | | | | | | | | Now flags any commit whose committer name+email doesn't match the local user.name / user.email (which respects the includeIf rules in ~/.config/git/config, so per-tree work/personal identities work). Author is left free: pulling someone else's commit and rebasing it locally re-stamps the committer to you, satisfies this gate, and the original author is preserved in the commit metadata. Both checks (signature + committer) run in one rev-list pass with tab-separated fields so awk parses unambiguously.
* feat(git): global pre-push hook rejecting unsigned commitsLibravatar sommerfeld2026-05-132-0/+60
| | | | | | | | | | | | | | Activated via core.hooksPath = ~/.config/git/hooks in the global git config. The hook walks each ref being pushed (range: remote..local or, for new branches, local --not --remotes) and checks %G? on every commit. Accepts G/U/X/Y (good signature variants), rejects N/B/E/R (no signature, bad, missing key, revoked). Bypass: git push --no-verify This repo overrides hooksPath to .githooks/ for its just-check pre-commit gate, so a thin .githooks/pre-push delegates to the global hook to keep the policy enforced here too.
* feat(sway,waybar): scratch nvim+ipython binds; bolder VPN visualsLibravatar sommerfeld2026-05-133-4/+10
| | | | | | | | | | | | | | | | | VPN module: - Pango markup colours the text directly so up/down is visually unambiguous even without CSS classes (green shield up, dim strikethrough down) - .down also gets a faint red background tint for at-a-glance scan Sway: - Super+Shift+t -> floating ghostty with nvim editing a fresh $XDG_RUNTIME_DIR/scratch-<epoch>.txt (auto-cleared on reboot via tmpfs) - Super+c -> floating ghostty with ipython (quick calculator / python scratch) KEYBINDS.md updated.
* feat(waybar,sway): htop click handler, app keybinds, VPN toggleLibravatar sommerfeld2026-05-135-0/+54
| | | | | | | | | | | | | | | | | | | | waybar: - cpu / custom/memory: on-click opens floating ghostty with htop - new custom/vpn module between custom/memory and network#bond: shows 'VPN' coloured by interface UP flag (green up, dim down); on-click toggles networkctl up/down hodor; SIGRTMIN+8 used for instant refresh after toggle sway: - Super+Shift+Return -> ghostty -e yazi - Super+Shift+b -> librewolf vpn-toggle.sh runs networkctl (no sudo) thanks to a new polkit rule allowing wheel-group members to invoke org.freedesktop.network1.* without a password prompt. systemd-networkd's polkit gate is a separate path from sudoers, so this is the idiomatic fix. KEYBINDS.md updated for both new sway bindings.
* feat(mako-history): reopen picker after each selectionLibravatar sommerfeld2026-05-131-22/+25
| | | | | | After Enter copies+dismisses an entry, reopen the wofi window so the remaining notifications can be processed without re-triggering the keybind. Esc closes the loop.
* fix(mako-history): drop Alt-d; Enter copies+dismissesLibravatar sommerfeld2026-05-131-20/+7
| | | | | | | | wofi's key_custom_N only stages an exit code; it does not actually exit on the keybind, so Alt-d alone did nothing visible. Drop the custom keybind entirely and let Enter copy+dismiss in one stroke. Esc cancels. Since dismissed entries are now hidden, walking the list with Enter is a workable replacement for the dropped "dismiss without copy" path.
* fix(webcam-status): silence SC2086 on intentional word-splittingLibravatar sommerfeld2026-05-131-0/+1
|
* feat(mako-history): hide dismissed entries; consolidate keybindsLibravatar sommerfeld2026-05-131-41/+38
| | | | | | | | | | | | | | | | | Two behaviour changes: - Hide entries that were previously dismissed via the picker (the state file now acts as a hide-list, not a marker). The list shrinks as you process it; no more grey ' ' rows clogging the view. - Drop the secondary Alt-c custom key. wofi's '--define key_custom_N' appears unreliable past N=0, so Alt-c and Alt-d both silently failed. Reduce to a single custom slot (Alt-d) and remap actions: Enter -> copy + dismiss (was: re-emit + mark seen) Alt-d -> dismiss without copy Re-emit was rarely useful given mako already shows the bubble on arrival; copying is the common need. KEYBINDS.md updated to reflect the new action set.
* chore: drop dot_copilot tree; format clangd configLibravatar sommerfeld2026-05-131-6/+6
| | | | | - Remove dot_copilot/ entirely (no longer needed). - Run prettier on dot_config/clangd/config.yaml.
* style: apply formatter drift across repoLibravatar sommerfeld2026-05-1310-41/+54
| | | | | | | Pre-existing whitespace/style drift caught by `just check`. Touch nothing semantic — pure formatter output (shfmt -i 2 -ci -s, ruff, prettier, taplo). Excludes dot_config/clangd/config.yaml whose manual indentation is intentionally preserved.
* feat(privesc): migrate from opendoas to sudo-rsLibravatar sommerfeld2026-05-133-15/+13
| | | | | | | | | | | | | | | | | | | | | | | | | | | doas's one-shot password and absent 'sudo -v' kept wasting hour-long paru AUR builds. sudo-rs is a memory-safe Rust rewrite (ISRG/Ferrous Systems), drop-in CLI compatible, and the same one Ubuntu 25.10 ships as default. We follow the Arch wiki 'Using sudo-rs without the sudo package' recipe verbatim — no custom shims. - meta/base.txt: -doas-sudo-shim +sudo-rs - etc/sudoers-rs (mode 0440): wiki minimal config + NOPASSWD reboot/poweroff - etc/pam.d/sudo: 4-line copy of upstream sudo's PAM file - run_onchange_after_deploy-etc.sh.tmpl: use real sudo, deploy sudoers-rs at 0440, create /etc/pam.d/sudo-i and /usr/local/bin/{sudo,sudoedit, su,visudo} → sudo-rs symlinks idempotently - delete etc/doas.conf, dot_local/bin/{doasedit,sudo} - zshrc: drop sudo=doas/sudoedit=doasedit aliases; rewrite ss/gimme/ pacdiff/ssys to call sudo - justfile: s/doas/sudo/g (status/diff/restore helpers) - nvim: rename :DoasWrite → :SudoWrite (uses sudo -S) - sway config: reboot/poweroff buttons call sudo - bootstrap.sh: update step-5 comment - README/KEYBINDS/copilot-instructions: flip the privesc convention No Defaults overrides: sudo's defaults (passwd_tries=3, timestamp_timeout=5) already fix the doas pain, and paru SudoLoop (kept) refreshes the 5-min window via real sudo -v.
* feat(doas): smarter sudo shim + paru SudoLoopLibravatar sommerfeld2026-05-131-1/+1
| | | | | | | | | | | | | | | | | | | The packaged doas-sudo-shim is just 'exec doas "$@"', which means 'sudo -v' (used by paru --sudoloop to keep the auth timestamp fresh during long AUR builds) hits doas, which doesn't implement -v, and the loop dies. Then when the build finally finishes and tries the real install, the cached timestamp has long expired, so we reprompt — and opendoas only allows one attempt before bailing, so a single mistype throws an hour of compilation away. Replace it (per-user, via $HOME/.local/bin precedence) with a shim that translates: -v -> doas true (refresh persist timestamp) -k / -K -> doas -L (clear) -E -H -i -S etc -> dropped (no doas equivalent) rest -> doas "$@" Then enable SudoLoop in paru.conf so the timestamp stays fresh.
* style(waybar): use real anchor U+2693 (⚓) for dock indicatorLibravatar sommerfeld2026-05-131-1/+1
| | | | | Plain Unicode anchor renders via the system emoji font everywhere instead of the nerd-font private-use-area glyph.
* style(waybar): swap dock glyph to anchor (nf-md-anchor)Libravatar sommerfeld2026-05-131-1/+1
| | | | | Pun on "ship docked at port" — and just looks better than the dock_window glyph at small sizes.
* feat(waybar): add dock indicator next to batteryLibravatar sommerfeld2026-05-133-0/+40
| | | | | | | | | | Detects the ThinkPad USB-C Dock Gen2 by its built-in ethernet adapter (USB 17ef:a387) — the dock's USB hubs share product IDs with internal ThinkPad hubs but the ethernet only exists when the dock is attached. The custom/dock module sits to the left of battery; collapses to empty text when undocked so the bar stays clean on the go. Green dock glyph when docked.
* fix(emoji): split skin-tone filter into its own picker scriptLibravatar sommerfeld2026-05-132-5/+10
| | | | | | | | The previous one-liner stuffed an inline pipeline into BEMOJI_PICKER_CMD via 'sh -c' with three layers of nested quoting, which broke under bemoji's eval ("grep: 1: Syntax error: Unterminated quoted string"). Move the filter+wofi pipeline into emoji-wofi.sh and point the env var directly at it. No more quoting gymnastics.
* feat(emoji): filter out skin-tone variants in bemoji pickerLibravatar sommerfeld2026-05-132-1/+12
| | | | | | | | Skin-tone modifiers (U+1F3FB..U+1F3FF) clutter search results with five near-duplicates per people-emoji. New ~/.config/sway/emoji-picker.sh wraps bemoji and pipes its emoji list through grep -vP before handing it to wofi. Quoting was getting hairy inline in sway's exec, so the wrapper script makes it readable.
* fix(wofi): allow fuzzy search in emoji pickerLibravatar sommerfeld2026-05-132-11/+8
| | | | | | | | | The bemoji invocation passed --hide-search, and the shared wofi stylesheet additionally forced #input opacity to 0, so even without the flag the search box was unusable. Drop --hide-search from bemoji's picker cmd and replace the CSS hack with a normal styled input. Pickers that want arrow-only UI (mako-history, clip-picker) keep --hide-search and continue to render without an input row.
* feat: vim nav in wofi, bemoji, clip picker, webcam glyph fixLibravatar sommerfeld2026-05-134-3/+46
| | | | | | | | | | | | | | | | | | | | | | | - wofi config: key_up/key_down accept Up,k / Down,j; Ctrl-u/Ctrl-d for page jumps. Picker scripts auto-load this since they only pass --style. - waybar webcam glyph: U+F0D5D (camera/photo, looked Instagram-y) -> U+F0567 nf-md-video (handheld video camera). - Clipboard picker migrated from fuzzel to wofi for consistency with the notification picker. New driver dot_config/waybar/clip-picker.sh: pick (Mod+p) Enter pastes, Alt-d deletes delete (Mod+Shift+p) Enter deletes No clipboard "read" indicator: Wayland has no API for observing reads. - Emoji picker: bemoji on Mod+period, driven through wofi (so vim nav applies there too) and configured to type + copy via wtype. - LibreWolf flatpak: --device=all override so v4l2 webcams work. Flatpak has no finer-grained device flag. - KEYBINDS.md updated: Mod+p / Mod+Shift+p now describe wofi behavior; Mod+period documented.
* fix(waybar): dismiss/restore wrappers parse mako text formatLibravatar sommerfeld2026-05-132-3/+11
| | | | | | | | | | Same -f-doesn't-exist regression as 3205afc / d76ff3c. Without -f the inner pipeline produced no ids, so the dismissed-set never grew and notifications stayed pending forever after Mod+n. Switch to sed extraction of 'Notification N:' lines for both dismiss-visible.sh (list) and restore-pending.sh (history). Verified the dismissed-set is populated correctly for top/all modes.
* fix(waybar): mako-status counts ids by parsing text dumpLibravatar sommerfeld2026-05-131-9/+11
| | | | | | | | Same root cause as 3205afc: this makoctl version has no -f flag, so the '%i' lookup silently produced no ids and the bar always showed empty. Switch to a sed extraction of 'Notification N:' lines from list+history. Verified against simulated input matching the user's real makoctl output: 0/some/all dismissed all render correctly.
* fix(waybar): parse real makoctl text format (no -f support)Libravatar sommerfeld2026-05-131-24/+44
| | | | | | | | | | | | This makoctl version doesn't accept -f. Drop that path and parse the actual text dump: Notification N: <summary> <- summary on the same line App name: <app> [Category: <cat>] [Body: ...] <- absent on this version, kept anyway Urgency: <urgency> Verified against the user's pasted output.
* fix(waybar): use makoctl -f format for history pickerLibravatar sommerfeld2026-05-131-33/+25
| | | | | | | | | | The text-mode parser was looking for 'Notification N:' on a line by itself, but makoctl prints 'Notification N: <summary>' with the summary inline — so every record was dropped and the picker came up empty. Switch to makoctl list/history -f '%i\t%a\t%s\t%b' which emits one clean tab-separated record per notification (mako >= 1.4). Multi-line bodies are folded back into the previous record.
* fix(waybar): notification picker also lists currently-visible bubblesLibravatar sommerfeld2026-05-131-5/+21
| | | | | | | makoctl list and makoctl history are disjoint — visible notifications aren't in history yet. The picker was only reading history, so it came up empty whenever the bar showed pending bubbles that were still on screen. Merge both lists, dedupe by id, visible first.
* feat(notifications): persistent-pending model + wofi history pickerLibravatar sommerfeld2026-05-138-45/+298
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Notifications now behave like a phone: pop briefly, auto-disappear, and remain "pending" until the user explicitly acknowledges them. The waybar count reflects pending only; idle uses a quieter glyph. State model: pending = ids in mako history/list MINUS dismissed-set state file: $XDG_RUNTIME_DIR/mako-dismissed (per-session id list) Glyph change: idle (0 pending) bell_outline U+F009C has pending bell_ring U+F009E (the previous bell_check_outline U+F11E8 "history present but nothing pending" branch is gone — there is no separate history concept now) Bindings (all now go through wrappers that maintain the dismissed-set): Super+n dismiss top visible + mark seen Super+Shift+n dismiss all visible + mark seen Super+Ctrl+n restore most recent + pop it from dismissed-set XF86Favorites history picker (rewritten on wofi) History picker (dot_config/waybar/executable_mako-history.py): - wofi --hide-search: arrow-only navigation, no fuzzy input - lines tagged [pending] / [seen] with app + summary + body - Enter re-emit via notify-send (re-shows the bubble) + mark seen - Alt-c copy "summary\nbody" to clipboard via wl-copy - Alt-d mark seen without re-showing - empty history shows a sentinel, no-op on Enter New scripts: executable_dismiss-visible.sh capture id(s) then makoctl dismiss executable_restore-pending.sh capture top-of-history id, restore, then drop that id from dismissed-set executable_mako-history.py Python rewrite (parses makoctl text output, drives wofi) Other: meta/wayland.txt add wofi (only used by this picker) dot_config/wofi/style.css minimal gruvbox style; hides input row as belt-and-suspenders even though --hide-search already does it
* style(waybar): swap obvious literal labels for Nerd Font glyphsLibravatar sommerfeld2026-05-136-29/+33
| | | | | | | | | | | | | | | | | | | | | | | Numeric/identity labels stay (CPU, MEM, °C, network arrows, clock). Iconic labels are replaced with codepoints from ttf-noto-nerd: battery BAT/CHR/PLG -> nf-md-battery_*, _charging, power_plug (U+F0079..F0084, U+F06A5) pulseaudio VOL/MUTE -> nf-md-volume_low/medium/high/off (U+F057E..F0581) bluetooth BT on/off -> nf-md-bluetooth/_off/_connect (U+F00AF/B0/B2) idle_inhib. INH/IDL -> nf-md-eye_off_outline/_outline (U+F06D1, F06D0) custom/wifi text only -> prefix nf-md-wifi/_off (U+F05A9, F05AA) custom/webcam CAM -> nf-md-camera (U+F0D5D) custom/notif. NTF -> nf-md-bell_outline/_check_outline/_ring (U+F009C, F11E8, F009E) custom/tb MAIL -> nf-md-email/_alert (U+F01EE, F0D42) style.css font-family widened from 'mono' to a declarative fallback chain so glyph rendering doesn't depend on fontconfig auto-fallback.
* feat(waybar): add webcam privacy indicatorLibravatar sommerfeld2026-05-133-0/+31
| | | | | | | | | | V4L2 capture goes directly through /dev/videoN and never traverses the PipeWire portal, so the built-in privacy module misses it. New custom/webcam module polls fuser on /dev/video* every 2s and shows a red 'CAM' badge when any device is held open. Empty text when idle, so the slot collapses and stays out of the way when the webcam is unused (i.e. always, on a usual day).
* fix(sway): call doas with absolute paths for reboot/poweroffLibravatar sommerfeld2026-05-131-2/+2
| | | | | | | | | | | doas matches the 'cmd' rule literally against argv[0], not against the resolved PATH lookup. With 'cmd /usr/bin/poweroff' in doas.conf, 'doas poweroff' is denied silently — works only as 'doas /usr/bin/poweroff'. The interactive shell aliases sudo->doas and was hiding the issue when typing the bare command in a terminal (PATH expansion happens in the shell before doas sees argv[0]... only when explicitly typed with absolute path).
* feat(sway): replace exit prompt with full session menu; drop fuzzel $PATH ↵Libravatar sommerfeld2026-05-132-3/+6
| | | | | | | | | | | listing - Mod+Shift+e: swaynag now offers Lock / Logout / Reboot / Poweroff instead of just 'Exit sway? Yes'. Reboot+Poweroff use doas; that's already nopass-permitted for wheel in etc/doas.conf - fuzzel.ini: drop list-executables-in-path=yes (back to upstream default). The launcher now shows only .desktop entries; power actions live in the Mod+Shift+e menu
* feat(waybar+sway): bluetooth module + unify wifi/bt toggle pathsLibravatar sommerfeld2026-05-134-8/+35
| | | | | | | | | | | | | | | - systemd-units/system/bt.txt: new file pairing the meta/bt.txt group; enables bluetooth.service via 'just unit-apply' - waybar: add the built-in bluetooth module; on-click runs the same bt-toggle.sh that XF86Bluetooth has always invoked. Status colors: blue when adapter is up, green when a device is connected, gray off - sway: XF86WLAN now runs wifi-toggle.sh (iwd D-Bus) instead of 'rfkill toggle wifi'. The latter required rfkill group membership (user is in wheel only), and aligning on the busctl path means the keybind and the waybar click drive the same code XF86RFKill (panic-disable all radios) keeps using 'rfkill toggle all' — that scope is genuinely rfkill-shaped.
* style(waybar): tighten right cluster — tray rightmost, drop disk, compact ↵Libravatar sommerfeld2026-05-132-17/+8
| | | | | | | | | | | | | MEM, drop LOAD label - modules-right: tray moved past clock to the rightmost slot; disk dropped (used% on btrfs is ambiguous and the value rarely moves) - custom/memory: drop the available-side readout, output 'MEM 3.2G 40%' instead of 'MEM 3.2G (40%) / 4.5G (56%)' - cpu: drop the 'LOAD' literal — bare '{load:0.2f}' next to the usage% is unambiguous in context The disk module config block is left intact for easy reactivation.
* style(waybar): group clickable modules on the right edgeLibravatar sommerfeld2026-05-131-3/+3
| | | | | | | Read-only stats (cpu, temp, memory, disk, network, battery, privacy) on the left half of modules-right; interactive ones (pulseaudio mute, wifi toggle, idle_inhibitor, mako history, thunderbird, tray, clock) clustered on the right.
* feat(waybar): more clickable modules + load avg in CPU readoutLibravatar sommerfeld2026-05-132-6/+34
| | | | | | | | | | | | | - cpu: append 'LOAD {load:0.2f}' (1-min load average) to every state - custom/wifi: left click toggles iwd Powered via D-Bus (new wifi-toggle.sh) - custom/notifications: left click opens fuzzel history picker (mako-history.sh, previously bound to middle-click); the awkward per-click 'makoctl dismiss' is dropped — dismiss-all stays on right, restore stays on middle - clock: left click runs tb-toggle.sh (closest practical proxy for 'open Calendar tab' — Thunderbird hasn't shipped a -calendar CLI flag since Lightning was integrated, so the user lands on whatever tab TB was last on)
* fix(sway): bump tb-autostart post-IMAP grace period 5s -> 10sLibravatar sommerfeld2026-05-131-1/+1
| | | | | 5s still wasn't enough on cold boot — Thunderbird kept racing the SMTP listener and showing the connection-failure dialog.
* fix(sway): import PASSWORD_STORE_DIR into user manager + dbus envLibravatar sommerfeld2026-05-131-2/+2
| | | | | | | | | | | | | zprofile sets PASSWORD_STORE_DIR to $XDG_DATA_HOME/password-store, but systemd-user-launched services (notably waybar's tb-unread.sh, which calls 'pass show') don't inherit it. Sway is started from the login shell so the var is in its environment — propagate it to the user manager and dbus activation env, same pattern as the XDG_SESSION_* vars. Resolves the same problem already worked around for protonmail-bridge.service via a drop-in override; that override is now redundant but kept as belt-and-braces.
* feat(waybar): add Thunderbird inbox-unread moduleLibravatar sommerfeld2026-05-133-1/+74
| | | | | | | | | | | Polls the protonmail-bridge IMAP socket every 60s with STATUS INBOX (UNSEEN), displays the count next to the tray, and clicking the badge runs tb-toggle.sh to bring TB out of the scratchpad (or launch it). Setup: store bridge credentials in pass at email/protonmail-bridge/{user, pass}. The bridge surfaces them via 'protonmail-bridge --cli' -> 'info'. With no entries (or with the bridge unreachable) the module shows 'MAIL ?' in red and is otherwise inert.
* fix(sway): extend post-IMAP SMTP grace period 1s -> 5sLibravatar sommerfeld2026-05-131-1/+1
| | | | | | The IMAP '* OK' banner arrives before the SMTP listener on 1025 is fully ready. 1s wasn't always enough — Thunderbird would still race into a 'failed to connect to 127.0.0.1, please retry' dialog.
* Revert "fix(sway): bump tb-autostart bridge IMAP wait 60s -> 180s"Libravatar sommerfeld2026-05-131-1/+1
| | | | This reverts commit 8b6d81742fa71aff76e602edc023c45ca4b38066.
* fix(sway): bump tb-autostart bridge IMAP wait 60s -> 180sLibravatar sommerfeld2026-05-131-1/+1
| | | | | | | ProtonMail Bridge cold-start (keyring unlock + account decryption) occasionally exceeds 60s, so the IMAP '* OK' banner never arrives in time and Thunderbird launches into a 'failed to connect to 127.0.0.1, please retry' dialog. Triple the budget to 180s.
* Revert "fix(sway): bump tb-autostart window-mark wait 20s -> 60s"Libravatar sommerfeld2026-05-131-1/+1
| | | | This reverts commit 9c051b2cb47ca6e60b6c76877be78cc529d9f4da.
* fix(sway): bump tb-autostart window-mark wait 20s -> 60sLibravatar sommerfeld2026-05-131-1/+1
| | | | | | | | Flatpak Thunderbird has a slower cold start than the native package used to. On a busy session start, the main window with the tb-main mark sometimes appears after the existing 20s budget, and the script exits without moving it to the scratchpad — leaving TB tiled on the current workspace.
* fix(signal): import XDG_SESSION_TYPE/DESKTOP into user systemd + clean stopLibravatar sommerfeld2026-05-132-2/+7
| | | | | | | | | | | | | | | | | | | | Two issues with the sway autostart of signal.service: 1. Electron picks its tray backend from XDG_SESSION_TYPE and XDG_SESSION_DESKTOP. The sway config only imported DISPLAY, WAYLAND_DISPLAY, SWAYSOCK and XDG_CURRENT_DESKTOP into the systemd user manager, so services launched there got a partial env and Electron registered no SNI tray icon. Worked when launched from a terminal (which inherits sway's full env, including the bits set by pam_systemd). Add the two missing variables to both systemctl import-environment and dbus-update-activation-environment. 2. With minimize-to-tray on, Electron treats SIGTERM as a window-close and just hides the window, so 'systemctl --user stop signal' did nothing visible until the 90s default timeout SIGKILLed. Switch to ExecStop=flatpak kill org.signal.Signal, which uses flatpak's own instance manager to actually terminate the sandboxed app, plus a short TimeoutStopSec as a safety net.
* Revert "fix(signal): wait for StatusNotifierWatcher before launching"Libravatar sommerfeld2026-05-131-6/+1
| | | | This reverts commit 6eafc884f77a367f04dc4e7b35ca999de5bea271.
* fix(signal): wait for StatusNotifierWatcher before launchingLibravatar sommerfeld2026-05-131-1/+6
| | | | | | | | Without this, signal.service races with waybar at session start: if Signal asks for the SNI watcher before waybar has registered it on the bus, it launches with no tray icon and --start-in-tray hides the main window with no way to bring it back. Add Requires/After=waybar and an ExecStartPre that polls busctl for the watcher (up to 30s).
* feat(sway): autostart Signal via user systemd unitLibravatar sommerfeld2026-05-132-1/+15
| | | | | | | Sway does not honour XDG $HOME/.config/autostart/, so the in-app 'start at login' toggle is a no-op. Use a user unit wired into sway-session.target with --start-in-tray, matching the existing waybar/swayidle/cliphist/etc. pattern.
* feat(flatpak): sandbox zathura + add mpv hybrid for browser/mail handoffsLibravatar sommerfeld2026-05-131-74/+74
| | | | | | | | | | | | | | | | | | | | | | | | | | Defense-in-depth for the cross-sandbox handoff vector: when the LibreWolf/Thunderbird flatpaks open a downloaded PDF or video via the OpenURI portal, the receiving app currently runs natively with full $HOME access — defeating part of the browser/mail isolation. - meta/flatpak.txt: add org.pwmt.zathura, io.mpv.Mpv - meta/wayland.txt: drop native zathura + zathura-pdf-mupdf - meta/media.txt: keep native mpv (streamlink, /tmp/mpvsocket IPC, fast yt-dlp) — flatpak mpv is *additional*, only as the mimeapps default for video/audio to receive sandboxed handoffs - dot_config/mimeapps.list: rewrite mpv.desktop -> io.mpv.Mpv.desktop, zathura-pdf-mupdf.desktop -> org.pwmt.zathura.desktop, and replace stale userapp-Thunderbird-* entries with org.mozilla.Thunderbird.desktop - run_onchange_after_deploy-flatpak-overrides.sh.tmpl (new): --filesystem=xdg-config/{zathura,mpv}:ro so the flatpaks read our chezmoi-managed configs as a single source of truth - README: media row + new deploy-script row Manual one-shot on host: chezmoi apply -v. The pteid bridge already iterates a flatpak app list, so cartão de cidadão remains correctly registered for the Mozilla flatpaks. Native mpv config (input-ipc-server) keeps working since each flatpak has its own /tmp; no socket collision.
* feat(browser): migrate librewolf to flatpak for host-isolationLibravatar sommerfeld2026-05-131-21/+21
| | | | | | | | | | | | | | | | | | | | Move LibreWolf from native librewolf-bin to Flathub io.gitlab.librewolf-community. Bubblewrap isolates the browser from $HOME (\\.ssh, password-store, gnupg, ssh-agent socket) at the cost of namespace chroot + IPC/network namespace isolation between content processes (mozilla bug 1756236, P3, considered defense-in-depth). seccomp-bpf — the dominant sandbox layer — is preserved. - meta/flatpak.txt: + io.gitlab.librewolf-community - meta/browser.txt: - librewolf-bin - run_onchange_after_deploy-firefox.sh.tmpl: profile path moves to ~/.var/app/io.gitlab.librewolf-community/.librewolf - dot_config/mimeapps.list: librewolf.desktop -> flatpak app id - dot_local/bin/executable_linkhandler: flatpak run wrapper - README.md: blurb + new profile path arkenfox-user.js + chezmoi user-overrides.js deploy keep working unchanged because the flatpak profile is still on the host fs.
* feat(nix): hybrid setup with flakes + direnv for per-project dev shellsLibravatar sommerfeld2026-05-135-0/+60
| | | | | | | | | | | | | | | | | | Install Nix (multi-user daemon) on Arch and wire up direnv so any project can declare its toolchain in a flake.nix and get a hermetic dev shell on cd. No NixOS, no home-manager, no migration off paru/chezmoi — just one new package manager scoped to project dev shells. - meta/nix.txt: nix from extra repo - meta/dev.txt: direnv (general-purpose, not nix-specific) - systemd-units/system/nix.txt: nix-daemon.socket (socket-activated) - etc/nix/nix.conf: enable flakes + nix-command, trusted-users=@wheel, auto-optimise-store, keep-outputs/derivations so direnv envs survive GC - dot_config/direnv/direnvrc: load nix-direnv 3.1.1 via source_url with pinned sha256 (not packaged for Arch; refusing -git AUR) - dot_config/nix/templates/{flake.nix,dev/}: flake template usable via 'nix flake init -t ~/.config/nix/templates' - dot_config/zsh/dot_zshrc: 'eval "$(direnv hook zsh)"'
* fix(git): allow self-signed cert for ProtonMail Bridge SMTPLibravatar sommerfeld2026-05-131-0/+1
| | | | | | | | | The Bridge presents a self-signed cert on its 127.0.0.1:1025 STARTTLS listener, so git send-email's default cert verification fails with SSL_verify_cert. Setting smtpSslCertPath to empty disables chain verification for this single, loopback-only endpoint. Per https://git-send-email.io/#step-2 (Proton Bridge note).
* feat(git): configure git send-email via ProtonMail BridgeLibravatar sommerfeld2026-05-131-0/+13
| | | | | | | | | | | Add a [sendemail] block targeting the local Bridge SMTP listener (127.0.0.1:1025, STARTTLS) and a credential helper scoped to that URL that fetches the password from pass (proton/bridge-smtp). The helper command is public; the secret stays in the password store. The bridge SMTP username (sensitive but not secret) goes in the per-identity private overlay (~/doxfiles), not here. Also pull in the Perl SMTP modules git send-email needs at runtime.