| Commit message (Collapse) | Author | Age | Files | Lines |
| ... | |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Mason's installer tries one source per package. For tools that we
already provide via the system package manager (Arch pkgs on the
host) or nix-profile (on the remote-dev VM), Mason will keep trying
to (re-)install via cargo/pip/etc. and report failures — but
conform.nvim/nvim-lint resolve their binary from PATH anyway, so
the Mason install is redundant.
Filter ensure_installed at startup against vim.fn.executable(). Keeps
behaviour identical on a fresh host (Mason still pulls everything),
but silences spurious failures for tools that the user has chosen to
provide system-wide (shellharden via nix-profile being the immediate
case).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
JRE/shellharden/python3-venv
copilot.lua was hard-coding the chezmoi-pinned Node 24 at
~/.local/share/copilot-node/bin/node, which only exists on the Arch
host where chezmoi runs run_onchange_after_install-copilot-node.sh.
On the remote-dev VM the path is absent, so copilot-language-server
spawned with cmd[0]=<missing> and printed 'Could not determine
Node.js version'. Probe the pinned path with vim.fn.executable() and
fall back to 'node' from PATH otherwise.
For the VM PATH 'node' to be a supported version, switch home.nix
from the rolling 'nodejs' alias to 'nodejs_24' (the version the
chezmoi script also pins on the host).
Address the cluster of Mason install failures on the VM:
- autotools-language-server, codespell, mdformat,
nginx-language-server, systemdlint -- pip-installed; fail because
Ubuntu's python3 ships without venv. bootstrap.sh now apt-installs
python3-venv; README documents the manual command for existing VMs.
- groovy-language-server -- needs a JRE. Add 'jre' to home.packages.
- shellharden -- Mason's cargo fallback can't run under our
leaf-tools policy. Provide the binary via nix-profile instead so
Mason finds it on PATH.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Previous guard checked `$+commands[Y]` (binary present in PATH), but the
`compdef: unknown command or service: Y` message comes from compdef when
the *completion function* `_Y` isn't registered — on the remote-dev VM
`systemctl`, `just`, `lsd` are all on PATH yet zsh has no `_systemctl`
because Ubuntu's system zsh doesn't include nix-profile's
share/zsh/site-functions in fpath.
Two-part fix:
1. Prepend $HOME/.nix-profile/share/zsh/{site-functions,vendor-completions}
to fpath (when they exist) before compinit, so the completions get
loaded on the VM the same way they do on Arch.
2. Switch the compdef guard to `$+_comps[Y]` — the assoc-array compinit
actually populates with every command that has a registered completion
handler. Still belt-and-suspenders in case something ships a binary
without a matching completion file.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
On minimal hosts (remote-dev VM, fresh container) several of the
`compdef alias=target` lines fail at login with messages like:
compdef: unknown command or service: just
compdef: unknown command or service: systemctl
compdef: unknown command or service: lsd
— because zsh has no `_just`/`_systemctl`/`_lsd` completion function
loaded when the binary isn't on the system. Wrap each call in a small
helper that checks $commands[<target>] first so absent tools just
silently skip their alias completion instead of spamming the prompt.
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The hand-rolled `N:dir:cmd` tab labels could never stay in sync:
- After session resurrection, tab names are restored from disk but no
shell-visible event fires, so labels stayed stale until the user hit
Enter to trigger precmd.
- After closing a middle tab, zellij renumbers surviving tabs but again
emits no per-pane event, so the `N:` prefix on every tab to the right
silently became wrong.
- Once a tab has a custom name, zellij's tab-bar plugin uses it verbatim
— there's no way to keep the default `Tab #N` numbering while also
injecting dir/cmd info. The only plugin that addresses this (vmaerten/
zellij-tab-rename) requires zellij built from main.
Dropping the hooks restores zellij's built-in `Tab #N`, which is the
single label that stays correct across resurrect and renumber. The zsh
prompt already shows CWD inside the pane.
|
| |
|
|
|
|
| |
workspace_auto_back_and_forth yes makes `workspace number N` jump
back to the previously focused workspace when N is already current.
Applies to both $mod+N keybinds and waybar workspace clicks.
|
| |
|
|
|
|
|
|
|
|
|
| |
New custom/snx-vpn module sits next to custom/vpn (the wireguard one):
- snx-vpn-status.sh shells out to `snxctl status` (timeout 2s) and maps
the output to three states: down (grey strikethrough), connecting/MFA
(amber), up (green). Tooltip shows the full status block when up.
- snx-vpn-toggle.sh disconnects when up, runs snxctl-chromium detached
when down (so SAML lands in the flatpak ungoogled-chromium without
blocking waybar). Both paths refresh the module via SIGRTMIN+9.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
snx-rs.service is a system unit, not --user, so the prior approach of
overriding the daemon's PATH via a systemd drop-in could never apply.
And it wasn't needed anyway: snxctl itself runs opener::open(url)
in-process, so prepending the shim dir to snxctl's PATH is enough.
- Drop dot_config/systemd/user/snx-rs.service.d/10-chromium-saml.conf.
- snxctl-chromium now just sets PATH and exec's snxctl connect.
- xdg-open shim no longer forces --new-window so chromium can reuse a
warm window (faster SAML round-trip).
|
| |
|
|
|
| |
Drop --hide-search and enable --matching=fuzzy --insensitive so typing
'po' jumps to Poweroff, 'su' to Suspend, etc.
|
| |
|
|
|
|
|
| |
Fetches the current code from pass-otp's vpn/totp entry and types it
into the focused surface with wtype. Falls back to wl-copy + a
notification when wtype isn't available or the focused surface lacks
virtual-keyboard support (e.g. an Xwayland window).
|
| |
|
|
|
|
|
| |
Rebases onto @{u} re-signing each commit with the current author
identity and key, while stripping any Co-authored-by lines. Hooks are
disabled (core.hooksPath=/dev/null) so chezmoi's post-commit hook
doesn't fire once per replayed commit.
|
| |
|
|
|
|
| |
teams-for-linux --minimized=true makes the app honor systemd autostart
without popping a window on every login (parity with Signal's
--start-in-tray).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
systemd/user/teams-{sii,xsight}.service: autostart both Teams flatpak
profiles on sway-session.target login. KillMode=mixed so SIGTERM hits
only the wrapper process — both instances share the same flatpak app
id, so killing by app id would take down the sibling instance. A 15s
SIGKILL fallback covers the case where Electron tray-hides instead of
quitting. Both units listed in systemd-units/user.txt.
etc/pacman.conf: IgnorePkg = llama-cpp-vulkan. The AUR package rebuilds
on every llama.cpp commit (multi-hour build). Update manually with
`paru -S llama-cpp-vulkan` when intended.
snxctl-chromium wrapper:
- dot_local/share/snx-rs/bin/xdg-open: shim that flatpak-runs
ungoogled-chromium, used only by snx-rs.
- dot_config/systemd/user/snx-rs.service.d/10-chromium-saml.conf:
drop-in prepending that dir to the daemon's PATH so snx-rs's
opener-crate call to xdg-open lands in chromium, without affecting
xdg-open for any other process.
- dot_local/bin/snxctl-chromium: convenience wrapper that
daemon-reloads and restarts snx-rs.service if the drop-in isn't yet
applied, then execs `snxctl connect`.
firefox/user-overrides.js: revert the dom.security.https_only_mode.
upgrade_local and network.lna.local-network-to-localhost.skip-checks
prefs — they didn't actually fix the SAML flow. Replaced with a
comment pointing to the wrapper instead.
|
| |
|
|
|
|
| |
Pure formatter output from shfmt (2-space indent, '|' line breaks),
prettier (KEYBINDS.md), and 'just fmt' (justfile blank line).
No behavior change.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
SSH-format signing
home.nix:
- Add zoxide (fixes 'command not found' on shell start), clang-tools
(no compiler driver), nodejs (Mason npm LSPs), uv (Mason python LSPs;
does not install python3 in PATH, so Ubuntu's /usr/bin/python3 stays
the system default), claude-code, github-copilot-cli.
- Refine the leaf-tools policy comment: explicit denylist of build-
toolchain binaries that would shadow Ubuntu's via PATH, plus a
carve-out for editor/AI runtimes (node, uv, clang-tools).
- Symlink ~/.config/git/{config,attributes,ignore} and ~/.ssh/config
from the dotfiles tree.
dot_config/zsh/dot_zshrc: guard direnv/zoxide/fzf inits with
'command -v X >/dev/null &&' so a fresh machine without one of them
no longer prints a stderr error on every shell start.
dot_config/git/config: append unconditional '[include] path =
~/.config/git/config.local' for machine-local overrides (used on the
remote-dev VM to switch to SSH-format signing via the forwarded
agent). Git silently skips missing include files.
remote-dev/README.md: document the update flow (config-only vs HM
rebuild), the single-shell leaf-tools policy, and the one-time VM
setup for SSH-format commit signing (allowed_signers + config.local,
ForwardAgent yes on the host).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Set mako default-timeout=0 so notifications stay until acted upon. With
auto-timeout off, mako's list IS the pending set, so the
$XDG_RUNTIME_DIR/mako-dismissed bridge becomes dead weight.
- mako/config: default-timeout=0; drop redundant [urgency=critical]
default-timeout=0 override.
- Delete dismiss-visible.sh and restore-pending.sh; sway calls makoctl
directly (Mod+n=dismiss, Mod+Shift+n=dismiss --all,
Mod+Ctrl+n=restore as undo).
- Shrink mako-status.sh to a 20-line counter of makoctl list.
- Rename mako-history.py -> notification-picker.py; lists only
visible, dismisses via makoctl dismiss -n <id>.
- Update waybar config.jsonc on-click path.
- Update KEYBINDS.md wording (no more 'marks seen' / 'pending set').
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
New remote-dev/ subdir with a Home-Manager flake that provisions a
headless dev environment on a remote Ubuntu 22.04 VM accessed via SSH.
Shares nvim, zellij, zsh, direnv, and ghostty configs from the same
dotfiles repo via mkOutOfStoreSymlink (no rebuilds on config edits).
CLI tool set mirrors the dev-tool subset of meta/base.txt; sysadmin
tools (procs, gdu, duf), lazygit, and node/yarn (only needed for
markdown-preview on GUI hosts) are excluded.
bootstrap.sh is one-shot: installs Nix via Determinate Systems
installer, clones the repo to ~/.local/share/dotfiles, runs
home-manager switch, and chshes to the nix-store zsh.
dot_config/zsh/dot_zshrc loses its hardcoded Arch plugin/git-prompt
paths in favour of a fallback search: Arch path first, then
$HOME/.nix-profile/share/. Same file works on host and VM.
.chezmoiignore: exclude remote-dev/ from chezmoi deploy on the host.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Remote hosts without xterm-ghostty terminfo print 'xterm-ghostty: unknown
terminal type' on connect. Ghostty's shell integration ships two features
for this:
- ssh-terminfo: pipes `infocmp -x xterm-ghostty` to the remote and
installs it under ~/.terminfo on first connect, permanently fixing TERM
recognition on hosts where you have a writable home.
- ssh-env: falls back to TERM=xterm-256color (plus COLORTERM=truecolor and
TERM_PROGRAM=ghostty) for the ssh subprocess, so hosts where terminfo
install fails or home is read-only still get sane defaults.
Both required shell-integration to be on, which it already is (zsh).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Vanilla sway only has splith/splitv with no auto-orientation, so new
windows always split along whatever axis the parent container is set
to (default splith). The result: opening a third window in a workspace
that's already split horizontally just keeps stacking horizontally,
even when each pane is now narrower than it is tall.
swayr's daemon (swayrd) subscribes to sway IPC and, with
[layout].auto_tile = true, issues splith or splitv on the focused
container based on its width-vs-height before sway places the next
window. The result is the i3/awesome-style spiral tiling: each new
window splits the focused pane along its longest side.
Run swayrd as a systemd user service bound to sway-session.target so
it starts/stops with the session (matching the pattern used by
waybar, swayidle, mako, etc.). No keybind changes; only the placement
algorithm.
|
| |
|
|
|
|
|
| |
librewolf was migrated from a native package to the flatpak
io.gitlab.librewolf-community in commit f5796c7; the $mod+Shift+b
binding still called the native binary, so the keybind silently did
nothing. Use 'flatpak run' instead.
|
| |
|
|
|
|
|
|
|
| |
Spice/virt-viewer ask sway for keyboard-shortcuts-inhibit so they can
forward the Super key to the guest. That swallows all $mod+... binds
on the host while the VM window is focused. Refuse the inhibit for
those three app_ids; sway forwards Super to the guest only when the
keyboard is explicitly grabbed (click-into-VM + virt-viewer's own
Ctrl+Alt toggle), not via the wm-bind shortcut.
|
| |
|
|
|
|
|
| |
virt-install and other libvirt CLI tools default to qemu:///session
even when the user is in the libvirt group, where the default NAT
network does not exist. Pin uri_default so virt-install, virsh, etc.
agree with virt-manager's system view.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
- Drop auto-optimise-store: slows every build for modest disk savings.
Run 'nix store optimise' manually if disk pressure ever shows up.
- max-jobs=auto, cores=0: defaults are 1/1, which left most of the box
idle during large closures (LLVM, protobuf, …).
- Add nix-community.cachix.org as an extra substituter with its public
key. Big hit-rate boost against nixos-unstable, which is what the new
user registry points 'nixpkgs' at.
- dot_config/nix/registry.json pins 'nixpkgs' indirect ref to
github:NixOS/nixpkgs/nixos-unstable, so 'nix shell nixpkgs#foo' is
fast + reproducible. Project flakes are unaffected — they pin their
own inputs via flake.lock.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
copilot-language-server emits 'HTTP 200 response does not appear to
originate from GitHub' under Node 26 (the current Arch nodejs). Upstream
tracking:
https://github.com/zbirenbaum/copilot.lua/issues/695
https://github.com/github/copilot.vim/issues/282
https://github.com/github/copilot-language-server-release/issues/45
Workaround universally confirmed in those threads is to run the
language-server under Node 24. Rather than downgrade system nodejs (used
by lots of other tooling) install a private Node 24 under
~/.local/share/copilot-node/ via a chezmoi run_onchange script that
verifies the official sha256, and point copilot.lua at it via
copilot_node_command. Drop in once, bump NODE_VERSION when the upstream
incompatibility is resolved.
|
| |
|
|
|
|
|
|
| |
The exec_always change was only justified by a one-off migration: on
the first reload after the include-file refactor, outputs.conf didn't
exist yet. After that bootstrap, plain `exec` is sufficient -- the
include file persists across reloads and only needs to be (re)written
when the user actually toggles modes or hotplugs.
|
| |
|
|
|
|
|
| |
Plain `exec` doesn't re-run on reload. If outputs.conf is missing
(fresh deploy, never toggled) reload falls back to sway's
side-by-side defaults. `exec_always` regenerates the include on
every reload, so the next reload after that is already flash-free.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Persist the layout as a sway-include file (~/.config/sway/outputs.conf)
so sway's own parser applies output directives natively on every
reload. Eliminates the side-by-side flash that came from sway's
default "enable everything side-by-side" before exec_always could
override it.
- display-toggle.sh: write outputs.conf alongside the live swaymsg
commands, mirroring the same enable/disable/pos directives.
- sway/config: `include ~/.config/sway/outputs.conf` next to the
background line; downgrade exec_always back to plain exec since the
include handles reloads now (script only needs to run once at
startup to bootstrap the include file on first boot).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Real cause of the silent switch back to side-by-side: sway reload
(Super+Shift+c or swaymsg reload) re-evaluates output config and
defaults to all-outputs-enabled-side-by-side, dropping the runtime
positions set by display-toggle.sh.
- sway config: `exec` -> `exec_always` so the saved layout is
re-applied on every reload, and use `apply` instead of `init` so
user-chosen layouts (e.g. side-by-side picked deliberately) survive
reloads. First boot still defaults to laptop-off via the script's
state-file fallback.
- swayidle.service: drop the after-resume hook -- DPMS resume isn't
what was breaking the layout, reload was. Less surface area.
|
| |
|
|
|
| |
Move OSD to top, increase height/width, thicker border and padding.
Colors were already fully opaque (ff alpha) -- no change needed there.
|
| |
|
|
|
|
|
| |
Reading directly from the fifo (`wob <fifo`) makes wob exit as soon
as the first wrapper closes its write end (EOF after one printf). The
upstream pattern is to pipe `tail -f` into wob so there's always a
writer holding the fifo open.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- xdg-desktop-portal: pin wlr for ScreenCast/Screenshot, gtk for the
rest, so flatpak browsers (Meet, Slack, Discord) get a working
screen-share path instead of whatever the portal frontend happens to
pick first.
- wob: small wayland overlay bar fed via a fifo. New vol-osd.sh /
brightness-osd.sh wrappers replace the bare pactl/brightnessctl
invocations in keybinds so adjusting volume or backlight flashes a
bar at the bottom of the screen. wob.service owns the fifo lifecycle
(mkfifo before, rm after).
- mako: add a [mode=do-not-disturb] section that hides notifications
while the mode is active, plus a Super+x n submode binding to toggle
it. Notifications still accumulate in history; just no popups.
|
| |
|
|
|
|
|
|
| |
dismiss-visible.sh's 'all' mode previously only recorded visible
notification ids and ran 'makoctl dismiss --all'. Notifications already
in mako's history (auto-expired) still counted as pending in waybar's
mako-status. Now also append history ids to the dismissed state file so
the pending counter actually drops to zero.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
After resume from suspend sway resets output config to defaults (both
monitors enabled side-by-side), so a laptop-off mode set before suspend
silently snapped back to side-by-side on wake. The display-watcher
script only reacts to changes in the count of connected externals, so
it doesn't notice this.
- Add an 'apply' mode to display-toggle.sh that reads the saved state
and applies it (no toggle, no notification).
- Wire it into swayidle's after-resume directive.
|
| |
|
|
|
|
|
|
|
| |
- wofi --dmenu --hide-search: pure j/k arrow-key picker, no fuzzy
search field. Matches existing wofi config (key_up/key_down already
include j/k).
- systemctl reboot/poweroff/suspend instead of sudo: rely on polkit,
which permits these for active session users by default — no
passwordless sudo required.
|
| |
|
|
|
|
| |
swaynag buttons require a mouse click. Replace the Mod+Shift+e session
prompt with a fuzzel --dmenu picker so the whole menu is keyboard
navigable. Adds Suspend as a new entry while we're here.
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
|
|
| |
Replaces the resume-lock-grace.sh + after-resume hook from the previous
commit with the simpler observation that sway already provides a wake
grace for free: it pauses the idle counter during suspend and resets it
on the first input event post-resume, so the existing timeout 300 lock
naturally gives ~5min to interact before locking. Just dropping the
before-sleep lock is enough; the script and after-resume directive were
overcomplicating it.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Two related session-idle improvements:
1. ScreenSaver inhibit bridge. Browsers (LibreWolf/Chromium flatpaks)
ask the session not to idle via the legacy
org.freedesktop.ScreenSaver D-Bus API during video calls and
fullscreen video; swayidle only honors logind's BlockInhibited
property. Add inhibridge as a user unit to translate the former
into the latter, so e.g. a Google Meet tab now keeps the screen
from locking, dimming and (downstream) suspending.
2. Post-resume grace period. Locking on before-sleep meant every wake
demanded the password even for a quick check. Replace with:
before-sleep -> only pause media
after-resume -> resume-lock-grace.sh 30
The grace script runs a one-shot swayidle that locks iff the user
stays idle for 30s after the wake, with a watchdog that exits as
soon as swaylock comes up (or after a hard cap) so it never lingers
alongside the main swayidle. The 5-min main idle-lock and explicit
loginctl lock-session paths are unchanged.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The previous fix sidestepped sudo-rs's env scrubbing by setting
DIFFPROG inside a nested root shell. That works but it's the wrong
shape — every command that wants to honour a user UX env var would
have to do the same dance. Configure the policy once instead.
etc/sudoers-rs:
Defaults env_keep += "DIFFPROG"
Defaults env_keep += "EDITOR VISUAL SUDO_EDITOR GIT_EDITOR"
Defaults env_keep += "PAGER MANPAGER GIT_PAGER SYSTEMD_PAGER"
Defaults env_keep += "LESS LESSOPEN SYSTEMD_LESS"
env_keep is the unconditional pass-through list, so no '-E' is needed
on the call site — `DIFFPROG='nvim -d' sudo pacdiff` Just Works, same
as it does for `EDITOR=nvim sudo systemctl edit foo`,
`PAGER=less sudo journalctl …`, etc. None of these vars influence
privilege boundaries; they only configure user-facing program
behaviour, so widening env_keep to cover them carries no security
trade-off worth accounting for. The existing per-visudo env_keep
lines are kept for documentation value (they're now subsumed by the
global rule but make the intent explicit at the visudo call sites).
The waybar pacdiff click handler reverts to the canonical form
`DIFFPROG='nvim -d' sudo pacdiff`, matching the recipe pacman.git
ships in /usr/share/doc/pacman/.
Will take effect after the next `chezmoi apply` redeploys
/etc/sudoers-rs (the run_onchange_after_deploy-etc.sh.tmpl script
re-installs it with mode 0440 whenever its hash changes).
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
sudo-rs scrubs the env by default, so neither `DIFFPROG=… sudo pacdiff`
nor `sudo DIFFPROG=… pacdiff` reaches pacdiff with the variable set.
Sidestep the env-policy question entirely by running
sudo sh -c 'DIFFPROG="nvim -d" pacdiff'
so the assignment happens inside the privileged shell, after the
env-scrubbing boundary. No sudoers-rs change required, and the same
form works identically under stock sudo if the user ever switches
back.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Bar layout: insert the four new modules between custom/update and
custom/thunderbird so that all 'something needs your attention'
indicators live as a contiguous group on the right side, in roughly
escalating actionability:
custom/notifications -- mako history (always present, gray baseline)
custom/update -- '`just update` was N hours/days ago'
custom/pacdiff -- '.pacnew/.pacsave waiting'
custom/arch-audit -- 'fixable CVE in installed package'
custom/failed-units -- 'systemd unit failed'
custom/lostfiles -- 'unowned files under tracked dirs'
custom/thunderbird -- 'unread mail'
Click handlers all use the floating-ghostty + 'press enter to close'
idiom established by the existing update module so output stays
inspectable. arch-audit and lostfiles open their /run report in
`nvim -R` (read-only) since the source of truth lives in those files.
style.css: extend the shared 6px-padding selector list, the .fresh
zero-padding rule (so empty-state modules disappear cleanly), and add
.warn/.critical color rules consistent with the rest of the palette
(yellow #fabd2f for 'review when convenient', red #fb4934 for 'review
soon').
systemd-units/system.txt: enable the three new system timers
- btrfs-balance@-.timer (monthly partial balance on /)
- arch-audit.timer (daily CVE report refresh)
- lostfiles.timer (weekly unowned-files report refresh)
Picked up automatically on the next `just unit-apply`.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Two live waybar modules — no timer/state-file pipeline because the
inputs are cheap to compute on every poll:
custom/pacdiff (interval 300s)
Counts unresolved .pacnew / .pacsave files via `pacdiff -o` (output
mode — lists only, takes no action). Hidden at zero. Yellow 'pacdiff
N' otherwise. Mako fires once on the 0→N transition, so you get
exactly one nudge per upgrade wave, not a sustained re-nag for files
you've decided to defer. Click runs `sudo DIFFPROG='nvim -d' pacdiff`
in a floating ghostty.
custom/failed-units (interval 30s)
Sums `systemctl --failed` (system) and `systemctl --user --failed`
counts. Hidden at zero. Red 'failed N' otherwise. Mako fires only on
upward transition (count went up since last poll), so already-known
failures don't keep paging you while you investigate. Click prints
both `systemctl --failed` outputs in a floating ghostty.
Both modules use the same $XDG_RUNTIME_DIR/waybar-X-prev pattern as the
update reminder for state, which makes 'reboot resets the nag' the
default behaviour — exactly the right semantics for both: a fresh boot
deserves a fresh look at pending pacdiffs and any failed units.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Wiring (mirrors arch-audit, with weekly cadence and Nice=19/idle I/O):
lostfiles.timer (weekly, Persistent=true, RandomizedDelaySec=1h)
→ lostfiles.service
→ /run/lostfiles.txt (default mode — strict produces too many
false positives for a passive reminder)
→ custom/lostfiles waybar module (interval 600s)
→ mako 'normal' once/7d while count > 0
→ on-click: `ghostty -e nvim -R /run/lostfiles.txt`
Default mode (no `strict` argument) is intentional: it already filters
the package's curated false-positive list at /etc/lostfiles.conf, which
is what we want for a low-noise weekly nudge. Switching to `strict` is
a one-line change in lostfiles.service if signal-vs-noise tilts later.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Wiring:
arch-audit.timer (daily, RandomizedDelaySec=1h, Persistent=true)
→ arch-audit.service (After=network-online.target)
→ /run/arch-audit.txt ('--upgradable' output, atomic via .tmp+mv)
→ custom/arch-audit waybar module (interval 300s)
→ mako 'critical' once/24h while count > 0
→ on-click: `ghostty -e nvim -R /run/arch-audit.txt`
The bar entry stays hidden when there are no fixable CVEs, fades in as
red 'CVE N' the moment arch-audit finds at least one, and the throttled
mako means you'll see exactly one notification per day instead of one
per waybar poll. No -Sy refresh and no auto-update — this only reports
the gap between what's installed and what's already in the repos.
Why /run and not the user's runtime dir: the producer is a system unit
(needs the system's pacman db on the network-online path), the consumer
is a user-scope waybar that just reads it; /run is the canonical 'fast,
volatile, world-readable' system-tmpfs and survives the reboot cycle in
exactly the way we want — fresh empty file on every boot, repopulated
on the next timer fire.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
`zstyle ':completion:*' rehash true` makes zle re-scan $PATH directories
on every TAB instead of caching the hash table at shell startup. Cost is
trivial (one stat() per PATH entry per completion), benefit is that newly
installed binaries — from paru, cargo install, pip install --user, npm
install -g, manual /usr/local/bin drops, anything — show up immediately
without an explicit `hash -r` or new shell.
The pacman-hook alternative at https://wiki.archlinux.org/title/Zsh#Persistent_rehash
only catches paru/pacman installs, missing cargo/pip/manual; rehash=true
catches them all for the same negligible cost.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Two related changes around the 'just update' UX:
1. nvim-update no longer runs --headless. The diff buffer that
vim.pack.update opens *is* the per-plugin changelog, and that was
being thrown away under headless. Drop --headless from the justfile
recipe and the trailing :qa! from config.update.run() so the buffer
stays open until the user reviews and quits manually. Mason output
was already visible because mason-tool-installer print()s.
2. New waybar 'custom/update' module + matching mako notification as a
gentle staleness reminder, replacing any temptation to run
unattended pacman -Syu (a bad idea on Arch: rolling, news-driven
manual interventions, AUR rebuilds, partial-upgrade hazards).
Source of truth: /var/log/pacman.log — last '[PACMAN] starting full
system upgrade'. No daemon, no -Sy poll, no extra state file beyond
a per-session notify-throttle stamp in $XDG_RUNTIME_DIR.
Tiers (hours since last full upgrade):
< 24h hidden (":empty" via #custom-update.fresh padding 0)
24-168h yellow + normal-urgency mako, throttled to 1/24h
>= 168h red + critical-urgency mako, throttled to 1/24h
Click runs 'just update' in a floating ghostty.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Every sway action that was reachable only via an XF86 keysym now has
a Super-based alternative, so all bindings work on keyboards without
a multimedia row.
Frequent (direct binds, vim-direction layout on Super+Ctrl):
Super+Ctrl+k/j = volume +/-
Super+Ctrl+space = play/pause
Super+Ctrl+l/h = next/previous track
Super+Ctrl+]/[ = brightness +/-
Rare (submode 'system' via Super+x; one letter runs and exits):
b bluetooth · w wifi · r rfkill · s suspend · d display
v pulsemixer · k KEYBINDS viewer · m mako history
Escape/Return exits
Existing Super+m / Super+Shift+m / Super+Shift+s already covered
mic-mute / sink-mute / lock; XF86 binds untouched so the laptop's
Fn-row keeps working. KEYBINDS.md updated.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
Same substring blacklist (copilot, claude, codex, ...) is now also
applied to every Co-authored-by trailer in the commit message, not
just the author header. Agents commonly slip in via that route.
Trailers extracted with %(trailers:key=Co-authored-by,valueonly,
unfold,separator=%x1f) and split in awk on \037, which can't appear
in identity strings, so the tab-delimited record format stays
unambiguous.
To fix a flagged trailer use git commit --amend / interactive rebase
to drop the Co-authored-by line; --reset-author won't help here.
|