Commit Graph

1282 Commits (d5da519c9be2594de3c781f80441bdb26d85805c)

Author SHA1 Message Date
Amir Alexander Abdelbaki d5da519c9b fix(hyprlua): fix the touchpad toggle keybind
Two independent bugs, both silent no-ops:

1. hyprlua's hyprland.lua config is Lua-generated, not the classic hyprlang
   parser, so `hyprctl keyword device[...]:enabled ...` fails outright
   ("keyword can't work with non-legacy parsers. Use eval."). Switched to
   `hyprctl eval "hl.device({name=..., enabled=...})"`, the Lua API's
   live-reachable equivalent — same hl.* eval bridge eww's workspace
   switching already uses, and the same hl.device() block hyprland.lua
   itself uses at config-load time for per-device overrides.

2. The device name was hardcoded to a previous machine's touchpad
   ("synaptics-tm3053-009"), so even a working keyword/eval call would
   silently match nothing on this Framework 12's
   "pixa3854:...-touchpad". Resolve it dynamically from `hyprctl devices -j`
   instead.

Also renamed the copy-pasted enable_keyboard/disable_keyboard functions and
keyboard.status state file to match what this script actually toggles.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-30 20:15:37 +02:00
Amir Alexander Abdelbaki fc929d4747 fix(hyprlua): flatten presence-detect's check cycle to 20s
Replace the three-tier load-adaptive polling (20s/120s/600s based on CPU-or-
RAM usage) with a flat 20s interval — fido2-token -L is cheap enough that
backing off under load isn't worth the added complexity or the latency in
noticing a key was removed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-30 20:03:48 +02:00
Amir Alexander Abdelbaki 3b6cdb8dbd fix(greetd): give hyprlua its own plain greeter skin, separate from hyprdrive
There was only one ReGreet skin in the whole repo (etc-greetd/), hand-styled
to match hyprdrive's glowy "Cosmonaut Shell" look (translucent glass, box-
shadow glow, scanlines). sysupdate.sh's _ensure_plymouth_regreet() offers to
deploy it on any machine that migrates to greetd, with no DE-awareness — so
it landed on a hyprlua box too.

Move the existing skin to desktopenvs/hyprdrive/greetd-regreet/ and add a
plain hyprlua variant at desktopenvs/hyprlua/greetd-regreet/ (flat @bg cards,
2px @violet border, @accent on hover/focus/active — no glow, matching
mnotifd/audio-panel/astal-menu's established look). config.toml and
regreet-session.sh have no DE-specific styling, so they stay shared at
etc-greetd/.

sysupdate.sh's _deploy_greetd() and the greetd-regreet.sh setup module now
resolve the active DE (reusing the same config-updater SOURCE_BASE detection
_de_source_dir() already uses elsewhere) and deploy the matching skin,
falling back to hyprdrive's for DEs without their own variant yet.
apply-theme.sh needed no functional change since it recolors whatever's
already deployed rather than reading the source path — just relabeled its
SYS_FILES entry for accuracy.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-30 20:03:43 +02:00
Amir Alexander Abdelbaki 37da84422a fix(hyprlua): match notif/audio-panel theming to eww's violet/magenta look
mnotifd, mnotifhist, and audio-panel filled cards/pills with solid @violet
(border indistinguishable from fill), unlike the hollow @bg-fill +
@violet-border pills used everywhere else (eww bar, astal-menu). Flip
default-state fills to @bg, keep @accent for hover/checked/active states,
and drop the audio-panel default-device button's hardcoded green in favour
of @accent.

Also give the eww bar's drawer/notif/caffeine buttons the same circular
.icon-btn treatment as the screen-rotation buttons (touch variant only —
the laptop bar's 20px height has no room for a 40px circle), and make the
notif bell light up @accent whenever mnotifd's history cache has entries
(new notif-active-status.sh poll), rather than only matching hover.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-30 20:03:18 +02:00
Amir Alexander Abdelbaki 4afba5d3ea fix(alot): stop shipping real mail identity as the tracked default
alot/config was symlinked directly into ~/.config/alot, and mail-notmuch.sh
wrote real account details straight back into that tracked repo file — so a
fresh clone/deployment inherited a real name/email/maildir path as alot's
configured identity by default, and any re-run of the install risked
committing real PII back into the repo.

alot/config is now a template with placeholder identity (bindings unchanged).
shell-setup.sh seeds it into ~/.config/alot/config via a one-time copy
instead of a symlink, and mail-notmuch.sh writes real account details into
that local copy only — never back into the tracked file.

No password was ever involved: msmtp/mbsync credentials live in
~/.msmtprc/~/.mbsyncrc, which were never tracked in the repo, in the current
tree or anywhere in git history (verified via git log -p across all history).
2026-07-30 16:30:02 +02:00
Amir Alexander Abdelbaki c16a17f10b feat(hyprlua,hyprdrive,niri): switch presence detection from webcam motion to FIDO key
Replace the OpenCV motion-detection daemon with a fido2-token -L check —
presence now means "a FIDO2/U2F key is plugged in", queried without any
touch/tap. Adaptive poll: 20s under light load, 120s under moderate,
600s under heavy. Drops the old motion "grace window" since key presence
doesn't flicker like camera motion did.

Removes presence_detect.py, the presence camera config/test flow from
enroll-biometrics.sh, and the python-opencv dependency (kept v4l-utils,
still used by howdy's camera setup). Adds a standalone presence-test.sh
instead of folding the FIDO check into enroll-biometrics.sh's dialog TUI —
there's nothing to enroll, so it doesn't belong in that flow.
2026-07-30 13:22:38 +02:00
Amir Alexander Abdelbaki 96f15c82af feat(archiso): embed every installer script at /installer, with an offline repo snapshot
The ISO carried only the three entry scripts launch.sh dispatches to;
tui-install.sh, its modules/ and the desktopenvs/ configs it deploys existed
solely inside the repo the installer clones at run time. A live environment
without working networking therefore ran the whole install and only failed at
the very last step, on a missing /home/<user>/Dotfiles/setup/tui-install.sh.

build.sh now embeds the entire setup/ tree at /installer (so every installer
script is on the ISO), plus a full repo snapshot — .git included, so a seeded
checkout is a real repo — at /installer/dotfiles. launch.sh moves there too
and the overlay/motd/docs follow; profiledef's file_permissions list is
repointed, which matters because mkarchiso hard-errors on an entry whose path
does not exist.

Tree resolution in both installers is now: an existing checkout, else a fresh
clone (online installs still get what is newest), else the ISO snapshot. Each
candidate is accepted only if it actually contains setup/tui-install.sh — the
old check was a bare `-d .git`, which any leftover or half-finished checkout
satisfied.

Sudo can no longer stop the install to ask for a password:
  - before the chroot hands over to the TUI, the temporary NOPASSWD drop-in is
    proven with `sudo -n true` and `sudo -n -v` (both forms modules rely on).
    A rule that didn't apply now skips the TUI instead of stalling forever on a
    hidden prompt, and the drop-in is removed on that path too rather than
    being left behind as permanent passwordless sudo;
  - tui-install.sh's root sudo shim moves to the top of the file, ahead of the
    require_jq() bootstrap that shells out through sudo, so running it as root
    straight from /installer never needs a real sudo binary.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-29 19:16:45 +02:00
Amir Alexander Abdelbaki 72e0fa8edc fix(hyprdrive,hyprlua): keep the last tab clear of the floating close button
.sb-tabbar now reserves 64px on the right, the same way .sb-header already
does for the title: the ✕ is a Gtk.Overlay child, so it claims no layout
space and the tab row grew straight under it once the row got wide enough
(the "General Settings" pill was overlapping the button's circle).

Also documents, next to `config vicinae` in hyprdrive's updater.conf, that
the cosmonaut.toml this deploys to ~/.config/vicinae/ is inert — vicinae only
reads named themes from ~/.local/share/vicinae/themes/, and silently falls
back to its default grey theme when the file isn't there. That is exactly
what happened on this machine: the theme was added after hyprdrive.sh last
ran, so the launcher had been rendering the stock grey palette.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-29 18:41:56 +02:00
Amir Alexander Abdelbaki f500dd550e feat(hyprdrive,hyprlua): vertical mixer meters with the live peak column inside the fill
The per-channel volume meters are now vertical faders (Gtk.Scale, inverted so
loud is up) instead of horizontal sliders, and the live peak indicator moved
out of its own bar above the card into the meter itself: a narrow violet
column Cairo-drawn inside the trough, so one glance reads both "what the
volume is set to" (the fill) and "what is actually reaching the mix" (the
column inside it).

  - ui/peakbar.py is a DrawingArea rather than a Gtk.LevelBar: it has to grow
    bottom-to-top over the same span as the scale's highlight, minus the
    half-slider inset, and it sits in a Gtk.Overlay with can_target=False so
    the scale underneath still gets every click and drag.
  - ui/meter.py draws the value as its own label and drops the 100% mark;
    either one would push the trough off-centre under the overlaid column.
    The channel label is always appended (empty for mono) so a lone meter and
    a split L/R pair keep the same trough height inside the card's stack.
  - ui/card_base.py fans one peak monitor out to every meter of the card —
    parec reports one mixed level per target, not a per-channel one.
  - The trough's empty portion is transparent now (an idle meter and a silent
    monitor both read as "nothing here"), and supersonic-booster's fill gets
    the suite's emitted-magenta glow. Both stylesheets re-assert the
    transparent background at class specificity: the CyberQueer theme's
    `* { background-color: #1a1a1a }` was otherwise painting a dark stripe
    straight through the fill where the peak column sits.

hyprlua's audio-panel is regenerated via regen-audio-panel.sh; its plain
stylesheet stays flat and glow-free by design, with @accent as the fill.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-29 18:22:52 +02:00
Amir Alexander Abdelbaki 55d443ecdb feat(hyprdrive,hyprlua): add a Cards tab, move profile switching off device cards
Adds a fifth mixer tab, Cards: one row per pactl card (onboard audio, USB
headsets, HDMI, Bluetooth) with just its profile dropdown (Analog Stereo
Duplex, Pro Audio, Off, etc.).

Profile is a card-level setting, not a per-device one — a single card can
back a device in both Output and Input Devices at once, and switching its
profile can make either side appear or disappear entirely. It used to live
on individual DeviceCards in both tabs, which was confusing (same card,
edited from two places) and is exactly what pavucontrol avoids by giving
profiles their own "Configuration" tab. Pulled it out of DeviceCard/
OutputTab/InputTab (which also drops their now-unneeded list_cards() fetch)
and into a new ui/profile_card.py + ui/cards_tab.py.

hyprlua's audio-panel picks this up via regen-audio-panel.sh, unchanged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TkkH9eiCBfpWysUXAD9bDG
2026-07-29 16:55:29 +02:00
Amir Alexander Abdelbaki ed43cd2ac7 feat(hyprdrive,hyprlua): mirror output-device dropdown with input-device on Applications tab
Each app card in the mixer panel's Applications tab now also shows an Input
dropdown next to Output, letting you re-route that app's own microphone
stream (pactl move-source-output) the same way Output already re-routes its
playback stream. Matches an app's sink-input to its source-output via
application.process.binary (falling back to name) — the same client tags
both when an app plays and records, e.g. Discord. Apps with no matching
recording stream get the dropdown disabled rather than hidden, so card
layout stays consistent across the row.

hyprlua's audio-panel picks this up via regen-audio-panel.sh, unchanged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TkkH9eiCBfpWysUXAD9bDG
2026-07-29 16:42:07 +02:00
Amir Alexander Abdelbaki ad386f3c89 feat(hyprdrive): give vicinae its own "cosmonaut" holographic theme
hyprdrive's vicinae used to ship the exact same "cyberqueer" theme as
hyprlua/hyprland. Vicinae's theme format is colors-only (no border-radius/
box-shadow/blur/animation hooks), so it can't reproduce the Cosmonaut Shell
suite's live Cairo-drawn scanline/sweep/noise overlay — but it can reuse the
same static palette that overlay sits on top of: emitted-magenta text
(#EB00A6), glow-violet borders (#8A5CFF), a near-black-violet background, and
translucent violet-glass secondary surfaces, matching orbit-menu/astro-menu/
station-bar/transmitter-panel/supersonic-booster's look.

Replaces desktopenvs/hyprdrive/vicinae/cyberqueer.toml with cosmonaut.toml,
repoints settings.json and hyprdrive.sh's install step at it, and adds a
second apply-theme.sh entry so live colors.conf edits keep syncing it
(alongside the fix for the pre-existing hyprlua/hyprland entry, which was
pointing at the inert ~/.config/vicinae/ copy instead of the
~/.local/share/vicinae/themes/ file vicinae actually reads).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TkkH9eiCBfpWysUXAD9bDG
2026-07-29 16:21:51 +02:00
Amir Alexander Abdelbaki 516adeb5ae fix(hyprdrive,hyprlua): anchor the audio mixer panel top-right and shrink it
Layer-shell surfaces can only anchor to a screen edge with a margin, not to
another process's widget, so this can't truly follow the invoking volume
button — but every bar variant in this repo (station-bar, eww/eww-touch/
eww-nobattery) keeps its volume control in the top-right zone, so anchoring
there approximates "under the control that opened it" well enough. Also
shrunk the panel (900px -> 460px, smaller cards/meters/tab height) so it
reads as a compact popover instead of a full-width mixer.

hyprlua's audio-panel is regenerated via regen-audio-panel.sh; its
hand-maintained plain theme seed (audio-panel-theme/style.css) got the same
sizing tweaks by hand since the regen script doesn't touch it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TkkH9eiCBfpWysUXAD9bDG
2026-07-29 16:04:41 +02:00
Amir Alexander Abdelbaki bda4640b54 feat(hyprdrive,hyprlua): add supersonic-booster/audio-panel PipeWire mixer panel
A new layer-shell mixer panel with four tabs (Applications / Input Devices /
Output Devices / General Settings): per-app and per-device volume meters with
an independent left/right toggle, mute, live parec-based amplitude bars (so a
silent stream is visually distinct from a quiet one), output-device routing,
card profile switching (pro-audio vs stereo duplex etc.), and default-device
pickers. Backed by pactl -f json + pactl subscribe over pipewire-pulse
(verified against this box's real pactl; wpctl was dropped for lacking
per-channel volume and profile verbs).

hyprdrive gets the hologram-styled original (supersonic-booster); hyprlua's
plain-themed audio-panel is generated by a new
desktopenvs/hyprlua/scripts/regen-audio-panel.sh, extending the existing
regen-beacon.sh derivation pattern rather than hand-duplicating the app.

Wired into both DEs: Super+Shift+S keybind, autostart, config-updater,
apply-theme.sh, and the respective bars (station-bar's volume badge now opens
the panel; eww/eww-touch/eww-nobattery's volume slider does too, replacing
the old pavucontrol launch).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TkkH9eiCBfpWysUXAD9bDG
2026-07-29 15:41:57 +02:00
Amir Alexander Abdelbaki b92a43c8ea fix(hyprlua,hyprdrive): float/center the xdg-desktop-portal-hyprland share picker
Discord's screen-share source picker wasn't matching the modal-dialog
windowrules and tiled instead of floating. It's the Qt "hyprland-share-picker"
binary, which sets its app_id/class via
QCoreApplication::setApplicationName("org.hyprland.xdg-desktop-portal-hyprland")
— neither the GTK portal-dialog rule (different class) nor the title-based
dialog-float rule (title doesn't match) catches it. Added a dedicated rule
matching that class with the same float+center-on-monitor treatment.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-29 08:40:20 +02:00
Amir Alexander Abdelbaki 9cd8eb2065 feat(setup): add UEFI/Secure Boot preflight checks, force mkfs.btrfs, bake nomodeset into ISO
Both installers now fail fast if booted non-UEFI or warn on Secure Boot,
since GRUB install/NVRAM registration silently "succeeds" in both broken
cases and the failure only surfaces on next boot. mkfs.btrfs now forces
past leftover filesystem signatures on reinstalls. build.sh patches
nomodeset into every boot entry (BIOS/UEFI/PXE) to work around early-KMS
hangs on Optimus laptops (e.g. Lenovo Legion).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-29 08:33:25 +02:00
Amir Alexander Abdelbaki 3f05f64281 feat(hyprdrive,hyprlua): trap pointer to focused window in monocle (super+ctrl+f)
Monocle now also confines the cursor to the focused full-size window so it
can't slip onto another monitor. Hyprland has no cursor-confine dispatcher, so
this drives the confine_pointer window rule: one lazily-created rule per
workspace, matched by workspace id (follows focus), enabled/disabled in
lock-step with the monocle toggle and refreshed immediately.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-26 17:35:00 +02:00
Amir Alexander Abdelbaki 967af1c0f2 feat(hyprlua): configurable/live-polled workspace layout picker in astal-menu
Ports hyprdrive's astro-menu update to astal-menu (hand-maintained separately,
no regen script for this pair): a new config.py with a "layouts" key to
narrow/reorder which hypr/layouts-discovered layouts are offered and override
their per-layout options, plus 1s polling of the taskbar's workspace/layout
panel while the menu is open so it doesn't go stale across workspace
switches. No hologram code path here since astal-menu doesn't have one.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-24 15:14:30 +02:00
Amir Alexander Abdelbaki 7ebff0d2a4 feat(hyprdrive): configurable/live-polled workspace layout picker in astro-menu
config.json gains a "layouts" key to narrow which hypr/layouts-discovered
layouts astro-menu offers (and reorder them), plus per-layout option
overrides (trim directions, hide fit_method/stepper), without touching the
.lua layout sources.

Also: the taskbar's workspace/layout panel now polls every second while the
menu is open, since switching workspaces doesn't notify (or get blocked by)
the menu and the panel previously only refreshed on open.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-24 15:07:02 +02:00
Amir Alexander Abdelbaki 008e4d980c feat(hyprdrive,hyprlua): notification action buttons for timer/screenrec
timer-run now offers Dismiss/Snooze 2m/Snooze 5m buttons via notify-send -A
(beacon/mnotifd both implement the freedesktop Actions spec) and rings the
alarm on a loop until the notification resolves, instead of playing once and
going silent.

screenrec.sh gets a real "Stop Recording" button in the same vein, replacing
a broken anonymous --action= and a `$nid=` assignment bug that never actually
captured the notification id; also fixes hyprlua's stale `dunstctl close`
call left over from the mnotifd migration (dunst is no longer running).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-24 15:06:55 +02:00
Amir Alexander Abdelbaki 9640e09677 feat(hyprlua): migrate to mnotifd/mnotifhist, generated from hyprdrive's beacon
Adds regen-beacon.sh, a by-hand generator that produces hyprlua's plain-themed
notification daemon (mnotifd) and history viewer (mnotifhist) from hyprdrive's
beacon/transmitter-panel sources — stripping the Cosmonaut Shell hologram/
squiggle sci-fi treatment (now config-toggleable on beacon itself) and
renaming every beacon/transmitter-panel reference throughout, so future edits
to the hyprdrive originals propagate with one script run instead of two
hand-diverging copies. Wires mnotifd/mnotifhist into hyprlua in place of
dunst (autostart, keybinds, config-updater, install script incl. the D-Bus
activation shadow file).

Also adds a notification-history launcher button (verified bell glyph) to
station-bar and all three hyprlua EWW bar variants.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-24 12:34:19 +02:00
Amir Alexander Abdelbaki c86afef147 feat(hyprdrive): add beacon notification history/controls + transmitter-panel viewer
beacon gains a disk-persisted history D-Bus interface (eu.abdelbaki.beacon.History1
- List/Get/Pop/PopLatest/Remove/Clear/InvokeAction, live Added/Removed/Cleared
signals) and support for apps to embed rich controls (toggle/slider/entry, not
just fire-and-dismiss buttons) via a custom x-beacon-controls notification hint,
plus a beaconctl CLI. transmitter-panel is a new Cosmonaut Shell popup (Super+
Ctrl+N) that browses that history, with a Clear All button and a per-entry
close button.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-24 11:48:16 +02:00
Amir Alexander Abdelbaki ba12c31e3e feat(hypr): rework Super+E/F binds, add magnifier zoom and monocle toggle
Super+E now toggles cursor "glass magnifier" zoom (wiki trick); Thunar
moves to Super+Shift+E and the pcmanfm-qt alt bind is dropped. Super+Alt+F
drops the calculator launch in favor of a real fullscreen toggle, and
Super+Ctrl+F is added to toggle the workspace's "monocle" layout via the
existing layouts registry. Also inlines unified-rotate.sh cw/ccw directly
in the Super+Ctrl+E/D rotation binds instead of going through the
confusingly-named (and reversed) screenrotationwcw/acw.sh wrapper scripts.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-24 10:49:59 +02:00
Amir Alexander Abdelbaki a8b98166cf feat(nvim): auto-quit when only NERDTree/dadbod/Claude Code remain
After closing the file you were working on, if every remaining window
in the (only) tab is NERDTree, the dadbod-ui browser, or the Claude
Code terminal, there's nothing left to edit — a WinClosed autocmd
force-quits (qa!) rather than leaving you staring at bare utility
sidebars. qa! also bypasses the "terminal job still running" prompt
for the live Claude Code process; nothing there is a real file buffer.

Verified live: closing a file while another real file window remains
does not quit; closing the last real file with only utility windows
left (individually tested with NERDTree, dadbod-ui, and a
claude-named terminal buffer) does.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 11:31:59 +02:00
Amir Alexander Abdelbaki f769ed5e7d feat(nvim): auto-reload buffers changed on disk by Claude Code
Claude Code can write files outside claudecode.nvim's diff-review
pipeline (plain Bash tool calls), leaving open buffers stale. Turn on
autoread and run :checktime on FocusGained/BufEnter/CursorHold(I) plus
claudecode.nvim's own ClaudeCodeDiffClosed/ClaudeCodeSendComplete User
autocmds, so buffers refresh the moment you leave the Claude Code
terminal or a diff/edit lands, without clobbering unsaved local edits.

Verified live against the installed plugin set: all four core events
and both User autocmds register and resolve to :checktime.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 11:03:22 +02:00
Amir Alexander Abdelbaki ad691e69e0 feat(nvim): set leader to Space
Space is otherwise a no-op duplicate of "l" in normal mode, making it
free to claim without losing any real functionality. Verified live
against the installed plugin set that <leader>a... (Claude Code) and
<leader>x (CoC snippet convert) now resolve under <Space>.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 10:55:33 +02:00
Amir Alexander Abdelbaki 1135d22b39 feat(nvim): switch to coder/claudecode.nvim, document all keybinds
Replace greggh/claude-code.nvim (bare terminal wrapper) with
coder/claudecode.nvim's native WebSocket bridge — inline diff review,
buffer/selection context, model switching. Runs with
terminal.provider = "native" to avoid pulling in snacks.nvim. New
commands are bound under the previously-unused <leader>a prefix, so
none of the existing single-key app toggles are disturbed.

Move the alot floating-terminal toggle from bare "n" to "m", freeing
"n" back to Vim's default repeat-search behavior.

Document the full Neovim keybind set (window nav, app toggles, Claude
Code, insert-mode completion, misc) in docs/md/editors.md — previously
undocumented.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 10:47:24 +02:00
Amir Alexander Abdelbaki 1faec197a7 docs(theming): document terminal ANSI palette and its deployment targets
Record the CyberQueer 16-colour ANSI palette (with hex values per slot)
and note that it's mirrored identically across kitty, Alacritty, and
Ghostty configs.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 09:06:38 +02:00
Amir Alexander Abdelbaki cd2f1424c7 feat(freeipa-ansible): split login monitoring and add usr_ctl capability grants
Split usr_mon_logins into three focused checks: failed local (console/
tty/greeter) logins, SSH logins (usr_mon_sshlogins), and sudo/SELinux/
AppArmor rights violations (usr_mon_rightsviolations) — plus a new
usr_mon_iploc check that flags public-IP geolocation country changes.

Add usr_ctl_dnshostfile, usr_ctl_netman, and usr_ctl_wifi policies that
grant members scoped, non-root capability (hosts file ACL, NetworkManager
connection permissions) resolved from IPA group membership and
re-applied every enforcer tick.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 09:06:34 +02:00
Amir Alexander Abdelbaki 042103f131 fix(astro-menu): clip card bloom so corners stop poking out of the rounded border
bordered()'s glow re-strokes the rounded ring at widths up to border+22, so half
of each stroke falls outside the ring path. GTK clips a DrawingArea to its own
square allocation: along the straight edges that trims the outward spill to
nothing, but inside each corner the square patch between the arc and the widget
corner is still in-allocation and got painted solid accent red — square corners
peeking out from behind every rounded card border.

Clip the glow passes to the ring's outer silhouette (the widget rect rounded by
radius + border/2, exactly where the crisp stroke's outer edge runs) so the
bloom only reads inward. Crisp stroke and fill are unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 23:13:29 +02:00
Amir Alexander Abdelbaki 78971fd9d8 hyprdrive: route notification D-Bus activation to beacon, not dunst
The dunst package ships org.knopwob.dunst.service with
Name=org.freedesktop.Notifications, so D-Bus auto-activates dunst the
moment any app posts a notification, beating beacon to the name (beacon
then exits on name-lost). Shadow it with a user-level activation file
that Execs beacon-start.sh; ~/.local/share/dbus-1/services takes
precedence over /usr/share. Documented the install-time deploy in
updater.conf.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 17:59:10 +02:00
Amir Alexander Abdelbaki e5d58622fe Revert "feat(freeipa-ansible): gateway-wide Basic Auth in front of the ansipa portal"
This reverts commit 4730f89e82.
2026-07-22 16:24:31 +02:00
Amir Alexander Abdelbaki 4730f89e82 feat(freeipa-ansible): gateway-wide Basic Auth in front of the ansipa portal
Adds a deliberate extra sign-in layer covering the entire nginx gateway
(portal page + every proxied web UI) via a shared htpasswd credential
generated on the FreeIPA container and published to nginx through a new
portal-auth volume. FreeIPA, CheckMK and Keycloak still each enforce their
own login behind it — two prompts beats one attacker who only had to beat
one lock. Healthcheck updated to treat 401 as healthy accordingly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-22 16:08:10 +02:00
Amir Alexander Abdelbaki 4200557757 feat(freeipa-ansible): git-based signed policy distribution for ANSIPA
Replaces the unsigned SMB-policystore auto-sync (enforcer blindly sourced
whatever .sh files sat on the share, no integrity check) with a dedicated
git-over-SSH server plus GPG commit signing: nodes pull on a timer, verify
every commit's signature and fast-forward history before an unprivileged
puller account hands off to root via one exact scoped sudo command, and a
fetch failure is a safe no-op that keeps the last-known-good policy running.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-22 15:56:19 +02:00
Amir Alexander Abdelbaki 2a1113018d chore: mark sway.sh install module executable
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 20:52:32 +02:00
Amir Alexander Abdelbaki ab6e330bed style(greetd): restyle ReGreet login as Cosmonaut Shell
Rework regreet.css into holographic-glass login cards — magenta scanlines,
violet top-glow, thin glowing magenta borders, glowing monospace text — to
match hyprdrive's Cosmonaut Shell, with fixed cq_magenta/cq_cyan colours kept
outside apply-theme's palette map. Switch the greeter font to Agave Nerd Font
Mono and the greeting to "-< CREW AUTHENTICATION >-" (regreet.toml).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 20:52:32 +02:00
Amir Alexander Abdelbaki 057a5a44d8 fix(station-bar): make SNI watcher D-Bus calls async (self-deadlock)
The bar hosts the StatusNotifierWatcher in-process (sni_watcher.py), so the
*_sync proxy creation and RegisterStatusNotifierHost call blocked the main
loop waiting on a reply only that same loop could produce — a self-deadlock
freezing the whole bar (clock, holo intro) until the 25s D-Bus timeout. Switch
to new_for_bus + call (async, fire-and-forget).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 20:52:32 +02:00
Amir Alexander Abdelbaki 4da704cb5d feat(hyprdrive): default wallpaper -> ESA/Hubble "Rings of Relativity"
Swap the module's default background.jpg for ESA/Hubble Picture of the Week
potw2050a, "Rings of Relativity" (GAL-CLUS-022058s, one of the most complete
Einstein rings observed). Update CREDITS.md and the hyprdrive.sh install-module
comments to match. Credit: ESA/Hubble & NASA, S. Jha; Ack. L. Shatz — CC BY 4.0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 20:49:04 +02:00
Amir Alexander Abdelbaki f040cac729 feat(hypr): float dialog-like windows at cursor, minimum size
Add a `dialog-float` window rule to both hyprdrive and hyprlua: float any
window whose title looks like a dialog (Rename/Save/Open/Opening/Confirm/
Delete/Move/Copy/Replace/Properties/Preferences — covers file-manager rename
dialogs and Firefox "Opening <file>" download prompts), centred on the cursor
at its natural (minimum) size. Catches dialogs that carry no xdg/X11 dialog
hint and would otherwise tile; Hyprland still auto-floats the ones that do.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 20:49:04 +02:00
Amir Alexander Abdelbaki 6ef9f31dee feat(hyprdrive): tune beacon notification open/close animation
- beacon: snappier in-app dissolve (OUTRO_DURATION 0.4 -> 0.2).
- hyprland.lua: split the global `layers` animation into layersIn/layersOut
  so open and close differ. layersIn keeps the springy myBezier slide-in;
  layersOut slides the surface back off-screen with a new easeInQuint-ish
  `slideOutLate` curve — it creeps slowly then whips away in the final
  quarter, instead of a uniform fade.
- windowrules.lua: drop `no_anim` from the beacon layerrule (keep blur) so
  notification cards ride those layer animations again (they slid in/out via
  the global anim before, since no per-namespace no_anim was deployed).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 20:37:22 +02:00
Amir Alexander Abdelbaki b7eba3f967 feat(hyprdrive): switch notifications from dunst to beacon
beacon (the Cosmonaut Shell notif daemon) already renders its holo
fade-in-from-noise intro (materialise out of static), but dunst held the
org.freedesktop.Notifications bus so beacon never started. Make beacon the
deployed and active notification daemon:

- updater.conf: manage `config beacon`; drop `config dunst` (now `ignore`d,
  superseded). Also carries the pre-existing `config ghostty` line that was
  already sitting uncommitted in this file.
- beacon: add a SIGUSR1 close-all handler (window.close_all) so the old
  `dunstctl close-all` keybind has an equivalent.
- binds.lua: Super+Ctrl+C now runs `pkill -USR1 -f '[b]eacon/main.py'`
  (bracket idiom avoids pkill self-matching its own wrapper).
- screenrec.sh: `dunstctl close` -> freedesktop CloseNotification via gdbus.
- timer-run: resolve the session bus via the beacon process, not dunst.

hyprlua keeps its own independent updater.conf + dunst and is untouched.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 20:04:13 +02:00
Amir Alexander Abdelbaki f94a825c82 feat(hyprdrive): dark holo scanlines for kitty + caffeine widget in station-bar
kitty: regenerate scanlines.png — the old tile was a washed-out near-white
overlay that milked out the terminal. Replace it with a dark holographic tile
(gentle violet #5018DD tint + crisp violet scanlines every 4px + sparse
magenta/crimson grain) on a transparent base, so the window's own opacity/blur
still show the wallpaper through it. Seamlessly tileable; matches the suite's
HologramOverlay palette.

station-bar: add a caffeine badge to the right zone, a faithful port of
hyprlua's 4-state eww caffeine widget. Click toggles the shared idle-inhibit
lock via the same scripts/caffeine.sh; the glyph tracks manual inhibit (coffee)
/ webcam presence (eye) / idle (sleep) and glows magenta while presence holds
the lock, reading the same lock/flag files the status scripts do. Nerd Font
codepoints verified against Agave's cmap.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 19:38:51 +02:00
Amir Alexander Abdelbaki fa78fc9a66 Add md-to-pdf.sh: convert Markdown to PDF via python-markdown + weasyprint
Companion to docs/md-to-html.sh, for cases needing a standalone PDF
rather than a themed HTML page.
2026-07-21 13:32:10 +02:00
Amir Alexander Abdelbaki c1e54f4f75 feat(freeipa-ansible): add CheckMK monitoring for Proxmox VE + PBS
Proxmox VE hypervisors and Proxmox Backup Server aren't FreeIPA clients,
so they sit outside the dev_mon_base host-group flow. Add standalone
CheckMK local checks (cluster/storage/guests/backup for PVE; datastore
usage/last-backup/task-failures for PBS) plus a small installer that
detects the role, installs the agent, and registers the host under
/ansipa/infra — mirroring the existing dev_mon.sh pattern without
requiring IPA enrollment.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-20 11:31:03 +02:00
Amir Alexander Abdelbaki dce26b2dcf feat(terminals): deploy CyberQueer palette across kitty/alacritty everywhere
hyprland's kitty theme was still the stock template (only 5 colors set,
ANSI colors commented out); brought it in line with hyprdrive/hyprlua's
full neon 16-color palette and dropped the now-redundant inline cursor
overrides in kitty.conf. Alacritty had no color scheme at all in any DE,
so added matching [colors] blocks to hyprdrive/hyprlua/hyprland so it
renders identically to kitty/ghostty. Registered alacritty.toml and
ghostty/config in apply-theme.sh so future colors.conf edits propagate.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-20 10:01:35 +02:00
Amir Alexander Abdelbaki ace372780d feat(hyprdrive): holographic glow for kitty + new Ghostty CyberQueer config
kitty: add a seamlessly-tiled scanlines+noise+ambient-bloom PNG as
background_image, giving kitty a static approximation of the suite's
HologramOverlay treatment since it has no per-frame draw hook or shader
support to do real bloom.

ghostty: port the CyberQueer theme (palette, cursor/selection colors)
to a new Ghostty config, with a real per-pixel custom-shader instead of
a static image — color-preserving bloom, procedural scanlines/grain, an
occasional analog glitch/roll burst (tear + vertical roll + chromatic
aberration), and a one-time hologram boot intro that resolves out of
colored static via a downward sweep. Window decorations and the tab bar
are disabled to match kitty's borderless look under Hyprland.

Not wired up anywhere yet — no keybind or $TERMINAL changes point at
Ghostty. This is just the config, ready to test.
2026-07-20 09:46:14 +02:00
Amir Alexander Abdelbaki 2d7336c593 feat(hyprlua/kitty): finish the CyberQueer kitty theme
Same fix as hyprdrive's kitty (6c07c10): the 16 ANSI colors were still
stock template defaults clashing with the violet/crimson palette used
everywhere else in the suite. Fill them in from colors.conf plus a
few new neon tints in the same hue family, set background to the
real #1A1A1A instead of pure black, add matching border/bell/mark
colors, and drop the stale cursor-color pair in kitty.conf that the
theme include was silently overriding anyway.
2026-07-20 08:56:52 +02:00
Amir Alexander Abdelbaki 6c07c10370 feat(hyprdrive/kitty): finish the CyberQueer kitty theme
The 16 ANSI colors were still stock template defaults (plain green/
blue/cyan) clashing with the violet/crimson palette used everywhere
else in the suite. Fill them in from colors.conf plus a few new neon
tints in the same hue family, set background to the real #1A1A1A
instead of pure black, and add matching border/bell/mark colors. Also
drop a stale cursor-color pair in kitty.conf that the theme include
was silently overriding anyway.
2026-07-20 08:52:31 +02:00
Amir Alexander Abdelbaki 9d59565469 revert(hyprlua): remove Cosmonaut Shell components, restore pre-Friday state
orbit-menu and horizon-dock (and their eww-bar launcher buttons, autostart
hooks, and O-bind wrapping) were built inside hyprlua before hyprdrive
existed as a separate DE. hyprdrive is now the home for the full Cosmonaut
Shell suite, so hyprlua drops back to eww bars + vicinae launcher + the
astal-menu pop-open menu, unchanged, matching last Thursday's state.
hyprdrive itself is untouched.
2026-07-20 08:37:12 +02:00
Amir Alexander Abdelbaki 74fc9aefaf feat(hyprdrive/beacon): draw the divider as a Cairo magenta sine path
Replaces the ∿-glyph label divider with a Gtk.DrawingArea that strokes a sampled
sine wave (soft-glow + bright-core passes), colour per urgency (magenta / accent),
phase-advanced each tick so it travels like a live signal. Background stays
transparent — a class-specific rule overrides the CyberQueer theme's universal
`background-color`, so no dark pill shows behind it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 17:36:04 +02:00