MouseDown cancelled copy-mode before a drag could start, so selecting text
after scrolling up jumped back to the bottom. MouseUp1Pane (sent only when
no drag happened) now cancels; MouseDown clears the selection as before.
MouseDown1Pane in copy-mode-vi now cancels the mode instead of only clearing
the selection. Drag-select (root MouseDrag1Pane re-enters copy-mode) and
click-to-switch-pane are unchanged.
- mode-style bg=yellow,fg=black (black on a dark terminal was invisible)
- MouseDragEnd1Pane copies (pbcopy on macOS, tmux buffer elsewhere) without leaving copy-mode
- y/p use pbcopy/pbpaste (xsel is X11, absent on macOS); xsel kept as the Linux variant in a comment
- bind C-a send-prefix: C-a C-a sends a literal C-a to the shell
- is_vim reads #{pane_current_command}; the @tmux_vim_<pane> variable was never set, so C-h/j/k/l never reached vim
Git never expands $VARS in its config, so gitconfig carries @USER@ and
@EMAIL@ placeholders that install.sh fills from the deployed bashrc's
USER/EMAIL exports. A differing ~/.gitconfig is kept as
~/.gitconfig.backup-<date>; an identical one is left alone. A repo's
.git/config still overrides it. excludesfile uses ~ (git expands it,
not $HOME).
The rc files now override $USER, so the installer takes the login name
from id -un for dscl and the code-server unit.
gitleaks, web stack (mariadb-server, imagemagick, unversioned php-* modules),
ubuntu-desktop-minimal before the RDP setup, and a lspci-gated
install_nvidia_driver() that runs ubuntu-drivers install. README + TODO updated.
Always applied in the Linux block, no prompt, idempotent:
- install_fail2ban: fail2ban + nftables, etc/fail2ban/jail.d/local.conf.
sshd jail reads the journal (backend systemd, works with or without
auth.log) and bans the offender on every port, so the SSH port is
irrelevant: the previous server's jail banned 22 while sshd listened
on 337. 5 failures / 10 min / 1 h. Loopback + RFC1918 never banned.
- install_unattended_upgrades: package + 20auto-upgrades (the file
dpkg-reconfigure writes, without the prompt).
- harden_sshd: sshd_config.d/20-hardening.conf (PermitRootLogin no,
MaxAuthTries 3, LoginGraceTime 20), sshd -t gated: a rejected file is
removed and the install continues with a warning. Auth methods, port
and user lists untouched.
Docs: README table + step 13 + packages, CLAUDE.md layout.
cloudpex/cloudpex no longer carries the NAS host, share name, SMB user,
mount point or SMB version. It reads /etc/cloudpex.conf (root:root 0600,
KEY=value) line by line, never sources it, and dies with a hint when the
file is missing, incomplete or has a relative mount point.
cloudpex/install.sh prompts for the five values (regex-validated, re-asked
on bad input so the main installer never aborts), shows and keeps an
existing config unless answered n, and skips the config when no terminal
is attached. README (FR) + root README + CLAUDE.md updated.
/tmp is a RAM-backed tmpfs on Ubuntu (50% of RAM). Agent runs fill it: half
the RAM goes, then every temp-file creation fails with ENOSPC and shells
break. Swap does not lift the cap, so the fix is /tmp on disk.
End-of-install offers (Linux, [y/N], skipped without a terminal, idempotent):
- offer_tmp_on_disk: mask tmp.mount + etc/tmpfiles.d/tmp.conf (wipe at
boot, 10-day purge, /var/tmp rule kept). Effective at next reboot.
- offer_ssh_memory_guard: the previous server's rules. ssh.service drop-in
(OOMScoreAdjust=-1000, MemoryMin=256M) + earlyoom with --avoid sshd and
--prefer node/java. MemoryMin covers sshd only; earlyoom is the real guard.
install_cloudpex deploys the NAS mount helper in the Linux block.
Docs: README steps 12-14 + table, CLAUDE.md layout + lint command.
cloudpex/cloudpex mounts //192.168.1.111/CloudPex on /mnt/cloudpex on demand
(password prompted, nothing stored, noexec/nosuid/nodev, dir_mode 0750).
cloudpex/install.sh reproduces the live deployment: /usr/local/bin/cloudpex
root:root 0755, /mnt/cloudpex, cifs-utils if mount.cifs is missing.
README (FR) explains why on-demand and not fstab (RECOVERY doc 04).