From 227ea2371b2c4a2fe88e9fb536fcea06ffdf1f19 Mon Sep 17 00:00:00 2001 From: Bas Grolleman Date: Sat, 10 Oct 2026 11:10:33 +0200 Subject: [PATCH] Cleanup dotfiles: niri float rules, tmux agent status, noctalia, claude settings Co-Authored-By: Claude Sonnet 5.5 --- CHANGELOG.md | 8 +++ CLAUDE.md | 9 ++-- claude/settings.json | 57 ++++++++++++++++------ niri/cfg/rules.kdl | 7 +++ noctalia/settings.json | 108 +++++++++++++++++++++-------------------- tmux/tmux.conf | 21 ++++---- 6 files changed, 130 insertions(+), 80 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 651ccc0..f4ffa11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 2026-10-10 (cleanup) + +- Niri: floating windows open bottom-left by default; Picture-in-picture floats at a fixed offset. +- Noctalia v4 `settings.json`: move workspaces and system monitor to the right, add taskbar, enable idle. +- tmux: add per-window agent status indicator, 2s status refresh and a Prefix+Tab window switcher popup. +- Claude settings: pin model to sonnet, add herdr SessionStart hook, humanizer and ui-ux-pro-max plugins. +- CLAUDE.md: document claude/fish/kanshi linking, `workspaces.kdl` and the tmux helper script living outside the repo. + ## 2026-10-10 - Fix niri login: Mod+T bind had three actions, niri rejected the config and fell back to defaults (no bar, no kanshi). diff --git a/CLAUDE.md b/CLAUDE.md index cd8801f..ff574cd 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -8,7 +8,7 @@ Personal dotfiles for a Linux desktop, currently running **Niri** (Wayland compo ## Deployment -Configs are deployed by symlinking into `~/.config/` and `~/.profile`: +Configs are deployed by symlinking into `~/.config/`, `~/.profile` and `~/.claude/settings.json` (fish is linked per file): ```bash bash ~/.dotfiles/setup.sh @@ -35,13 +35,14 @@ This installs ansible if missing, then runs the playbook. Tasks are split by cat - `display.kdl` — monitor layout and scaling - `autostart.kdl` — apps launched on compositor start - `rules.kdl` — window-specific rules +- `workspaces.kdl` — named workspaces - `animation.kdl`, `misc.kdl` — tweaks Edit the relevant split file, not `config.kdl` itself. ### Noctalia (desktop shell / bar) Runs **Noctalia v5** (`noctalia`, native). Config is `noctalia/config.toml` (TOML, hot-reloaded); validate with `noctalia config validate`. -`noctalia/settings.json` is the legacy v4 config. See `docs/noctalia-v5.md` for details and `CHANGELOG.md` for history. +`noctalia/settings.json` is the legacy v4 config (kept for rollback, still tweaked occasionally). See `docs/noctalia-v5.md` for details and `CHANGELOG.md` for history. ### Neovim Uses **LazyVIM** framework. Entry point is `nvim/init.lua` which bootstraps lazy.nvim via `nvim/lua/config/lazy.lua`. @@ -53,13 +54,15 @@ Uses **LazyVIM** framework. Entry point is `nvim/init.lua` which bootstraps lazy LazyVIM handles most plugin management; only deviations from LazyVIM defaults need entries in `lua/plugins/`. ### tmux -`tmux/tmux.conf` + catppuccin theme as a git submodule at `tmux/plugins/catppuccin/tmux`. After cloning, initialize the submodule: +`tmux/tmux.conf` + catppuccin theme as a git submodule at `tmux/plugins/catppuccin/tmux`. The agent-status indicators call `~/.local/bin/tmux-window-agent-status`, which is **not** in this repo. After cloning, initialize the submodule: ```bash git submodule update --init ``` ### Shell / profile +`fish/` holds the fish config (`config.fish`, `conf.d/ssh-keychain.fish`); machine-specific vars go in untracked `~/.config/fish/local.fish`. + `profile` is symlinked to `~/.profile`. It sets up SSH keys via `keychain` and defines the `notes` alias (attaches/creates a tmux session with nvim opening `~/Notes/Personal`). `zoxide.bash` provides shell integration for zoxide (directory jumping) — sourced separately, not via `profile`. diff --git a/claude/settings.json b/claude/settings.json index 1bed264..cf808c5 100644 --- a/claude/settings.json +++ b/claude/settings.json @@ -2,17 +2,8 @@ "permissions": { "defaultMode": "auto" }, + "model": "sonnet", "hooks": { - "Stop": [ - { - "hooks": [ - { - "type": "command", - "command": "notify-send 'Claude' 'Task complete' --icon=dialog-information 2>/dev/null || true" - } - ] - } - ], "Notification": [ { "hooks": [ @@ -22,6 +13,28 @@ } ] } + ], + "SessionStart": [ + { + "matcher": "*", + "hooks": [ + { + "type": "command", + "command": "bash '/home/bgrolleman/.claude/hooks/herdr-agent-state.sh' session", + "timeout": 10 + } + ] + } + ], + "Stop": [ + { + "hooks": [ + { + "type": "command", + "command": "notify-send 'Claude' 'Task complete' --icon=dialog-information 2>/dev/null || true" + } + ] + } ] }, "statusLine": { @@ -30,20 +43,34 @@ }, "enabledPlugins": { "frontend-design@claude-plugins-official": true, + "humanizer@humanizer": true, "lua-lsp@claude-plugins-official": true, - "ponytail@ponytail": true + "ponytail@ponytail": true, + "ui-ux-pro-max@ui-ux-pro-max-skill": true }, "extraKnownMarketplaces": { + "caveman": { + "source": { + "source": "github", + "repo": "juliusbrussee/caveman" + } + }, + "humanizer": { + "source": { + "source": "github", + "repo": "blader/humanizer" + } + }, "ponytail": { "source": { "source": "github", "repo": "DietrichGebert/ponytail" } }, - "caveman": { + "ui-ux-pro-max-skill": { "source": { "source": "github", - "repo": "juliusbrussee/caveman" + "repo": "nextlevelbuilder/ui-ux-pro-max-skill" } } }, @@ -59,10 +86,10 @@ "voiceEnabled": true, "mcpServers": { "comfyui-image-gen": { - "command": "/home/bgrolleman/Project/ComfyUI/.venv/bin/python", "args": [ "/home/bgrolleman/Project/ComfyUI/mcp_server.py" - ] + ], + "command": "/home/bgrolleman/Project/ComfyUI/.venv/bin/python" } } } diff --git a/niri/cfg/rules.kdl b/niri/cfg/rules.kdl index 4dd5bec..321386c 100644 --- a/niri/cfg/rules.kdl +++ b/niri/cfg/rules.kdl @@ -1,6 +1,7 @@ window-rule { geometry-corner-radius 5 // Set every window radius to 20 clip-to-geometry true + default-floating-position x=10 y=10 relative-to="bottom-left" } // if you use steam you will probably like these @@ -16,6 +17,12 @@ open-focused false } + window-rule { + match title="^Picture-in-picture$" + open-floating true + default-floating-position x=50 y=50 relative-to="bottom-left" + } + layer-rule { match namespace="^noctalia-wallpaper*" place-within-backdrop true diff --git a/noctalia/settings.json b/noctalia/settings.json index c697527..f6886b2 100644 --- a/noctalia/settings.json +++ b/noctalia/settings.json @@ -87,6 +87,22 @@ "id": "Clock", "tooltipFormat": "HH:mm ddd, MMM dd", "useCustomFont": false + }, + { + "compactMode": false, + "hideMode": "hidden", + "hideWhenIdle": true, + "id": "MediaMini", + "maxWidth": 500, + "panelShowAlbumArt": true, + "scrollingMode": "hover", + "showAlbumArt": true, + "showArtistFirst": true, + "showProgressRing": true, + "showVisualizer": false, + "textColor": "none", + "useFixedWidth": false, + "visualizerType": "linear" } ], "left": [ @@ -100,6 +116,42 @@ "id": "Launcher", "useDistroLogo": false }, + { + "colorizeIcons": false, + "hideMode": "hidden", + "iconScale": 0.8, + "id": "Taskbar", + "maxTaskbarWidth": 40, + "onlyActiveWorkspaces": true, + "onlySameOutput": true, + "showPinnedApps": false, + "showTitle": true, + "smartWidth": true, + "titleWidth": 120 + } + ], + "right": [ + { + "characterCount": 2, + "colorizeIcons": false, + "emptyColor": "secondary", + "enableScrollWheel": true, + "focusedColor": "primary", + "followFocusedScreen": false, + "fontWeight": "bold", + "groupedBorderOpacity": 1, + "hideUnoccupied": true, + "iconScale": 0.8, + "id": "Workspace", + "labelMode": "name", + "occupiedColor": "secondary", + "pillSize": 0.6, + "showApplications": true, + "showApplicationsHover": false, + "showBadge": true, + "showLabelsOnlyWhenOccupied": true, + "unfocusedIconsOpacity": 1 + }, { "compactMode": true, "diskPath": "/", @@ -122,56 +174,6 @@ "useMonospaceFont": true, "usePadding": false }, - { - "compactMode": false, - "hideMode": "hidden", - "hideWhenIdle": false, - "id": "MediaMini", - "maxWidth": 145, - "panelShowAlbumArt": true, - "scrollingMode": "hover", - "showAlbumArt": true, - "showArtistFirst": true, - "showProgressRing": true, - "showVisualizer": false, - "textColor": "none", - "useFixedWidth": false, - "visualizerType": "linear" - }, - { - "characterCount": 2, - "colorizeIcons": false, - "emptyColor": "secondary", - "enableScrollWheel": true, - "focusedColor": "primary", - "followFocusedScreen": false, - "fontWeight": "bold", - "groupedBorderOpacity": 1, - "hideUnoccupied": false, - "iconScale": 0.8, - "id": "Workspace", - "labelMode": "name", - "occupiedColor": "secondary", - "pillSize": 0.6, - "showApplications": false, - "showApplicationsHover": false, - "showBadge": true, - "showLabelsOnlyWhenOccupied": true, - "unfocusedIconsOpacity": 1 - }, - { - "colorizeIcons": false, - "hideMode": "visible", - "id": "ActiveWindow", - "maxWidth": 350, - "scrollingMode": "hover", - "showIcon": true, - "showText": true, - "textColor": "none", - "useFixedWidth": true - } - ], - "right": [ { "blacklist": [ ], @@ -453,7 +455,7 @@ }, "idle": { "customCommands": "[]", - "enabled": false, + "enabled": true, "fadeDuration": 5, "lockCommand": "", "lockTimeout": 660, @@ -463,7 +465,7 @@ "screenOffCommand": "", "screenOffTimeout": 600, "suspendCommand": "", - "suspendTimeout": 1800 + "suspendTimeout": 0 }, "location": { "analogClockInCalendar": false, @@ -488,7 +490,7 @@ "bluetoothRssiPollIntervalMs": 60000, "bluetoothRssiPollingEnabled": false, "disableDiscoverability": false, - "networkPanelView": "ethernet", + "networkPanelView": "wifi", "wifiDetailsViewMode": "list" }, "nightLight": { diff --git a/tmux/tmux.conf b/tmux/tmux.conf index 3c86bb1..fbfb94c 100644 --- a/tmux/tmux.conf +++ b/tmux/tmux.conf @@ -14,19 +14,22 @@ set -g @catppuccin_window_status_style "slanted" # Load catppuccin run ~/.config/tmux/plugins/catppuccin/tmux/catppuccin.tmux -# Make the status line pretty and add some modules +# Status line on top (tmux only supports top/bottom, no vertical sidebar) set-option -g status-position top set -g status-right-length 100 set -g status-left-length 100 -set -g status-left "#[fg=#{@thm_teal},bg=#{@thm_crust}]#[fg=#{@thm_crust},bg=#{@thm_teal}] #(hostname -s) " - -#set -g status-left "#[fg=$thm_green,bg=$thm_bg,nobold,nounderscore,noitalics]#[fg=$thm_bg,bg=$thm_green,nobold,nounderscore,noitalics] #[fg=$thm_fg,bg=$thm_bg]#(hostname -s) " +set -g status-left "#[fg=#{@thm_teal},bg=#{@thm_crust}]#[fg=#{@thm_crust},bg=#{@thm_teal}] #(hostname -s) " set -g status-right "#{E:@catppuccin_status_application}" -#set -agF status-right "#{E:@catppuccin_status_cpu}" set -ag status-right "#{E:@catppuccin_status_session}" -#set -ag status-right "#{E:@catppuccin_status_uptime}" -#set -agF status-right "#{E:@catppuccin_status_battery}" -#run ~/.config/tmux/plugins/tmux-plugins/tmux-cpu/cpu.tmux -#run ~/.config/tmux/plugins/tmux-plugins/tmux-battery/battery.tmux +# Per-window agent indicator: 🤖 = busy, ⏸ = waiting for input +set -g @catppuccin_window_text " #W#(~/.local/bin/tmux-window-agent-status '#{session_name}' '#I')" +set -g @catppuccin_window_current_text " #W#(~/.local/bin/tmux-window-agent-status '#{session_name}' '#I')" + +# Refresh status regularly so agent indicators stay current +set -g status-interval 2 + +# Vertical window switcher ("sidebar"): prefix+Tab opens a popup listing all +# windows top-to-bottom with agent status; Enter jumps to the selected window +bind-key Tab choose-tree -Zw -F "#{?window_format,#W#(~/.local/bin/tmux-window-agent-status '#{session_name}' '#{window_index}'),}"