Commit Graph

1124 Commits (4332abde350111fe0f0895e683151cb7cf588549)

Author SHA1 Message Date
Amir Alexander Abdelbaki 4332abde35 fix(core-packages): make PipeWire the jack/pulse provider to avoid DE conflict
core-packages installs ffmpeg, which depends on the virtual `jack`. With only
`pipewire` (not pipewire-jack) requested, pacman --noconfirm picks the default
provider `jack2`. The DE modules then install `pipewire-jack`, which conflicts
with the already-installed jack2 — pacman can't auto-resolve it and aborts the
whole DE module ("pipewire-jack and jack2 are in conflict").

Explicitly list pipewire-jack/pipewire-pulse/pipewire-alsa in core-packages so
PipeWire is the chosen provider from the start; jack2 is never pulled and the DE
package install no longer conflicts.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R5kHioUMK3mtf2eiLEozCM
2026-06-27 13:25:49 +02:00
Amir Alexander Abdelbaki 8bf778e487 fix(modules): resolve rust/rustup conflict and greetd config-dir abort
Two more module aborts surfaced by the live VM test (both pre-existing, only
unmasked once the wprs bug was fixed and the transaction got further):

1. core-packages.sh listed BOTH `rust` and `rustup`. They conflict (both provide
   cargo/rustc); pacman --noconfirm cannot auto-resolve it and aborts the whole
   core-packages transaction ("unresolvable package conflicts"), so wget and the
   other core tools never installed. Drop `rust` — the setup uses rustup
   exclusively (`rustup default stable`).

2. core.sh copied the greetd config into /etc/greetd before that directory
   existed (greetd is pulled in later by the DE module), so the cp failed and
   `set -e` aborted Core Services before fail2ban/udisks2 were enabled. mkdir -p
   /etc/greetd first.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R5kHioUMK3mtf2eiLEozCM
2026-06-27 04:15:36 +02:00
Amir Alexander Abdelbaki a9796bb036 fix(modules): remove invalid wprs from core packages; DEs use curl not wget
Live VM test revealed the HyprLua DE install aborted at the cursor-download step
("wget: command not found", exit 127), leaving ~/.config/hypr undeployed. Two
root causes:

1. core-packages.sh listed `wprs` in the pacman array, but wprs is AUR-only
   (wprs-git). pacman aborts the ENTIRE transaction on an unknown target, so the
   whole core-packages install failed with "target not found: wprs" — and NONE
   of the core packages installed, including wget. Removed wprs (it has its own
   optional wprs.sh AUR module) and documented why it must never be re-added.

2. hyprlua/hyprland/niri downloaded the cursor theme and wallpaper with wget,
   which is not part of the base system. Switched them to curl (always present),
   so the DE install no longer depends on an earlier module having installed wget.

Without these, HyprLua silently half-installed (packages yes, config no) and the
booted system had no Hyprland configuration.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R5kHioUMK3mtf2eiLEozCM
2026-06-27 03:05:11 +02:00
Amir Alexander Abdelbaki 6251eb8218 fix(shell-setup): set default shell without a password prompt
A bare `chsh -s /usr/bin/zsh` authenticates the calling user through PAM and
prompts "Password:", stalling an unattended install right after oh-my-zsh.
Run it via `sudo chsh ... "$(whoami)"` so it uses the passwordless setup sudo
rule and completes silently (also more reliable: it targets the account
explicitly rather than relying on the ambient user).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R5kHioUMK3mtf2eiLEozCM
2026-06-27 02:13:32 +02:00
Amir Alexander Abdelbaki 9a711013ce fix(shell-setup): install oh-my-zsh non-interactively
oh-my-zsh's install script, even with RUNZSH=no/CHSH=no, still prompts
"Do you want to overwrite it with the Oh My Zsh template? [Y/n]" in interactive
mode — which hangs an unattended/answerfile install at the shell-setup module.

Pass --unattended to skip all prompts, and KEEP_ZSHRC=yes so it preserves the
dotfiles ~/.zshrc symlink (created earlier in this module) instead of replacing
it with the oh-my-zsh template.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R5kHioUMK3mtf2eiLEozCM
2026-06-27 02:11:55 +02:00
Amir Alexander Abdelbaki 61ff61d432 fix(modules): guard remaining interactive prompts for unattended installs
Audited every module for prompts that would hang an answerfile/unattended run.
The EWW form-factor question and several interactive-config modules were still
unguarded (only hyprlua had been fixed):

- hyprland.sh, niri.sh: skip the EWW form-factor `read` when MARCHY_UNATTENDED=1
  or stdin is not a TTY, defaulting to the desktop/no-battery bar (matches hyprlua).
- mail-notmuch.sh, caldav-sync.sh: install the tools, then exit cleanly in
  unattended mode instead of blocking on the account/server credential prompts —
  the user configures the account after first boot.
- freeipa-server.sh: bail out early in unattended mode; FreeIPA server provisioning
  is interactive and must run on a booted system (ipa-server-install needs running
  services), so it can never run during the install.

freeipa-client.sh is left as-is: it has a genuine --unattended enrolment path.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R5kHioUMK3mtf2eiLEozCM
2026-06-27 02:09:04 +02:00
Amir Alexander Abdelbaki 2774a00554 fix(installer): make sudo -v passwordless during in-chroot TUI install
The temporary setup drop-in granted `NOPASSWD: ALL`, which covers `sudo <cmd>`
but NOT `sudo -v`. Installers run by the TUI (starship, rustup, …) call `sudo -v`
to pre-authorise, and that check still demands a password whenever the user has
any password-required sudoers entry — which they do, via the wheel rule in
10-wheel. The result was a hidden `[sudo] password for <user>:` prompt that
stalled the otherwise-unattended module install.

Add `Defaults:<user> !authenticate` to the 99-setup-nopasswd drop-in (in both
the auto and guided installers) so the auth check is skipped entirely for the
setup user; `sudo -v` and `sudo <cmd>` are now both passwordless during setup.
Verified live in a VM: `sudo -nv` for the user went from "a password is required"
to rc=0 after adding the line.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R5kHioUMK3mtf2eiLEozCM
2026-06-27 01:50:17 +02:00
Amir Alexander Abdelbaki e7f251dde3 feat(installer): allow user/LUKS passwords to be set via the answerfile
Previously the user password (and the LUKS passphrase for encrypted installs)
were always prompted interactively, so an answerfile install could never be
fully hands-free. Add optional "password" and "luks_password" answerfile fields:

- arch-autoinstall.sh: read both via af_get; when present use them (chpasswd /
  cryptsetup --key-file=- with --batch-mode and stdin-piped luksAddKey auth),
  otherwise fall back to the interactive prompt. Empty/null/absent => prompt.
- generate-answerfile.sh: replace the "passwords are never stored" notice with
  an optional confirmed-entry password prompt (and a LUKS one when encryption is
  enabled); emit both as JSON (null when declined).

Secrets stored this way are plain text in the file (and world-readable once
embedded in an ISO) — documented in the header; decline to keep prompting.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R5kHioUMK3mtf2eiLEozCM
2026-06-27 01:43:17 +02:00
Amir Alexander Abdelbaki 587b95cada fix(installer): make the unattended module path non-interactive
An answerfile/PXE install runs the TUI modules with no operator present, so any
interactive prompt or confirmation hangs the deployment forever.

- tui-install.sh: run each module in the FOREGROUND with a background `tail -f`
  mirroring its log, instead of backgrounding the module. Backgrounding made
  interactive module reads (e.g. the EWW form-factor question) trigger SIGTTIN
  and stop; the file-based log still avoids the `| tee` pipe-inherit hang that
  paused installs after a module spawned a daemon. Export MARCHY_UNATTENDED=1
  in answerfile mode so modules can detect it.
- hyprlua.sh: skip the EWW form-factor `read` when MARCHY_UNATTENDED=1 or stdin
  is not a TTY, defaulting to the desktop/no-battery bar; add --noconfirm to the
  tablet-branch yay call.
- python.sh: add --noconfirm --needed to its `pacman -Syu` so it no longer waits
  on the "Proceed?" prompt during unattended installs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R5kHioUMK3mtf2eiLEozCM
2026-06-27 01:15:43 +02:00
Amir Alexander Abdelbaki d445f965ce fix(modules): make service/session ops chroot-safe to prevent install aborts
When the TUI modules run inside the archiso installer chroot, the new
system's systemd is not the running init and there is no user session bus.
Operations like `systemctl start`, `enable --now`, `systemctl --user`, and
`gsettings` fail there and, under `set -e`, abort the whole module.

- logging.sh: add in_chroot/have_user_bus/enable_service/start_service
  helpers. enable_service warns instead of aborting; start_service skips in
  a chroot (unit starts on first boot via its enable symlink).
- core.sh, hyprland.sh, hyprlua.sh, niri.sh: route enables through
  enable_service, starts through start_service, and guard gsettings behind
  have_user_bus. Fixes the cronie-enable failure and the ly/DM setup abort.
- app modules (tlp, timeshift, open-webui, mysql, qemu, ollama, cockpit,
  docker, ssh-server): convert `enable --now`/plain enables to
  enable_service + start_service so they no longer abort during chroot install.
- tui-install.sh: run modules with output to a file plus a pid-bound tail,
  waiting on the module PID, so a daemon child inheriting the pipe can no
  longer hang the installer after a module (e.g. flatpak) finishes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R5kHioUMK3mtf2eiLEozCM
2026-06-26 20:58:37 +02:00
Amir Alexander Abdelbaki f0db333fa4 fix(installer): stop sudo re-prompting during in-chroot module install
The base installers granted wheel sudo with `echo '%wheel ... ALL' >> /etc/sudoers`.
Because the stock sudoers ends with `@includedir /etc/sudoers.d`, that appended
rule is parsed AFTER the drop-ins, and since sudo applies the last matching rule,
it overrode the temporary 99-setup-nopasswd NOPASSWD rule — so the user had to
re-enter their password on every pacman/yay/flatpak call while the TUI installed
modules.

Grant wheel via /etc/sudoers.d/10-wheel instead, which sorts before
99-setup-nopasswd so NOPASSWD wins during the TUI run and password auth resumes
once the temp file is removed. Also guard that @includedir is present (so the
drop-ins are always read) and set both drop-ins to the canonical 0440 mode.
Applied to both archbaseos-guided-install.sh and arch-autoinstall.sh.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 19:39:32 +02:00
Amir Alexander Abdelbaki b32859779e feat(modules): enable timeshift, ffmpeg, imagemagick, sox, yt-dlp, inkscape by default
Flip their default field to "on" in modules.conf and regenerate the checklist
blocks in tui-install.sh and generate-answerfile.sh so they come pre-selected
in both the TUI installer and the answerfile generator.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 19:32:13 +02:00
Amir Alexander Abdelbaki 0e04a7cada fix(archiso): use oflag=direct so USB write progress isn't misleading
Without oflag=direct, dd copies the ISO into the page cache at high speed, the
status=progress counter races to ~100%, then appears to hang at the end while
the slow USB drains and conv=fsync flushes — looking frozen when it is still
writing. write-usb.sh now writes with oflag=direct (honest device-level
progress) and falls back to a cached write if the bridge rejects O_DIRECT;
build.sh's dd hint and explanation are updated to match.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 19:22:23 +02:00
Amir Alexander Abdelbaki 3b0bf17210 fix(archiso): document/automate block-level USB write to fix ldlinux.c32 error
"failed to load ldlinux.c32" when booting from USB is caused by writing the
isohybrid ISO at file level (drag-and-drop, Rufus "ISO" mode, UNetbootin), which
destroys the MBR/isolinux layout. The ISO build itself is correct — archiso's
bios.syslinux mode installs isolinux.bin + isohdpfx.bin + the c32 modules and
applies the isohybrid MBR, and the profile's bootmodes match upstream releng.

Add archiso/write-usb.sh: a safe block-level (dd) writer that lists removable
disks, refuses partitions and the system/root disk, requires an all-caps YES,
unmounts the target, then writes with conv=fsync. build.sh's completion output
now points at it and warns that file-level copies cause exactly this error.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 19:08:33 +02:00
Amir Alexander Abdelbaki fb617185df chore(installer): shellcheck-clean the archiso answerfile flow
shellcheck passes (default severity) on the base installer and the whole
answerfile chain: generate-answerfile.sh → build.sh → .automated_script.sh →
launch.sh → arch-autoinstall.sh → tui-install.sh. Verified the generator's
JSON schema (drive, kernel, keymap, hostname, username, encrypt, fido2_root,
fido2_user, run_tui, components, desktop_environment, apps, shell_rc, colors)
parses correctly through both the auto base installer (af_get/af_bool) and the
TUI installer (load_answerfile), for full and minimal/empty answerfiles.

Fixed the three legitimate findings surfaced along the way:
- generate-answerfile.sh: drop unused AVAIL_DRIVES (SC2034); the drive list is
  rendered inline in the dialog prompt.
- tui-install.sh: drop unused C_RULE (SC2034); write log truncation as
  ': > "$LOG"' so the redirection has an explicit command (SC2188).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 18:52:31 +02:00
Amir Alexander Abdelbaki db4079d543 fix(installer): always append separator-free MAC to answerfile hostname
In answerfile mode the hostname now always gets the machine's MAC appended as
"<name>-<mac>" with the MAC stripped of all separators (colons/dots/dashes), so
fleet deployments from one answerfile stay unique. The default "arch" name now
also receives the suffix, and the dash is only added when a MAC is actually
found (no trailing "-" on NIC-less machines).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 18:43:54 +02:00
Amir Alexander Abdelbaki bc13de7508 feat(installer): global flatpaks, drop redundant TUI hostname, upfront passwords
- Flatpaks now install globally again: ensure_flatpak adds the Flathub remote at
  --system and all 19 app modules use `sudo flatpak install --system`. Running
  via sudo (root) performs the system op directly, avoiding the SystemHelper/
  polkit D-Bus path that caused "The name is not activatable" for non-root users.

- tui-install.sh no longer prompts for or sets the hostname — the base installer
  already configures it. Removed the Hostname section, the MAC-suffix helper, the
  AF_HOSTNAME field and the summary line.

- archbaseos-guided-install.sh now gathers ALL input up front, including
  passwords. New ask_password() prompts in clear text (by request) and requires a
  confirmation entry, looping until the two match — so each password is typed
  exactly twice and never again. The LUKS passphrase is captured once and fed to
  luksFormat/open/luksAddKey (--key-file=-) and cryptenroll ($PASSWORD), instead
  of cryptsetup prompting repeatedly. After all input, a single all-caps "type
  YES" gate replaces the old per-step confirmations (answerfile mode keeps its
  5-second abort window). The run-TUI choice is also asked up front.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 18:40:49 +02:00
Amir Alexander Abdelbaki 9107b9961a fix(installer): root-owned ~/.config, wrong logging path, flatpak system scope
Diagnosed from a full guided-install log plus a Hyprland startup log. Three
distinct remaining failures:

1. ~/.config left root-owned. The FIDO/Yubico setup runs `mkdir -p
   ~/.config/Yubico` as root (creating ~/.config itself), then chowned only
   Yubico/. ~/.config stayed root-owned, so every later user step failed with
   EACCES: shell-setup symlinks (starship.toml), the mail/caldav systemd --user
   timers, and Hyprland creating ~/.config/hypr at startup. Chown the whole
   ~/.config in both Yubico spots, and defensively reclaim it in shell-setup.

2. python/wprs/plymouth/zfs sourced ../lib/logging.sh, but apps/ modules need
   ../../lib — so they aborted with "No such file or directory". Corrected.

3. Flatpak app modules ran `flatpak install -y` at system scope, which needs the
   Flatpak SystemHelper D-Bus service + polkit (unavailable in a chroot/TTY
   install) — the "The name is not activatable" failures (wireshark, xournal,
   rnote, firefox-browser, …). Switch ensure_flatpak and all 19 main-flow
   installs to --user scope, matching apply_flatpak_theme's --user overrides.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 18:27:04 +02:00
Amir Alexander Abdelbaki 2c05c4e274 fix(installer): repair broken package lists and make user-timer setup non-fatal
The core, hyprlua and hyprland package installs used backslash-continued
`pacman` commands with inline `#` comments. Bash treats the first inline
comment as the end of the command, so pacman ran with only the packages
before it and every later name (7zip, cronie, nwg-dock-hyprland, …) was
executed as a shell command — failing under `set -e`. Move all three lists
into arrays, where per-item comments are valid, and install with `--`.

Also:
- himalaya: install the official `himalaya` package (AUR `himalaya-bin` is gone).
- mail-notmuch / caldav-sync: make the systemd *user* timer setup and the
  initial sync best-effort. A bare TTY/chroot install has no user session bus
  (and ~/.config may not be writable yet), so `systemctl --user` and the mkdir
  could abort the module; warn and continue instead.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 18:20:21 +02:00
Amir Alexander Abdelbaki cb88b315a9 fix(tui-install): paginate ui_checklist so long lists fit the screen
The applications menu (~80 entries) overflowed the terminal. Render
the checklist one terminal-height page at a time, clearing and homing
the cursor each round for a stable scrollable view, with n/p paging.
Item numbering stays global so any entry can be toggled from any page.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 17:08:32 +02:00
Amir Alexander Abdelbaki 1354dc4fd1 refactor(tui-install): replace dialog with plain-bash CLI prompts
Drop the dialog dependency entirely so the installer runs on a bare
console with only bash + coreutils. Reimplement the needed widgets
(msgbox, yesno, input, menu, checklist, form) as ui_* helpers using
read, preserving the cyberqueer magenta/cyan palette via ANSI codes
and the stdout/stderr fd convention so existing capture sites work
unchanged. Update generate-modules.sh to emit the ui_checklist form.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 16:44:48 +02:00
Amir Alexander Abdelbaki 0ab535f772 fix(installer): install OpenDeck from AUR instead of Flatpak
opendeck is not in the official repos, so install the native AUR package
with yay (matching the repo's other AUR modules) and drop the Flatpak
path. Wire `opendeck` into Hyprland autostart instead of
`flatpak run com.mairtech.OpenDeck`, and update the idempotency guard.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 16:04:13 +02:00
Amir Alexander Abdelbaki 10a5fbb33b feat(monitor-manager): write live config and resolve snap overlaps
Target ~/.config/hypr/usr/monitors.lua (the config Hyprland actually
loads) so `hyprctl reload` applies layouts immediately; the Dotfiles
repo copy stays the deploy source and is no longer written.

Add overlap geometry helpers and integrate them into the apply flow:
- block moves that would drive a monitor into a neighbor (TUI coords)
- snap positions to the MOVE_STEP_FINE grid to avoid frozen digits
- auto-resolve snap-induced collisions by re-reading the live layout
  and nudging the moved monitor clear, up to MAX_RESOLVE_ITERS
- warn on residual overlap after apply and after save/reload

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 16:00:52 +02:00
Amir Alexander Abdelbaki a1d5185ac8 fix(hyprlua): launch OpenDeck via native opendeck binary
Replace the flatpak invocation with the native `opendeck` command in
autostart.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 16:00:42 +02:00
Amir Alexander Abdelbaki 32420fd2c8 refactor(hyprlua): make monitors.lua a generic single-screen default
Replace the machine-specific DP-1/DP-3/HDMI-A-1 layout with a wildcard
catch-all rule (preferred mode, auto position, auto scale) that brings up
any connected output. Per-machine layout stays the job of monitor-manager,
which overwrites this file.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 15:59:29 +02:00
Amir Alexander Abdelbaki a09d509da8 fix(installer): address remaining sanity-check issues (LUKS2, lvm2, FIDO2, plymouth)
- arch-autoinstall.sh: use --type luks2 so systemd-cryptenroll can enroll FIDO2
- arch-autoinstall.sh: drop spurious lvm2 initramfs hook (no LVM in use)
- arch-autoinstall.sh: mkinitcpio -P (all presets) instead of -p <kernel>
- arch-autoinstall.sh: add rd.luks.options=fido2-device=auto to GRUB cmdline
- arch-autoinstall.sh: move pamu2fcfg outside chroot (host udev owns /dev/hidraw*)
- generate-answerfile.sh: remove plymouth from core components checklist
- tui-install.sh: component dialog list-height 5→4 (plymouth was removed)
- tui-install.sh: correct stale comment about word-boundary glob matching

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MibNTaLZrLnqyAzVCQe1YA
2026-06-26 14:25:06 +02:00
Amir Alexander Abdelbaki a92de3193a fix(installer): address issues 2-8 from sanity check
#2 — Word-boundary match for all module patterns
  Generator now pads SELECTED_APPS with spaces and uses *" id "* in
  counters, summary, and dispatch, matching the conflict fix from #1.
  plymouth-custom no longer false-triggers any plymouth check.

#3 — Guided installer now runs tui-install.sh
  archbaseos-guided-install.sh was calling simple-install.sh; both
  paths now use the full TUI (sentinel-managed, modules.conf-driven).

#4 — EFI/boot partition size unified at 10 GiB
  arch-autoinstall.sh was 15 GiB, archbaseos-guided-install.sh was
  5 GiB. Both now use 10 GiB.

#5 — Interactive retry for dotfiles clone (guided installer)
  Clone moved outside the chroot heredoc so read() reaches the terminal.
  Loops until success or the user skips; AF_MODE warns and continues.

#6 — PAM target unified on system-local-login
  archbaseos-guided-install.sh was writing to system-auth (affects
  sudo). Both installers now target system-local-login only.

#7 — Redundant second clone removed from autoinstaller
  arch-autoinstall.sh had a second git clone inside the chroot as a
  fallback that collided with the skel copy and printed a spurious
  warning. Removed; skel-only approach matches the guided installer
  (last updated). Also removed the individual .zshrc/.bashrc/.vimrc
  cp block; aligned to the guided installer's cleaner skel structure.

#8 — Docs: remove stale plymouth core-module section
  docs/md/modules.md still described plymouth under Core Modules.
  Section removed; plymouth appears in Optional Applications (system
  category) via the generated sentinel.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 14:12:09 +02:00
Amir Alexander Abdelbaki b227c73fcc fix(installer): add warn() and fix conflict false-match for plymouth pair
Two bugs in the module-conflicts system:

1. warn() was called by the generated conflict block but never defined —
   any conflict would crash with 'warn: command not found'.
   Added warn() to helpers: dialog msgbox in interactive mode, logged
   printf in answerfile mode.

2. Conflict patterns used substring globs (*"id"*) which caused
   plymouth-custom to match the plymouth check — selecting only
   plymouth-custom would trigger the conflict block, call the missing
   warn(), and then remove plymouth-custom from SELECTED_APPS, leaving
   no boot splash running at all.
   Fixed by padding SELECTED_APPS with spaces and using *" id "* word-
   boundary patterns in both the condition and the removal substitution.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 13:57:51 +02:00
Amir Alexander Abdelbaki d99e323ed3 removed old agent worktrees 2026-06-26 13:46:30 +02:00
Amir Alexander Abdelbaki 5abb5d1ba6 started tracking .claude 2026-06-26 13:45:24 +02:00
Amir Alexander Abdelbaki 2ff5b9b61d refactor(installer): move plymouth fully into optional apps
Both plymouth and plymouth-custom are now optional — neither is strictly
required, so removing plymouth from the core COMPONENTS checklist and
treating it identically to plymouth-custom.

- Remove plymouth from COMPONENTS checklist, counter, summary, and dispatch
- Add plymouth back to modules.conf (default=on, excludes=plymouth-custom)
- Regenerate all sentinel regions; plymouth now appears in optional apps
  checklist/summary/conflicts/dispatch alongside plymouth-custom

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 13:42:11 +02:00
Amir Alexander Abdelbaki 69aacec8fa fix(installer): correct plymouth path + remove from optional apps registry
plymouth is a core component (COMPONENTS checklist), not an optional app.
Moving plymouth.sh to apps/ left the core dispatch pointing at the deleted
path; also incorrectly added it to modules.conf, duplicating it in the
optional apps checklist.

- Fix core dispatch: $MODULES/optional-Modules/plymouth.sh → $APPS/plymouth.sh
- Remove plymouth from modules.conf (plymouth-custom remains as optional app)
- Regenerate all sentinel regions; conflict block now only has plymouth-custom

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 13:38:37 +02:00
Amir Alexander Abdelbaki 8e9c460713 refactor(tools): move module generation tooling into setup/tools/
sync-modules.sh and generate-modules.sh are developer tooling, not part of
the installer runtime — same rationale as freeipa-image.sh. Update SETUP_DIR
paths in both scripts to resolve correctly from the new location.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 13:31:12 +02:00
Amir Alexander Abdelbaki 5647852ee6 refactor(modules): move plymouth into apps/, retire freeipa-image to tools/
apps/ is for modules that install software during setup. freeipa-image is
support tooling for the ansipa controller, run manually before installation,
so it has no place in the TUI module picker.

- git mv optional-Modules/plymouth.sh → apps/plymouth.sh
- git mv apps/freeipa-image.sh → setup/tools/freeipa-image.sh
- modules.conf: add plymouth (default=on, excludes=plymouth-custom); remove freeipa-image
- generate-modules.sh: regenerate all sentinel regions (81 → 81 active modules,
  freeipa-image dropped from checklist/summary/dispatch, plymouth added with on default,
  conflict block gains plymouth ↔ plymouth-custom pair)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 13:30:03 +02:00
Amir Alexander Abdelbaki 5d7c97409b feat(installer): modules.conf registry + sentinel-based code generation
Collapse 5 manual touch points per optional app module (counter, checklist,
summary, conflict check, dispatch in tui-install.sh + answerfile generator +
docs table row) into a single source of truth at setup/modules.conf.

- setup/modules.conf: 80-module registry (id|category|description|default|excludes)
  with sensible defaults (python, firefox-browser, onlyoffice) and conflict pairs
  (plymouth-custom ↔ plymouth)
- setup/sync-modules.sh: scans apps/*.sh, stubs any IDs missing from modules.conf
- setup/generate-modules.sh: regenerates all sentinel regions from modules.conf
  (supports --dry-run); fixes Python re.sub backslash-n corruption via lambda repl
- tui-install.sh: 5 sentinel regions added (module-counters, module-checklist,
  module-summary, module-conflicts, module-dispatch); fixes 19 modules missing
  from count_steps() and mail-notmuch/caldav-sync missing from SUMMARY
- generate-answerfile.sh: module-checklist sentinel; list-height now auto-computed
- docs/md/modules.md: per-category sentinels; all sections regenerated from conf
- Renames: prismlauncher→prism, freeipa-image-builder→freeipa-image,
  firefox→firefox-browser, zed→zed-ide; moves python/zfs/wprs into apps/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 13:24:02 +02:00
Amir Alexander Abdelbaki 9289f01965 feat(ansipa): unify FreeIPA group naming with dev_* / usr_* prefixes
All ansipa host/user group names now follow a consistent prefix scheme:

  dev_mod_<name>          — dotfiles module install (was ansipa-module-)
  dev_fp_<app-id>         — Flatpak install (was fp_install_)
  dev_pkg_<package>       — native package install (was ansipa-install-)
  dev_daemon-enable-<u>   — service enable policy (was policy-daemon-enable-)
  dev_daemon-disable-<u>  — service disable policy (was policy-daemon-disable-)
  dev_timeshift-backup    — backup policy (was policy-timeshift-backup)
  dev_security-scan       — scan policy (was policy-security-scan)
  dev_no-local-users      — auth lockdown (was no_local_users)
  dev_local-sudo-<user>   — per-device sudo grant (was local_sudo_)
  usr_block-binary-<name> — per-user binary block (was policy-block-binary-)
  usr_scan-notify         — per-user alert notification (was policy-scan-notify)

Also adds a JSON state manifest (manifest.json) to ansipa-install-modules
and tightens the FreeIPA enrollment guard to check /etc/ipa/default.conf.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LcnnA1whUwQkDv1omsgh9Y
2026-06-26 11:48:24 +02:00
Amir Alexander Abdelbaki 2be85739b5 feat(apps): add Tangent Notes module (Flatpak)
Installs io.github.suchnsuch.Tangent via Flatpak with cyberqueer theme
applied. Registered in TUI installer, answerfile generator, and docs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 11:20:25 +02:00
Amir Alexander Abdelbaki e278795610 feat(apps): add Obsidian module (Flatpak)
Installs md.obsidian.Obsidian via Flatpak with cyberqueer theme applied.
Registered in TUI installer, answerfile generator, and docs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 11:15:08 +02:00
Amir Alexander Abdelbaki 394927573d feat(apps): add Rnote module (Flatpak)
Installs com.github.flxzt.rnote via Flatpak with cyberqueer theme
applied. Registered in TUI installer, answerfile generator, and docs
alongside xournal++ in the Productivity section.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 11:11:19 +02:00
Amir Alexander Abdelbaki 66e51474a1 feat(apps): add OpenDeck + ydotool module
Installs ydotool via pacman and OpenDeck via Flatpak, wires ydotoold
and OpenDeck into the Hyprland autostart. Registers the module in the
TUI installer, answerfile generator, and docs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 11:08:32 +02:00
Amir Alexander Abdelbaki 29dc304e4f remigrating to custom monitor manager - setup reverted 2026-06-26 11:00:51 +02:00
Amir Alexander Abdelbaki f5a1182a3d feat(plymouth): add custom-logo variant, sync answerfile + docs
- plymouth.sh: accepts PLYMOUTH_LOGO_SRC env var; PNG used as-is, SVG
  converted via rsvg-convert (librsvg only installed when needed)
- apps/plymouth-custom.sh: thin wrapper that validates the caller-supplied
  path and delegates to plymouth.sh with PLYMOUTH_LOGO_SRC exported
- install-modules.sh: adds 'Plymouth (custom)' checklist entry; prompts
  for image path via inputbox before the confirmation dialog; exports
  PLYMOUTH_LOGO_SRC into the module run
- generate-answerfile.sh: adds 'plymouth' (on by default) to the
  components checklist to match tui-install.sh
- docs: installation.md and modules.md updated with Plymouth component,
  answerfile schema, mkinitcpio note, and custom-logo module entry

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SyBNiWy3wpawrWb9ryVk7p
2026-06-26 10:57:32 +02:00
Amir Alexander Abdelbaki 52fe3a910e feat(plymouth+resources): bundle bg-skull.svg in repo and archiso
Move the splash logo into resources/bg-skull.svg so it's tracked in git
and always available alongside the dotfiles.  build.sh now copies
resources/ into /root/installer/resources/ on the ISO.  The Plymouth
module resolves the SVG from the repo copy first, ISO copy second —
no user intervention or ~/Pictures setup required.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SyBNiWy3wpawrWb9ryVk7p
2026-06-26 10:48:45 +02:00
Amir Alexander Abdelbaki fe72a4c71b feat(plymouth): add M-Archy boot splash module with skull logo + spinner
Installs a custom Plymouth theme (m-archy) with bg-skull.svg converted
to PNG (Plymouth is PNG-only via libpng — no SVG support) and a 12-dot
magenta spinner animation. Enabled by default in tui-install.sh; also
available as an optional module in install-modules.sh. Archiso image
remains Plymouth-free.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SyBNiWy3wpawrWb9ryVk7p
2026-06-26 10:44:02 +02:00
Amir Alexander Abdelbaki d9e4d67013 feat(archiso+branding): rebrand to m-archy, ship fastfetch logo and os-release
Steps taken:
- Added overlay/airootfs/etc/os-release with NAME="M-Archy", ID=m-archy,
  ID_LIKE=arch so fastfetch and other tools show the correct distro name while
  keeping pacman/AUR helpers happy via ID_LIKE.
- Added overlay/airootfs/etc/fastfetch/config.jsonc — system-wide fastfetch
  config equivalent to:
    --logo-type file --logo /etc/fastfetch/m-archy-SPC.txt
    --logo-color-1 red --logo-color-2 red --color red
  (keys + title colored red, custom file logo, no other defaults changed).
- Added overlay/airootfs/etc/fastfetch/m-archy-SPC.txt — copy of the pin.txt
  ASCII logo; lands on the live ISO via the existing cp -r overlay/airootfs/
  step in build.sh, no build.sh or profiledef.sh changes needed.
- Renamed resources/pin.txt → resources/m-archy-SPC.txt and updated all
  references in .bashrc, .zshrc, and both kitty/bash-remoteconf files.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 09:50:39 +02:00
Amir Alexander Abdelbaki 8b9c5c70b2 feat(installer): add shell_rc preference to skip copying .*rcs to skel
Adds a dialog (interactive + answerfile) letting the user choose whether
to copy the dotfiles' .zshrc / .bashrc / .vimrc into /etc/skel, or leave
system defaults in place. The choice is persisted as shell_rc in the
answerfile JSON and respected by both the TUI installer and the generator.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 09:05:00 +02:00
Amir Alexander Abdelbaki 357a19cb8c remigrating to custom monitor manager solution 2026-06-26 08:39:40 +02:00
Amir Alexander Abdelbaki 7016388210 fix(monitor-manager): account for scale when computing logical monitor size
logical_width/height now divide physical pixels by scale so the canvas
correctly represents the compositor's coordinate space (e.g. 3840px @1.5x
is 2560 logical px wide, not 3840).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 08:34:34 +02:00
Amir Alexander Abdelbaki f8b5f1aa6a reverted starship config because claude fucked it up 2026-06-25 14:11:14 +02:00
Amir Alexander Abdelbaki 523ec416e8 chore: merge comment annotations from agent worktrees into main
133 files annotated with inline comments and section headers across:
- setup scripts (install, core, packages, shell, DEs, apps)
- hyprlua/hypr configs (hyprland.lua, hypridle, hyprlock, monitorhandler)
- niri config KDL modules
- dotfiles (.bashrc, .zshrc, starship.toml, colors.conf, etc.)
- hyprlua scripts and waybar scripts
- archiso build scripts

Monitor configuration (hyprmoncfg / monitors.lua / binds.lua) untouched.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 14:00:57 +02:00