Compare commits

..
9 Commits
Author SHA1 Message Date
mw cd63df4f59 docs(caddy): add agent0.localhost reverse proxy + RFC 6761 wildcard learning
- New site: https://agent0.localhost -> reverse_proxy 192.168.0.141:8090
  (first non-localhost backend; remote LAN host running uvicorn)
- Config in dedicated /etc/caddy/conf.d/agent0.localhost.conf
- Regenerated mkcert cert: 19 -> 20 SANs, valid until 2028-10-21
- Key learning: *.localhost wildcard is NOT honored by curl/system
  trust even for single-label subdomains - .localhost is a special-use
  TLD per RFC 6761; every subdomain needs an explicit SAN. Corrects
  prior assumption in stack.md and manual-overrides.md.

Updates: docs/tech/stack.md, docs/tech/manual-overrides.md, CHANGELOG.md
2026-07-21 14:08:07 +02:00
mw c67dd74e0b docs: add memory inventory and migration log
- 4x 8 GiB DDR4-3000 DIMMs (32 GiB total) in workstation
- 64 GiB DDR4-2400 migrated to homeoffice, swapped for 32 GiB
2026-07-13 17:29:00 +02:00
mw cbe24c03df docs: add platform/packages/onlyoffice.docs localhost sites + cert regen to Caddy docs
- Added platform.localhost (-> localhost:10080) and packages.localhost
  (-> localhost:20080) to stack.md sites table (total now 17)
- Documented onlyoffice.docs.localhost (pre-existing in Caddy config, was undocumented)
- Regenerated mkcert cert with explicit SANs for the 3 new hostnames
  (onlyoffice.docs.localhost is multi-label, not covered by *.localhost wildcard)
- Fixed wildcard note: multi-label hosts require explicit SANs
- Updated manual-overrides with cert regeneration row + site delta
- Updated CHANGELOG with cert regen + site additions
2026-07-12 13:10:21 +02:00
mwandJunie 269079df34 chore(hyprland): enable mouse window drag/resize and migrate cheatsheets to learn portal
Co-authored-by: Junie <junie@jetbrains.com>
2026-07-09 11:01:51 +02:00
mw b888ef90c4 docs(changelog): merge duplicate '### Fixed' section into one block
Complete the Keep a Changelog compliance started in 441e28b. The second
'### Fixed' block at end of [Unreleased] (kitty, GRUB regex,
changed_when, OOM, keyring) is merged into the first block, preserving
newest-first ordering (2026-05-22 -> 2026-03-17).

Section order remains Fixed -> Added -> Removed -> Changed (pre-existing,
non-standard vs Keep a Changelog's recommended Added-first order).
Reordering all sections is a larger refactor beyond this fix's scope.
2026-07-06 09:33:56 +02:00
mw 441e28bda3 docs: fix CHANGELOG duplicate Added section + missing period in learning doc
Address review feedback on ce99f58:
- Merge the two '### Added' blocks in [Unreleased] into one (Keep a
  Changelog: each category appears once). New 2026-07-06 entries now
  sit at the top of the existing Added block.
- Add missing period after 'required SSE headers' in the liveness
  verification prose (was a run-on sentence).
2026-07-06 09:14:13 +02:00
mw ce99f58374 docs: Caddy manual override + OnlyOffice MCP SSE investigation (#92)
Record the Caddy reverse-proxy at /etc/caddy/ (14 *.localhost sites,
mkcert TLS, systemd caddy.service) as a manual override in
docs/tech/manual-overrides.md - no caddy Ansible role exists yet.

Add a 'Local Dev Services' section to docs/tech/stack.md listing all
*.localhost sites and useful Caddy commands.

New learning record docs/learnings/2026-07-06-caddy-onlyoffice-mcp-sse-
investigation.md: Caddy emits 'context canceled' SSE aborts (~1.5ms) on
onlyoffice.localhost/mcp -> localhost:3847. Upstream verified alive
(HTTP 406 to plain GET = expected). Handed off to GitLab issue
satware/mcp/onlyoffice#92 with 5 hypotheses, 7 tasks, and a proposed
flush_interval -1 + transport http { versions 1.1 } mitigation (not
applied yet to avoid masking root cause).
2026-07-06 08:58:27 +02:00
mw 2b6ce0d635 docs: Remmina Wayland crash fix + upstream MR !2757
- Added learning doc for 2026-07-03 session: diagnosed SIGSEGV in
  XKeysymToKeycode (missing NULL check on XOpenDisplay), forked Remmina
  to gitlab.com/satware, built with FreeRDP3, verified fix, submitted MR.
- Added manual override entry for patched remmina-plugin-rdp.so in
  ~/.config/remmina/plugins/
2026-07-03 12:13:34 +02:00
mw d72e3782e8 docs(passwords): document git.satware.ai PAT libsecret migration and rotation TODO 2026-06-30 14:13:15 +02:00
12 changed files with 479 additions and 479 deletions
+13 -6
View File
@@ -8,10 +8,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
### Fixed ### Fixed
- Fixed Hyprland configuration warning/error by changing the DVI-D-1 monitor `transform` property from a string `"1"` to an integer `1` (2026-07-09).
- tuigreet boot error: removed invalid `--numlock` flag from greetd config (not a valid tuigreet parameter). Replaced X11-only `numlockx on` in Hyprland with native `numlock_by_default = true` in the `input` section (2026-06-01). - tuigreet boot error: removed invalid `--numlock` flag from greetd config (not a valid tuigreet parameter). Replaced X11-only `numlockx on` in Hyprland with native `numlock_by_default = true` in the `input` section (2026-06-01).
- hypridle SEGV crash loop (ADR N/A, hotfix): sdbus-cpp 2.3.0 had an ABI incompatibility causing hypridle to SIGSEGV in `libsdbus-c++.so.2` `registerSignalHandler`. Fixed by upgrading sdbus-cpp from 2.3.0-1 to 2.3.1-1 (Arch upstream, pulled ahead of Manjaro mirror sync). Also resolves latent ABI issues for hyprlock and xdg-desktop-portal-hyprland (2026-05-22). - hypridle SEGV crash loop (ADR N/A, hotfix): sdbus-cpp 2.3.0 had an ABI incompatibility causing hypridle to SIGSEGV in `libsdbus-c++.so.2` `registerSignalHandler`. Fixed by upgrading sdbus-cpp from 2.3.0-1 to 2.3.1-1 (Arch upstream, pulled ahead of Manjaro mirror sync). Also resolves latent ABI issues for hyprlock and xdg-desktop-portal-hyprland (2026-05-22).
- Resolved kitty cursor keys not working by disabling the `TERM=xterm-256color` override in `.bashrc`, allowing Kitty to correctly set `TERM=xterm-kitty`. Added Ansible management for `kitty.conf` to ensure proper terminal behavior and shell integration (2026-05-19).
- `system-upgrade` role: GRUB menu assertion now matches Manjaro's real `menuentry 'Manjaro Linux (Kernel: X.Y.Z-MANJARO x64)'` format (counted per-kernel-family) instead of the wrong `menuentry .*linux(612|70)` regex that always returned 0 hits on Manjaro and broke the live run with a false-negative failure (2026-05-18).
- `system-upgrade` role: migration task `changed_when` now matches pacman's progress lines `^<!--(SECTION)-->(N/M)<!--(--SECTION)-->s+(installing|upgrading|removing)s` instead of plain substring matching, so the role's own echo lines no longer trigger spurious `changed=true` on idempotent re-runs. Verified: second live re-run reports `ok=16 changed=0 failed=0 skipped=5` (2026-05-18).
- Resolved system unresponsiveness issue by addressing critical memory/swap pressure with increased headroom and proactive OOM killing (2026-03-17).
- Identified failed `archlinux-keyring-wkd-sync.service` in system health check.
### Added ### Added
- Added `agent0.localhost` (-> `reverse_proxy 192.168.0.141:8090`, `flush_interval -1`) to Caddy in a dedicated file `/etc/caddy/conf.d/agent0.localhost.conf`. First non-localhost backend (remote LAN host running a uvicorn app). Regenerated mkcert cert to add explicit `agent0.localhost` SAN; cert now has 20 SANs, valid until 2028-10-21 (2026-07-21). Key learning: the `*.localhost` wildcard is NOT honored by curl/system trust even for single-label subdomains - `.localhost` is a special-use TLD per RFC 6761, so every subdomain needs an explicit SAN. This corrects the prior assumption in `docs/tech/stack.md` and `docs/tech/manual-overrides.md` that single-label subdomains were wildcard-covered. Total `*.localhost` sites now 18.
- Regenerated mkcert cert at `/etc/caddy/localhost{,-key}.pem` to add explicit SANs for `platform.localhost`, `packages.localhost`, and `onlyoffice.docs.localhost` (pre-existing in Caddy config but missing from cert, causing TLS validation failures). Cert now has 19 SANs, valid until 2028-10-12 (2026-07-12).
- Added `platform.localhost` (-> `localhost:10080`, amicron-platform Docker) and `packages.localhost` (-> `localhost:20080`, satis Docker) to `/etc/caddy/conf.d/localhost-dev.conf`. Docker port mappings updated: `~/internal/amicron-platform/docker-compose.override.yml` `10080:80`, `~/internal/satis/docker-compose.yml` nginx `20080:80`. Both upstreams plain HTTP on high ports; Caddy terminates TLS. Also documented `onlyoffice.docs.localhost` in `docs/tech/stack.md` (pre-existing in Caddy config, was undocumented). Total `*.localhost` sites now 17. The three form the local E2E test triangle: `platform.localhost` (ERP) -> `packages.localhost` (Satis) -> shared Firebird 3.0.14 database (token validation), mirroring the production `platform.auc.de` + `packages.auc.de` + shared Firebird setup (2026-07-12).
- Enabled click-and-drag window movement and resizing under the SUPER modifier, and enabled border dragging to resize tiled windows natively, updating both the Hyprland configuration template and keybindings cheatsheet (2026-07-09).
- Documented local dev services in `docs/tech/stack.md`: Caddy (systemd `caddy.service` on port 443) with 14 `*.localhost` sites and mkcert TLS at `/etc/caddy/`. Registered as a manual override in `docs/tech/manual-overrides.md` (no `caddy` Ansible role exists yet) (2026-07-06).
- Investigation learning record `docs/learnings/2026-07-06-caddy-onlyoffice-mcp-sse-investigation.md`: Caddy `context canceled` SSE aborts (~1.5ms) on `onlyoffice.localhost/mcp` forwarded to `localhost:3847` (OnlyOffice MCP server). Upstream verified alive (HTTP 406 to plain GET = expected). Handed off to GitLab issue [satware/mcp/onlyoffice#92](https://gitlab.satware.com/satware/mcp/onlyoffice/-/work_items/92) with 5 hypotheses, 7 investigation tasks, and a proposed Caddy `flush_interval -1` + `transport http { versions 1.1 }` mitigation (not applied yet) (2026-07-06).
- Waybar USB module: auto-mount USB sticks via udisks2, show hover details (device/model/size/fs/mountpoint), left-click opens in yazi, right-click ejects. Script at `~/.config/waybar/scripts/usb.sh`, Ansible-managed via `hyprland` role template `waybar_usb_script.sh.j2` (2026-05-22). - Waybar USB module: auto-mount USB sticks via udisks2, show hover details (device/model/size/fs/mountpoint), left-click opens in yazi, right-click ejects. Script at `~/.config/waybar/scripts/usb.sh`, Ansible-managed via `hyprland` role template `waybar_usb_script.sh.j2` (2026-05-22).
- `udisks2` explicitly listed in `hyprland_packages` (was transitive dep of Dolphin; now direct dep of USB module) (2026-05-22). - `udisks2` explicitly listed in `hyprland_packages` (was transitive dep of Dolphin; now direct dep of USB module) (2026-05-22).
- Yazi optional deps provisioned via Ansible: `chafa`, `7zip`, `resvg` added to `hyprland_packages` (2026-05-22). - Yazi optional deps provisioned via Ansible: `chafa`, `7zip`, `resvg` added to `hyprland_packages` (2026-05-22).
@@ -30,6 +42,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Comprehensive health report for `mw-pfeddersheim-workstation` (2026-03-09). - Comprehensive health report for `mw-pfeddersheim-workstation` (2026-03-09).
### Removed ### Removed
- Moved workstation-specific cheatsheets (`hyprland-keybindings.md`, `screenshot-cheatsheet.md`, `yazi-cheatsheet.md`, and the obsolete workstation copy of `neovim-cheatsheet.md`) to the central `learn` repository (2026-07-09).
- `alesi-routine-morning.service` / `alesi-routine-morning.timer` user-level systemd units — daily 07:45 morning routine was failing (exit 128, git outside repo). Script `scripts/daily-routine.sh` retained for manual use (2026-05-26). - `alesi-routine-morning.service` / `alesi-routine-morning.timer` user-level systemd units — daily 07:45 morning routine was failing (exit 128, git outside repo). Script `scripts/daily-routine.sh` retained for manual use (2026-05-26).
- Tier 1 package cleanup (ADR 0007): removed 25 X11/KDE/legacy packages via Ansible — lightdm, lightdm-slick-greeter, lightdm-settings, sddm, sddm-kcm, sddm-breath-theme, xf86-video-{amdgpu,ati,intel,nouveau,vesa}, xf86-input-synaptics, xterm, xorg-{twm,xinit,xkill,server-xvfb}, x11vnc, numlockx, startup-notification, illyria-wallpaper, ntp, spectacle, pamac-tray-icon-plasma. All have Wayland-native replacements already in use. Frees ~80-120 MiB direct + cascade deps (2026-05-22). - Tier 1 package cleanup (ADR 0007): removed 25 X11/KDE/legacy packages via Ansible — lightdm, lightdm-slick-greeter, lightdm-settings, sddm, sddm-kcm, sddm-breath-theme, xf86-video-{amdgpu,ati,intel,nouveau,vesa}, xf86-input-synaptics, xterm, xorg-{twm,xinit,xkill,server-xvfb}, x11vnc, numlockx, startup-notification, illyria-wallpaper, ntp, spectacle, pamac-tray-icon-plasma. All have Wayland-native replacements already in use. Frees ~80-120 MiB direct + cascade deps (2026-05-22).
- Tier 2 package cleanup (ADR 0007): removed KDE Plasma stack — kwin, plasma-desktop, plasma-workspace, kdeplasma-addons, plasma-nm, plasma-pa, plasma-x11-session, kde-gtk-config, powerdevil, xdg-desktop-portal-kde, plasma-integration, dolphin, dolphin-plugins, kdegraphics-thumbnailers. Plus 45 cascade orphan deps. Dolphin replaced by yazi. Frees ~400 MiB total (2026-05-22). - Tier 2 package cleanup (ADR 0007): removed KDE Plasma stack — kwin, plasma-desktop, plasma-workspace, kdeplasma-addons, plasma-nm, plasma-pa, plasma-x11-session, kde-gtk-config, powerdevil, xdg-desktop-portal-kde, plasma-integration, dolphin, dolphin-plugins, kdegraphics-thumbnailers. Plus 45 cascade orphan deps. Dolphin replaced by yazi. Frees ~400 MiB total (2026-05-22).
@@ -59,9 +72,3 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Cleaned up deprecated software information from `docs/tech/stack.md` (2026-03-13). - Cleaned up deprecated software information from `docs/tech/stack.md` (2026-03-13).
- Synchronized software versions across documentation files (2026-03-13). - Synchronized software versions across documentation files (2026-03-13).
### Fixed
- Resolved kitty cursor keys not working by disabling the `TERM=xterm-256color` override in `.bashrc`, allowing Kitty to correctly set `TERM=xterm-kitty`. Added Ansible management for `kitty.conf` to ensure proper terminal behavior and shell integration (2026-05-19).
- `system-upgrade` role: GRUB menu assertion now matches Manjaro's real `menuentry 'Manjaro Linux (Kernel: X.Y.Z-MANJARO x64)'` format (counted per-kernel-family) instead of the wrong `menuentry .*linux(612|70)` regex that always returned 0 hits on Manjaro and broke the live run with a false-negative failure (2026-05-18).
- `system-upgrade` role: migration task `changed_when` now matches pacman's progress lines `^<!--(SECTION)-->(N/M)<!--(--SECTION)-->s+(installing|upgrading|removing)s` instead of plain substring matching, so the role's own echo lines no longer trigger spurious `changed=true` on idempotent re-runs. Verified: second live re-run reports `ok=16 changed=0 failed=0 skipped=5` (2026-05-18).
- Resolved system unresponsiveness issue by addressing critical memory/swap pressure with increased headroom and proactive OOM killing (2026-03-17).
- Identified failed `archlinux-keyring-wkd-sync.service` in system health check.
@@ -18,7 +18,7 @@ local mainMod = "SUPER"
-- 2. DVI-D-1 BenQ BL2405 1920x1080@60 (rotated 90 CW) -- 2. DVI-D-1 BenQ BL2405 1920x1080@60 (rotated 90 CW)
-- 3. HDMI-A-1 TERRA 3280W 2560x1440@144 (3640x0) -- 3. HDMI-A-1 TERRA 3280W 2560x1440@144 (3640x0)
hl.monitor({ output = "DP-1", mode = "2560x1440@60", position = "0x0", scale = "1" }) hl.monitor({ output = "DP-1", mode = "2560x1440@60", position = "0x0", scale = "1" })
hl.monitor({ output = "DVI-D-1", mode = "1920x1080@60", position = "2560x0", scale = "1", transform = "1" }) hl.monitor({ output = "DVI-D-1", mode = "1920x1080@60", position = "2560x0", scale = "1", transform = 1 })
hl.monitor({ output = "HDMI-A-1", mode = "2560x1440@60", position = "3640x0", scale = "1" }) hl.monitor({ output = "HDMI-A-1", mode = "2560x1440@60", position = "3640x0", scale = "1" })
hl.workspace_rule({ workspace = 1, monitor = "DP-1", default = true }) hl.workspace_rule({ workspace = 1, monitor = "DP-1", default = true })
@@ -62,7 +62,7 @@ hl.config({
active_border = { colors = {"rgba(33ccffee)", "rgba(00ff99ee)"}, angle = 45 }, active_border = { colors = {"rgba(33ccffee)", "rgba(00ff99ee)"}, angle = 45 },
inactive_border = "rgba(595959aa)", inactive_border = "rgba(595959aa)",
}, },
resize_on_border = false, allow_tearing = false, layout = "dwindle", resize_on_border = true, allow_tearing = false, layout = "dwindle",
}, },
decoration = { decoration = {
rounding = 10, rounding_power = 2, rounding = 10, rounding_power = 2,
@@ -172,6 +172,10 @@ hl.bind(mainMod .. " + Print", hl.dsp.exec_cmd("grimblast copysave activ
hl.bind(mainMod .. " + SHIFT + Print", hl.dsp.exec_cmd("grimblast copysave output")) hl.bind(mainMod .. " + SHIFT + Print", hl.dsp.exec_cmd("grimblast copysave output"))
hl.bind(mainMod .. " + ALT + Print", hl.dsp.exec_cmd('grim -g "$(slurp)" - | satty -f -')) hl.bind(mainMod .. " + ALT + Print", hl.dsp.exec_cmd('grim -g "$(slurp)" - | satty -f -'))
-- Mouse binds
hl.bind(mainMod .. " + mouse:272", hl.dsp.window.drag(), { mouse = true })
hl.bind(mainMod .. " + mouse:273", hl.dsp.window.resize(), { mouse = true })
-------------------------------- --------------------------------
---- WINDOW RULES ---- ---- WINDOW RULES ----
-------------------------------- --------------------------------
-135
View File
@@ -1,135 +0,0 @@
# Hyprland Keybindings - Full Cheatsheet
**Layout:** German (de) | **Mod key:** SUPER (Windows key) | **Config:** `hyprland.lua` (Hyprland 0.55+)
---
## General
| Shortcut | Action | Details |
|----------|--------|---------|
| `SUPER+Q` | Kill active window | killactive |
| `SUPER+T` | Open terminal | kitty |
| `SUPER+Enter` | Open terminal | kitty |
| `SUPER+M` | Exit Hyprland | exit |
| `SUPER+E` | File manager | dolphin |
| `SUPER+V` | Toggle floating | togglefloating |
| `SUPER+D` | App launcher | hyprlauncher |
| `SUPER+P` | Toggle pseudo-split | pseudo |
| `SUPER+J` | Toggle split direction | layoutmsg togglesplit |
| `SUPER+F` | Toggle fullscreen | fullscreen 0 |
| `SUPER+R` | Reload config | hyprctl reload |
| `SUPER+SPACE` | Toggle float (popup) | togglefloating |
| `SUPER+TAB` | Cycle next window | cyclenext |
| `SUPER+SHIFT+TAB` | Cycle previous window | cyclenext prev |
| `SUPER+` `` ` `` (Grave) | Toggle scratchpad | togglespecialworkspace |
| `SUPER+SHIFT+` `` ` `` | Send window to scratchpad | movetoworkspace special |
| `SUPER+CTRL+K` | Keybind cheat menu | *(broken - pipelines to grep+fuzzel)* |
| `SUPER+CTRL+L` | Lock screen | hyprlock |
| `SUPER+B` | Web browser | google-chrome-stable |
## Navigation / Focus
| Shortcut | Action |
|----------|--------|
| `SUPER+TAB` | Cycle next window |
| `SUPER+SHIFT+TAB` | Cycle previous window |
| `SUPER+H` | Move focus left |
| `SUPER+L` | Move focus right |
| `SUPER+left arrow` | Move focus left |
| `SUPER+right arrow` | Move focus right |
| `SUPER+up arrow` | Move focus up |
| `SUPER+down arrow` | Move focus down |
## Window Movement
| Shortcut | Action |
|----------|--------|
| `SUPER+SHIFT+H` | Move window left |
| `SUPER+SHIFT+L` | Move window right |
| `SUPER+SHIFT+K` | Move window up |
| `SUPER+SHIFT+J` | Move window down |
| `SUPER+SHIFT+left` | Move window left |
| `SUPER+SHIFT+right` | Move window right |
| `SUPER+SHIFT+up` | Move window up |
| `SUPER+SHIFT+down` | Move window down |
## Window Resize
| Shortcut | Action |
|----------|--------|
| `SUPER+ALT+H` | Resize active: width -40 |
| `SUPER+ALT+L` | Resize active: width +40 |
| `SUPER+ALT+K` | Resize active: height -40 |
| `SUPER+ALT+J` | Resize active: height +40 |
## Screenshots
| Shortcut | Action | Tool |
|----------|--------|------|
| `Print` | Area select → save + copy | grimblast copysave area |
| `SUPER+Print` | Active window → save + copy | grimblast copysave active |
| `SUPER+SHIFT+Print` | Full monitor → save + copy | grimblast copysave output |
| `SUPER+ALT+Print` | Area select → annotate | grim | slurp | satty |
## Workspaces
| Shortcut | Action |
|----------|--------|
| `SUPER+1..9` | Switch to workspace 1-9 |
| `SUPER+SHIFT+1..9` | Move active window to workspace 1-9 |
| `SUPER+` `` ` `` | Toggle scratchpad (togglespecialworkspace) |
| `SUPER+SHIFT+` `` ` `` | Move to scratchpad (movetoworkspace special) |
### Workspace Layout
| Workspace | Monitor | Position |
|-----------|---------|----------|
| 1 | DP-1 (TERRA 3280W) | Left, 2560x1440@60 |
| 2 | DVI-D-1 (BenQ BL2405) | Center, 1920x1080@60 rotated 90deg |
| 3 | HDMI-A-1 (TERRA 3280W) | Right, 2560x1440@60 |
## Kitty Title Bar
Every kitty terminal tile shows a title bar with:
| Field | Description |
|-------|-------------|
| `{hostname}` | Machine hostname |
| `{cwd}` | Current working directory |
| `{title}` | Process/window title |
**Config:** `window_title_bar top` + `window_title_bar_min_windows 1` (kitty 0.46.2)
## Notes
- `SUPER+CTRL+K` (keybind menu) does **not work** - the `sed` pipeline breaks.
The Lua config format makes this harder to grep; consider a different approach.
- Config migrated from `.conf` to `.lua` format (Hyprland 0.55+).
See `docs/tech/hyprland-lua-migration.md` for the migration mapping.
## Troubleshooting
| Issue | Check |
|-------|-------|
| Print key not working | `hyprctl binds | grep Print` |
| `SUPER+R` not working | `hyprctl binds | grep 'reload'` |
| Screenshots fail | `which grimblast satty slurp grim` |
| Clipboard empty | `echo test | wl-copy && wl-paste` |
## Satty Editor Shortcuts
| Action | Shortcut |
|--------|----------|
| Freehand | F |
| Rectangle | R |
| Ellipse | E |
| Line/Arrow | L |
| Text | T |
| Blur | B |
| Crop | C |
| Undo | Ctrl+Z |
| Redo | Ctrl+Shift+Z |
| Copy | Ctrl+C |
| Save | Ctrl+S |
| Quit | Esc or Ctrl+Q |
@@ -0,0 +1,163 @@
---
description: >-
Session record (2026-07-03): diagnosed a Remmina SIGSEGV on Wayland when
keymap was set, traced it to a missing NULL check on XOpenDisplay in
remmina-plugin-rdp, forked Remmina to gitlab.com/satware, built from
source, verified the fix, and submitted MR !2757 upstream.
tags:
- learning
- remmina
- wayland
- rdp
- crash-analysis
- gitlab
- upstream-contribution
last_updated: '2026-07-03'
---
# Remmina SIGSEGV on Wayland - diagnosis, fix, upstream MR - 2026-07-03
## Summary
Remmina crashed (SIGSEGV) every time the "Mothership" RDP profile was
selected. The root cause was a missing NULL check on `XOpenDisplay(0)` in
`remmina_get_rdp_kbd_remap()` (`plugins/rdp/rdp_plugin.c`), triggered only
when a `keymap` profile setting was non-empty (e.g. `Map Meta Keys`) and
the session was Wayland without accessible X11.
Forked Remmina to `gitlab.com/satware/Remmina`, built from source with
FreeRDP3, reproduced the crash, applied a 4-line fix, verified it, and
submitted merge request [!2757](https://gitlab.com/Remmina/Remmina/-/merge_requests/2757)
to the upstream project.
## Incident
| Field | Value |
|-------|-------|
| Symptom | Remmina closes immediately when selecting "Mothership" and clicking connect |
| Signal | SIGSEGV (segfault) |
| Crash location | `XKeysymToKeycode()` in `libX11.so.6`, called from `remmina-plugin-rdp.so` |
| Profile | `group_rdp_mothership_10-10-202-4.remmina` (server `10.10.202.4`) |
| Working profile | `srv-app-2` (`100.64.0.78`) - identical protocol, no crash |
## Diagnosis
### Stack trace (from coredumpctl)
```
#0 XKeysymToKeycode (libX11.so.6 + 0x92cd7)
#1 remmina-plugin-rdp.so + 0xff27
#2 remmina-plugin-rdp.so + 0x1296b
```
### Root cause
In `plugins/rdp/rdp_plugin.c`, function `remmina_get_rdp_kbd_remap()`:
```c
display = XOpenDisplay(0); // Returns NULL on Wayland
// NO NULL CHECK
XKeysymToKeycode(display, table[i]) // SIGSEGV - dereferences NULL
```
The function is only called when `keymap` is non-empty in the profile.
The working profile had `keymap=` (empty), which skipped the entire code
path. The crashing profile had `keymap=Map Meta Keys`.
### Environment
| Component | Version |
|-----------|---------|
| OS | Manjaro Linux, Wayland session (`XDG_SESSION_TYPE=wayland`) |
| Remmina | 1.4.43 (git n/a) |
| FreeRDP | 3.27.0 |
| Display | `DISPLAY=:0` (Xwayland) but `XOpenDisplay(0)` fails from RDP worker thread |
### Key config difference
| Setting | Mothership (crashes) | srv-app-2 (works) |
|---------|---------------------|-------------------|
| `keymap` | `Map Meta Keys` | (empty) |
## Fix
4-line addition in `plugins/rdp/rdp_plugin.c`, function `remmina_get_rdp_kbd_remap()`:
```diff
display = XOpenDisplay(0);
+if (!display) {
+ g_free(rdp_kbd_remap);
+ return NULL;
+}
for (i = 0; table[i] > 0; i += 2) {
```
The caller at line ~2148 already checks `if (rdp_kbd_remap != NULL)` before
use, so returning NULL causes graceful degradation (empty
`KeyboardRemappingList`) instead of a crash.
## Verification
| Test | Result |
|------|--------|
| Reproduce crash (unpatched, `keymap=Map Meta Keys`) | SIGSEGV - new coredump at 12:05:54 |
| Apply fix, rebuild, same profile | No crash - exit code 0, no new coredump |
| Debug log after fix | `rdp_keyboard_remapping_list:` (empty, as expected) |
## Local workaround (applied)
| Item | Value |
|------|-------|
| Mothership profile `keymap` | Set to empty (`keymap=`) as safe setting |
| Patched plugin | `~/.config/remmina/plugins/remmina-plugin-rdp.so` (loads before system plugin) |
| Source build | `~/external/remmina/` (branch `fix/rdp-xopendisplay-null-check`) |
The patched plugin in `~/.config/remmina/plugins/` protects the system
Remmina (`/usr/bin/remmina`) even if `keymap` is set to a non-empty value.
## Upstream contribution
### GitLab.com setup (one-time)
| Item | Value |
|------|-------|
| GitLab.com group | `gitlab.com/satware` (public, ID 136548341) |
| User | `ironmikechw` (ID 39970188, Owner of `satware` group) |
| PAT | Stored in `~/.env` as `GITLAB_COM_API_TOKEN` |
| glab CLI | Authenticated to both `gitlab.satware.com` and `gitlab.com` |
### Fork and MR
| Item | Value |
|------|-------|
| Upstream | `gitlab.com/Remmina/Remmina` (canonical, project ID 7153509) |
| Fork | `gitlab.com/satware/Remmina` (project ID 84057632) |
| Local clone | `~/external/remmina/` with `upstream` remote added |
| Build | `cmake -Bbuild -H. -DCMAKE_BUILD_TYPE=Debug -DWITH_FREERDP3=ON` |
| Branch | `fix/rdp-xopendisplay-null-check` |
| Commit | `e6084bd7f` - "rdp: fix SIGSEGV when XOpenDisplay returns NULL on Wayland" |
| MR | [!2757](https://gitlab.com/Remmina/Remmina/-/merge_requests/2757) (opened, target: master) |
### Build notes
- CMake flag `-DWITH_FREERDP3=ON` is required (default is OFF/FreeRDP2)
- All build deps present on this workstation (FreeRDP3 3.27.0, GTK3 3.24.52, etc.)
- Build time: ~30 seconds (incremental, 16 cores)
- Plugin loads from `~/.config/remmina/plugins/` (alt dir, checked before system)
## Files touched
| File | Change |
|------|--------|
| `~/.local/share/remmina/group_rdp_mothership_10-10-202-4.remmina` | `keymap=Map Meta Keys` -> `keymap=` (safe setting) |
| `~/.config/remmina/plugins/remmina-plugin-rdp.so` | Patched plugin (built from source) |
| `~/external/remmina/plugins/rdp/rdp_plugin.c` | 4-line NULL check fix (committed + pushed) |
| `~/.env` | `GITLAB_COM_API_TOKEN` added (for glab CLI) |
| `~/.config/glab-cli/config.yml` | gitlab.com host added (glab auth login) |
## References
- MR: https://gitlab.com/Remmina/Remmina/-/merge_requests/2757
- Fork: https://gitlab.com/satware/Remmina
- Upstream: https://gitlab.com/Remmina/Remmina
- CONTRIBUTING.md: fork-and-pull model on GitLab
@@ -0,0 +1,208 @@
---
description: >-
Session record (2026-07-06): triaged Caddy journald warnings on
onlyoffice.localhost/mcp showing "context canceled" SSE aborts (~1.5ms)
from opencode 1.17.13 MCP client against the OnlyOffice MCP server on
:3847. Verified upstream liveness, opened GitLab issue #92 in
satware/mcp/onlyoffice, and documented the Caddy reverse-proxy as a
manual override.
tags:
- learning
- caddy
- onlyoffice
- mcp
- sse
- reverse-proxy
- investigation
last_updated: '2026-07-06'
---
# Caddy "context canceled" on onlyoffice.localhost/mcp - investigation - 2026-07-06
## Summary
Caddy (systemd `caddy.service`) on `mw-manjaro-pf` is emitting a high
volume of `warn`-level journald entries: `aborting with incomplete
response ... error: "reading: context canceled"` for `GET /mcp` requests
on `https://onlyoffice.localhost`. Each abort fires ~1.5ms after the
request is forwarded to the upstream `localhost:3847` (OnlyOffice MCP
server). The upstream is alive and correctly rejects non-SSE GETs with
HTTP 406, so this is a stream-lifecycle issue, not a server-down issue.
Investigation handed off to the OnlyOffice MCP repo as GitLab issue #92.
This workstation's Caddy reverse-proxy config is now recorded as a manual
override (not Ansible-managed).
## Incident
| Field | Value |
|-------|-------|
| Symptom | Repeated `context canceled` warnings in `journalctl -u caddy` |
| Caddy site | `https://onlyoffice.localhost` -> `reverse_proxy localhost:3847` |
| Upstream | `localhost:3847` (OnlyOffice MCP server) |
| Request | `GET /mcp` with `Accept: text/event-stream` |
| Client | `opencode/1.17.13` (MCP streamable-HTTP transport) |
| MCP protocol | `2025-11-25` |
| Abort duration | ~1.5ms (request forwarded, then read context canceled) |
| Frequency | Multiple per minute, across distinct `Mcp-Session-Id` values |
## Evidence
### Caddy log sample (recurring)
```json
{
"level": "warn",
"logger": "http.handlers.reverse_proxy",
"msg": "aborting with incomplete response",
"upstream": "localhost:3847",
"duration": 0.00173631,
"request": {
"method": "GET",
"host": "onlyoffice.localhost",
"uri": "/mcp",
"headers": {
"Accept": ["text/event-stream"],
"Mcp-Protocol-Version": ["2025-11-25"],
"Mcp-Session-Id": ["a5e859b4-01f1-4c24-81bb-78ee02d74357"],
"User-Agent": ["opencode/1.17.13"],
"Via": ["1.1 Caddy"]
}
},
"error": "reading: context canceled"
}
```
Observed `Mcp-Session-Id` values (each retried over several minutes):
`a5e859b4...`, `4bfbb912...`, `3c4a0454...`, `08397c3d...`,
`ed762f08...`, `b0fae341...`.
### Upstream liveness verification
```bash
$ ss -tlnp | grep :3847
LISTEN 0 4096 0.0.0.0:3847 0.0.0.0:*
$ curl -sS -o /dev/null -w "HTTP %{http_code} in %{time_total}s\n" \
--max-time 3 http://localhost:3847/mcp
HTTP 406 in 0.004665s
```
HTTP 406 is expected for a plain GET without the required SSE headers.
The MCP server is alive and rejecting non-SSE requests correctly.
## Diagnosis
### Root cause (not yet confirmed - under investigation)
Five candidate hypotheses, listed in the GitLab issue. The leading
suspect is **client-side disconnect**: opencode 1.17.13 opens the SSE
stream then immediately closes it (the ~1.5ms duration is too short for
a genuine read). Secondary suspects are server-side stream teardown,
MCP protocol-version mismatch (`2025-11-25`), Caddy HTTP/1.1 framing of
SSE, or a client session-pool bug creating and abandoning sessions.
### Why this workstation's concern
The Caddy reverse-proxy is the boundary that surfaces the symptom. Even
if the root cause is client- or server-side, the local config matters
because:
1. Caddy logs are being polluted with warn-level noise (masks real errors).
2. The reverse-proxy block has no SSE-specific tuning (`flush_interval`,
explicit HTTP/1.1 transport) that could mask or mitigate upstream
misbehavior.
3. The Caddy config at `/etc/caddy/conf.d/localhost-dev.conf` is **not**
Ansible-managed by this repo - it is a manual override that must be
recorded (see `docs/tech/manual-overrides.md`).
## Environment
| Component | Version / Value |
|-----------|----------------|
| Host | `mw-manjaro-pf` (mw-pfeddersheim-workstation) |
| OS | Manjaro Linux, Wayland session |
| Caddy | systemd `caddy.service`, active since 2026-07-02 |
| Caddy config | `/etc/caddy/Caddyfile` + `/etc/caddy/conf.d/localhost-dev.conf` |
| TLS cert | mkcert pair at `/etc/caddy/localhost{,-key}.pem` |
| Upstream | `localhost:3847` (OnlyOffice MCP server, process TBD) |
| MCP client | `opencode/1.17.13` |
| MCP protocol | `2025-11-25` (streamable HTTP transport) |
## *.localhost sites configured
All defined in `/etc/caddy/conf.d/localhost-dev.conf` (14 sites total):
| Site | Backend / Handler |
|------|-------------------|
| `mcp.localhost` | `reverse_proxy localhost:50880` |
| `artifacts.localhost` | `file_server browse` root `/var/www/artifacts` |
| `onlyoffice.localhost` | `reverse_proxy localhost:3847` (subject of this issue) |
| `project-1.localhost` ... `project-10.localhost` | `respond "project-N - placeholder"` (10 reserved) |
| `demo.satware.com.localhost` | `reverse_proxy localhost:38081` (webdevops/php-apache-dev container) |
## Handoff
### GitLab issue
| Item | Value |
|------|-------|
| Project | `satware/mcp/onlyoffice` (`gitlab.satware.com`) |
| Issue | [#92](https://gitlab.satware.com/satware/mcp/onlyoffice/-/work_items/92) |
| Title | Investigation: Caddy reports 'context canceled' on onlyoffice.localhost/mcp SSE stream (~1.5ms aborts) |
| Labels | `bug`, `investigation`, `mcp` |
| State | open |
The issue body contains the full evidence, 5 hypotheses, 7 investigation
tasks, and a proposed Caddy mitigation (`flush_interval -1` +
`transport http { versions 1.1 }`).
### Next actions (assigned to OnlyOffice MCP repo)
1. Identify the process listening on `:3847` (`sudo ss -tlnp | grep 3847`).
2. Collect server-side logs for the `Mcp-Session-Id` values cited above.
3. Reproduce with `curl -N -H "Accept: text/event-stream" -H "Mcp-Protocol-Version: 2025-11-25" https://onlyoffice.localhost/mcp`.
4. Check opencode 1.17.13 changelog for MCP SSE session bugs.
5. Verify Caddy `reverse_proxy` SSE tuning (proposed block in issue #92).
6. Confirm whether `notifications/initialized` round-trip completes.
7. Log the negotiated MCP protocol version server-side.
## Local documentation updates
| File | Change |
|------|-------|
| `docs/tech/manual-overrides.md` | Added row for `/etc/caddy/` config (not Ansible-managed) |
| `docs/tech/stack.md` | Added "Local Dev Services" section listing Caddy + `*.localhost` sites |
| `CHANGELOG.md` | Added `[Unreleased] -> Added` entry |
| GitLab issue #92 | Created with full evidence + hypotheses + tasks |
## Proposed Caddy mitigation (to test on this workstation)
```caddyfile
https://onlyoffice.localhost {
tls /etc/caddy/localhost.pem /etc/caddy/localhost-key.pem
reverse_proxy localhost:3847 {
flush_interval -1
transport http {
versions 1.1
}
}
}
```
`flush_interval -1` disables Caddy's buffering so SSE events flush to the
client immediately; `transport http { versions 1.1 }` pins the upstream
leg to HTTP/1.1 (Caddy logs already show HTTP/1.1 for the upstream, this
makes it explicit and avoids HTTP/2 SSE framing surprises).
Not applied yet - pending GitLab issue #92 resolution to avoid masking
the root cause.
## References
- GitLab issue: https://gitlab.satware.com/satware/mcp/onlyoffice/-/work_items/92
- Caddy config: `/etc/caddy/conf.d/localhost-dev.conf`
- Local skill: `caddy` (`~/.config/opencode/skills/caddy/SKILL.md`)
- MCP transport spec: https://modelcontextprotocol.io/specification/2025-11-25/basic/transports
- Manual overrides: `docs/tech/manual-overrides.md`
- Software stack: `docs/tech/stack.md`
-64
View File
@@ -1,64 +0,0 @@
---
title: "Neovim v0.12.2 Cheatsheet"
author: "mw-pfeddersheim-workstation"
date: "June 2026"
---
# Neovim Cheatsheet
**Version:** v0.12.2 (LuaJIT 2.1) **Config:** `~/.config/nvim/init.lua`
## Search
### Buffer Search (current file)
| Command | Action |
|---------|--------|
| `/pattern` | Search forward |
| `?pattern` | Search backward |
| `n` | Next match (forward) |
| `N` | Previous match (backward) |
### File Search (across files)
| Command | Action |
|---------|--------|
| `:grep pattern` | Search current directory with ripgrep |
| `:grep pattern /path/to/dir` | Search specific directory |
| `:cfirst` | Jump to first match |
| `:cnext` / `:cprev` | Next / previous match |
| `:copen` | Open quickfix window with all results |
| `:cclose` | Close quickfix window |
## Editing
| Command | Action |
|---------|--------|
| `D` | Delete from cursor to end of line |
| `d$` | Delete to end of line (same as `D`) |
| `dd` | Delete entire line |
| `C` | Change from cursor to end of line (delete + insert mode) |
## Text Objects
Delete or operate on structured text by type:
| Command | Action |
|---------|--------|
| `di{` | Delete **inside** `{}` (keeps braces) |
| `da{` | Delete **a** `{}` (removes braces too) |
| `di"` | Delete inside double quotes |
| `da"` | Delete a double-quoted section |
| `di(` | Delete inside parentheses |
| `da(` | Delete a parenthesized section |
| `di[` | Delete inside brackets |
| `da[` | Delete a bracketed section |
| `di<` | Delete inside angle brackets |
| `da<` | Delete an angle-bracketed section |
**Pattern:** `d` (delete) + `i` (inside) / `a` (around) + `{type}`
**Also works with:**
- `v` + text object — select (e.g. `vi{` selects inside braces)
- `y` + text object — yank/copy (e.g. `ya{` copies including braces)
- `c` + text object — change (e.g. `ci{` deletes + enters insert mode)
+13 -1
View File
@@ -27,6 +27,7 @@
- `himalaya` → IMAP/SMTP passwords via `secret-tool lookup email <addr>` - `himalaya` → IMAP/SMTP passwords via `secret-tool lookup email <addr>`
- `ssh-agent` → SSH key passphrases via `secret-tool lookup ... ssh-key <path>` - `ssh-agent` → SSH key passphrases via `secret-tool lookup ... ssh-key <path>`
- `git-credential-libsecret` → Git passwords via libsecret - `git-credential-libsecret` → Git passwords via libsecret
(github.com via `gh`, gitlab.satware.com via `glab`, **git.satware.ai via libsecret PAT**)
- `JetBrains IDEs` → auto-detect D-Bus secrets service - `JetBrains IDEs` → auto-detect D-Bus secrets service
## Quick Verification ## Quick Verification
@@ -42,6 +43,7 @@ rbw get "SSH Key: id_ed25519" # should return "SSH gitlab.satware.com"
# Can apps read secrets? # Can apps read secrets?
secret-tool lookup application ssh-agent service ssh ssh-key /home/mw/.ssh/id_ed25519 secret-tool lookup application ssh-agent service ssh ssh-key /home/mw/.ssh/id_ed25519
secret-tool lookup application git service gitlab.satware.com secret-tool lookup application git service gitlab.satware.com
secret-tool lookup server git.satware.ai protocol https user mw # Gitea PAT (git-credential-libsecret schema)
secret-tool lookup application nextcloud service cloud.satware.com user mw secret-tool lookup application nextcloud service cloud.satware.com user mw
``` ```
@@ -51,7 +53,7 @@ secret-tool lookup application nextcloud service cloud.satware.com user mw
|----------|---------|---------| |----------|---------|---------|
| **SSH passphrases** | id_ed25519, id_ed25519_ja_manjaro | BW + GK | | **SSH passphrases** | id_ed25519, id_ed25519_ja_manjaro | BW + GK |
| **SSH host passwords** | b0t@192.168.0.141 | BW + GK | | **SSH host passwords** | b0t@192.168.0.141 | BW + GK |
| **Git tokens** | GitLab PAT, GitHub token | BW + GK | | **Git tokens** | GitLab PAT, GitHub token, Gitea PAT (git.satware.ai) | GK (BW pending) |
| **Remmina** | 5 VNC/RDP passwords | BW + GK | | **Remmina** | 5 VNC/RDP passwords | BW + GK |
| **Nextcloud** | 3 instance passwords | BW + GK | | **Nextcloud** | 3 instance passwords | BW + GK |
| **Browser crypto** | Chrome, Brave, Chromium safe storage | BW + GK | | **Browser crypto** | Chrome, Brave, Chromium safe storage | BW + GK |
@@ -114,3 +116,13 @@ systemctl --user restart gnome-keyring-daemon.service # if D-Bus secrets missin
- Data file preserved at `~/.local/share/kwalletd/kdewallet.kwl` (backup) - Data file preserved at `~/.local/share/kwalletd/kdewallet.kwl` (backup)
- PAM references already commented out - PAM references already commented out
- No longer used by any application - No longer used by any application
## Gitea PAT (git.satware.ai)
- Cached in gnome-keyring via `git credential approve` (schema `org.git.Password`, attributes: `protocol=https, server=git.satware.ai, user=mw`)
- Git reads it via `credential.helper=libsecret` (global; no host-specific `store` override)
- tea reads its own copy from `~/.config/tea/config.yml` (tea has no `auth git-credential` subcommand; file hardened to `chmod 600`)
- Scopes: `write:repository`, `read:user`. Token lacks admin scope - **rotation must be done via web UI** at https://git.satware.ai/user/settings/applications
- TODO (rotate): create new PAT with `write:repository, read:user, write:admin`; store in Bitwarden entry `Gitea PAT: git.satware.ai` + keyring + tea; revoke old token via API (now possible with admin scope); update this section
- TODO (Bitwarden): create Bitwarden entry `Gitea PAT: git.satware.ai` (username `mw`, uri `https://git.satware.ai`) - blocked on rbw pinentry not supporting non-interactive password entry; create manually via `rbw add` or Bitwarden web UI
- Tracked in Gitea issue #1: https://git.satware.ai/infrastructure/mw-pfeddersheim-workstation/issues/1
-102
View File
@@ -1,102 +0,0 @@
# Screenshot Cheatsheet — Hyprland + grimblast + satty
## Quick Reference (German Keyboard Layout)
| Key Combo | Action | Tool | Pipeline |
|-----------|--------|------|----------|
| `Print` | Select area → save to file + clipboard | grimblast | area → copysave |
| `SUPER + Print` | Active window → save to file + clipboard | grimblast | active window → copysave |
| `SUPER + SHIFT + Print` | Full monitor → save to file + clipboard | grimblast | output → copysave |
| `SUPER + ALT + Print` | Select area → open in satty for annotation | grim+satty | area → satty editor |
## Test Checklist
Run through these to verify everything works:
### Test 1: Area Screenshot (Print)
1. Press `Print`
2. Drag to select a region
3. Expected: Screenshot saved to `~/Pictures/` AND copied to clipboard
4. Verify: Paste clipboard into a test doc
### Test 2: Current Window (SUPER+Print)
1. Focus any window
2. Press `SUPER+Print`
3. Expected: That window captured, saved + copied
### Test 3: Full Monitor (SUPER+SHIFT+Print)
1. Press `SUPER+SHIFT+Print`
2. Expected: Current monitor captured, saved + copied
### Test 4: Annotate in Satty (SUPER+ALT+Print)
1. Press `SUPER+ALT+Print`
2. Drag to select a region
3. Expected: Satty window opens with the screenshot
4. Try these Satty actions:
- Freehand drawing (left toolbar)
- Rectangle/Arrow annotations
- Blur/redact sections
- Copy annotated result to clipboard
- Save annotated result to file
5. Exit Satty with `Esc` or `Ctrl+Q`
## Manual CLI Commands
If keybindings fail, test tools directly:
```bash
# Capture area and save to specific file
grim -g "$(slurp)" ~/Pictures/test-area.png
# Capture area and pipe to satty for editing
grim -g "$(slurp)" - | satty -f -
# Capture full screen and pipe to satty
grim - | satty -f -
# Copy area screenshot to clipboard
grim -g "$(slurp)" - | wl-copy
# grimblast manual modes
grimblast copysave area # area
grimblast copysave active # current window
grimblast copysave output # current monitor
grimblast save area ~/Pictures/test-grimblast.png # save only
```
## Satty Editor Shortcuts
| Action | Shortcut |
|--------|----------|
| Freehand | `F` |
| Rectangle | `R` |
| Ellipse | `E` |
| Line/Arrow | `L` |
| Text | `T` |
| Blur | `B` |
| Crop | `C` |
| Undo | `Ctrl+Z` |
| Redo | `Ctrl+Shift+Z` |
| Copy to clipboard | `Ctrl+C` |
| Save to file | `Ctrl+S` |
| Save As | `Ctrl+Shift+S` |
| Quit | `Esc` or `Ctrl+Q` |
## Dependencies
| Tool | Purpose | Status |
|------|---------|--------|
| grim | Wayland screenshot capture | Installed |
| slurp | Region/window selection | Installed |
| wl-clipboard | Clipboard support | Installed |
| satty | Annotation editor | Installed |
| grimblast | Hyprland screenshot helper | Installed |
| hyprshot | Alternative screenshot tool | Installed (not used in keybinds) |
## Troubleshooting
- **Print key not working**: Verify binding with `hyprctl binds | grep Print`
- **satty won't open**: Check `which satty` and `echo $XDG_SESSION_TYPE` (must be wayland)
- **slurp selector invisible**: Check if `grim` and `slurp` are in PATH
- **Screenshots not saving**: Check `~/Pictures/` directory exists
- **Clipboard empty**: Verify `wl-copy` and `wl-paste` work (`echo test | wl-copy && wl-paste`)
+6 -1
View File
@@ -6,7 +6,7 @@ tags:
- manual-overrides - manual-overrides
- infrastructure - infrastructure
- configuration - configuration
last_updated: '2026-06-17' last_updated: '2026-07-21'
--- ---
# Manual System Overrides # Manual System Overrides
@@ -22,5 +22,10 @@ This document tracks all persistent system changes implemented manually that are
| Date | Change | Rationale | Ansible Status | | Date | Change | Rationale | Ansible Status |
|------|--------|-----------|----------------| |------|--------|-----------|----------------|
| 2026-07-21 | Added `agent0.localhost` (-> `reverse_proxy 192.168.0.141:8090`, `flush_interval -1`) in dedicated file `/etc/caddy/conf.d/agent0.localhost.conf`. First non-localhost backend (remote LAN host running a uvicorn app). Regenerated mkcert cert to add explicit `agent0.localhost` SAN; cert now has 20 SANs total, valid until 2028-10-21. Old cert/key backed up as `localhost{,-key}.pem.bak.<ts>`. Total `*.localhost` sites now 18. | User request to expose the remote agent backend on local HTTPS. Key learning: the `*.localhost` wildcard is NOT honored by curl/system trust even for single-label subdomains - `.localhost` is a special-use TLD (RFC 6761), so every subdomain needs an explicit SAN. This corrects the prior assumption that single-label subdomains were covered by the wildcard. | Same as parent Caddy row - candidate for Ansible role when issue #92 resolves |
| 2026-07-12 | Regenerated mkcert cert at `/etc/caddy/localhost{,-key}.pem` to add explicit SANs for `platform.localhost`, `packages.localhost`, and `onlyoffice.docs.localhost` (the latter was pre-existing in Caddy config but missing from the cert, causing TLS validation failures). Cert now has 19 SANs total, valid until 2028-10-12. | `onlyoffice.docs.localhost` is a multi-label subdomain not covered by `*.localhost` wildcard. Required explicit SAN. | Same as parent Caddy row |
| 2026-07-12 | Added `platform.localhost` (-> `localhost:10080`) and `packages.localhost` (-> `localhost:20080`) to `/etc/caddy/conf.d/localhost-dev.conf`. Docker port mappings: `~/internal/amicron-platform/docker-compose.override.yml` `10080:80`, `~/internal/satis/docker-compose.yml` nginx `20080:80`. Both upstreams are plain HTTP on high ports; Caddy terminates TLS. Also documented `onlyoffice.docs.localhost` (pre-existing in config, was undocumented). Total sites now 17. | Local HTTPS dev for amicron-platform (ERP), satis (Composer package repository), and shared Firebird 3.0.14 database. The three form the local E2E test triangle: `platform.localhost` (ERP) -> `packages.localhost` (Satis) -> Firebird (token validation). Mirrors the production `platform.auc.de` + `packages.auc.de` + shared Firebird setup. | Same as parent Caddy row - candidate for Ansible role when issue #92 resolves |
| 2026-07-06 | Caddy reverse-proxy + mkcert TLS at `/etc/caddy/` (`Caddyfile` + `conf.d/localhost-dev.conf` + `localhost{,-key}.pem`) | Local HTTPS dev for 14 `*.localhost` sites (mcp, artifacts, onlyoffice, demo.satware.com clone, 10 placeholders). Caddy runs as systemd `caddy.service` on port 443. NOT managed by this repo - no `caddy` Ansible role exists. The `onlyoffice.localhost` site (-> `localhost:3847`) is emitting `context canceled` SSE aborts; see `docs/learnings/2026-07-06-caddy-onlyoffice-mcp-sse-investigation.md` and GitLab issue [satware/mcp/onlyoffice#92](https://gitlab.satware.com/satware/mcp/onlyoffice/-/work_items/92). | Candidate for Ansible role (`caddy` + `mkcert`); defer until issue #92 resolves to avoid masking root cause |
| 2026-07-03 | Patched `remmina-plugin-rdp.so` in `~/.config/remmina/plugins/` | Remmina 1.4.43 crashes (SIGSEGV) on Wayland when `keymap` is set in a profile. Built from `~/external/remmina/` fork with NULL check fix. Alt plugin dir loads before system plugin. MR !2757 submitted upstream. See `docs/learnings/2026-07-03-remmina-wayland-crash-fix.md`. | Remove when upstream fix is released and packaged |
| 2026-06-17 | Discovered and deleted `br_vm_internal` bridge (10.10.2.0/24) | Externally-created bridge, no NM config file, no VMs attached. Origin unknown — likely ad-hoc `nmcli con add` or manual `brctl` session (Jun 10). Traffic-shaping qdisc (`htb`) suggests prior VM network isolation attempt. Deleted via `nmcli con delete` + `ip link delete`. | N/A (removed) | | 2026-06-17 | Discovered and deleted `br_vm_internal` bridge (10.10.2.0/24) | Externally-created bridge, no NM config file, no VMs attached. Origin unknown — likely ad-hoc `nmcli con add` or manual `brctl` session (Jun 10). Traffic-shaping qdisc (`htb`) suggests prior VM network isolation attempt. Deleted via `nmcli con delete` + `ip link delete`. | N/A (removed) |
| 2026-04-02 | Moved LLM models to `/home/mw/models/` (SATA SSD) with symlinks | Free root NVMe space (93%→87%, +25G freed) | Not yet | | 2026-04-02 | Moved LLM models to `/home/mw/models/` (SATA SSD) with symlinks | Free root NVMe space (93%→87%, +25G freed) | Not yet |
+22
View File
@@ -0,0 +1,22 @@
# Memory — mw-pfeddersheim-workstation
> **Status**: 64 GiB migrated to `homeoffice` on 2026-07-13.
## Current Configuration
4x 8 GiB DDR4-3000 DIMMs = **32 GiB total**, dual-channel (A/B).
| Slot | Size | Type | Speed | Channel |
|------|------|------|-------|---------|
| DIMM_A1 | 8 GiB | DDR4 SDRAM | 3000 MT/s | BANK 0 |
| DIMM_A2 | 8 GiB | DDR4 UDIMM | 3000 MT/s | BANK 1 |
| DIMM_B1 | 8 GiB | DDR4 UDIMM | 3000 MT/s | BANK 2 |
| DIMM_B2 | 8 GiB | DDR4 UDIMM | 3000 MT/s | BANK 3 |
Note: DIMM_A1 reports "Unknown" form factor — different brand from the other three DIMMs.
## Migration History
| Date | Change |
|------|--------|
| 2026-07-13 | Removed 4x 16 GiB DDR4-2400 DIMMs (64 GiB) and transferred to `homeoffice`. Installed 4x 8 GiB DDR4-3000 DIMMs taken from `homeoffice` in exchange. |
+48 -1
View File
@@ -6,7 +6,7 @@ tags:
- software-stack - software-stack
- inventory - inventory
- tech-stack - tech-stack
last_updated: '2026-06-17' last_updated: '2026-07-12'
--- ---
# Software Stack - mw-pfeddersheim-workstation # Software Stack - mw-pfeddersheim-workstation
@@ -92,3 +92,50 @@ Packages previously listed as "Misc" reclassified to functional domains:
- **Ansible**: `/usr/bin/ansible` - **Ansible**: `/usr/bin/ansible`
- **Python**: `/usr/bin/python` - **Python**: `/usr/bin/python`
- **Docker**: `/usr/bin/docker` - **Docker**: `/usr/bin/docker`
## Local Dev Services (Manual - not Ansible-managed)
System-level services running on this workstation that are configured manually
outside this repo's Ansible roles. See `docs/tech/manual-overrides.md` for the
full override table and `docs/learnings/2026-07-06-caddy-onlyoffice-mcp-sse-investigation.md`
for the active Caddy/OnlyOffice investigation.
### Caddy (port 443, systemd `caddy.service`)
| Item | Value |
|------|-------|
| Package | `caddy` (pacman) |
| Service | `caddy.service` (enabled, runs as `caddy` user) |
| Config | `/etc/caddy/Caddyfile` + `/etc/caddy/conf.d/*.conf` (main site file `localhost-dev.conf`, plus per-service files like `agent0.localhost.conf`) |
| TLS cert | mkcert-generated pair at `/etc/caddy/localhost{,-key}.pem`; includes explicit SANs for all 20 hostnames, valid until 2028-10-21. The `*.localhost` wildcard is NOT honored by curl/system trust even for single-label subdomains like `agent0.localhost` (empirically verified 2026-07-21: `.localhost` is a special-use TLD per RFC 6761); every subdomain MUST be listed explicitly. Multi-label hosts like `onlyoffice.docs.localhost` additionally require explicit SANs because wildcards only cover one level. |
| Admin endpoint | Unix socket `/run/caddy/admin.socket` |
| Sites | 18 `*.localhost` virtual hosts (see table below) |
#### `*.localhost` sites
| Site | Backend / Handler | Notes |
|------|-------------------|-------|
| `mcp.localhost` | `reverse_proxy localhost:50880` | MCP server (node, pid 1167) |
| `artifacts.localhost` | `file_server browse` root `/var/www/artifacts` | Static artifacts |
| `onlyoffice.localhost` | `reverse_proxy localhost:3847` | OnlyOffice MCP server; emitting `context canceled` SSE aborts (issue [#92](https://gitlab.satware.com/satware/mcp/onlyoffice/-/work_items/92)) |
| `project-1.localhost` ... `project-10.localhost` | `respond "project-N - placeholder"` | 10 reserved placeholders |
| `demo.satware.com.localhost` | `reverse_proxy localhost:38081` | webdevops/php-apache-dev container |
| `platform.localhost` | `reverse_proxy localhost:10080` | amicron-platform Docker (Symfony 7.4 + Vue 3 + Firebird 3.0.14); `~/internal/amicron-platform` |
| `packages.localhost` | `reverse_proxy localhost:20080` | satis Docker (Composer package repository with token-based access control); `~/internal/satis` |
| `onlyoffice.docs.localhost` | `file_server` root `/home/mw/internal/onlyoffice/docs-site/dist` | Starlight static docs build |
| `agent0.localhost` | `reverse_proxy 192.168.0.141:8090` | First non-localhost backend (remote host on LAN, uvicorn app). Config in dedicated `/etc/caddy/conf.d/agent0.localhost.conf`. `flush_interval -1` enabled. |
Wildcard `*.localhost` only matches single-label subdomains (e.g. `mcp.localhost`)
AND is not honored by curl/system trust for the `.localhost` special-use TLD
(RFC 6761) - every subdomain needs an explicit SAN. Multi-label hosts like
`onlyoffice.docs.localhost` and `demo.satware.com.localhost` require explicit
SANs for both reasons.
### Useful Caddy commands
```bash
sudo caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile
sudo systemctl reload caddy
sudo journalctl -u caddy --no-pager -n 50
curl -sk https://onlyoffice.localhost/ping # test (skips cert verify)
```
-167
View File
@@ -1,167 +0,0 @@
---
title: "Yazi v26.5.6 Cheatsheet"
author: "mw-pfeddersheim-workstation"
date: "May 2026"
---
# Yazi Cheatsheet
**Version:** 26.5.6 (Arch Linux 2026-05-10) **Config:** `~/.config/yazi/`
## Quick Start
| Key | Action |
|-----|--------|
| `yazi` | Launch Yazi |
| `y` | Shell wrapper (cd persists on exit) |
| `q` | Quit normal (apply cwd) |
| `Q` | Quit without cwd change |
| `F1` | Show help |
## Navigation
| Key | Action |
|-----|--------|
| `h` | Parent directory |
| `l` | Enter dir / open file |
| `j` / `k` | Down / Up |
| `H` / `L` | History back / forward |
| `Enter` | Open hovered file |
| `Tab` | Toggle file details |
| `.` | Toggle hidden files |
| `~` | Home directory (DE: Shift+^+Space) |
| `g g` | Go to top |
| `G` | Go to bottom |
## Search
| Key | Action |
|-----|--------|
| `/` | Search forward |
| `?` | Search backward |
| `n` / `N` | Next / previous match |
| `f` | Interactive filter (fuzzy) |
| `S` | Search with fd |
## File Operations
| Key | Action |
|-----|--------|
| `Space` | Toggle selection |
| `v` | Visual mode range select |
| `Ctrl+A` | Select all |
| `Esc` | Clear selection |
| `y` | Yank (copy) |
| `p` | Paste |
| `X` | Cut |
| `x` | Undo cut |
| `D` | Delete to trash |
| `Shift+D` | Permanent delete |
| `a` | New file |
| `Shift+A` | New directory |
| `R` | Rename |
| `Shift+R` | Bulk rename |
| `O` | "Open with..." menu |
## Sorting (comma prefix)
| Key | Action |
|-----|--------|
| `, m` | Modified (newest) |
| `, M` | Modified reverse |
| `, c` | Created (newest) |
| `, C` | Created reverse |
| `, e` | Extension (alpha) |
| `, a` | Alphabetic |
| `, s` | Size (largest) |
| `, S` | Size (smallest, reverse) |
## Tabs
| Key | Action |
|-----|--------|
| `t` | New tab |
| `1` ... `9` | Switch to tab |
| `[` / `]` | Prev / next tab |
| `W` | Close tab |
## Shell & Commands
| Key | Action |
|-----|--------|
| `!` | Drop into shell here |
| `:` | Command line |
| `Ctrl+S` | Run shell command |
## Emit Commands (`:` prefix)
| Command | Action |
|---------|--------|
| `:cd <path>` | Change directory |
| `:reveal` | Reveal file in parent dir |
| `:tab_create` | Open new tab |
| `:tab_switch N` | Switch to tab N |
| `:quit` | Quit Yazi |
| `:yank` | Yank selected |
| `:paste` | Paste yanked |
| `:remove` | Trash |
| `:rename` | Rename hovered |
| `:shell <cmd>` | Run shell command |
## Power Tricks
### 1. Shell Wrapper (cd persists)
Use the `y` wrapper instead of raw `yazi` so your shell cds into the directory you navigated to on exit.
### 2. Clipboard on Yank (Wayland)
Bind `y` in `keymap.toml` to `wl-copy -t text/uri-list` then yank for system clipboard integration.
### 3. Git Root Jump
Bind `g r` to `ya emit cd "$(git rev-parse --show-toplevel)"`
### 4. Escape Closes Input
In `keymap.toml` input section: map `Esc` to `close` (skip vim mode).
### 5. Disable Image Previews
In `yazi.toml` `plugin` section: `preloaders = []` and `previewers = []`.
For network mounts: `url = /remote/** run = noop`.
### 6. Hostname in Header
In `init.lua`: `Header:children_add` with `user_name()` + `host_name()` spans.
### 7. Show Symlink Target in Status Bar
In `init.lua`: `Status:children_add` with `h.link_to`.
## Configuration Files
| File | Purpose |
|------|---------|
| `keymap.toml` | Custom key bindings |
| `yazi.toml` | Behavior, preview rules, openers |
| `theme.toml` | Colors and UI theme |
| `init.lua` | Lua startup script |
| `plugins/` | Plugin directory |
## Recommended Plugins
| Plugin | Purpose |
|--------|---------|
| `smart-enter` | One key: open file or enter dir |
| `smart-paste` | Paste without entering dir |
| `smart-tab` | New tab + enter hovered dir |
| `toggle-pane` | Maximize / hide preview pane |
| `full-border` | Full panel borders |
| `confirm-quit` | Confirm on multi-tab |
| `zoxide` | Zoxide dir jumping |
| `chmod` | Change file permissions |
## Daily Drill
| Area | Keys |
|------|------|
| **Nav** | `j/k` move / `l` enter / `h` back |
| **Files** | `Space` select / `y` copy / `p` paste / `X` cut |
| **Delete** | `D` trash / `R` rename / `a` create |
| **Search** | `/` search / `f` filter / `g` top / `G` bottom |
| **Tabs** | `t` new / `1-9` switch / `W` close |
| **Misc** | `!` shell / `q` quit / `F1` help |