Compare commits
9
Commits
07bd3f8699
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cd63df4f59 | ||
|
|
c67dd74e0b | ||
|
|
cbe24c03df | ||
|
|
269079df34 | ||
|
|
b888ef90c4 | ||
|
|
441e28bda3 | ||
|
|
ce99f58374 | ||
|
|
2b6ce0d635 | ||
|
|
d72e3782e8 |
+13
-6
@@ -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 ----
|
||||||
--------------------------------
|
--------------------------------
|
||||||
|
|||||||
@@ -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`
|
||||||
@@ -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)
|
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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,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 |
|
||||||
|
|||||||
@@ -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
@@ -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)
|
||||||
|
```
|
||||||
|
|||||||
@@ -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 |
|
|
||||||
Reference in New Issue
Block a user