From fb9cb3ae3f8e74cd815e55f1960b250cee7111ad Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 16 Apr 2026 22:01:36 -0700 Subject: [PATCH 01/22] updated zshrc --- .gitignore | 2 + home_config/nvim/lazy-lock.json | 32 +- home_config/zellij/config.kdl | 260 ++++++------ home_config/zellij/config.kdl.bak.1 | 598 ++++++++++++++++++++++++++++ home_root/.zshrc | 2 +- 5 files changed, 741 insertions(+), 153 deletions(-) create mode 100644 home_config/zellij/config.kdl.bak.1 diff --git a/.gitignore b/.gitignore index ec2f92a..ebb44e2 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ .config/btop .config/neofetch /.aider* +./home_config/nvim/lazy-lock.json +home_config/nvim/lazy-lock.json diff --git a/home_config/nvim/lazy-lock.json b/home_config/nvim/lazy-lock.json index 5e6d8af..9441bad 100644 --- a/home_config/nvim/lazy-lock.json +++ b/home_config/nvim/lazy-lock.json @@ -1,34 +1,34 @@ { - "LazyVim": { "branch": "main", "commit": "ec5981dfb1222c3bf246d9bcaa713d5cfa486fbd" }, - "blink.cmp": { "branch": "main", "commit": "1c8d8e45d6fba3d11512f4762b1fdf906bffca42" }, + "LazyVim": { "branch": "main", "commit": "3f034d0a7f58031123300309f2efd3bb0356ee21" }, + "blink.cmp": { "branch": "main", "commit": "4607923f60029f8cb28e6950a078f93fd33e1288" }, "bufferline.nvim": { "branch": "main", "commit": "655133c3b4c3e5e05ec549b9f8cc2894ac6f51b3" }, "catppuccin": { "branch": "main", "commit": "5b5e3aef9ad7af84f463d17b5479f06b87d5c429" }, - "conform.nvim": { "branch": "master", "commit": "9a06e83527407a7600a2fe4e0d10adf432b6215e" }, + "conform.nvim": { "branch": "master", "commit": "f9ef25a7ef00267b7d13bfc00b0dea22d78702d5" }, "flash.nvim": { "branch": "main", "commit": "3c942666f115e2811e959eabbdd361a025db8b63" }, "friendly-snippets": { "branch": "main", "commit": "efff286dd74c22f731cdec26a70b46e5b203c619" }, - "gitsigns.nvim": { "branch": "main", "commit": "8df63f2ddc615feb71fd4aee45a4cee022876df1" }, - "grug-far.nvim": { "branch": "main", "commit": "6b1aca6018cb6ce18a46b9e8583074a2f820b51e" }, - "lazy.nvim": { "branch": "main", "commit": "c501b429cf995c645454539b924aaefae45bb9eb" }, + "gitsigns.nvim": { "branch": "main", "commit": "7010000889bfb6c26065e0b0f7f1e6aa9163edd9" }, + "grug-far.nvim": { "branch": "main", "commit": "2c7ef09353714bd4954f5459d9a7e2579a050dc7" }, + "lazy.nvim": { "branch": "main", "commit": "6c3bda4aca61a13a9c63f1c1d1b16b9d3be90d7a" }, "lazydev.nvim": { "branch": "main", "commit": "2367a6c0a01eb9edb0464731cc0fb61ed9ab9d2c" }, "lualine.nvim": { "branch": "master", "commit": "9fef261b53fbe3a2ef01ee9667f6fde064b1ed10" }, - "mason-lspconfig.nvim": { "branch": "main", "commit": "37a336b653f8594df75c827ed589f1c91d91ff6c" }, - "mason.nvim": { "branch": "main", "commit": "0950b15060067f752fde13a779a994f59516ce3d" }, + "mason-lspconfig.nvim": { "branch": "main", "commit": "1a31f824b9cd5bc6f342fc29e9a53b60d74af245" }, + "mason.nvim": { "branch": "main", "commit": "fc98833b6da5de5a9c5b1446ac541577059555be" }, "mini.ai": { "branch": "main", "commit": "978ffc65c6b513fde9ef075326d34d89197f1ea5" }, "mini.icons": { "branch": "main", "commit": "ec61af6e606fc89ee3b1d8f2f20166a3ca917a36" }, - "mini.pairs": { "branch": "main", "commit": "1a3e73649c0eaef2f6c48ce1e761c6f0a7c11918" }, + "mini.pairs": { "branch": "main", "commit": "cd9d95e33645781f86ca5ffe0a6885a22d59f127" }, "noice.nvim": { "branch": "main", "commit": "0427460c2d7f673ad60eb02b35f5e9926cf67c59" }, "nui.nvim": { "branch": "main", "commit": "8d3bce9764e627b62b07424e0df77f680d47ffdb" }, "nvim-lint": { "branch": "master", "commit": "936197073214c26a347fb933c9459c8766376b23" }, - "nvim-lspconfig": { "branch": "master", "commit": "f43135c38a37c588053ad5e209c7460f43f6340c" }, - "nvim-treesitter": { "branch": "master", "commit": "b967bbc27b564001c3d3b8ea93444cf6d0b21d23" }, + "nvim-lspconfig": { "branch": "master", "commit": "fb733ac734249ccf293e5c8018981d4d8f59fa8f" }, + "nvim-treesitter": { "branch": "master", "commit": "d26ce0126694283cf32bf1f4192ef37ef404c037" }, "nvim-treesitter-textobjects": { "branch": "master", "commit": "9937e5e356e5b227ec56d83d0a9d0a0f6bc9cad4" }, "nvim-ts-autotag": { "branch": "main", "commit": "a1d526af391f6aebb25a8795cbc05351ed3620b5" }, "persistence.nvim": { "branch": "main", "commit": "166a79a55bfa7a4db3e26fc031b4d92af71d0b51" }, - "plenary.nvim": { "branch": "master", "commit": "a3e3bc82a3f95c5ed0d7201546d5d2c19b20d683" }, + "plenary.nvim": { "branch": "master", "commit": "857c5ac632080dba10aae49dba902ce3abf91b35" }, "snacks.nvim": { "branch": "main", "commit": "bc0630e43be5699bb94dadc302c0d21615421d93" }, - "todo-comments.nvim": { "branch": "main", "commit": "51e10f838e84b4756c16311d0b1ef0972c6482d2" }, - "tokyonight.nvim": { "branch": "main", "commit": "81c867c5f638597a82c82094dcb90ed42444dabc" }, + "todo-comments.nvim": { "branch": "main", "commit": "304a8d204ee787d2544d8bc23cd38d2f929e7cc5" }, + "tokyonight.nvim": { "branch": "main", "commit": "057ef5d260c1931f1dffd0f052c685dcd14100a3" }, "trouble.nvim": { "branch": "main", "commit": "85bedb7eb7fa331a2ccbecb9202d8abba64d37b3" }, "ts-comments.nvim": { "branch": "main", "commit": "1bd9d0ba1d8b336c3db50692ffd0955fe1bb9f0c" }, - "which-key.nvim": { "branch": "main", "commit": "0099511294f16b81c696004fa6a403b0ae61f7a0" } -} \ No newline at end of file + "which-key.nvim": { "branch": "main", "commit": "370ec46f710e058c9c1646273e6b225acf47cbed" } +} diff --git a/home_config/zellij/config.kdl b/home_config/zellij/config.kdl index b980257..bdb29cb 100644 --- a/home_config/zellij/config.kdl +++ b/home_config/zellij/config.kdl @@ -1,5 +1,5 @@ // -// THIS FILE WAS AUTOGENERATED BY ZELLIJ, THE PREVIOUS FILE AT THIS LOCATION WAS COPIED TO: /home/lkraven/.config/zellij/config.kdl.bak +// THIS FILE WAS AUTOGENERATED BY ZELLIJ, THE PREVIOUS FILE AT THIS LOCATION WAS COPIED TO: /home/lkraven/.config/zellij/config.kdl.bak.1 // keybinds clear-defaults=true { @@ -247,6 +247,126 @@ keybinds clear-defaults=true { bind "z" { ToggleFocusFullscreen; SwitchToMode "normal"; } } } +themes { + australis { + text_unselected { + base 204 231 236 + background 65 71 81 + emphasis_0 164 196 255 + emphasis_1 22 184 102 + emphasis_2 99 136 216 + emphasis_3 66 220 209 + } + text_selected { + base 230 250 255 + background 99 136 216 + emphasis_0 255 225 78 + emphasis_1 22 184 102 + emphasis_2 99 136 216 + emphasis_3 255 133 79 + } + ribbon_selected { + base 65 71 81 + background 99 136 216 + emphasis_0 81 224 138 + emphasis_1 22 184 102 + emphasis_2 225 198 49 + emphasis_3 255 133 79 + } + ribbon_unselected { + base 204 231 236 + background 86 95 105 + emphasis_0 81 224 138 + emphasis_1 22 184 102 + emphasis_2 99 136 216 + emphasis_3 255 133 79 + } + table_title { + base 169 188 195 + background 34 37 49 + emphasis_0 255 133 79 + emphasis_1 22 184 102 + emphasis_2 99 136 216 + emphasis_3 255 73 26 + } + table_cell_selected { + base 204 231 236 + background 65 71 81 + emphasis_0 255 225 78 + emphasis_1 22 184 102 + emphasis_2 99 136 216 + emphasis_3 255 133 79 + } + table_cell_unselected { + base 169 188 195 + background 34 37 49 + emphasis_0 255 73 26 + emphasis_1 22 184 102 + emphasis_2 99 136 216 + emphasis_3 255 133 79 + } + list_selected { + base 204 231 236 + background 65 71 81 + emphasis_0 255 225 78 + emphasis_1 22 184 102 + emphasis_2 99 136 216 + emphasis_3 255 133 79 + } + list_unselected { + base 169 188 195 + background 34 37 49 + emphasis_0 225 198 49 + emphasis_1 22 184 102 + emphasis_2 99 136 216 + emphasis_3 255 133 79 + } + frame_selected { + base 99 136 216 + background 34 37 49 + emphasis_0 255 73 26 + emphasis_1 22 184 102 + emphasis_2 225 198 49 + emphasis_3 255 133 79 + } + frame_highlight { + base 81 224 138 + background 34 37 49 + emphasis_0 255 133 79 + emphasis_1 99 136 216 + emphasis_2 225 198 49 + emphasis_3 255 73 26 + } + exit_code_success { + base 22 184 102 + background 0 + emphasis_0 255 73 26 + emphasis_1 99 136 216 + emphasis_2 225 198 49 + emphasis_3 255 133 79 + } + exit_code_error { + base 255 73 26 + background 0 + emphasis_0 22 184 102 + emphasis_1 99 136 216 + emphasis_2 225 198 49 + emphasis_3 255 133 79 + } + multiplayer_user_colors { + player_1 255 73 26 + player_2 255 133 79 + player_3 225 198 49 + player_4 255 225 78 + player_5 157 120 255 + player_6 216 173 255 + player_7 99 136 216 + player_8 0 177 168 + player_9 66 220 209 + player_10 164 196 255 + } + } +} // Plugin aliases - can be used to change the implementation of Zellij // changing these requires a restart to take effect @@ -270,141 +390,9 @@ plugins { // Plugins to load in the background when a new session starts // eg. "file:/path/to/my-plugin.wasm" // eg. "https://example.com/my-plugin.wasm" -themes { - australis { - - text_unselected { - base 204 231 236 // #CCE7EC - Bright text - background 65 71 81 // #414751 - Dark 30 - emphasis_0 164 196 255 // #A4C4FF - Bright blue - emphasis_1 22 184 102 // #16B866 - Green - emphasis_2 99 136 216 // #6388D8 - Blue - emphasis_3 66 220 209 // #42DCD1 - Bright cyan (was 255 133 79 - Bright red) - } - - text_selected { - base 230 250 255 // #E6FAFF - Brighter white (was 204 231 236) - background 99 136 216 // #6388D8 - Blue - emphasis_0 255 225 78 // #FFE14E - Bright yellow - emphasis_1 22 184 102 // #16B866 - Green - emphasis_2 99 136 216 // #6388D8 - Blue - emphasis_3 255 133 79 // #FF854F - Bright red - } - - ribbon_unselected { - base 204 231 236 // #CCE7EC - Bright white - background 86 95 105 // #565f69 - Dark 40 (was 65 71 81 - Dark 30) - emphasis_0 81 224 138 // #51E08A - Bright green - emphasis_1 22 184 102 // #16B866 - Green - emphasis_2 99 136 216 // #6388D8 - Blue - emphasis_3 255 133 79 // #FF854F - Bright red - } - - ribbon_selected { - base 65 71 81 // #414751 - Dark 30 - background 99 136 216 // #6388D8 - Blue - emphasis_0 81 224 138 // #51E08A - Bright green - emphasis_1 22 184 102 // #16B866 - Green - emphasis_2 225 198 49 // #E1C631 - Yellow - emphasis_3 255 133 79 // #FF854F - Bright red - } - - table_title { - base 169 188 195 // #A9BCC3 - White - background 34 37 49 // #222531 - Black - emphasis_0 255 133 79 // #FF854F - Bright red - emphasis_1 22 184 102 // #16B866 - Green - emphasis_2 99 136 216 // #6388D8 - Blue - emphasis_3 255 73 26 // #FF491A - Red - } - - table_cell_unselected { - base 169 188 195 // #A9BCC3 - White - background 34 37 49 // #222531 - Black - emphasis_0 255 73 26 // #FF491A - Red - emphasis_1 22 184 102 // #16B866 - Green - emphasis_2 99 136 216 // #6388D8 - Blue - emphasis_3 255 133 79 // #FF854F - Bright red - } - - table_cell_selected { - base 204 231 236 // #CCE7EC - Bright white - background 65 71 81 // #414751 - Dark 30 - emphasis_0 255 225 78 // #FFE14E - Bright yellow - emphasis_1 22 184 102 // #16B866 - Green - emphasis_2 99 136 216 // #6388D8 - Blue - emphasis_3 255 133 79 // #FF854F - Bright red - } - - list_unselected { - base 169 188 195 // #A9BCC3 - White - background 34 37 49 // #222531 - Black - emphasis_0 225 198 49 // #E1C631 - Yellow - emphasis_1 22 184 102 // #16B866 - Green - emphasis_2 99 136 216 // #6388D8 - Blue - emphasis_3 255 133 79 // #FF854F - Bright red - } - - list_selected { - base 204 231 236 // #CCE7EC - Bright white - background 65 71 81 // #414751 - Dark 30 - emphasis_0 255 225 78 // #FFE14E - Bright yellow - emphasis_1 22 184 102 // #16B866 - Green - emphasis_2 99 136 216 // #6388D8 - Blue - emphasis_3 255 133 79 // #FF854F - Bright red - } - - frame_selected { - base 99 136 216 // #6388D8 - Blue - background 34 37 49 // #222531 - Black - emphasis_0 255 73 26 // #FF491A - Red - emphasis_1 22 184 102 // #16B866 - Green - emphasis_2 225 198 49 // #E1C631 - Yellow - emphasis_3 255 133 79 // #FF854F - Bright red - } - - frame_highlight { - base 81 224 138 // #51E08A - Bright green - background 34 37 49 // #222531 - Black - emphasis_0 255 133 79 // #FF854F - Bright red - emphasis_1 99 136 216 // #6388D8 - Blue - emphasis_2 225 198 49 // #E1C631 - Yellow - emphasis_3 255 73 26 // #FF491A - Red - } - - exit_code_success { - base 22 184 102 // #16B866 - Green - emphasis_0 255 73 26 // #FF491A - Red - emphasis_1 99 136 216 // #6388D8 - Blue - emphasis_2 225 198 49 // #E1C631 - Yellow - emphasis_3 255 133 79 // #FF854F - Bright red - } - - exit_code_error { - base 255 73 26 // #FF491A - Red - emphasis_0 22 184 102 // #16B866 - Green - emphasis_1 99 136 216 // #6388D8 - Blue - emphasis_2 225 198 49 // #E1C631 - Yellow - emphasis_3 255 133 79 // #FF854F - Bright red - } - - multiplayer_user_colors { - player_1 255 73 26 // #FF491A - Red - player_2 255 133 79 // #FF854F - Bright red - player_3 225 198 49 // #E1C631 - Yellow - player_4 255 225 78 // #FFE14E - Bright yellow - player_5 157 120 255 // #9D78FF - Magenta - player_6 216 173 255 // #D8ADFF - Bright magenta - player_7 99 136 216 // #6388D8 - Blue - player_8 0 177 168 // #00B1A8 - Cyan - player_9 66 220 209 // #42DCD1 - Bright cyan - player_10 164 196 255 // #A4C4FF - Bright blue - } - } -} load_plugins { } - + // Use a simplified UI without special fonts (arrow glyphs) // Options: // - true @@ -414,7 +402,7 @@ load_plugins { // Choose the theme that is specified in the themes section. // Default: default - +// theme "australis" // Choose the base input mode of zellij. @@ -590,7 +578,7 @@ default_mode "normal" // Whether to show tips on startup // Default: true // -// show_startup_tips false +show_startup_tips false // Whether to show release notes on first version run // Default: true diff --git a/home_config/zellij/config.kdl.bak.1 b/home_config/zellij/config.kdl.bak.1 new file mode 100644 index 0000000..b980257 --- /dev/null +++ b/home_config/zellij/config.kdl.bak.1 @@ -0,0 +1,598 @@ +// +// THIS FILE WAS AUTOGENERATED BY ZELLIJ, THE PREVIOUS FILE AT THIS LOCATION WAS COPIED TO: /home/lkraven/.config/zellij/config.kdl.bak +// + +keybinds clear-defaults=true { + locked { + bind "Ctrl g" { SwitchToMode "normal"; } + } + pane { + bind "left" { MoveFocus "left"; } + bind "down" { MoveFocus "down"; } + bind "up" { MoveFocus "up"; } + bind "right" { MoveFocus "right"; } + bind "c" { SwitchToMode "renamepane"; PaneNameInput 0; } + bind "d" { NewPane "down"; SwitchToMode "normal"; } + bind "e" { TogglePaneEmbedOrFloating; SwitchToMode "normal"; } + bind "f" { ToggleFocusFullscreen; SwitchToMode "normal"; } + bind "h" { MoveFocus "left"; } + bind "i" { TogglePanePinned; SwitchToMode "normal"; } + bind "j" { MoveFocus "down"; } + bind "k" { MoveFocus "up"; } + bind "l" { MoveFocus "right"; } + bind "n" { NewPane; SwitchToMode "normal"; } + bind "p" { SwitchFocus; } + bind "Ctrl p" { SwitchToMode "normal"; } + bind "r" { NewPane "right"; SwitchToMode "normal"; } + bind "w" { ToggleFloatingPanes; SwitchToMode "normal"; } + bind "z" { TogglePaneFrames; SwitchToMode "normal"; } + } + tab { + bind "left" { GoToPreviousTab; } + bind "down" { GoToNextTab; } + bind "up" { GoToPreviousTab; } + bind "right" { GoToNextTab; } + bind "1" { GoToTab 1; SwitchToMode "normal"; } + bind "2" { GoToTab 2; SwitchToMode "normal"; } + bind "3" { GoToTab 3; SwitchToMode "normal"; } + bind "4" { GoToTab 4; SwitchToMode "normal"; } + bind "5" { GoToTab 5; SwitchToMode "normal"; } + bind "6" { GoToTab 6; SwitchToMode "normal"; } + bind "7" { GoToTab 7; SwitchToMode "normal"; } + bind "8" { GoToTab 8; SwitchToMode "normal"; } + bind "9" { GoToTab 9; SwitchToMode "normal"; } + bind "[" { BreakPaneLeft; SwitchToMode "normal"; } + bind "]" { BreakPaneRight; SwitchToMode "normal"; } + bind "b" { BreakPane; SwitchToMode "normal"; } + bind "h" { GoToPreviousTab; } + bind "j" { GoToNextTab; } + bind "k" { GoToPreviousTab; } + bind "l" { GoToNextTab; } + bind "n" { NewTab; SwitchToMode "normal"; } + bind "r" { SwitchToMode "renametab"; TabNameInput 0; } + bind "s" { ToggleActiveSyncTab; SwitchToMode "normal"; } + bind "Ctrl t" { SwitchToMode "normal"; } + bind "x" { CloseTab; SwitchToMode "normal"; } + bind "tab" { ToggleTab; } + } + resize { + bind "left" { Resize "Increase left"; } + bind "down" { Resize "Increase down"; } + bind "up" { Resize "Increase up"; } + bind "right" { Resize "Increase right"; } + bind "+" { Resize "Increase"; } + bind "-" { Resize "Decrease"; } + bind "=" { Resize "Increase"; } + bind "H" { Resize "Decrease left"; } + bind "J" { Resize "Decrease down"; } + bind "K" { Resize "Decrease up"; } + bind "L" { Resize "Decrease right"; } + bind "h" { Resize "Increase left"; } + bind "j" { Resize "Increase down"; } + bind "k" { Resize "Increase up"; } + bind "l" { Resize "Increase right"; } + bind "Ctrl n" { SwitchToMode "normal"; } + } + move { + bind "left" { MovePane "left"; } + bind "down" { MovePane "down"; } + bind "up" { MovePane "up"; } + bind "right" { MovePane "right"; } + bind "h" { MovePane "left"; } + bind "Ctrl h" { SwitchToMode "normal"; } + bind "j" { MovePane "down"; } + bind "k" { MovePane "up"; } + bind "l" { MovePane "right"; } + bind "n" { MovePane; } + bind "p" { MovePaneBackwards; } + bind "tab" { MovePane; } + } + scroll { + bind "Alt left" { MoveFocusOrTab "left"; SwitchToMode "normal"; } + bind "Alt down" { MoveFocus "down"; SwitchToMode "normal"; } + bind "Alt up" { MoveFocus "up"; SwitchToMode "normal"; } + bind "Alt right" { MoveFocusOrTab "right"; SwitchToMode "normal"; } + bind "e" { EditScrollback; SwitchToMode "normal"; } + bind "Alt h" { MoveFocusOrTab "left"; SwitchToMode "normal"; } + bind "Alt j" { MoveFocus "down"; SwitchToMode "normal"; } + bind "Alt k" { MoveFocus "up"; SwitchToMode "normal"; } + bind "Alt l" { MoveFocusOrTab "right"; SwitchToMode "normal"; } + bind "s" { SwitchToMode "entersearch"; SearchInput 0; } + } + search { + bind "c" { SearchToggleOption "CaseSensitivity"; } + bind "n" { Search "down"; } + bind "o" { SearchToggleOption "WholeWord"; } + bind "p" { Search "up"; } + bind "w" { SearchToggleOption "Wrap"; } + } + session { + bind "a" { + LaunchOrFocusPlugin "zellij:about" { + floating true + move_to_focused_tab true + } + SwitchToMode "normal" + } + bind "c" { + LaunchOrFocusPlugin "configuration" { + floating true + move_to_focused_tab true + } + SwitchToMode "normal" + } + bind "Ctrl o" { SwitchToMode "normal"; } + bind "p" { + LaunchOrFocusPlugin "plugin-manager" { + floating true + move_to_focused_tab true + } + SwitchToMode "normal" + } + bind "w" { + LaunchOrFocusPlugin "session-manager" { + floating true + move_to_focused_tab true + } + SwitchToMode "normal" + } + } + shared_except "locked" { + bind "Alt +" { Resize "Increase"; } + bind "Alt -" { Resize "Decrease"; } + bind "Alt =" { Resize "Increase"; } + bind "Alt [" { PreviousSwapLayout; } + bind "Alt ]" { NextSwapLayout; } + bind "Alt f" { ToggleFloatingPanes; } + bind "Ctrl g" { SwitchToMode "locked"; } + bind "Alt i" { MoveTab "left"; } + bind "Alt n" { NewPane; } + bind "Alt o" { MoveTab "right"; } + bind "Ctrl q" { Quit; } + } + shared_except "locked" "move" { + bind "Ctrl h" { SwitchToMode "move"; } + } + shared_except "locked" "session" { + bind "Ctrl o" { SwitchToMode "session"; } + } + shared_except "locked" "scroll" { + bind "Alt left" { MoveFocusOrTab "left"; } + bind "Alt down" { MoveFocus "down"; } + bind "Alt up" { MoveFocus "up"; } + bind "Alt right" { MoveFocusOrTab "right"; } + bind "Alt h" { MoveFocusOrTab "left"; } + bind "Alt j" { MoveFocus "down"; } + bind "Alt k" { MoveFocus "up"; } + bind "Alt l" { MoveFocusOrTab "right"; } + } + shared_except "locked" "scroll" "search" "tmux" { + bind "Ctrl b" { SwitchToMode "tmux"; } + } + shared_except "locked" "scroll" "search" { + bind "Ctrl s" { SwitchToMode "scroll"; } + } + shared_except "locked" "tab" { + bind "Ctrl t" { SwitchToMode "tab"; } + } + shared_except "locked" "pane" { + bind "Ctrl p" { SwitchToMode "pane"; } + } + shared_except "locked" "resize" { + bind "Ctrl n" { SwitchToMode "resize"; } + } + shared_except "normal" "locked" "entersearch" { + bind "enter" { SwitchToMode "normal"; } + } + shared_except "normal" "locked" "entersearch" "renametab" "renamepane" { + bind "esc" { SwitchToMode "normal"; } + } + shared_among "pane" "tmux" { + bind "x" { CloseFocus; SwitchToMode "normal"; } + } + shared_among "scroll" "search" { + bind "PageDown" { PageScrollDown; } + bind "PageUp" { PageScrollUp; } + bind "left" { PageScrollUp; } + bind "down" { ScrollDown; } + bind "up" { ScrollUp; } + bind "right" { PageScrollDown; } + bind "Ctrl b" { PageScrollUp; } + bind "Ctrl c" { ScrollToBottom; SwitchToMode "normal"; } + bind "d" { HalfPageScrollDown; } + bind "Ctrl f" { PageScrollDown; } + bind "h" { PageScrollUp; } + bind "j" { ScrollDown; } + bind "k" { ScrollUp; } + bind "l" { PageScrollDown; } + bind "Ctrl s" { SwitchToMode "normal"; } + bind "u" { HalfPageScrollUp; } + } + entersearch { + bind "Ctrl c" { SwitchToMode "scroll"; } + bind "esc" { SwitchToMode "scroll"; } + bind "enter" { SwitchToMode "search"; } + } + renametab { + bind "esc" { UndoRenameTab; SwitchToMode "tab"; } + } + shared_among "renametab" "renamepane" { + bind "Ctrl c" { SwitchToMode "normal"; } + } + renamepane { + bind "esc" { UndoRenamePane; SwitchToMode "pane"; } + } + shared_among "session" "tmux" { + bind "d" { Detach; } + } + tmux { + bind "left" { MoveFocus "left"; SwitchToMode "normal"; } + bind "down" { MoveFocus "down"; SwitchToMode "normal"; } + bind "up" { MoveFocus "up"; SwitchToMode "normal"; } + bind "right" { MoveFocus "right"; SwitchToMode "normal"; } + bind "space" { NextSwapLayout; } + bind "\"" { NewPane "down"; SwitchToMode "normal"; } + bind "%" { NewPane "right"; SwitchToMode "normal"; } + bind "," { SwitchToMode "renametab"; } + bind "[" { SwitchToMode "scroll"; } + bind "Ctrl b" { Write 2; SwitchToMode "normal"; } + bind "c" { NewTab; SwitchToMode "normal"; } + bind "h" { MoveFocus "left"; SwitchToMode "normal"; } + bind "j" { MoveFocus "down"; SwitchToMode "normal"; } + bind "k" { MoveFocus "up"; SwitchToMode "normal"; } + bind "l" { MoveFocus "right"; SwitchToMode "normal"; } + bind "n" { GoToNextTab; SwitchToMode "normal"; } + bind "o" { FocusNextPane; } + bind "p" { GoToPreviousTab; SwitchToMode "normal"; } + bind "z" { ToggleFocusFullscreen; SwitchToMode "normal"; } + } +} + +// Plugin aliases - can be used to change the implementation of Zellij +// changing these requires a restart to take effect +plugins { + about location="zellij:about" + compact-bar location="zellij:compact-bar" + configuration location="zellij:configuration" + filepicker location="zellij:strider" { + cwd "/" + } + plugin-manager location="zellij:plugin-manager" + session-manager location="zellij:session-manager" + status-bar location="zellij:status-bar" + strider location="zellij:strider" + tab-bar location="zellij:tab-bar" + welcome-screen location="zellij:session-manager" { + welcome_screen true + } +} + +// Plugins to load in the background when a new session starts +// eg. "file:/path/to/my-plugin.wasm" +// eg. "https://example.com/my-plugin.wasm" +themes { + australis { + + text_unselected { + base 204 231 236 // #CCE7EC - Bright text + background 65 71 81 // #414751 - Dark 30 + emphasis_0 164 196 255 // #A4C4FF - Bright blue + emphasis_1 22 184 102 // #16B866 - Green + emphasis_2 99 136 216 // #6388D8 - Blue + emphasis_3 66 220 209 // #42DCD1 - Bright cyan (was 255 133 79 - Bright red) + } + + text_selected { + base 230 250 255 // #E6FAFF - Brighter white (was 204 231 236) + background 99 136 216 // #6388D8 - Blue + emphasis_0 255 225 78 // #FFE14E - Bright yellow + emphasis_1 22 184 102 // #16B866 - Green + emphasis_2 99 136 216 // #6388D8 - Blue + emphasis_3 255 133 79 // #FF854F - Bright red + } + + ribbon_unselected { + base 204 231 236 // #CCE7EC - Bright white + background 86 95 105 // #565f69 - Dark 40 (was 65 71 81 - Dark 30) + emphasis_0 81 224 138 // #51E08A - Bright green + emphasis_1 22 184 102 // #16B866 - Green + emphasis_2 99 136 216 // #6388D8 - Blue + emphasis_3 255 133 79 // #FF854F - Bright red + } + + ribbon_selected { + base 65 71 81 // #414751 - Dark 30 + background 99 136 216 // #6388D8 - Blue + emphasis_0 81 224 138 // #51E08A - Bright green + emphasis_1 22 184 102 // #16B866 - Green + emphasis_2 225 198 49 // #E1C631 - Yellow + emphasis_3 255 133 79 // #FF854F - Bright red + } + + table_title { + base 169 188 195 // #A9BCC3 - White + background 34 37 49 // #222531 - Black + emphasis_0 255 133 79 // #FF854F - Bright red + emphasis_1 22 184 102 // #16B866 - Green + emphasis_2 99 136 216 // #6388D8 - Blue + emphasis_3 255 73 26 // #FF491A - Red + } + + table_cell_unselected { + base 169 188 195 // #A9BCC3 - White + background 34 37 49 // #222531 - Black + emphasis_0 255 73 26 // #FF491A - Red + emphasis_1 22 184 102 // #16B866 - Green + emphasis_2 99 136 216 // #6388D8 - Blue + emphasis_3 255 133 79 // #FF854F - Bright red + } + + table_cell_selected { + base 204 231 236 // #CCE7EC - Bright white + background 65 71 81 // #414751 - Dark 30 + emphasis_0 255 225 78 // #FFE14E - Bright yellow + emphasis_1 22 184 102 // #16B866 - Green + emphasis_2 99 136 216 // #6388D8 - Blue + emphasis_3 255 133 79 // #FF854F - Bright red + } + + list_unselected { + base 169 188 195 // #A9BCC3 - White + background 34 37 49 // #222531 - Black + emphasis_0 225 198 49 // #E1C631 - Yellow + emphasis_1 22 184 102 // #16B866 - Green + emphasis_2 99 136 216 // #6388D8 - Blue + emphasis_3 255 133 79 // #FF854F - Bright red + } + + list_selected { + base 204 231 236 // #CCE7EC - Bright white + background 65 71 81 // #414751 - Dark 30 + emphasis_0 255 225 78 // #FFE14E - Bright yellow + emphasis_1 22 184 102 // #16B866 - Green + emphasis_2 99 136 216 // #6388D8 - Blue + emphasis_3 255 133 79 // #FF854F - Bright red + } + + frame_selected { + base 99 136 216 // #6388D8 - Blue + background 34 37 49 // #222531 - Black + emphasis_0 255 73 26 // #FF491A - Red + emphasis_1 22 184 102 // #16B866 - Green + emphasis_2 225 198 49 // #E1C631 - Yellow + emphasis_3 255 133 79 // #FF854F - Bright red + } + + frame_highlight { + base 81 224 138 // #51E08A - Bright green + background 34 37 49 // #222531 - Black + emphasis_0 255 133 79 // #FF854F - Bright red + emphasis_1 99 136 216 // #6388D8 - Blue + emphasis_2 225 198 49 // #E1C631 - Yellow + emphasis_3 255 73 26 // #FF491A - Red + } + + exit_code_success { + base 22 184 102 // #16B866 - Green + emphasis_0 255 73 26 // #FF491A - Red + emphasis_1 99 136 216 // #6388D8 - Blue + emphasis_2 225 198 49 // #E1C631 - Yellow + emphasis_3 255 133 79 // #FF854F - Bright red + } + + exit_code_error { + base 255 73 26 // #FF491A - Red + emphasis_0 22 184 102 // #16B866 - Green + emphasis_1 99 136 216 // #6388D8 - Blue + emphasis_2 225 198 49 // #E1C631 - Yellow + emphasis_3 255 133 79 // #FF854F - Bright red + } + + multiplayer_user_colors { + player_1 255 73 26 // #FF491A - Red + player_2 255 133 79 // #FF854F - Bright red + player_3 225 198 49 // #E1C631 - Yellow + player_4 255 225 78 // #FFE14E - Bright yellow + player_5 157 120 255 // #9D78FF - Magenta + player_6 216 173 255 // #D8ADFF - Bright magenta + player_7 99 136 216 // #6388D8 - Blue + player_8 0 177 168 // #00B1A8 - Cyan + player_9 66 220 209 // #42DCD1 - Bright cyan + player_10 164 196 255 // #A4C4FF - Bright blue + } + } +} +load_plugins { +} + +// Use a simplified UI without special fonts (arrow glyphs) +// Options: +// - true +// - false (Default) +// +// simplified_ui true + +// Choose the theme that is specified in the themes section. +// Default: default + +theme "australis" + +// Choose the base input mode of zellij. +// Default: normal +// +default_mode "normal" + +// Choose the path to the default shell that zellij will use for opening new panes +// Default: $SHELL +// +// default_shell "fish" + +// Choose the path to override cwd that zellij will use for opening new panes +// +// default_cwd "/tmp" + +// The name of the default layout to load on startup +// Default: "default" +// +// default_layout "compact" + +// The folder in which Zellij will look for layouts +// (Requires restart) +// +// layout_dir "/tmp" + +// The folder in which Zellij will look for themes +// (Requires restart) +// +// theme_dir "/tmp" + +// Toggle enabling the mouse mode. +// On certain configurations, or terminals this could +// potentially interfere with copying text. +// Options: +// - true (default) +// - false +// +// mouse_mode false + +// Toggle having pane frames around the panes +// Options: +// - true (default, enabled) +// - false +// +// pane_frames false + +// When attaching to an existing session with other users, +// should the session be mirrored (true) +// or should each user have their own cursor (false) +// (Requires restart) +// Default: false +// +// mirror_session true + +// Choose what to do when zellij receives SIGTERM, SIGINT, SIGQUIT or SIGHUP +// eg. when terminal window with an active zellij session is closed +// (Requires restart) +// Options: +// - detach (Default) +// - quit +// +// on_force_close "quit" + +// Configure the scroll back buffer size +// This is the number of lines zellij stores for each pane in the scroll back +// buffer. Excess number of lines are discarded in a FIFO fashion. +// (Requires restart) +// Valid values: positive integers +// Default value: 10000 +// +// scroll_buffer_size 10000 + +// Provide a command to execute when copying text. The text will be piped to +// the stdin of the program to perform the copy. This can be used with +// terminal emulators which do not support the OSC 52 ANSI control sequence +// that will be used by default if this option is not set. +// Examples: +// +// copy_command "xclip -selection clipboard" // x11 +// copy_command "wl-copy" // wayland +// copy_command "pbcopy" // osx +// +// copy_command "pbcopy" + +// Choose the destination for copied text +// Allows using the primary selection buffer (on x11/wayland) instead of the system clipboard. +// Does not apply when using copy_command. +// Options: +// - system (default) +// - primary +// +// copy_clipboard "primary" + +// Enable automatic copying (and clearing) of selection when releasing mouse +// Default: true +// +// copy_on_select true + +// Path to the default editor to use to edit pane scrollbuffer +// Default: $EDITOR or $VISUAL +// scrollback_editor "/usr/bin/vim" + +// A fixed name to always give the Zellij session. +// Consider also setting `attach_to_session true,` +// otherwise this will error if such a session exists. +// Default: +// +// session_name "My singleton session" + +// When `session_name` is provided, attaches to that session +// if it is already running or creates it otherwise. +// Default: false +// +// attach_to_session true + +// Toggle between having Zellij lay out panes according to a predefined set of layouts whenever possible +// Options: +// - true (default) +// - false +// +// auto_layout false + +// Whether sessions should be serialized to the cache folder (including their tabs/panes, cwds and running commands) so that they can later be resurrected +// Options: +// - true (default) +// - false +// +// session_serialization false + +// Whether pane viewports are serialized along with the session, default is false +// Options: +// - true +// - false (default) +// +// serialize_pane_viewport false + +// Scrollback lines to serialize along with the pane viewport when serializing sessions, 0 +// defaults to the scrollback size. If this number is higher than the scrollback size, it will +// also default to the scrollback size. This does nothing if `serialize_pane_viewport` is not true. +// +// scrollback_lines_to_serialize 10000 + +// Enable or disable the rendering of styled and colored underlines (undercurl). +// May need to be disabled for certain unsupported terminals +// (Requires restart) +// Default: true +// +// styled_underlines false + +// How often in seconds sessions are serialized +// +// serialization_interval 10000 + +// Enable or disable writing of session metadata to disk (if disabled, other sessions might not know +// metadata info on this session) +// (Requires restart) +// Default: false +// +// disable_session_metadata false + +// Enable or disable support for the enhanced Kitty Keyboard Protocol (the host terminal must also support it) +// (Requires restart) +// Default: true (if the host terminal supports it) +// +// support_kitty_keyboard_protocol false + +// Whether to stack panes when resizing beyond a certain size +// Default: true +// +// stacked_resize false + +// Whether to show tips on startup +// Default: true +// +// show_startup_tips false + +// Whether to show release notes on first version run +// Default: true +// +// show_release_notes false diff --git a/home_root/.zshrc b/home_root/.zshrc index a2ac8d5..de3eeb0 100644 --- a/home_root/.zshrc +++ b/home_root/.zshrc @@ -5,7 +5,7 @@ path=(~/.cache/lk-tools/fzf/bin $path) # Init OhMyPosh -eval "$(oh-my-posh init zsh --config https://gitea.phasefinal.com/vh/dotfiles/raw/branch/master/home_config/ohmyposh/lkraven.toml)" +eval "$(oh-my-posh init zsh --config https://333e8677ac54a1845fe68813017ab7e807c87ab2@gitea.phasefinal.com/vh/dotfiles/raw/branch/master/home_config/ohmyposh/lkraven.toml)" # Set ZINIT Home ZINIT_HOME="${HOME}/.config/zinit/zinit.git" From 77a8d25488299abc1adbeb6c3ea387c8333d3657 Mon Sep 17 00:00:00 2001 From: lkrav Date: Mon, 8 Jun 2026 13:22:33 -0700 Subject: [PATCH 02/22] Add Windows support: linker, oh-my-posh installer, README - link-dotfiles.ps1: stow-equivalent for Windows using junctions/symlinks (no admin required), idempotent with .bak backups and -DryRun - lk-installers/install-ohmyposh.ps1: winget-based install with fallback - README.md: document Linux/macOS (stow) and Windows flows - .gitignore: resolve leftover merge conflict markers, ignore *.bak - ohmyposh/lkraven.toml: oh-my-posh v3 auto-migrated this on load (same theme, upgraded schema) Co-Authored-By: Claude Opus 4.8 --- .gitignore | 5 +- README.md | 61 +++++++++++ home_config/ohmyposh/lkraven.toml | 161 ++++++++++++++++------------- link-dotfiles.ps1 | 105 +++++++++++++++++++ lk-installers/install-ohmyposh.ps1 | 27 +++++ 5 files changed, 281 insertions(+), 78 deletions(-) create mode 100644 README.md create mode 100644 link-dotfiles.ps1 create mode 100644 lk-installers/install-ohmyposh.ps1 diff --git a/.gitignore b/.gitignore index 32e46fc..55f015b 100644 --- a/.gitignore +++ b/.gitignore @@ -2,9 +2,6 @@ .config/btop .config/neofetch /.aider* -<<<<<<< HEAD -./home_config/nvim/lazy-lock.json home_config/nvim/lazy-lock.json -======= __pycache__/ ->>>>>>> 00717500056db846954b09bcfac4ebb3f1aa84e6 +*.bak diff --git a/README.md b/README.md new file mode 100644 index 0000000..18114ee --- /dev/null +++ b/README.md @@ -0,0 +1,61 @@ +# dotfiles + +Personal dotfiles. Configs are organized by where they get linked: + +| Folder | Links into | Examples | +| -------------- | ------------ | --------------------------------- | +| `home_root` | `~` | `.zshrc`, `.wezterm.lua`, `.nanorc` | +| `home_config` | `~/.config` | `nvim`, `ohmyposh`, `zellij`, `ghostty` | +| `lk-installers`| n/a | helper scripts to install tooling | + +## Linux / macOS (GNU stow) + +Requires [`stow`](https://www.gnu.org/software/stow/). + +```bash +./link-dotfiles +``` + +This runs `stow home_root` and `stow --target=$HOME/.config home_config`. + +## Windows (PowerShell) + +`stow` doesn't run natively on Windows, so use the PowerShell equivalent. It +mirrors stow by creating **junctions** for directories and **symlinks/hardlinks** +for files — none of which require administrator rights: + +```powershell +pwsh -File .\link-dotfiles.ps1 +``` + +- Re-running is safe: already-correct links are skipped. +- Any real file/dir that would be overwritten is moved aside to `.bak`. +- Preview without changing anything: `pwsh -File .\link-dotfiles.ps1 -DryRun` + +The repo stays the source of truth — edit files under `home_root` / +`home_config` and the linked locations update live. + +## Installers + +| Script | Platform | Purpose | +| ------------------------------- | -------- | ------------------ | +| `lk-installers/install-ohmyposh` | bash | oh-my-posh (Linux/macOS) | +| `lk-installers/install-ohmyposh.ps1` | pwsh | oh-my-posh (Windows, via winget) | + +```powershell +# Windows: install oh-my-posh, then link +pwsh -File .\lk-installers\install-ohmyposh.ps1 +pwsh -File .\link-dotfiles.ps1 +``` + +### oh-my-posh + +The prompt theme lives at `home_config/ohmyposh/lkraven.toml` and is loaded from +your shell profile, e.g. in PowerShell: + +```powershell +oh-my-posh init pwsh --config '~/.config/ohmyposh/lkraven.toml' | Invoke-Expression +``` + +It expects a Nerd Font (e.g. **VictorMono Nerd Font Mono**) to be installed and +selected in your terminal for the glyphs to render correctly. diff --git a/home_config/ohmyposh/lkraven.toml b/home_config/ohmyposh/lkraven.toml index e6704bc..b92eac0 100644 --- a/home_config/ohmyposh/lkraven.toml +++ b/home_config/ohmyposh/lkraven.toml @@ -1,126 +1,152 @@ -#:schema https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/schema.json console_title_template = '{{if .Root}}(Admin){{end}} {{.PWD}}' -version = 2 +version = 3 [palette] black = '#222531' - bright_black = '#373b46' blue = '#6388D8' + bright_70 = '#9daeb6' + bright_80 = '#b3cbcf' + bright_90 = '#cce7ec' + bright_black = '#373b46' bright_blue = '#a4c4ff' - cyan = '#00b1a8' bright_cyan = '#42dcd1' - green = '#16B866' bright_green = '#51e08a' - magenta = '#9d78ff' bright_magenta = '#d8adff' - red = '#ff491a' bright_red = '#ff854f' - white = '#a9bcc3' bright_white = '#cce7ec' - yellow = '#e1c631' bright_yellow = '#FFE14E' + cyan = '#00b1a8' dark_30 = '#414751' dark_40 = '#565f69' dark_50 = '#6e7882' dark_60 = '#86929d' - bright_70 = '#9daeb6' - bright_80 = '#b3cbcf' - bright_90 = '#cce7ec' + green = '#16B866' + magenta = '#9d78ff' + red = '#ff491a' + white = '#a9bcc3' + yellow = '#e1c631' + +[secondary_prompt] + template = '❯❯ ' + foreground = 'p:bright_green' + background = 'transparent' + +[transient_prompt] + template = '❯ ' + background = 'transparent' + foreground_templates = ['{{if gt .Code 0}}p:red{{end}}', '{{if eq .Code 0}}p:bright_green{{end}}'] [[blocks]] - alignment = 'left' type = 'prompt' + alignment = 'left' [[blocks.segments]] + template = '{{.Icon}} ' + foreground = 'p:cyan' type = 'os' style = 'plain' - foreground = 'p:cyan' - template = '{{.Icon}} ' - - [[blocks.segments]] - foreground = 'p:dark_50' - style = 'plain' - template = '{{ .Path }} {{ if not .Writable}}󰌾 {{end}}' - type = 'path' [blocks.segments.properties] + cache_duration = 'none' + + [[blocks.segments]] + template = '{{ .Path }} {{ if not .Writable}}󰌾 {{end}}' + foreground = 'p:dark_50' + type = 'path' + style = 'plain' + + [blocks.segments.properties] + cache_duration = 'none' style = 'agnoster' [[blocks]] - alignment = 'left' type = 'prompt' + alignment = 'left' [[blocks.segments]] - type = 'python' + leading_diamond = '' + trailing_diamond = ' ' + template = '  {{ .Venv }} ' foreground = 'p:blue' - background = "p:bright_black" - leading_diamond = "" - style = "diamond" - trailing_diamond = " " - template = "  {{ .Venv }} " + background = 'p:bright_black' + type = 'python' + style = 'diamond' [blocks.segments.properties] + cache_duration = 'none' display_default = false [[blocks.segments]] + leading_diamond = '' + trailing_diamond = '' + template = ' {{ .UpstreamIcon }}{{ .HEAD }}{{if .BranchStatus }} {{ .BranchStatus }}{{ end }}{{ if .Working.Changed }}  {{ .Working.String }}{{ end }}{{ if and (.Working.Changed) (.Staging.Changed) }} |{{ end }}{{ if .Staging.Changed }}  {{ .Staging.String }}{{ end }}{{ if gt .StashCount 0 }}  {{ .StashCount }}{{ end }} ' foreground = 'p:bright_cyan' - background = "p:bright_black" - leading_diamond = "" - style = "diamond" - trailing_diamond = "" - template = " {{ .UpstreamIcon }}{{ .HEAD }}{{if .BranchStatus }} {{ .BranchStatus }}{{ end }}{{ if .Working.Changed }}  {{ .Working.String }}{{ end }}{{ if and (.Working.Changed) (.Staging.Changed) }} |{{ end }}{{ if .Staging.Changed }}  {{ .Staging.String }}{{ end }}{{ if gt .StashCount 0 }}  {{ .StashCount }}{{ end }} " + background = 'p:bright_black' type = 'git' + style = 'diamond' [blocks.segments.properties] branch_icon = ' ' + cache_duration = 'none' commit_icon = ' ' + fetch_stash_count = true + fetch_status = true + fetch_upstream_icon = true merge_icon = ' ' no_commits_icon = ' ' rebase_icon = ' ' revert_icon = ' ' tag_icon = ' ' - fetch_stash_count = true - fetch_status = true - fetch_upstream_icon = true [[blocks]] - type = "prompt" - alignment = "right" + type = 'prompt' + alignment = 'right' [[blocks.segments]] - foreground = 'p:green' - style = 'plain' template = '{{ .FormattedMs }}' + foreground = 'p:green' type = 'executiontime' + style = 'plain' [blocks.segments.properties] + cache_duration = 'none' style = 'austin' [[blocks.segments]] - type = "time" - style = "plain" - foreground = "p:dark_30" + foreground = 'p:dark_30' + type = 'time' + style = 'plain' [blocks.segments.properties] - time_format = "3:04:05pm" + cache_duration = 'none' + time_format = '3:04:05pm' [[blocks.segments]] - type = "session" - style = "plain" - foreground = "p:dark_50" - template = "{{.UserName}}" + template = '{{.UserName}}' + foreground = 'p:dark_50' + type = 'session' + style = 'plain' + + [blocks.segments.properties] + cache_duration = 'none' [[blocks.segments]] - type = "session" - style = "plain" - foreground = "p:cyan" - template = " {{ if .SSHSession }}󰄙 {{ else }}@{{ end }} " + template = ' {{ if .SSHSession }}󰄙 {{ else }}@{{ end }} ' + foreground = 'p:cyan' + type = 'session' + style = 'plain' + + [blocks.segments.properties] + cache_duration = 'none' [[blocks.segments]] - type = "session" - style = "plain" - foreground = "p:blue" - template = "{{.HostName}}" + template = '{{.HostName}}' + foreground = 'p:blue' + type = 'session' + style = 'plain' + + [blocks.segments.properties] + cache_duration = 'none' [[blocks]] type = 'prompt' @@ -128,24 +154,11 @@ version = 2 newline = true [[blocks.segments]] + template = '❯ ' + background = 'transparent' type = 'text' style = 'plain' - foreground_templates = [ - "{{if gt .Code 0}}p:red{{end}}", - "{{if eq .Code 0}}p:bright_green{{end}}", - ] - background = 'transparent' - template = '❯ ' + foreground_templates = ['{{if gt .Code 0}}p:red{{end}}', '{{if eq .Code 0}}p:bright_green{{end}}'] -[transient_prompt] - foreground_templates = [ - "{{if gt .Code 0}}p:red{{end}}", - "{{if eq .Code 0}}p:bright_green{{end}}", - ] - background = 'transparent' - template = '❯ ' - -[secondary_prompt] - foreground = 'p:bright_green' - background = 'transparent' - template = '❯❯ ' + [blocks.segments.properties] + cache_duration = 'none' diff --git a/link-dotfiles.ps1 b/link-dotfiles.ps1 new file mode 100644 index 0000000..0a4a843 --- /dev/null +++ b/link-dotfiles.ps1 @@ -0,0 +1,105 @@ +#!/usr/bin/env pwsh +<# +.SYNOPSIS + Windows equivalent of ./link-dotfiles (the GNU stow script). + +.DESCRIPTION + stow can't run natively on Windows, so this mirrors what it does: + home_root/* -> ~\ (e.g. ~\.zshrc) + home_config/* -> ~\.config\ (e.g. ~\.config\ohmyposh) + + Directories are linked with junctions and files with symlinks/hardlinks, + none of which need administrator rights (junctions and hardlinks never do; + symlinks are attempted first in case Developer Mode is on, then we fall + back). Re-running is safe: correct links are skipped, and any real file or + directory that would be clobbered is moved aside to .bak first. + +.EXAMPLE + pwsh -File .\link-dotfiles.ps1 +#> +[CmdletBinding()] +param( + # Print what would happen without changing anything. + [switch]$DryRun +) + +$ErrorActionPreference = 'Stop' +$repo = $PSScriptRoot +$home_ = $HOME + +# stow metadata files we must never link into the home tree. +$skip = @('.stow-local-ignore', '.stow-global-ignore') + +function Get-LinkTarget { + param([string]$Path) + $item = Get-Item -LiteralPath $Path -Force -ErrorAction SilentlyContinue + if ($item -and $item.LinkType) { return $item.Target } + return $null +} + +function Link-Item { + param( + [string]$Source, # absolute path inside the repo + [string]$Dest # absolute path under the home tree + ) + + $isDir = (Get-Item -LiteralPath $Source -Force).PSIsContainer + + # Already linked to the right place? Nothing to do. + $existingTarget = Get-LinkTarget $Dest + if ($existingTarget -and ($existingTarget -ieq $Source)) { + Write-Host " ok $Dest" -ForegroundColor DarkGray + return + } + + if (Test-Path -LiteralPath $Dest) { + if ($existingTarget) { + # A link, but pointing elsewhere -> replace it. + if ($DryRun) { Write-Host " relink $Dest (was -> $existingTarget)" -ForegroundColor Yellow; return } + Remove-Item -LiteralPath $Dest -Force -Recurse + } else { + # A real file/dir -> back it up rather than destroy it. + $bak = "$Dest.bak" + Write-Host " backup $Dest -> $bak" -ForegroundColor Yellow + if (-not $DryRun) { Move-Item -LiteralPath $Dest -Destination $bak -Force } + } + } + + if ($DryRun) { Write-Host " link $Dest -> $Source" -ForegroundColor Cyan; return } + + $parent = Split-Path $Dest -Parent + if (-not (Test-Path $parent)) { New-Item -ItemType Directory -Path $parent -Force | Out-Null } + + if ($isDir) { + New-Item -ItemType Junction -Path $Dest -Target $Source | Out-Null + Write-Host " junc $Dest -> $Source" -ForegroundColor Green + } else { + # Prefer a real symlink (needs admin or Developer Mode); fall back to a + # hardlink (same volume, no admin); finally just copy. + try { + New-Item -ItemType SymbolicLink -Path $Dest -Target $Source -ErrorAction Stop | Out-Null + Write-Host " link $Dest -> $Source" -ForegroundColor Green + } catch { + try { + New-Item -ItemType HardLink -Path $Dest -Target $Source -ErrorAction Stop | Out-Null + Write-Host " hard $Dest -> $Source" -ForegroundColor Green + } catch { + Copy-Item -LiteralPath $Source -Destination $Dest -Force + Write-Host " copy $Dest (could not link; copied)" -ForegroundColor Magenta + } + } + } +} + +Write-Host "home_root -> $home_" +Get-ChildItem -LiteralPath (Join-Path $repo 'home_root') -Force | + Where-Object { $skip -notcontains $_.Name } | + ForEach-Object { Link-Item $_.FullName (Join-Path $home_ $_.Name) } + +$configDir = Join-Path $home_ '.config' +Write-Host "home_config -> $configDir" +Get-ChildItem -LiteralPath (Join-Path $repo 'home_config') -Force | + Where-Object { $skip -notcontains $_.Name } | + ForEach-Object { Link-Item $_.FullName (Join-Path $configDir $_.Name) } + +Write-Host "Done." -ForegroundColor Green diff --git a/lk-installers/install-ohmyposh.ps1 b/lk-installers/install-ohmyposh.ps1 new file mode 100644 index 0000000..2a8a239 --- /dev/null +++ b/lk-installers/install-ohmyposh.ps1 @@ -0,0 +1,27 @@ +#!/usr/bin/env pwsh +<# +.SYNOPSIS + Install oh-my-posh on Windows (parity with ./lk-installers/install-ohmyposh). +.DESCRIPTION + Uses winget when available; otherwise falls back to the official installer. + No administrator rights are required (installs to the current user). +#> +[CmdletBinding()] +param() +$ErrorActionPreference = 'Stop' + +if (Get-Command oh-my-posh -ErrorAction SilentlyContinue) { + Write-Host "oh-my-posh already installed: $((Get-Command oh-my-posh).Source)" + return +} + +if (Get-Command winget -ErrorAction SilentlyContinue) { + Write-Host "Installing oh-my-posh via winget..." + winget install JanDeDobbeleer.OhMyPosh -s winget --accept-source-agreements --accept-package-agreements +} else { + Write-Host "winget not found; using the official installer script..." + Set-ExecutionPolicy Bypass -Scope Process -Force + Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://ohmyposh.dev/install.ps1')) +} + +Write-Host "Done. Open a new shell so PATH refreshes, then run .\link-dotfiles.ps1" From e87e55521f89f5fa35c265442c0d1b9c5b9f336d Mon Sep 17 00:00:00 2001 From: lkrav Date: Mon, 8 Jun 2026 13:29:45 -0700 Subject: [PATCH 03/22] Track Windows Terminal settings in the repo - windows/windows-terminal/settings.json: Australis scheme, VictorMono Nerd Font Mono, acrylic on the PowerShell profile - link-dotfiles.ps1: link it into the Terminal LocalState folder - README: document the windows/ folder and Terminal setup Co-Authored-By: Claude Opus 4.8 --- README.md | 10 ++ link-dotfiles.ps1 | 11 ++ windows/windows-terminal/settings.json | 143 +++++++++++++++++++++++++ 3 files changed, 164 insertions(+) create mode 100644 windows/windows-terminal/settings.json diff --git a/README.md b/README.md index 18114ee..61413ba 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ Personal dotfiles. Configs are organized by where they get linked: | -------------- | ------------ | --------------------------------- | | `home_root` | `~` | `.zshrc`, `.wezterm.lua`, `.nanorc` | | `home_config` | `~/.config` | `nvim`, `ohmyposh`, `zellij`, `ghostty` | +| `windows` | Windows-only | `windows-terminal/settings.json` | | `lk-installers`| n/a | helper scripts to install tooling | ## Linux / macOS (GNU stow) @@ -35,6 +36,15 @@ pwsh -File .\link-dotfiles.ps1 The repo stays the source of truth — edit files under `home_root` / `home_config` and the linked locations update live. +### Windows Terminal + +`windows/windows-terminal/settings.json` is linked into the Terminal package +folder (`...\Microsoft.WindowsTerminal_*\LocalState\settings.json`) by +`link-dotfiles.ps1`. Because it's linked, changes you make in the Terminal UI +write straight back into this repo. The settings include the **Australis** +color scheme and the **VictorMono Nerd Font Mono** profile font; install the +font (see below) so glyphs render. + ## Installers | Script | Platform | Purpose | diff --git a/link-dotfiles.ps1 b/link-dotfiles.ps1 index 0a4a843..91d7a53 100644 --- a/link-dotfiles.ps1 +++ b/link-dotfiles.ps1 @@ -102,4 +102,15 @@ Get-ChildItem -LiteralPath (Join-Path $repo 'home_config') -Force | Where-Object { $skip -notcontains $_.Name } | ForEach-Object { Link-Item $_.FullName (Join-Path $configDir $_.Name) } +# Windows Terminal lives in a package folder outside the stow tree, so link its +# settings.json explicitly. Skipped silently if Terminal isn't installed. +$wtPkg = Get-ChildItem (Join-Path $env:LOCALAPPDATA 'Packages') -Filter 'Microsoft.WindowsTerminal_*' -Directory -ErrorAction SilentlyContinue | + Select-Object -First 1 +$wtSrc = Join-Path $repo 'windows\windows-terminal\settings.json' +if ($wtPkg -and (Test-Path $wtSrc)) { + $wtDest = Join-Path $wtPkg.FullName 'LocalState\settings.json' + Write-Host "windows-terminal -> $wtDest" + Link-Item $wtSrc $wtDest +} + Write-Host "Done." -ForegroundColor Green diff --git a/windows/windows-terminal/settings.json b/windows/windows-terminal/settings.json new file mode 100644 index 0000000..9e8fe0b --- /dev/null +++ b/windows/windows-terminal/settings.json @@ -0,0 +1,143 @@ +{ + "$help": "https://aka.ms/terminal-documentation", + "$schema": "https://aka.ms/terminal-profiles-schema", + "actions": + [ + { + "command": + { + "action": "copy", + "singleLine": false + }, + "id": "User.copy.644BA8F2" + }, + { + "command": "paste", + "id": "User.paste" + }, + { + "command": + { + "action": "splitPane", + "split": "auto", + "splitMode": "duplicate" + }, + "id": "User.splitPane.A6751878" + }, + { + "command": "find", + "id": "User.find" + } + ], + "copyFormatting": "none", + "copyOnSelect": false, + "defaultProfile": "{574e775e-4f2a-5b96-ac1e-a2962a402336}", + "keybindings": + [ + { + "id": "User.copy.644BA8F2", + "keys": "ctrl+c" + }, + { + "id": "User.find", + "keys": "ctrl+shift+f" + }, + { + "id": "User.paste", + "keys": "ctrl+v" + }, + { + "id": "User.splitPane.A6751878", + "keys": "alt+shift+d" + } + ], + "newTabMenu": + [ + { + "type": "remainingProfiles" + } + ], + "profiles": + { + "defaults": + { + "colorScheme": "Australis", + "font": + { + "face": "VictorMono Nerd Font Mono", + "size": 11, + "features": + { + "calt": 1, + "liga": 1 + } + }, + "antialiasingMode": "grayscale", + "cursorShape": "bar", + "intenseTextStyle": "all", + "opacity": 95, + "padding": "10", + "scrollbarState": "visible", + "snapOnInput": true, + "useAcrylic": false + }, + "list": + [ + { + "commandline": "%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe", + "guid": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}", + "hidden": false, + "name": "Windows PowerShell" + }, + { + "commandline": "%SystemRoot%\\System32\\cmd.exe", + "guid": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}", + "hidden": false, + "name": "Command Prompt" + }, + { + "guid": "{b453ae62-4e3d-5e58-b989-0a998ec441b8}", + "hidden": false, + "name": "Azure Cloud Shell", + "source": "Windows.Terminal.Azure" + }, + { + "elevate": true, + "guid": "{574e775e-4f2a-5b96-ac1e-a2962a402336}", + "hidden": false, + "name": "PowerShell", + "opacity": 95, + "source": "Windows.Terminal.PowershellCore", + "useAcrylic": true + } + ] + }, + "schemes": + [ + { + "name": "Australis", + "foreground": "#a9bcc3", + "background": "#222531", + "cursorColor": "#6388d8", + "selectionBackground": "#6388d8", + "black": "#222531", + "red": "#ff491a", + "green": "#16b866", + "yellow": "#e1c631", + "blue": "#6388d8", + "purple": "#9d78ff", + "cyan": "#00b1a8", + "white": "#a9bcc3", + "brightBlack": "#373b46", + "brightRed": "#ff854f", + "brightGreen": "#51e08a", + "brightYellow": "#ffe14e", + "brightBlue": "#a4c4ff", + "brightPurple": "#d8adff", + "brightCyan": "#42dcd1", + "brightWhite": "#cce7ec" + } + ], + "themes": [], + "windowingBehavior": "useAnyExisting" +} \ No newline at end of file From 8bde6754eaf41801b4287471d72c3f87b7e5fbab Mon Sep 17 00:00:00 2001 From: lkrav Date: Mon, 8 Jun 2026 13:38:28 -0700 Subject: [PATCH 04/22] Use non-Mono VictorMono Nerd Font in Windows Terminal The "Mono" variant squeezes glyphs into single cells, distorting Victor Mono's cursive italics (bad kerning). Switch to "VictorMono Nerd Font" to match the WezTerm config, which renders italics correctly. Co-Authored-By: Claude Opus 4.8 --- windows/windows-terminal/settings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/windows/windows-terminal/settings.json b/windows/windows-terminal/settings.json index 9e8fe0b..66d46c1 100644 --- a/windows/windows-terminal/settings.json +++ b/windows/windows-terminal/settings.json @@ -64,7 +64,7 @@ "colorScheme": "Australis", "font": { - "face": "VictorMono Nerd Font Mono", + "face": "VictorMono Nerd Font", "size": 11, "features": { From afb8552d3762da5a843587440ed6632960184d1a Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 4 Jun 2026 14:16:09 -0700 Subject: [PATCH 05/22] add ~/.claude/CLAUDE.md as a managed dotfile Global Claude Code preferences (symlinked from ~/.claude/CLAUDE.md, like the other home_root dotfiles). Includes the new 'Global tools available' section documenting box-wide Playwright/Chromium on nh3-dev. --- home_root/.claude/CLAUDE.md | 574 ++++++++++++++++++++++++++++++++++++ 1 file changed, 574 insertions(+) create mode 100644 home_root/.claude/CLAUDE.md diff --git a/home_root/.claude/CLAUDE.md b/home_root/.claude/CLAUDE.md new file mode 100644 index 0000000..271bc7a --- /dev/null +++ b/home_root/.claude/CLAUDE.md @@ -0,0 +1,574 @@ +# CLAUDE.md — global preferences (lkraven) + +Loaded into every Claude Code session regardless of project. Project- +local `CLAUDE.md` files take precedence when they conflict; this file +is the baseline. + +## Core principles + +Four principles governing engineering choices across all projects. +Common lodestar: fitness-for-purpose. Each rejects a different +substitute goal that disguises itself as virtue. + +1. **Excellence over uniqueness.** Pick the shape that's right for + the problem, not the shape that's new. If uniqueness is a + byproduct of excellence, so be it; do not target it. + +2. **Explicit over implicit.** Make load-bearing assumptions, + constraints, and coupling visible. Idiomatic implicitness + (language conventions, well-known protocols) is fine — the rule + targets *invisible* implicitness, not all of it. Cost of + explicitness is verbosity; cost of invisible implicitness is + undetectable coupling. Pay the cost where auditability beats + the tax. + +3. **Elegance is a byproduct, not a target.** Excellent engineering + often produces elegant results; targeting elegance directly tends + to produce cleverness, which is a different thing. Review test: + "fit-for-purpose, debuggable, consistent" — not "feels nice." + +4. **Action-relevance over thoroughness.** Before investigating, + ask whether the answer would change the action. If both outcomes + lead to the same default, skip the question. + +## Operator cognitive-load reduction (core mission) + +A core mission: **reduce the operator's cognitive load as he context- +shifts across dozens of projects.** He knows the detailed workings of +each — the job is not to teach, it is to let him re-enter any project +and act without reloading its full context from scratch. Three +standing obligations layered on top of normal work: + +1. **Surface every architecture decision that matters to him.** + Material-consequence decisions — module boundaries, naming with + downstream reach, scope direction, anything hard to reverse — go to + him, not a peer, not a silent default. (The operator-owns- + architectural-calls rule, restated as a load-reduction duty.) Do + **not** dumb the decision down — he wants the real substance. + +2. **Pair every operator-facing decision with an `/elitk` decision + tree.** When you surface a decision for him to make, accompany the + technical framing with a King-grade (`/elitk`) decision tree: + plain-language, jargon-free, the branches and where each leads, so + he can decide in seconds without reloading the project's context. + The tree is the load-reducer; the technical framing is the + substance — give both, every time. Lead with your recommendation. + +3. **Keep a running `/elitk` summary of decisions made on his behalf.** + Every call you take autonomously (agent-discretion: patch bumps, + tie-breaks, routing, sequencing, implementation-level choices) earns + a plain-language line in a decisions summary, so he can audit what + happened in his absence without digging through the work. Offer the + `/elitk` summary unprompted at natural checkpoints and whenever he + asks "what have you decided?" + +4. **Always attach the real technical detail — never make him ask for + it.** Every `/elitk` decision tree and every decisions-summary line + carries its actual technical specifics alongside the plain-language, + clearly delineated (parentheses, brackets, an indented technical + note, a `details:` tail — your pick) so it can be read or skipped at + a glance. Plain-language is the fast-scan default; the technical + version rides *with* it, never behind a follow-up request. **He + chooses his own cognitive load by deciding whether to read the + bracketed detail** — the job is to make both present, not to + pre-decide which he needs. Example: "kept the version cadence + conservative `[F03 research work → patch v0.5.4 then v0.5.5; the two + docs-only edits → no bump per the SemVer docs-only skip-rule]`." + +This extends the non-technical-breakdown habit (auto-memory +`feedback_non_technical_breakdown_on_findings`) from findings to *all* +decisions, and sharpens it with the decision-tree-for-pending-calls +requirement. `/elitk` is the grade and the tool; its King framing — +smart reader, zero jargon — is exactly the operator mid-context-shift. + +## Cross-frontier-model consultation discipline + +Consults to non-Claude peer models (Heid = Codex/gpt-5.x oracle; +Eitri-Smithy = Codex-shaped embedded research peer; any future +non-Claude reviewer agent) operate under **two complementary +anti-failure framings**: + +1. **Authority-frame**: peers provide **fresh perspective**, not + **superior reasoning**. Different model families have different + priors and different training cutoffs — they catch different + blind spots. That is the load-bearing value, not authority. +2. **Role-frame**: peers are **peer-reviewers, not operator-level + oracles**. Routing operator-level decisions (architectural + choices, scope direction, what-to-build calls with material + consequence) to a peer for an authoritative answer is misuse — + those go to the operator regardless of what the peer says. + Peers can pressure-test, paraphrase, surface ambiguity, and + recommend implementation-level calls; they don't decide. + +Together: peers are useful reviewers whose value comes from a +different angle, not better answers; the operator owns the +architectural calls, period. + +**Default skepticism, never auto-adopt.** Every cross-frontier reply +gets triaged before any of it lands in a plan, contract, or commit. +Five-category triage: + +1. **Genuine add** — peer caught something my framing genuinely + missed. Take it. +2. **Sharpening** — peer reframed something I already had into a + sharper version. Merge into the existing variable; don't + double-count as net-new. +3. **Restatement of settled prior** — peer flagged as "missed" a + thing that is already settled in our findings/contracts/ADRs. + Useful as a coverage checklist; **not** a structural addition. +4. **Out-of-place** — peer's input is correct but belongs at a + different stage (e.g., implementation-stage detail surfaced + during frame-stage). Note and defer. +5. **Wrong-grounding** — peer reasoned from incomplete context and + manufactured a non-issue. Push back; do not adopt. + +**Watch for the ignorance-of-context failure mode.** A peer's "you +missed X" claim has two possible sources: (a) genuine fresh insight, +or (b) the peer did not read the artifact where X is settled. Before +treating an omission claim as new, check what the peer actually +read — if your settled artifact wasn't on their reading list, the +"miss" is probably category 3 or 5, not category 1. + +**Adoption criterion**: "this improves the outcome on its merits" +— never "the peer said so." Treating Codex (or any non-Claude +oracle) as an all-knowing authority is a category error; treat it +as a wise sounding board whose value is forcing you to defend +your framing against a differently-primed reader. + +**Applies hardest to `/heid*` skills.** Those skills' artifact-only +discipline protects the EMITTING side (Heid can't be primed by the +caller); the CONSUMING side rubber-stamp risk is on whoever invokes +the skill. Always triage Heid output before acting on it. + +## Development workflow shapes + +Two end-to-end shapes for taking a unit of work from idea to landed. +Pick by whether the work will be implemented by an AFK agent +(Sleipnir dispatch) or directly in-session. Both front-load the same +deliberation — heid consult → contract → heid contract review → +contract fixup — so the spec is sound before any code; they diverge +only at the implementation handoff. + +Stages are defaults, not a rigid gate. Skip a stage when it would be +ceremony (a trivial bug fix needs no vor pass; a one-liner needs no +contract). The heid consult and review stages follow the cross- +frontier triage discipline above: never auto-adopt. + +**Contract-skip is a direct-implementation privilege.** In the direct +shape, low-effort work — surgical test updates, localized bug fixes, +one-liners — runs straight to implementation without a fresh contract, +*provided* any existing contract governing the touched behavior is +updated in the same commit so it stays canonical (skip *authoring* a +contract, never let a live one go stale against the code). This does +not extend to AFK dispatch, which always requires a `prd:`-pinned +contract per § "Issue → AFK dispatch hygiene (Sleipnir)" (hard policy) +— and trivial work is not an AFK candidate in the first place: the +scaffold → contract → review → preflight ritual carries real overhead +that only pays for itself on higher-effort tasks. When in doubt, +low-effort stays direct. + +### AFK dispatch shape (Sleipnir) + +For work an AFK agent will implement off a contract. + +1. Issue created. +2. Heid consult on the issue (`/heid`) — pressure-test the framing. +3. Scaffold the issue for AFK dispatch (`/sleipnir-scaffold `) — + writes the `prd:`-pinned contract frontmatter. +4. Contract generation — the architect writes the contract body. +5. Heid contract review (`/heid-contract-review`). +6. Fixup the contract per triaged findings. +7. Preflight + mark ready-for-agent (`/sleipnir-preflight `) — the + irreversible dispatch authorization. See § "Issue → AFK dispatch + hygiene (Sleipnir)" for the gate's hard requirements. + +### Direct implementation shape + +For work implemented directly in-session. + +1. Issue created. +2. Heid consult on the issue (`/heid`). +3. `/vor` — or `/vor-frame` (ask too shapeless to draft a `/vor` + questionnaire) or `/vor-cross` (cross-frontier peer in the loop) — + if the ask warrants a pre-contract design pass. Skip when the + frame is already crisp. +4. Write the contract. +5. Heid contract review (`/heid-contract-review`). +6. Fixup the contract per triaged findings. +7. TDD implement (`/tdd`) — red-green-refactor against the contract. +8. Heid code review (`/heid-code-review`) — code-vs-contract drift. +9. Fixup the code per triaged findings. +10. Commit if clean. + +## Tooling preferences + +- **Python: prefer `uv` whenever possible.** Use `uv venv`, `uv pip + install`, `uv run`, `uv tool install`, etc. instead of `python -m + venv`, `pip`, `pipx`, `poetry`. Exception: if the project clearly + uses something else (a `poetry.lock` exists, the README says + `pip-tools`, the Dockerfile already pins `pip install`), follow the + project's tooling — don't fight it just to use uv. +- **Shell: I run interactive `zsh`.** Commands you hand me to paste + must be zsh-safe: quote glob-bearing args (`'pkg[extra]'`, not + `pkg[extra]` — zsh errors `no matches found` on unquoted brackets) + and don't rely on bash-only syntax. Inline `#` comments are fine + (`setopt interactive_comments` is set in `~/.zshrc`). Claude Code's + Bash tool also runs zsh here (it follows `$SHELL`), so the same + applies to tool commands. + +## Global tools available + +Tools standing ready in the working environment — assume present and use +them without a setup detour. (Most Claude Code sessions run natively on +**nh3-dev** `10.100.10.50`, the dev box; "available" means there unless a +note says otherwise. On other boxes, check first.) + +- **Playwright + headless Chromium** — installed **box-wide on nh3-dev**: + the system shared-libs (apt, via `playwright install-deps`), the browser + binaries in shared **`/opt/ms-playwright`** (chromium + headless-shell, + root-owned + world-readable), and + `PLAYWRIGHT_BROWSERS_PATH=/opt/ms-playwright` wired globally + (`/etc/environment` + `/etc/profile.d/`). A project only needs the + `playwright` module (`npm i playwright` — the browser download is + skippable, it resolves the shared binary); **no per-project + `playwright install`**. Use for anything that needs a real browser + engine: true DOM/SVG layout geometry, screenshots, headless rendering, + browser-based tests or scraping. Add a browser / bump via + `ssh infra-ops@10.100.10.50 'sudo env PLAYWRIGHT_BROWSERS_PATH=/opt/ms-playwright npx -y playwright install '`. + +## DevOps delegation + +For all DevOps work — deployments, infrastructure provisioning, +server administration, credential management, system-level package +installs, network/firewall configuration, service uptime — **prefer +routing to `infra-ops` via althing** rather than handling directly +in a project-dev session. + +When infra-ops needs auth keys or access it doesn't already hold, +**it asks the appropriate peer agent directly** rather than blocking +on the operator. Examples: + +- Heimdall scopes (Worldtree auth) → ask `worldtree-dev`. +- Gitea API tokens / repo permissions → ask the peer that holds + admin access for the relevant org. +- Vendor / subscription API keys (OpenAI, Anthropic, etc.) → ask + the operator or the peer that owns the consuming service. +- Cloud / hosting credentials → ask the operator. + +The principle: infra-ops is self-sufficient on the access-gathering +front. Exhaust peer-agent paths before escalating to the operator. +The operator (Vuong) is the final authority for credentials not in +any agent's possession, but the agent network should resolve +credential routing among itself when possible. + +## Attribution + +All attributions are to **Vuong Hoang**. Never reference Claude, +Claude Code, Anthropic, "AI-assisted", "Generated with …", or robot +emojis anywhere — git commit messages, PR bodies, README author lines, +LICENSE copyright, `pyproject.toml` authors, file headers, HTML +footers, or any other byline. The user is the author; the assistant +is invisible. + +Specifically, never append: + +- `Co-Authored-By: Claude …` +- `🤖 Generated with [Claude Code](…)` +- "with help from Claude / an AI assistant / etc." + +…to any committed artifact. + +## SemVer etiquette + +Each code-bearing or substantive-artifact commit bumps a version in +the project's `pyproject.toml` (or equivalent), refreshes the +lockfile, gets a `vX.Y.Z` git tag. Establishes a fine-grained +changelog and lets any peer pin against a known-good substrate +state. + +**Tier-bar test (the decision tool):** + +> *Does this release warrant a release note — or, in the case of a +> post-1.0 release, does it rise to the level of requiring a push +> notification to subscribed downstream consumers? Does this release +> warrant a blog post or a press release?* + +The escalation maps to communication metaphors: + +| Tier | Question | Communication metaphor | +|---|---|---| +| **Patch** (default) | n/a — patch is the workhorse default | Changelog line | +| **Minor** (pre-1.0) | Does this warrant a **release note**? | Subscribers glance at it | +| **Minor** (post-1.0) | Does this rise to **push-notification to subscribed downstream consumers**? | We actively reach out | +| **Major** | Does this warrant a **blog post or a press release**? | Story worth telling beyond subscribers | + +The crucial implicit calibration: **the bar for minor RISES at v1.0.** +Pre-1.0, minor is cheap (would you write a release-note paragraph?); +post-1.0, minor is expensive (would you actually interrupt downstream +consumers about this?). Pre-1.0 is iterative cheap-minors; post-1.0 +is stable deliberate-minors. Crossing v1.0 is a discipline-tightening +event, not just a number. + +**In Corviduo,** "push notification to subscribed downstream +consumers" maps concretely to: **an althing post to peer-dev handles +announcing the change**. That's the actual mechanism. Operator or +Brokkr pings worldtree-dev / galdrabok-dev / sleipnir-dev / etc. +when a post-1.0 minor lands. + +### Operator approval required for any non-patch bump + +**Patch bumps are at agent discretion.** Apply them autonomously as +part of the work. + +**Minor and major bumps REQUIRE explicit operator approval** before +the bump commit lands. The mechanism: + +1. Identify that the work warrants a non-patch bump per the + tier-bar test (release-note / push-notification / blog-post). +2. Surface to the operator with a concrete question: + *"This work appears minor-worthy because . Approve the + vX.Y.Z → vX.Y+1.0 bump?"* +3. **Wait for explicit approval** before applying the bump. +4. Apply the bump (edit pyproject.toml, run `uv lock`, commit, tag) + only after the operator has said yes. + +This guard exists because non-patch bumps in agent-applied autonomy +drifted upward — the operator caught a minor-cadence-too-fast +pathology on 2026-05-25 (three bumps in ~60 min, two of them +minor; would land at v0.4823.2 territory at sustained pace). The +tier-bar test alone wasn't sufficient discipline; explicit +operator-in-the-loop is the corrective. + +If the operator pre-authorizes a session-level batch (e.g., "just +ship the next minor when you reach the heid-orchestrator milestone"), +that constitutes approval — but the pre-authorization should be +explicit and bounded to a specific upcoming event, not "all minors +going forward." + +This rule applies UNIVERSALLY — even in repos where push is +agent-authorized (like Brokkr-Smithy per its project-local +CLAUDE.md). Push-discretion and bump-discretion are independent +authorizations. + +### Patch (`X.Y.Z` → `X.Y.Z+1`) — workhorse default + +The default for any code-bearing or substantive-artifact commit. +Includes: + +- Bug fixes +- Internal correctness improvements +- Refactors with no public-surface signature change +- New artifacts within an existing family (new R-target finding, new + spec doc, new feedback memory) +- Single-commit features that don't require downstream coordination +- Validator additions, security tightenings, drift-against-spec + corrections +- Skill specs authored (spec drafted; minor fires at implementation + ship) + +Patches accumulate routinely. Most commits are patches. + +### Minor (`X.Y.Z` → `X.Y+1.0`) — coordinated-release event + +Reserved for events where the tier-bar test fires: would you write a +release note (pre-1.0) or send a push notification to downstream +consumers (post-1.0)? + +Pre-1.0, the bar is "release-note-worthy paragraph." Post-1.0, it's +the stricter "actually-pinging-consumers." Examples that pass at +either bar: + +- **Cross-repo deliverable shipped to a peer agent** (e.g., Brokkr + R10 A01 ContextPromotion intelligence package → worldtree-dev). + Downstream HAS to react. +- **R-target full closure** — multi-finding + action lifecycle + complete; the package is the milestone landmark. +- **Skill IMPLEMENTATION shipped** at the implementation site + (post-spec absorption). Callers must adapt. +- **Methodology charter changes** (e.g., adding noise-floor + cross-check ambient to Brokkr's preregistration discipline). + High-leverage; affects every probe going forward. +- **Pre-v1.x breaking change** — under the no-backward-compatibility + rule, breaking changes ride in minor until v1.0. Breaking changes + are intrinsically release-note-worthy; minor is the right tier. +- **API signature change to publicly-callable surface** post-1.0 + that affects fewer callers than a full major (e.g., new optional + parameter, opt-in capability). Still warrants the + push-notification. + +Examples that DON'T pass the tier-bar and stay as patches: + +- A single new R-target finding (F-ID) within an active R-target's + lifecycle. The closure is the milestone, not each finding. +- A new feedback memory written. +- A spec doc authored (minor fires at implementation, not at spec). +- A new probe artifact added within an existing probe. +- A persistent-memory snapshot. + +### Major (`X.Y.Z` → `X+1.0.0`) — blog-post / press-release event + +Reserved for v1.0+ release milestones AND post-1.0 events whose +scale warrants telling people beyond your subscriber base. + +Pre-v1.x, the no-backward-compat rule means every minor can carry +breakage; major is the milestone-cut signal (v1.0 itself), not a +per-PR concern. + +Post-v1.0: + +- v1.0 release itself (the discipline-tightening crossover event). +- Substantial breaking changes that would otherwise force most + consumers to adapt at once. +- Architectural restructurings that downstream documentation, + integrations, and conceptual-mental-models depend on. + +### Decision rule when ambiguous + +**Default to patch.** Minor and major require explicit justification. +If the answer to "does this warrant a release note?" is "maybe, kind +of, I guess?" — that's a patch. Reserve minor for the unambiguous +yes-I'd-write-a-paragraph cases. + +**When both minor and patch can be justified, default to patch.** +Tie-breaks go to patch, not minor. The "both could apply" situation +is itself a signal that minor's mandate isn't strong — if minor were +clearly warranted, patch wouldn't also be defensible. Patch is the +workhorse default; let it work. This is a sharper statement of the +same posture above: the bar for non-patch is "patch is NOT defensible +for this commit," not "minor is defensible." Asymmetric default in +favor of the cheaper tier. + +The old "two callers react differently" rule remains a useful +internal check: if breaking-vs-keep-working applies to current +callers, it's at least minor. But the tier-bar is the load-bearing +test. + +### SKIP the bump entirely for + +- CI-only edits +- True docs-only edits (READMEs, comments, formatting) +- ADR commits with no code +- `.contract.md` commits with no code +- Memory-snapshot commits (`memory: snapshot — …`) +- Test-only commits with no production-code change +- WIP / TDD-RED commits where the tree is in a known-broken state +- Brokkr-side template edits with no runtime effect on Brokkr itself +- Worktree-rebuild or env-config changes +- `.claude/` configuration edits + +### Cadence + +Most commits should be patches. Minor should be rarer than commits — +often 5-15 patches between minors during active development. + +A TDD red/green/refactor cycle bumps once or twice (GREEN as patch, +REFACTOR as patch — never three times for the same logical change). +A feature shipped as several incremental green commits bumps each as +patch; the minor that "publishes" the feature can fire at the end of +the arc if it warrants a release-note, OR can be skipped if patches +were sufficient. + +If you find yourself bumping minor multiple times per session on the +same project, you're likely over-applying minor. Default back to +patch and ask: does this *specific* commit warrant a release-note +paragraph, or am I just accumulating substantive work? + +### Mechanics every bump + +0. **If non-patch, get operator approval first** per the § *Operator + approval required for any non-patch bump* rule above. Do not + proceed to step 1 until the operator has explicitly approved the + minor or major bump. (Patch bumps skip this step — apply + autonomously.) +1. Edit `pyproject.toml` (or equivalent project-file) version field. +2. Run `uv lock` (Python) or equivalent so the lockfile records the + new version. Don't hand-edit the lockfile. +3. Stage both files alongside the actual change. +4. Commit with the conventional shape (e.g., `feat(#N): …` / + `fix(#N): …` / `refactor: …`). +5. `git tag vX.Y.Z` after the commit. Lightweight (no `-a`, no + message) is deliberate for per-bump tags: the commit object + carries the rationale, and the tag is just a ref naming the + substrate state. + **Exception — milestone releases** (v1.0, v2.0, future major + cuts) get annotated tags (`git tag -a -m "…"`, or `git tag -s` + when signing). At a milestone the attestation matters separately + from the code change: release notes, tagger identity + date, and + optional GPG signature live in the tag object itself, where + downstream pins and supply-chain verifiers can read them. +6. Push is the operator's call — never push automatically. + (Project-local `CLAUDE.md` may grant push discretion, e.g., + Brokkr-Smithy; honor those when present.) + +### Calibration examples + +**Brokkr-Smithy 2026-05-25 session (the recalibration trigger):** + +Initially bumped under the pre-amendment rule: + +- `v0.1.0 → v0.2.0` (minor) — F02 R06 v2 taxonomy reduction ship +- `v0.2.0 → v0.3.0` (minor) — Heid orchestrator spec set v0.1 +- `v0.3.0 → v0.3.1` (patch) — migration runbook revision + +Under THIS amended rule: + +- F02 ship would be **patch** — single finding within R06 v2's + active lifecycle. R06 v2 closure (multi-finding + action) gets + the minor. +- Heid orchestrator spec set — **patch** strictly (spec authored, + not yet implemented). Galdrabok-dev's skill spec implementation + shipping IS minor (callers adapt). +- Runbook revision — **patch** (correct under both rules). + +The session would have ended at roughly v0.1.5 (five patches) with +maybe a v0.2.0 cut when the heid orchestrator's smoke-tests-pass + +galdrabok ship lands as the cohesive milestone. + +**Worldtree #185 (2026-05-21):** + +- `v0.20.0` (minor) — `ChromaLongTermMemory.store/search/retrieve/ + forget` gained required keyword-only `end_user_id`. Pre-v1.x + breaking change; every caller had to be updated. Release-note- + worthy in pre-1.0 framing. **Minor** under both old and new + rules. +- `v0.20.1` (patch) — Heid-flagged drift fixes within the v0.20.0 + surface. **Patch** under both rules. + +### Retroactive bumps + +Don't retroactively bump past commits to align with a tightened +rule. Substrate-state baseline is forward-looking: the bump-cadence +from this point forward reflects the discipline; past versions +record what happened under the previous rule. The pre/post boundary +is the amendment-effective commit, not the rule itself. + +## Issue → AFK dispatch hygiene (Sleipnir) + +Before marking any issue `ready-for-agent` (the label that gates AFK +dispatch via Sleipnir), it MUST have an issue-numbered contract at +`docs/contracts/issues/.contract.md` AND that contract MUST carry +a `prd:` block in its YAML frontmatter pinning it to: + +- the issue body (SHA-256, first 16 hex chars) +- the lock-in comment id + content SHA (or `null` if the issue body + alone is the spec) +- a `pinned_at` timestamp + +This is hard policy, not a suggestion. Without the contract Sleipnir's +gate refuses dispatch with `blocked-needs-contract`. Without the `prd:` +block PRD-↔-ship drift becomes invisible — the audit infrastructure +that detects it is a no-op. + +Verify before applying the label: + +- contract file exists at the expected path +- frontmatter has a populated `prd:` block +- `python scripts/contract_drift_check.py --contract ` returns + clean (i.e., the pinned hashes match the live issue + comment) + +The full convention — frontmatter shape, required fields, reasoning +behind the four drift entry points — lives in +`docs/contracts/CONTRACT-FORMAT.md` (the project that consumes +Sleipnir owns this file). Module-scoped contracts MAY adopt the same +`prd:` block when amended in response to a specific issue; for +issue-scoped contracts it is required. From 1045fdf9ad55b322bbea541c61f6f69963154f91 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 13 Jun 2026 12:13:23 -0700 Subject: [PATCH 06/22] claude/tools: granite-4.1-8b always-available summarizer/classifier + shared gateway key LiteLLM Global-tools entry: frame granite-4.1-8b as the standing always-available local summarizer/classifier endpoint (FP8, ana-ml2 GPU1, 131k ctx); add qwen3.5-9b-fp8 (vision) to the gateway listing; document the shared all-agents virtual key (alias all-agents-local) scoped to the free local models only (granite/vision/embed/rerank; paid GLM walled off). Internal-only gateway, rotatable. --- home_root/.claude/CLAUDE.md | 40 +++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/home_root/.claude/CLAUDE.md b/home_root/.claude/CLAUDE.md index 271bc7a..3c23122 100644 --- a/home_root/.claude/CLAUDE.md +++ b/home_root/.claude/CLAUDE.md @@ -236,6 +236,46 @@ note says otherwise. On other boxes, check first.) browser-based tests or scraping. Add a browser / bump via `ssh infra-ops@10.100.10.50 'sudo env PLAYWRIGHT_BROWSERS_PATH=/opt/ms-playwright npx -y playwright install '`. +- **Graphify** — open-source knowledge-graph skill for AI coding assistants + (`uv tool install graphifyy`; CLI `graphify`, MCP `graphify-mcp`). Turns a + repo into a queryable graph. The **free, deterministic path** is + `graphify update `: tree-sitter AST extraction + Leiden clustering, + **zero LLM / zero tokens**, ~25s for ~900 files; writes + `graphify-out/{graph.json,GRAPH_REPORT.md}`. Highest-value free output is + the **God Nodes** list (core-abstraction surfacing) plus `graphify explain + ` / `query` / `affected` / `path` traversals over `EXTRACTED` call + edges. The LLM layer (community **labeling** = low-caliber, and **semantic + extraction** of docs/INFERRED edges = higher-caliber + noisier) is optional + and points at any backend via `~/.graphify/providers.json` — pair labeling + with the cheap LiteLLM/Granite endpoint below; leave deep semantic + extraction off unless needed (its INFERRED/AMBIGUOUS edges fight the + explicit-over-implicit floor). Complements a hand-authored `docs/CODEBASE.md` + (curated geography), doesn't replace it. Pilot-validated on Worldtree + 2026-06-10. + +- **LiteLLM gateway (Granite 4.1 + friends)** — OpenAI-compatible gateway at + `http://10.250.50.70:4000/v1` (Logs UI `:4000/ui`) fronting vLLM services. + Essentially-**free local compute** for low-caliber, high-volume, + parallelizable LLM work. The **always-available summarizer / classifier + endpoint** is `granite-4.1-8b` — the go-to for summarization, naming/ + labeling, classification, and triage (fast, parallelizes well on vLLM): + served FP8 on ana-ml2 GPU 1, production-stable, 131k context (rebalanced + 2026-06-13). Treat it as a standing dependency you can reach for any time. + Also behind the gateway: `qwen3.5-9b-fp8` (vision / multimodal — image + + text chat, GPU 1), `qwen3-embedding`, `qwen3-reranker`, and `glm-5.1` / + `glm-4.7` (via z.ai passthrough). The gateway 401s without a **virtual API + key**. **Shared all-agents key** — internal-only gateway, scoped to the *free + local* models only (granite + qwen-vision + embed/rerank, NOT the paid GLM): + `sk-eA_XOdcs6nIkyYXonohtEQ` (alias `all-agents-local`). Use it directly for + the always-available local endpoints — no per-project provisioning needed. + Example: `curl http://10.250.50.70:4000/v1/chat/completions -H "Authorization: + Bearer sk-eA_XOdcs6nIkyYXonohtEQ" -d '{"model":"granite-4.1-8b","messages":[…]}'`. + For the **paid** GLM passthroughs or broader scope, still request a + project-scoped key from infra-ops via althing (the shared key deliberately + can't spend z.ai cost). Rotatable via infra-ops if it leaks. Reach for + this before spending premium API tokens on tasks a small fast local model + handles fine (the LLM-last-resort floor still applies — deterministic first). + ## DevOps delegation For all DevOps work — deployments, infrastructure provisioning, From c2eafe08d802e1563f26d8a36d1640956abf8bfb Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 15 Jun 2026 11:19:06 -0700 Subject: [PATCH 07/22] claude: add roadmap discipline (v1 target + parking lot, anti-creep) New "## Roadmap discipline" section in the global CLAUDE.md: every project carries a ROADMAP.md (v1 target = 3-7 capabilities + parking lot; the feature-gate defaults to parking lot regardless of who proposed the feature; creep-check at checkpoints). The feature-axis analog of value-of-information (probes) + patch-default (SemVer). Per-project file defined as a skeleton in corviduo-project-template. --- home_root/.claude/CLAUDE.md | 45 +++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/home_root/.claude/CLAUDE.md b/home_root/.claude/CLAUDE.md index 3c23122..37e2d0f 100644 --- a/home_root/.claude/CLAUDE.md +++ b/home_root/.claude/CLAUDE.md @@ -582,6 +582,51 @@ from this point forward reflects the discipline; past versions record what happened under the previous rule. The pre/post boundary is the amendment-effective commit, not the rule itself. +## Roadmap discipline — v1 target + parking lot (anti-creep) + +Projects sprawl at v0 when features land with **no v1 target to gate +them against** — every good idea, lacking a home, becomes v0 scope by +default, and the project never converges. This is the feature-axis +analog of two disciplines already in force: **value-of-information** +for probes (don't-measure-what-won't-change-behavior) and +**patch-default** for version bumps. Same posture — +*asymmetric default toward not-doing* — applied to features. + +**Every project carries a `ROADMAP.md`** (a screenful, not a PRD): + +1. **v1 target** — the small, explicit "what must be true to cut + 1.0": **3–7 capabilities**. A big v1 is itself the creep; keep it + tight. This is the done-definition AND the anchor every feature is + gated against. + +2. **Parking lot (post-v1 / vNext / spinout)** — every deferred idea, + named, with a home. Creep lands *here* instead of silently + becoming v0 scope. A "feature" that's really its own project is a + **spinout**, not v1 scope. + +3. **The gate (the anti-creep mechanism):** a proposed feature → *on + the v1 path? → in; else → parking lot.* **Default = parking lot.** + When both "v1" and "park" are defensible, park it — the same + tie-break-to-the-cheaper-tier asymmetry as the SemVer patch-default. + Applies regardless of who proposed the feature (operator included); + the gate is about v1-path-fit, not provenance. + +4. **Creep-check at checkpoints:** when surfacing progress, ask "is + what we're building on the v1 path?" Off-path-but-worth-keeping → + parking lot, surfaced to the operator, never silently into v0. + +The per-project `ROADMAP.md` file shape + location is defined in +`corviduo-project-template` as a copied-in **skeleton** (like +`persistent-memory.md` — new projects copy it, then the content +diverges per project), NOT a byte-identical canonical. The skeleton +carries the shape; the discipline itself lives in this rule (loaded +every session), so no byte-sync of content is needed. This mirrors +the SemVer global-rule + per-project-version-file split: the version +*field* is conventional, its *value* diverges per project — nobody +canonical-syncs version values, and likewise nobody syncs roadmap +content. v1.0 is cut when the ROADMAP's v1 target is met — tying +directly into the SemVer "v1.0 = discipline-tightening event." + ## Issue → AFK dispatch hygiene (Sleipnir) Before marking any issue `ready-for-agent` (the label that gates AFK From 9883a7c11d40d71a17b270eb8b3b2e7affb2ca4e Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 21 Jun 2026 10:52:24 -0700 Subject: [PATCH 08/22] claude: add Operator identity section to global CLAUDE.md Record Vuong Hoang's name + roles (Founder/Principal Developer/Chief Systems Architect of Corviduo AI and PhaseFinal, Inc; Partner + Chief Systems Architect at VastBlue AI) so identity surfaces in every Claude Code session, not just brokkr-smithy's per-project auto-memory. --- home_root/.claude/CLAUDE.md | 54 +++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/home_root/.claude/CLAUDE.md b/home_root/.claude/CLAUDE.md index 37e2d0f..45b925c 100644 --- a/home_root/.claude/CLAUDE.md +++ b/home_root/.claude/CLAUDE.md @@ -4,6 +4,19 @@ Loaded into every Claude Code session regardless of project. Project- local `CLAUDE.md` files take precedence when they conflict; this file is the baseline. +## Operator identity + +The operator is **Vuong Hoang** (lkraven@lkraven.com), addressed as +"Vuong". Roles across three organizations: + +- **Corviduo AI** — Founder, Principal Developer, Chief Systems Architect. +- **PhaseFinal, Inc** — Founder, Principal Developer, Chief Systems Architect. +- **VastBlue AI** — Partner, Chief Systems Architect. + +He is the final authority on architectural / material-consequence +calls. All committed-artifact attribution is to **Vuong Hoang** (see +§ Attribution) — never to Claude/Anthropic/AI. + ## Core principles Four principles governing engineering choices across all projects. @@ -140,6 +153,30 @@ discipline protects the EMITTING side (Heid can't be primed by the caller); the CONSUMING side rubber-stamp risk is on whoever invokes the skill. Always triage Heid output before acting on it. +## Althing async-reply monitoring + +When you ship an althing message that you expect to come back with a +reply — a consult (`/heid*`), a question to a peer agent, a request +awaiting an answer — and you do **not** already have an althing +monitor running for this session, **always start one** +(`/althing:monitor`). The dispatch and the monitor are one action: you +opened a loop, so arm the thing that closes it. + +Why: in an interactive session the inbox banner (📬) only fires on the +*next* user prompt. If the operator steps away after you dispatch an +async consult, the reply can sit unseen indefinitely — the loop you +opened never closes on its own. A monitor actively pings when the +reply lands, so the await-reply promise ("reply will land in your +inbox") is backed by a real notification, not by hoping the operator +prompts again. + +Scope: only messages where you're waiting on a response. Pure +fire-and-forget posts (an FYI ping, a post-1.0 downstream-consumer +announcement) don't need a monitor. When the exchange is done, sign +off (`/althing:sign-off`) so monitors don't accumulate — stop a stuck +one with `althing-light-monitor --stop`, never `pkill` (that kills +every agent's monitor, not just yours). + ## Development workflow shapes Two end-to-end shapes for taking a unit of work from idea to landed. @@ -167,6 +204,23 @@ scaffold → contract → review → preflight ritual carries real overhead that only pays for itself on higher-effort tasks. When in doubt, low-effort stays direct. +**Graphify the blast radius BEFORE writing the contract** — for ANY +contract that touches existing code (not greenfield). Run a graphify +pass over every symbol the contract will change, delete, or rename +(`graphify explain ` for callers/neighbors, `graphify path` +for reach) so the contract's scope section enumerates the *true* set +of affected files and call-sites — not an under-count that detonates +mid-implementation. **Cross-check with grep, always.** Graphify is +blind to function-local and DI-injected imports (`from .x import y` +inside a function body, store objects passed through constructors) — +the exact pattern that hides cross-module callers. Graphify confirms +the call structure; grep catches what its AST extraction misses; +neither alone is sufficient (graphify-only under-counts, grep-only +misses transitive reach). Both, before the contract — the scope +section is only as honest as the blast-radius pass behind it. (Lesson: +a contract that names 3 files when the rip touches 6 is a scope miss +the up-front pass would have caught.) + ### AFK dispatch shape (Sleipnir) For work an AFK agent will implement off a contract. From 7076d4019109df5c7be543da8edbac7f5b124cf4 Mon Sep 17 00:00:00 2001 From: lkrav Date: Fri, 26 Jun 2026 07:33:57 -0700 Subject: [PATCH 09/22] chore(shell): powerlevel10k prompt, host-aware bootstrap, drop thefuck MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - zsh prompt: replace oh-my-posh with powerlevel10k via zinit, with the instant-prompt preamble near the top of .zshrc for fast startup - remove thefuck/thefk entirely: .zshrc aliases, install-thefk, home_config/thefuck, and its .stow-global-ignore entry - link-dotfiles: one-shot host-aware bootstrap — detect macOS vs Linux, install GNU stow if missing (brew / apt/dnf/pacman), then stow both trees - retire oh-my-posh: delete the bash + pwsh installers and home_config/ohmyposh (starship covers PowerShell separately) - README: document the new bootstrap and prompt setup --- README.md | 39 ++--- home_config/ohmyposh/base.yaml | 136 --------------- home_config/ohmyposh/lkraven.toml | 164 ------------------ .../__pycache__/settings.cpython-311.pyc | Bin 150 -> 0 bytes .../__pycache__/settings.cpython-313.pyc | Bin 137 -> 0 bytes home_config/thefuck/settings.py | 26 --- home_root/.stow-global-ignore | 1 - home_root/.zshrc | 18 +- link-dotfiles | 54 +++++- link-dotfiles.ps1 | 2 +- lk-installers/install-ohmyposh | 1 - lk-installers/install-ohmyposh.ps1 | 27 --- lk-installers/install-thefk | 8 - 13 files changed, 79 insertions(+), 397 deletions(-) delete mode 100644 home_config/ohmyposh/base.yaml delete mode 100644 home_config/ohmyposh/lkraven.toml delete mode 100644 home_config/thefuck/__pycache__/settings.cpython-311.pyc delete mode 100644 home_config/thefuck/__pycache__/settings.cpython-313.pyc delete mode 100644 home_config/thefuck/settings.py delete mode 100755 lk-installers/install-ohmyposh delete mode 100644 lk-installers/install-ohmyposh.ps1 delete mode 100755 lk-installers/install-thefk diff --git a/README.md b/README.md index 61413ba..0dd7024 100644 --- a/README.md +++ b/README.md @@ -5,19 +5,22 @@ Personal dotfiles. Configs are organized by where they get linked: | Folder | Links into | Examples | | -------------- | ------------ | --------------------------------- | | `home_root` | `~` | `.zshrc`, `.wezterm.lua`, `.nanorc` | -| `home_config` | `~/.config` | `nvim`, `ohmyposh`, `zellij`, `ghostty` | +| `home_config` | `~/.config` | `nvim`, `zellij`, `ghostty`, `aerospace` | | `windows` | Windows-only | `windows-terminal/settings.json` | | `lk-installers`| n/a | helper scripts to install tooling | ## Linux / macOS (GNU stow) -Requires [`stow`](https://www.gnu.org/software/stow/). +One-shot, host-aware: ```bash ./link-dotfiles ``` -This runs `stow home_root` and `stow --target=$HOME/.config home_config`. +It detects the host (macOS vs Linux), installs [`stow`](https://www.gnu.org/software/stow/) +if missing (Homebrew on macOS; apt/dnf/pacman on Linux), then runs +`stow home_root` and `stow --target=$HOME/.config home_config`. Re-running is +safe — stow is idempotent. ## Windows (PowerShell) @@ -45,27 +48,15 @@ write straight back into this repo. The settings include the **Australis** color scheme and the **VictorMono Nerd Font Mono** profile font; install the font (see below) so glyphs render. -## Installers +## Prompt -| Script | Platform | Purpose | -| ------------------------------- | -------- | ------------------ | -| `lk-installers/install-ohmyposh` | bash | oh-my-posh (Linux/macOS) | -| `lk-installers/install-ohmyposh.ps1` | pwsh | oh-my-posh (Windows, via winget) | +**zsh uses [Powerlevel10k](https://github.com/romkatv/powerlevel10k)** — loaded +through zinit straight from `.zshrc`, with the instant-prompt preamble near the +top for fast startup. The theme config lives at `home_root/.p10k.zsh` (stowed to +`~/.p10k.zsh`); there's no separate installer — zinit fetches it on first shell +start. -```powershell -# Windows: install oh-my-posh, then link -pwsh -File .\lk-installers\install-ohmyposh.ps1 -pwsh -File .\link-dotfiles.ps1 -``` +PowerShell uses [starship](https://starship.rs/) (configured separately). -### oh-my-posh - -The prompt theme lives at `home_config/ohmyposh/lkraven.toml` and is loaded from -your shell profile, e.g. in PowerShell: - -```powershell -oh-my-posh init pwsh --config '~/.config/ohmyposh/lkraven.toml' | Invoke-Expression -``` - -It expects a Nerd Font (e.g. **VictorMono Nerd Font Mono**) to be installed and -selected in your terminal for the glyphs to render correctly. +Both expect a **Nerd Font v3** (e.g. **VictorMono Nerd Font Mono**) installed and +selected in your terminal for glyphs to render. diff --git a/home_config/ohmyposh/base.yaml b/home_config/ohmyposh/base.yaml deleted file mode 100644 index 3c4d2b0..0000000 --- a/home_config/ohmyposh/base.yaml +++ /dev/null @@ -1,136 +0,0 @@ -# yaml-language-server: $schema=https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/schema.json - -version: 2 -final_space: true -console_title_template: "{{ .Shell }} in {{ .Folder }}" -blocks: -- type: prompt - alignment: left - segments: - - type: session - style: diamond - foreground: p:black - background: p:yellow - leading_diamond:  - trailing_diamond:  - template: " {{ if .SSHSession }}\ueba9 {{ end }}{{ .UserName }} " - - type: path - style: powerline - powerline_symbol:  - foreground: p:white - background: p:orange - template: " \uea83 {{ path .Path .Location }} " - properties: - style: folder - - type: git - style: powerline - powerline_symbol:  - foreground: p:black - foreground_templates: - - "{{ if or (.Working.Changed) (.Staging.Changed) }}p:black{{ end }}" - - "{{ if and (gt .Ahead 0) (gt .Behind 0) }}p:white{{ end }}" - - "{{ if gt .Ahead 0 }}p:white{{ end }}" - background: p:green - background_templates: - - "{{ if or (.Working.Changed) (.Staging.Changed) }}p:yellow{{ end }}" - - "{{ if and (gt .Ahead 0) (gt .Behind 0) }}p:red{{ end }}" - - "{{ if gt .Ahead 0 }}#49416D{{ end }}" - - "{{ if gt .Behind 0 }}#7A306C{{ end }}" - template: " {{ if .UpstreamURL }}{{ url .UpstreamIcon .UpstreamURL }} {{ end }}{{ .HEAD }}{{if .BranchStatus }} {{ .BranchStatus }}{{ end }}{{ if .Working.Changed }} \uf044 {{ .Working.String }}{{ end }}{{ if .Staging.Changed }} \uf046 {{ .Staging.String }}{{ end }} " - properties: - branch_max_length: 25 - fetch_status: true - fetch_upstream_icon: true - - type: root - style: powerline - powerline_symbol:  - foreground: p:white - background: p:yellow - template: " \uf0e7 " - - type: status - style: diamond - foreground: p:white - background: p:blue - background_templates: - - "{{ if gt .Code 0 }}p:red{{ end }}" - leading_diamond:  - trailing_diamond:  - template: " {{ if gt .Code 0 }}\uf00d{{ else }}\uf00c{{ end }} " - properties: - always_enabled: true -- type: rprompt - segments: - - type: node - style: plain - foreground: p:green - background: transparent - template: "\ue718 " - properties: - display_mode: files - fetch_package_manager: false - home_enabled: false - - type: go - style: plain - foreground: p:blue - background: transparent - template: "\ue626 " - properties: - fetch_version: false - - type: python - style: plain - foreground: p:yellow - background: transparent - template: "\ue235 " - properties: - display_mode: files - fetch_version: false - fetch_virtual_env: false - - type: shell - style: plain - foreground: p:white - background: transparent - template: "in {{ .Name }} " - - type: time - style: plain - foreground: p:white - background: transparent - template: at {{ .CurrentDate | date "15:04:05" }} -tooltips: -- type: aws - tips: - - aws - style: diamond - foreground: p:white - background: p:orange - leading_diamond:  - trailing_diamond:  - template: " \ue7ad {{ .Profile }}{{ if .Region }}@{{ .Region }}{{ end }} " - properties: - display_default: true -- type: az - tips: - - az - style: diamond - foreground: p:white - background: p:blue - leading_diamond:  - trailing_diamond:  - template: " \uebd8 {{ .Name }} " - properties: - display_default: true -transient_prompt: - foreground: p:black - background: transparent - template: "\ue0b6<,p:yellow> {{ .Folder }} \ue0b0 " -secondary_prompt: - foreground: p:black - background: transparent - template: "\ue0b6<,p:yellow> > \ue0b0 " -palette: - black: "#262B44" - blue: "#4B95E9" - green: "#59C9A5" - orange: "#F07623" - red: "#D81E5B" - white: "#E0DEF4" - yellow: "#F3AE35" diff --git a/home_config/ohmyposh/lkraven.toml b/home_config/ohmyposh/lkraven.toml deleted file mode 100644 index b92eac0..0000000 --- a/home_config/ohmyposh/lkraven.toml +++ /dev/null @@ -1,164 +0,0 @@ -console_title_template = '{{if .Root}}(Admin){{end}} {{.PWD}}' -version = 3 - -[palette] - black = '#222531' - blue = '#6388D8' - bright_70 = '#9daeb6' - bright_80 = '#b3cbcf' - bright_90 = '#cce7ec' - bright_black = '#373b46' - bright_blue = '#a4c4ff' - bright_cyan = '#42dcd1' - bright_green = '#51e08a' - bright_magenta = '#d8adff' - bright_red = '#ff854f' - bright_white = '#cce7ec' - bright_yellow = '#FFE14E' - cyan = '#00b1a8' - dark_30 = '#414751' - dark_40 = '#565f69' - dark_50 = '#6e7882' - dark_60 = '#86929d' - green = '#16B866' - magenta = '#9d78ff' - red = '#ff491a' - white = '#a9bcc3' - yellow = '#e1c631' - -[secondary_prompt] - template = '❯❯ ' - foreground = 'p:bright_green' - background = 'transparent' - -[transient_prompt] - template = '❯ ' - background = 'transparent' - foreground_templates = ['{{if gt .Code 0}}p:red{{end}}', '{{if eq .Code 0}}p:bright_green{{end}}'] - -[[blocks]] - type = 'prompt' - alignment = 'left' - - [[blocks.segments]] - template = '{{.Icon}} ' - foreground = 'p:cyan' - type = 'os' - style = 'plain' - - [blocks.segments.properties] - cache_duration = 'none' - - [[blocks.segments]] - template = '{{ .Path }} {{ if not .Writable}}󰌾 {{end}}' - foreground = 'p:dark_50' - type = 'path' - style = 'plain' - - [blocks.segments.properties] - cache_duration = 'none' - style = 'agnoster' - -[[blocks]] - type = 'prompt' - alignment = 'left' - - [[blocks.segments]] - leading_diamond = '' - trailing_diamond = ' ' - template = '  {{ .Venv }} ' - foreground = 'p:blue' - background = 'p:bright_black' - type = 'python' - style = 'diamond' - - [blocks.segments.properties] - cache_duration = 'none' - display_default = false - - [[blocks.segments]] - leading_diamond = '' - trailing_diamond = '' - template = ' {{ .UpstreamIcon }}{{ .HEAD }}{{if .BranchStatus }} {{ .BranchStatus }}{{ end }}{{ if .Working.Changed }}  {{ .Working.String }}{{ end }}{{ if and (.Working.Changed) (.Staging.Changed) }} |{{ end }}{{ if .Staging.Changed }}  {{ .Staging.String }}{{ end }}{{ if gt .StashCount 0 }}  {{ .StashCount }}{{ end }} ' - foreground = 'p:bright_cyan' - background = 'p:bright_black' - type = 'git' - style = 'diamond' - - [blocks.segments.properties] - branch_icon = ' ' - cache_duration = 'none' - commit_icon = ' ' - fetch_stash_count = true - fetch_status = true - fetch_upstream_icon = true - merge_icon = ' ' - no_commits_icon = ' ' - rebase_icon = ' ' - revert_icon = ' ' - tag_icon = ' ' - -[[blocks]] - type = 'prompt' - alignment = 'right' - - [[blocks.segments]] - template = '{{ .FormattedMs }}' - foreground = 'p:green' - type = 'executiontime' - style = 'plain' - - [blocks.segments.properties] - cache_duration = 'none' - style = 'austin' - - [[blocks.segments]] - foreground = 'p:dark_30' - type = 'time' - style = 'plain' - - [blocks.segments.properties] - cache_duration = 'none' - time_format = '3:04:05pm' - - [[blocks.segments]] - template = '{{.UserName}}' - foreground = 'p:dark_50' - type = 'session' - style = 'plain' - - [blocks.segments.properties] - cache_duration = 'none' - - [[blocks.segments]] - template = ' {{ if .SSHSession }}󰄙 {{ else }}@{{ end }} ' - foreground = 'p:cyan' - type = 'session' - style = 'plain' - - [blocks.segments.properties] - cache_duration = 'none' - - [[blocks.segments]] - template = '{{.HostName}}' - foreground = 'p:blue' - type = 'session' - style = 'plain' - - [blocks.segments.properties] - cache_duration = 'none' - -[[blocks]] - type = 'prompt' - alignment = 'left' - newline = true - - [[blocks.segments]] - template = '❯ ' - background = 'transparent' - type = 'text' - style = 'plain' - foreground_templates = ['{{if gt .Code 0}}p:red{{end}}', '{{if eq .Code 0}}p:bright_green{{end}}'] - - [blocks.segments.properties] - cache_duration = 'none' diff --git a/home_config/thefuck/__pycache__/settings.cpython-311.pyc b/home_config/thefuck/__pycache__/settings.cpython-311.pyc deleted file mode 100644 index e41c17853076b0fd05e02b01bd9bbe0db9dd519e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 150 zcmZ3^%ge<81ha2!&iKm2!0;HvfdNJ+<1-tOF`XfWA(%mv(QhR~5l|t+XOQGCP5q4g z+*JLX?4rc7)I5E?gjEsy$%s>_Zs_7u| diff --git a/home_config/thefuck/settings.py b/home_config/thefuck/settings.py deleted file mode 100644 index 8478f6d..0000000 --- a/home_config/thefuck/settings.py +++ /dev/null @@ -1,26 +0,0 @@ -# The Fuck settings file -# -# The rules are defined as in the example bellow: -# -# rules = ['cd_parent', 'git_push', 'python_command', 'sudo'] -# -# The default values are as follows. Uncomment and change to fit your needs. -# See https://github.com/nvbn/thefuck#settings for more information. -# - -# rules = [] -# exclude_rules = [] -# wait_command = 3 -# require_confirmation = True -# no_colors = False -# debug = False -# priority = {} -# history_limit = None -# alter_history = True -# wait_slow_command = 15 -# slow_commands = ['lein', 'react-native', 'gradle', './gradlew', 'vagrant'] -# repeat = False -# instant_mode = False -# num_close_matches = 3 -# env = {'LC_ALL': 'C', 'LANG': 'C', 'GIT_TRACE': '1'} -# excluded_search_path_prefixes = [] diff --git a/home_root/.stow-global-ignore b/home_root/.stow-global-ignore index 067cc2e..f1592b8 100644 --- a/home_root/.stow-global-ignore +++ b/home_root/.stow-global-ignore @@ -1,5 +1,4 @@ ~/.config/tmux/plugins -~/.config/thefuck/__pycache__ ~/.config/btop ~/.config/neofetch ~/.config/zinit diff --git a/home_root/.zshrc b/home_root/.zshrc index 05776d9..a24ecf5 100644 --- a/home_root/.zshrc +++ b/home_root/.zshrc @@ -3,9 +3,12 @@ path=(~/bin $path) path=(~/.local/bin $path) path=(~/.cache/lk-tools/fzf/bin $path) - -# Init OhMyPosh -eval "$(oh-my-posh init zsh --config https://333e8677ac54a1845fe68813017ab7e807c87ab2@gitea.phasefinal.com/vh/dotfiles/raw/branch/master/home_config/ohmyposh/lkraven.toml)" +# Enable Powerlevel10k instant prompt. Should stay close to the top of ~/.zshrc. +# Initialization code that may require console input (password prompts, [y/n] +# confirmations, etc.) must go above this block; everything else may go below. +if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then + source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" +fi # Set ZINIT Home ZINIT_HOME="${HOME}/.config/zinit/zinit.git" @@ -20,6 +23,10 @@ fi source "${ZINIT_HOME}/zinit.zsh" # add zinit +# Powerlevel10k prompt theme (replaces oh-my-posh; instant prompt = fast startup) +zinit ice depth=1 +zinit light romkatv/powerlevel10k + zinit light zsh-users/zsh-syntax-highlighting zinit light zsh-users/zsh-completions zinit light zsh-users/zsh-autosuggestions @@ -67,7 +74,7 @@ alias cat='bat' alias tree='eza --tree' # To customize prompt, run `p10k configure` or edit ~/.p10k.zsh. -# [[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh +[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh [ -f ~/.fzf.zsh ] && source ~/.fzf.zsh export FZF_DEFAULT_COMMAND="fd --hidden --strip-cwd-prefix --exclude .git" @@ -99,9 +106,6 @@ export BAT_THEME=Nord eval "$(zoxide init zsh)" alias cd='z' -eval $(thefuck --alias) -eval $(thefuck --alias fk) - zinit light Aloxaf/fzf-tab diff --git a/link-dotfiles b/link-dotfiles index dd39023..a27e3cb 100755 --- a/link-dotfiles +++ b/link-dotfiles @@ -1,3 +1,53 @@ -#!/bin/bash +#!/usr/bin/env bash +# One-shot, host-aware dotfile linker for Linux & macOS. +# +# home_root/* -> ~/ (e.g. ~/.zshrc) via `stow home_root` +# home_config/* -> ~/.config/ (e.g. ~/.config/nvim) via `stow home_config` +# +# Ensures GNU stow is present first (Homebrew on macOS; apt/dnf/pacman on Linux), +# so a fresh box needs nothing pre-installed. Re-running is safe — stow is +# idempotent and refuses to clobber unrelated real files. +# +# Windows / PowerShell: run ./link-dotfiles.ps1 instead (stow has no native +# Windows port; the .ps1 mirrors this with junctions + symlinks). +set -euo pipefail + +repo="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$repo" + +ensure_stow() { + command -v stow >/dev/null 2>&1 && return + + echo "GNU stow not found — installing it…" + case "$(uname -s)" in + Darwin) + if ! command -v brew >/dev/null 2>&1; then + echo "error: Homebrew is required on macOS. Run ./lk-installers/macinstaller first." >&2 + exit 1 + fi + brew install stow + ;; + Linux) + if command -v apt >/dev/null 2>&1; then sudo apt update && sudo apt install -y stow + elif command -v dnf >/dev/null 2>&1; then sudo dnf install -y stow + elif command -v pacman >/dev/null 2>&1; then sudo pacman -S --noconfirm stow + else + echo "error: no supported package manager (apt/dnf/pacman). Install GNU stow manually." >&2 + exit 1 + fi + ;; + *) + echo "error: unsupported OS '$(uname -s)'. On Windows run ./link-dotfiles.ps1 instead." >&2 + exit 1 + ;; + esac +} + +ensure_stow + +echo "Linking home_root -> ~" stow -v home_root -stow -v --target=$HOME/.config/ home_config +echo "Linking home_config -> ~/.config" +stow -v --target="$HOME/.config" home_config + +echo "Done." diff --git a/link-dotfiles.ps1 b/link-dotfiles.ps1 index 91d7a53..06b8fcc 100644 --- a/link-dotfiles.ps1 +++ b/link-dotfiles.ps1 @@ -6,7 +6,7 @@ .DESCRIPTION stow can't run natively on Windows, so this mirrors what it does: home_root/* -> ~\ (e.g. ~\.zshrc) - home_config/* -> ~\.config\ (e.g. ~\.config\ohmyposh) + home_config/* -> ~\.config\ (e.g. ~\.config\nvim) Directories are linked with junctions and files with symlinks/hardlinks, none of which need administrator rights (junctions and hardlinks never do; diff --git a/lk-installers/install-ohmyposh b/lk-installers/install-ohmyposh deleted file mode 100755 index fc99f28..0000000 --- a/lk-installers/install-ohmyposh +++ /dev/null @@ -1 +0,0 @@ -curl -s https://ohmyposh.dev/install.sh | bash -s diff --git a/lk-installers/install-ohmyposh.ps1 b/lk-installers/install-ohmyposh.ps1 deleted file mode 100644 index 2a8a239..0000000 --- a/lk-installers/install-ohmyposh.ps1 +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env pwsh -<# -.SYNOPSIS - Install oh-my-posh on Windows (parity with ./lk-installers/install-ohmyposh). -.DESCRIPTION - Uses winget when available; otherwise falls back to the official installer. - No administrator rights are required (installs to the current user). -#> -[CmdletBinding()] -param() -$ErrorActionPreference = 'Stop' - -if (Get-Command oh-my-posh -ErrorAction SilentlyContinue) { - Write-Host "oh-my-posh already installed: $((Get-Command oh-my-posh).Source)" - return -} - -if (Get-Command winget -ErrorAction SilentlyContinue) { - Write-Host "Installing oh-my-posh via winget..." - winget install JanDeDobbeleer.OhMyPosh -s winget --accept-source-agreements --accept-package-agreements -} else { - Write-Host "winget not found; using the official installer script..." - Set-ExecutionPolicy Bypass -Scope Process -Force - Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://ohmyposh.dev/install.ps1')) -} - -Write-Host "Done. Open a new shell so PATH refreshes, then run .\link-dotfiles.ps1" diff --git a/lk-installers/install-thefk b/lk-installers/install-thefk deleted file mode 100755 index c66aa2f..0000000 --- a/lk-installers/install-thefk +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -sudo apt update -sudo apt install python3-dev python3-pip python3-setuptools python3-venv -python3 -m venv ~/homebase -source ~/homebase/bin/activate -pip3 install thefuck -mv ~/homebase/bin/fuck ~/.local/bin/ -mv ~/homebase/bin/thefuck ~/.local/bin/ From 262a59b8b26d60d3adcefc6f863bf3f97ff9185f Mon Sep 17 00:00:00 2001 From: Vuong Hoang Date: Fri, 26 Jun 2026 07:37:16 -0700 Subject: [PATCH 10/22] feat(ghostty): adopt live config into repo The repo carried an empty home_config/ghostty/config; the actual working config (Victor Mono Nerd Font, australis theme, ssh-terminfo, scrollback, macOS option-as-alt) lived only on the machine. Pull it in so stow links the real config instead of blanking it. --- home_config/ghostty/config | 53 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/home_config/ghostty/config b/home_config/ghostty/config index e69de29..4f7d1af 100644 --- a/home_config/ghostty/config +++ b/home_config/ghostty/config @@ -0,0 +1,53 @@ +# Ghostty configuration +# Docs: https://ghostty.org/docs/config +# Reload in-app without restarting: Cmd+Shift+, + +# --- Font --------------------------------------------------------------- +# VictorMono Nerd Font (installed in ~/Library/Fonts). The "Mono" variant +# keeps glyphs strictly fixed-width, which is what you want in a terminal. +font-family = VictorMono Nerd Font Mono +font-size = 14 +# Slightly heavier strokes render nicer on macOS Retina displays. +font-thicken = true + +# Victor Mono ships a gorgeous cursive italic — make sure it's used. +font-style-italic = Italic + +# --- Theme -------------------------------------------------------------- +# Australis (Aurora Australis) — a dark theme. Defined in +# ~/.config/ghostty/themes/australis (ported from the upstream WezTerm config). +theme = australis + +# --- Cursor ------------------------------------------------------------- +cursor-style = block +cursor-style-blink = false +mouse-hide-while-typing = true + +# --- Window ------------------------------------------------------------- +window-padding-x = 8 +window-padding-y = 6 +# Keep padding color matched to the background for a clean look. +window-padding-balance = true +# Reopen with the same windows/tabs you left. +window-save-state = always +macos-titlebar-style = tabs +background-opacity = 0.97 + +# --- Clipboard / selection --------------------------------------------- +copy-on-select = clipboard +clipboard-trim-trailing-spaces = true + +# --- macOS / shell behavior -------------------------------------------- +# Let the left Option key send Alt (so Alt+f, Alt+b, etc. work in shells/ +# editors); keep right Option for composing accented characters. +macos-option-as-alt = left +shell-integration = detect +# ssh-env + ssh-terminfo: on connect, propagate a compatible TERM and +# auto-install Ghostty's terminfo entry on the remote host (v1.2.0+), so +# remote apps render correctly without "unknown terminal type" errors. +shell-integration-features = cursor,sudo,title,ssh-env,ssh-terminfo + +# --- Misc --------------------------------------------------------------- +# Only prompt to close when a process is still running. +confirm-close-surface = true +scrollback-limit = 10000000 From ae1f13a8a3bda27d770c69318ef85adc7aabf402 Mon Sep 17 00:00:00 2001 From: Vuong Hoang Date: Fri, 26 Jun 2026 07:40:26 -0700 Subject: [PATCH 11/22] chore(shell): remove eza Drop the ls/tree eza aliases, swap the two fzf directory previews to a portable 'ls -la', and delete the install-eza installer. --- home_root/.zshrc | 6 ++---- lk-installers/install-eza | 17 ----------------- 2 files changed, 2 insertions(+), 21 deletions(-) delete mode 100755 lk-installers/install-eza diff --git a/home_root/.zshrc b/home_root/.zshrc index a24ecf5..9702c1c 100644 --- a/home_root/.zshrc +++ b/home_root/.zshrc @@ -69,9 +69,7 @@ zstyle ':fzf-tab:complete:__zoxide_z:*' fzf-preview 'ls --color $realpath' zstyle ':fzf-tab:*' fzf-command ftb-tmux-popup # aliases -alias ls='eza' alias cat='bat' -alias tree='eza --tree' # To customize prompt, run `p10k configure` or edit ~/.p10k.zsh. [[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh @@ -90,13 +88,13 @@ _fzf_compgen_dir() { source ~/fzf-git.sh/fzf-git.sh export FZF_CTRL_T_OPTS="--preview 'bat -n --color=always --line-range :500 {}'" -export FZF_ALT_C_OPTS="--preview 'eza --tree --color=always {} | head -200'" +export FZF_ALT_C_OPTS="--preview 'ls -la {} | head -200'" _fzf_comprun() { local command=$1 shift case "$command" in - cd) fzf --preview 'eza --tree --color=always {} | head -200' "$@" ;; + cd) fzf --preview 'ls -la {} | head -200' "$@" ;; export|unset) fzf --preview "eval 'echo \$' {}" "$@" ;; ssh) fzf --preview 'dig {}' "$@" ;; *) fzf --preview 'bat -n --color=always --line-range :500 {}' "$@" ;; diff --git a/lk-installers/install-eza b/lk-installers/install-eza deleted file mode 100755 index b09cb78..0000000 --- a/lk-installers/install-eza +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -# Check if Eza is installed - -if dpkg-query -Wf'${db:Status-abbrev}' eza; then - sudo apt install -y eza -else - sudo apt update - sudo apt install gpg - sudo mkdir -p /etc/apt/keyrings - wget -qO- https://raw.githubusercontent.com/eza-community/eza/main/deb.asc | sudo gpg --dearmor -o /etc/apt/keyrings/gierens.gpg - echo "deb [signed-by=/etc/apt/keyrings/gierens.gpg] http://deb.gierens.de stable main" | sudo tee /etc/apt/sources.list.d/gierens.list - sudo chmod 644 /etc/apt/keyrings/gierens.gpg /etc/apt/sources.list.d/gierens.list - sudo apt update - sudo apt install -y eza -fi - From bf179ef0b1e1ca339bf3fe436494d0d4928b64b1 Mon Sep 17 00:00:00 2001 From: Vuong Hoang Date: Fri, 26 Jun 2026 07:55:16 -0700 Subject: [PATCH 12/22] feat(installers): consolidate app installers into host-aware install-apps Fold macinstaller + install-apt-pkgs + install-tools + install-zellij into a single host-aware lk-installers/install-apps (macOS->Homebrew, bootstrapping Homebrew if absent; Linux->apt + upstream installers). Installs the tools the configs assume (bat, fd, fzf, zoxide, zellij, nvim, btop, htop, tldr) plus the fzf-git.sh helper and fzf shell integration; idempotent. link-dotfiles gains --apps to install then link in one shot. .zshrc drops the redundant brew/system zsh-autosuggestions source (zinit already loads it), fixing the missing-file error on a fresh box. README documents the new flow. --- README.md | 20 ++++++- home_root/.zshrc | 7 ++- link-dotfiles | 10 +++- lk-installers/install-apps | 99 ++++++++++++++++++++++++++++++++++ lk-installers/install-apt-pkgs | 3 -- lk-installers/install-tools | 8 --- lk-installers/install-zellij | 7 --- lk-installers/macinstaller | 35 ------------ 8 files changed, 130 insertions(+), 59 deletions(-) create mode 100755 lk-installers/install-apps delete mode 100755 lk-installers/install-apt-pkgs delete mode 100755 lk-installers/install-tools delete mode 100755 lk-installers/install-zellij delete mode 100755 lk-installers/macinstaller diff --git a/README.md b/README.md index 0dd7024..4a72d7d 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,8 @@ Personal dotfiles. Configs are organized by where they get linked: One-shot, host-aware: ```bash -./link-dotfiles +./link-dotfiles # link only (installs stow if missing) +./link-dotfiles --apps # fresh box: install all CLI tools, then link ``` It detects the host (macOS vs Linux), installs [`stow`](https://www.gnu.org/software/stow/) @@ -22,6 +23,23 @@ if missing (Homebrew on macOS; apt/dnf/pacman on Linux), then runs `stow home_root` and `stow --target=$HOME/.config home_config`. Re-running is safe — stow is idempotent. +### Installing the tools + +The configs assume a handful of CLI tools (`bat`, `fd`, `fzf`, `zoxide`, +`zellij`, `nvim`, `btop`, `htop`, `tldr`, plus the `fzf-git.sh` helper). One +host-aware installer covers them: + +```bash +./lk-installers/install-apps # macOS -> Homebrew; Linux -> apt + upstream +``` + +On macOS it bootstraps Homebrew if absent. It's idempotent — re-running only +fills gaps. `./link-dotfiles --apps` just runs this first, then links. + +The zsh prompt and plugins (zinit, Powerlevel10k, autosuggestions, +syntax-highlighting, completions, vi-mode, fzf-tab) **self-install** from +`.zshrc` on first shell start, so they're not part of `install-apps`. + ## Windows (PowerShell) `stow` doesn't run natively on Windows, so use the PowerShell equivalent. It diff --git a/home_root/.zshrc b/home_root/.zshrc index 9702c1c..c933994 100644 --- a/home_root/.zshrc +++ b/home_root/.zshrc @@ -107,10 +107,9 @@ alias cd='z' zinit light Aloxaf/fzf-tab -if [[ $(uname) == "Darwin" ]]; then - source $(brew --prefix)/share/zsh-autosuggestions/zsh-autosuggestions.zsh -elif [[ $(uname) == "Linux" ]]; then - source /usr/share/zsh-autosuggestions/zsh-autosuggestions.zsh +# zsh-autosuggestions is already loaded via zinit above; on Linux, also wire +# the terminfo arrow keys to history search. +if [[ $(uname) == "Linux" ]]; then bindkey "${terminfo[kcuu1]}" history-search-backward bindkey "${terminfo[kcud1]}" history-search-forward fi diff --git a/link-dotfiles b/link-dotfiles index a27e3cb..576b59f 100755 --- a/link-dotfiles +++ b/link-dotfiles @@ -15,6 +15,14 @@ set -euo pipefail repo="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" cd "$repo" +# `--apps`: install all host CLI tools first, then link. Without it, this only +# links (fast + idempotent). App install is delegated to the host-aware +# lk-installers/install-apps. +if [ "${1:-}" = "--apps" ]; then + echo "Installing apps first (--apps)…" + "$repo/lk-installers/install-apps" +fi + ensure_stow() { command -v stow >/dev/null 2>&1 && return @@ -22,7 +30,7 @@ ensure_stow() { case "$(uname -s)" in Darwin) if ! command -v brew >/dev/null 2>&1; then - echo "error: Homebrew is required on macOS. Run ./lk-installers/macinstaller first." >&2 + echo "error: Homebrew is required on macOS. Run ./lk-installers/install-apps (or ./link-dotfiles --apps) first." >&2 exit 1 fi brew install stow diff --git a/lk-installers/install-apps b/lk-installers/install-apps new file mode 100755 index 0000000..c9c3404 --- /dev/null +++ b/lk-installers/install-apps @@ -0,0 +1,99 @@ +#!/usr/bin/env bash +# Host-aware installer for every CLI tool the dotfiles assume at runtime. +# +# macOS -> Homebrew (bootstraps Homebrew itself if missing) +# Linux -> apt (Debian/Ubuntu) + upstream installers for tools not in apt +# +# zinit and all zsh plugins (powerlevel10k, zsh-autosuggestions, +# zsh-syntax-highlighting, zsh-completions, zsh-vi-mode, fzf-tab) bootstrap +# themselves from ~/.zshrc on first shell start — they are NOT installed here. +# +# Idempotent: re-running only fills gaps. Pairs with ./link-dotfiles, or run +# `./link-dotfiles --apps` to install then link in one shot. +# +# Consolidates the former macinstaller / install-apt-pkgs / install-tools / +# install-zellij scripts. +set -euo pipefail + +# fzf-git.sh is a sourced helper (not a package) — same on every platform. +clone_fzf_git() { + if [ -d "$HOME/fzf-git.sh" ]; then + echo "fzf-git.sh already cloned — skipping" + else + git clone --depth 1 https://github.com/junegunn/fzf-git.sh.git "$HOME/fzf-git.sh" + fi +} + +install_macos() { + if ! command -v brew >/dev/null 2>&1; then + echo "Homebrew not found — installing…" + /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" + if [ -x /opt/homebrew/bin/brew ]; then eval "$(/opt/homebrew/bin/brew shellenv)" + elif [ -x /usr/local/bin/brew ]; then eval "$(/usr/local/bin/brew shellenv)" + fi + fi + + echo "Installing CLI tools via Homebrew…" + brew install \ + zsh git curl wget stow \ + bat fd fzf zoxide \ + zellij neovim btop htop + # tldr and neofetch are deprecated/disabled upstream — best-effort so a dead + # formula can't abort the run. tlrc is the maintained `tldr` client. + brew install tlrc || brew install tldr || echo "tldr unavailable — skipping" + brew install neofetch || echo "neofetch unavailable — skipping" + + # fzf key-bindings + completion -> ~/.fzf.zsh (sourced by .zshrc). These flags + # make it non-interactive; --no-update-rc stops it editing .zshrc (the repo + # owns that file). + "$(brew --prefix)/opt/fzf/install" --key-bindings --completion --no-update-rc >/dev/null + + clone_fzf_git +} + +install_linux() { + if ! command -v apt >/dev/null 2>&1; then + echo "error: Linux app install targets Debian/Ubuntu (apt). Install the tools manually on this distro." >&2 + exit 1 + fi + + echo "Installing base packages via apt…" + sudo apt update + sudo apt install -y --no-install-recommends \ + neovim vim-nox btop htop neofetch curl wget tldr git zip unzip stow zsh cargo \ + zsh-autosuggestions zsh-syntax-highlighting + sudo apt install -y --no-install-recommends rar unrar || true + + # fzf (vendored under ~/.cache/lk-tools/fzf; .zshrc adds its bin to PATH) + if [ ! -d "$HOME/.cache/lk-tools/fzf" ]; then + git clone --depth 1 https://github.com/junegunn/fzf.git "$HOME/.cache/lk-tools/fzf" + "$HOME/.cache/lk-tools/fzf/install" --key-bindings --completion --no-update-rc + fi + clone_fzf_git + + # zoxide (upstream installer -> ~/.local/bin, already on PATH) + command -v zoxide >/dev/null 2>&1 || \ + curl -sS https://raw.githubusercontent.com/ajeetdsouza/zoxide/main/install.sh | sh + + # bat + fd: upstream .deb so the binaries are named `bat`/`fd` (Debian ships + # them as `batcat`/`fdfind`). amd64 assumed — adjust the URLs on arm64 boxes. + if ! command -v bat >/dev/null 2>&1; then + wget -qO /tmp/bat.deb https://github.com/sharkdp/bat/releases/download/v0.24.0/bat_0.24.0_amd64.deb + sudo apt install -y /tmp/bat.deb + fi + if ! command -v fd >/dev/null 2>&1; then + wget -qO /tmp/fd.deb https://github.com/sharkdp/fd/releases/download/v10.1.0/fd_10.1.0_amd64.deb + sudo apt install -y /tmp/fd.deb + fi + + # zellij: cargo build, fall back to apt + command -v zellij >/dev/null 2>&1 || cargo install zellij || sudo apt install -y zellij +} + +case "$(uname -s)" in + Darwin) install_macos ;; + Linux) install_linux ;; + *) echo "error: unsupported OS '$(uname -s)'." >&2; exit 1 ;; +esac + +echo "Done. Open a new shell (or 'exec zsh') to pick everything up." diff --git a/lk-installers/install-apt-pkgs b/lk-installers/install-apt-pkgs deleted file mode 100755 index 7f4e9be..0000000 --- a/lk-installers/install-apt-pkgs +++ /dev/null @@ -1,3 +0,0 @@ -sudo apt update -sudo apt install neovim vim-nox btop htop neofetch curl wget tldr git zip unzip stow zsh zsh-autosuggestions zsh-syntax-highlighting cargo --no-install-recommends -sudo apt install rar unrar --no-install-recommends diff --git a/lk-installers/install-tools b/lk-installers/install-tools deleted file mode 100755 index ac2cec2..0000000 --- a/lk-installers/install-tools +++ /dev/null @@ -1,8 +0,0 @@ -git clone --depth 1 https://github.com/junegunn/fzf.git ~/.cache/lk-tools/fzf -~/.cache/lk-tools/fzf/install -git clone https://github.com/junegunn/fzf-git.sh.git ~/fzf-git.sh -curl -sS https://raw.githubusercontent.com/ajeetdsouza/zoxide/main/install.sh | sh -wget -O /tmp/bat.deb https://github.com/sharkdp/bat/releases/download/v0.24.0/bat_0.24.0_amd64.deb -sudo apt install /tmp/bat.deb -wget -O /tmp/fdfind.deb https://github.com/sharkdp/fd/releases/download/v10.1.0/fd_10.1.0_amd64.deb -sudo apt install /tmp/fdfind.deb diff --git a/lk-installers/install-zellij b/lk-installers/install-zellij deleted file mode 100755 index 1047423..0000000 --- a/lk-installers/install-zellij +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -echo "Installing Zellij via cargo..." -cargo install zellij || { - echo "Cargo failed - trying apt instead" - sudo apt update && sudo apt install -y zellij -} diff --git a/lk-installers/macinstaller b/lk-installers/macinstaller deleted file mode 100755 index f57777b..0000000 --- a/lk-installers/macinstaller +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/bash -# filepath: /Users/vhpfi/dotfiles/lk-installers/macinstaller - -# Check if Homebrew is installed -if command -v brew >/dev/null 2>&1; then - echo "Homebrew is already installed. Updating..." - brew update -else - echo "Homebrew not found. Installing Homebrew..." - /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" - - # Add Homebrew to PATH for the current session - if [[ -f /opt/homebrew/bin/brew ]]; then - # For Apple Silicon Macs - eval "$(/opt/homebrew/bin/brew shellenv)" - echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile - echo "Homebrew has been installed and added to your PATH." - elif [[ -f /usr/local/bin/brew ]]; then - # For Intel Macs - eval "$(/usr/local/bin/brew shellenv)" - echo 'eval "$(/usr/local/bin/brew shellenv)"' >> ~/.zprofile - echo "Homebrew has been installed and added to your PATH." - else - echo "Error: Couldn't find the Homebrew binary after installation." - exit 1 - fi -fi - -echo "Installing packages with Homebrew..." -brew install neovim btop htop neofetch curl wget git zip unzip zsh tldr -brew install zsh-autosuggestions zsh-syntax-highlighting -brew install rustup-init -rustup-init -y - -echo "Installation complete!" \ No newline at end of file From 20d0b98df62e70b26105eda022f8a2f99cd98978 Mon Sep 17 00:00:00 2001 From: Vuong Hoang Date: Fri, 26 Jun 2026 07:59:20 -0700 Subject: [PATCH 13/22] feat(p10k): show hostname by the clock, tag native vs ssh Context segment already sat left of the time segment but was hidden in the local (DEFAULT) state. Show the hostname there: grey when native, yellow with an explicit ' ssh' tag when remote (p10k's REMOTE state detects SSH for free). Only the local-sudo state stays quiet. --- home_root/.p10k.zsh | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/home_root/.p10k.zsh b/home_root/.p10k.zsh index df1c9db..a289c59 100644 --- a/home_root/.p10k.zsh +++ b/home_root/.p10k.zsh @@ -105,12 +105,18 @@ # Blue current directory. typeset -g POWERLEVEL9K_DIR_FOREGROUND=$lightergrey - # Context format when root: user@host. The first part white, the rest grey. + # Context sits just left of the clock and shows the hostname, with the + # session type made obvious at a glance: + # native (local) -> grey hostname + # ssh (remote) -> yellow hostname tagged " ssh" + # root -> user@host, username in white typeset -g POWERLEVEL9K_CONTEXT_ROOT_TEMPLATE="%F{$white}%n%f%F{$grey}@%m%f" - # Context format when not root: user@host. The whole thing grey. typeset -g POWERLEVEL9K_CONTEXT_TEMPLATE="%F{$grey}%n@%m%f" - # Don't show context unless root or in SSH. - typeset -g POWERLEVEL9K_CONTEXT_{DEFAULT,SUDO}_CONTENT_EXPANSION= + typeset -g POWERLEVEL9K_CONTEXT_DEFAULT_TEMPLATE="%F{$grey}%m%f" + typeset -g POWERLEVEL9K_CONTEXT_REMOTE_TEMPLATE="%F{$yellow}%m%f%F{$grey} ssh%f" + typeset -g POWERLEVEL9K_CONTEXT_REMOTE_SUDO_TEMPLATE="%F{$white}%n%f%F{$yellow}@%m%f%F{$grey} ssh%f" + # Keep only the local-sudo state quiet (matches Pure); every other state shows. + typeset -g POWERLEVEL9K_CONTEXT_SUDO_CONTENT_EXPANSION= # Show previous command duration only if it's >= 5s. typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_THRESHOLD=5 From b106e80f0190503d3978068bde66f0f18ff5a806 Mon Sep 17 00:00:00 2001 From: Vuong Hoang Date: Fri, 26 Jun 2026 08:00:54 -0700 Subject: [PATCH 14/22] feat(installers): add fastfetch, drop dead neofetch fastfetch is the maintained successor to neofetch (removed from Homebrew). macOS installs it in the main brew list; Linux installs it best-effort with a neofetch fallback for older distros. README tool list updated. --- README.md | 4 ++-- lk-installers/install-apps | 11 ++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 4a72d7d..32ddf1b 100644 --- a/README.md +++ b/README.md @@ -26,8 +26,8 @@ safe — stow is idempotent. ### Installing the tools The configs assume a handful of CLI tools (`bat`, `fd`, `fzf`, `zoxide`, -`zellij`, `nvim`, `btop`, `htop`, `tldr`, plus the `fzf-git.sh` helper). One -host-aware installer covers them: +`zellij`, `nvim`, `btop`, `htop`, `tldr`, `fastfetch`, plus the `fzf-git.sh` +helper). One host-aware installer covers them: ```bash ./lk-installers/install-apps # macOS -> Homebrew; Linux -> apt + upstream diff --git a/lk-installers/install-apps b/lk-installers/install-apps index c9c3404..a04c084 100755 --- a/lk-installers/install-apps +++ b/lk-installers/install-apps @@ -37,11 +37,10 @@ install_macos() { brew install \ zsh git curl wget stow \ bat fd fzf zoxide \ - zellij neovim btop htop - # tldr and neofetch are deprecated/disabled upstream — best-effort so a dead - # formula can't abort the run. tlrc is the maintained `tldr` client. + zellij neovim btop htop fastfetch + # tldr is deprecated upstream — best-effort so a dead formula can't abort the + # run. tlrc is the maintained `tldr` client. brew install tlrc || brew install tldr || echo "tldr unavailable — skipping" - brew install neofetch || echo "neofetch unavailable — skipping" # fzf key-bindings + completion -> ~/.fzf.zsh (sourced by .zshrc). These flags # make it non-interactive; --no-update-rc stops it editing .zshrc (the repo @@ -60,9 +59,11 @@ install_linux() { echo "Installing base packages via apt…" sudo apt update sudo apt install -y --no-install-recommends \ - neovim vim-nox btop htop neofetch curl wget tldr git zip unzip stow zsh cargo \ + neovim vim-nox btop htop curl wget tldr git zip unzip stow zsh cargo \ zsh-autosuggestions zsh-syntax-highlighting sudo apt install -y --no-install-recommends rar unrar || true + # fastfetch (modern neofetch); falls back to neofetch on older distros. + sudo apt install -y fastfetch || sudo apt install -y neofetch || echo "fastfetch/neofetch unavailable — skipping" # fzf (vendored under ~/.cache/lk-tools/fzf; .zshrc adds its bin to PATH) if [ ! -d "$HOME/.cache/lk-tools/fzf" ]; then From 30d32d1eb81d8ef75acdd595f57bcb438271f70a Mon Sep 17 00:00:00 2001 From: Vuong Hoang Date: Fri, 26 Jun 2026 09:26:09 -0700 Subject: [PATCH 15/22] more updates --- home_config/zellij/config.kdl.bak | 452 --------------------- home_config/zellij/config.kdl.bak.1 | 598 ---------------------------- 2 files changed, 1050 deletions(-) delete mode 100644 home_config/zellij/config.kdl.bak delete mode 100644 home_config/zellij/config.kdl.bak.1 diff --git a/home_config/zellij/config.kdl.bak b/home_config/zellij/config.kdl.bak deleted file mode 100644 index fa30b12..0000000 --- a/home_config/zellij/config.kdl.bak +++ /dev/null @@ -1,452 +0,0 @@ -keybinds clear-defaults=true { - locked { - bind "Ctrl g" { SwitchToMode "normal"; } - } - pane { - bind "left" { MoveFocus "left"; } - bind "down" { MoveFocus "down"; } - bind "up" { MoveFocus "up"; } - bind "right" { MoveFocus "right"; } - bind "c" { SwitchToMode "renamepane"; PaneNameInput 0; } - bind "d" { NewPane "down"; SwitchToMode "normal"; } - bind "e" { TogglePaneEmbedOrFloating; SwitchToMode "normal"; } - bind "f" { ToggleFocusFullscreen; SwitchToMode "normal"; } - bind "h" { MoveFocus "left"; } - bind "i" { TogglePanePinned; SwitchToMode "normal"; } - bind "j" { MoveFocus "down"; } - bind "k" { MoveFocus "up"; } - bind "l" { MoveFocus "right"; } - bind "n" { NewPane; SwitchToMode "normal"; } - bind "p" { SwitchFocus; } - bind "Ctrl p" { SwitchToMode "normal"; } - bind "r" { NewPane "right"; SwitchToMode "normal"; } - bind "w" { ToggleFloatingPanes; SwitchToMode "normal"; } - bind "z" { TogglePaneFrames; SwitchToMode "normal"; } - } - tab { - bind "left" { GoToPreviousTab; } - bind "down" { GoToNextTab; } - bind "up" { GoToPreviousTab; } - bind "right" { GoToNextTab; } - bind "1" { GoToTab 1; SwitchToMode "normal"; } - bind "2" { GoToTab 2; SwitchToMode "normal"; } - bind "3" { GoToTab 3; SwitchToMode "normal"; } - bind "4" { GoToTab 4; SwitchToMode "normal"; } - bind "5" { GoToTab 5; SwitchToMode "normal"; } - bind "6" { GoToTab 6; SwitchToMode "normal"; } - bind "7" { GoToTab 7; SwitchToMode "normal"; } - bind "8" { GoToTab 8; SwitchToMode "normal"; } - bind "9" { GoToTab 9; SwitchToMode "normal"; } - bind "[" { BreakPaneLeft; SwitchToMode "normal"; } - bind "]" { BreakPaneRight; SwitchToMode "normal"; } - bind "b" { BreakPane; SwitchToMode "normal"; } - bind "h" { GoToPreviousTab; } - bind "j" { GoToNextTab; } - bind "k" { GoToPreviousTab; } - bind "l" { GoToNextTab; } - bind "n" { NewTab; SwitchToMode "normal"; } - bind "r" { SwitchToMode "renametab"; TabNameInput 0; } - bind "s" { ToggleActiveSyncTab; SwitchToMode "normal"; } - bind "Ctrl t" { SwitchToMode "normal"; } - bind "x" { CloseTab; SwitchToMode "normal"; } - bind "tab" { ToggleTab; } - } - resize { - bind "left" { Resize "Increase left"; } - bind "down" { Resize "Increase down"; } - bind "up" { Resize "Increase up"; } - bind "right" { Resize "Increase right"; } - bind "+" { Resize "Increase"; } - bind "-" { Resize "Decrease"; } - bind "=" { Resize "Increase"; } - bind "H" { Resize "Decrease left"; } - bind "J" { Resize "Decrease down"; } - bind "K" { Resize "Decrease up"; } - bind "L" { Resize "Decrease right"; } - bind "h" { Resize "Increase left"; } - bind "j" { Resize "Increase down"; } - bind "k" { Resize "Increase up"; } - bind "l" { Resize "Increase right"; } - bind "Ctrl n" { SwitchToMode "normal"; } - } - move { - bind "left" { MovePane "left"; } - bind "down" { MovePane "down"; } - bind "up" { MovePane "up"; } - bind "right" { MovePane "right"; } - bind "h" { MovePane "left"; } - bind "Ctrl h" { SwitchToMode "normal"; } - bind "j" { MovePane "down"; } - bind "k" { MovePane "up"; } - bind "l" { MovePane "right"; } - bind "n" { MovePane; } - bind "p" { MovePaneBackwards; } - bind "tab" { MovePane; } - } - scroll { - bind "e" { EditScrollback; SwitchToMode "normal"; } - bind "s" { SwitchToMode "entersearch"; SearchInput 0; } - } - search { - bind "c" { SearchToggleOption "CaseSensitivity"; } - bind "n" { Search "down"; } - bind "o" { SearchToggleOption "WholeWord"; } - bind "p" { Search "up"; } - bind "w" { SearchToggleOption "Wrap"; } - } - session { - bind "a" { - LaunchOrFocusPlugin "zellij:about" { - floating true - move_to_focused_tab true - } - SwitchToMode "normal" - } - bind "c" { - LaunchOrFocusPlugin "configuration" { - floating true - move_to_focused_tab true - } - SwitchToMode "normal" - } - bind "Ctrl o" { SwitchToMode "normal"; } - bind "p" { - LaunchOrFocusPlugin "plugin-manager" { - floating true - move_to_focused_tab true - } - SwitchToMode "normal" - } - bind "w" { - LaunchOrFocusPlugin "session-manager" { - floating true - move_to_focused_tab true - } - SwitchToMode "normal" - } - } - shared_except "locked" { - bind "Alt left" { MoveFocusOrTab "left"; } - bind "Alt down" { MoveFocus "down"; } - bind "Alt up" { MoveFocus "up"; } - bind "Alt right" { MoveFocusOrTab "right"; } - bind "Alt +" { Resize "Increase"; } - bind "Alt -" { Resize "Decrease"; } - bind "Alt =" { Resize "Increase"; } - bind "Alt [" { PreviousSwapLayout; } - bind "Alt ]" { NextSwapLayout; } - bind "Alt f" { ToggleFloatingPanes; } - bind "Ctrl g" { SwitchToMode "locked"; } - bind "Alt h" { MoveFocusOrTab "left"; } - bind "Alt i" { MoveTab "left"; } - bind "Alt j" { MoveFocus "down"; } - bind "Alt k" { MoveFocus "up"; } - bind "Alt l" { MoveFocusOrTab "right"; } - bind "Alt n" { NewPane; } - bind "Alt o" { MoveTab "right"; } - bind "Ctrl q" { Quit; } - } - shared_except "locked" "move" { - bind "Ctrl h" { SwitchToMode "move"; } - } - shared_except "locked" "session" { - bind "Ctrl o" { SwitchToMode "session"; } - } - shared_except "locked" "scroll" "search" "tmux" { - bind "Ctrl b" { SwitchToMode "tmux"; } - } - shared_except "locked" "scroll" "search" { - bind "Ctrl s" { SwitchToMode "scroll"; } - } - shared_except "locked" "tab" { - bind "Ctrl t" { SwitchToMode "tab"; } - } - shared_except "locked" "pane" { - bind "Ctrl p" { SwitchToMode "pane"; } - } - shared_except "locked" "resize" { - bind "Ctrl n" { SwitchToMode "resize"; } - } - shared_except "normal" "locked" "entersearch" { - bind "enter" { SwitchToMode "normal"; } - } - shared_except "normal" "locked" "entersearch" "renametab" "renamepane" { - bind "esc" { SwitchToMode "normal"; } - } - shared_among "pane" "tmux" { - bind "x" { CloseFocus; SwitchToMode "normal"; } - } - shared_among "scroll" "search" { - bind "PageDown" { PageScrollDown; } - bind "PageUp" { PageScrollUp; } - bind "left" { PageScrollUp; } - bind "down" { ScrollDown; } - bind "up" { ScrollUp; } - bind "right" { PageScrollDown; } - bind "Ctrl b" { PageScrollUp; } - bind "Ctrl c" { ScrollToBottom; SwitchToMode "normal"; } - bind "d" { HalfPageScrollDown; } - bind "Ctrl f" { PageScrollDown; } - bind "h" { PageScrollUp; } - bind "j" { ScrollDown; } - bind "k" { ScrollUp; } - bind "l" { PageScrollDown; } - bind "Ctrl s" { SwitchToMode "normal"; } - bind "u" { HalfPageScrollUp; } - } - entersearch { - bind "Ctrl c" { SwitchToMode "scroll"; } - bind "esc" { SwitchToMode "scroll"; } - bind "enter" { SwitchToMode "search"; } - } - renametab { - bind "esc" { UndoRenameTab; SwitchToMode "tab"; } - } - shared_among "renametab" "renamepane" { - bind "Ctrl c" { SwitchToMode "normal"; } - } - renamepane { - bind "esc" { UndoRenamePane; SwitchToMode "pane"; } - } - shared_among "session" "tmux" { - bind "d" { Detach; } - } - tmux { - bind "left" { MoveFocus "left"; SwitchToMode "normal"; } - bind "down" { MoveFocus "down"; SwitchToMode "normal"; } - bind "up" { MoveFocus "up"; SwitchToMode "normal"; } - bind "right" { MoveFocus "right"; SwitchToMode "normal"; } - bind "space" { NextSwapLayout; } - bind "\"" { NewPane "down"; SwitchToMode "normal"; } - bind "%" { NewPane "right"; SwitchToMode "normal"; } - bind "," { SwitchToMode "renametab"; } - bind "[" { SwitchToMode "scroll"; } - bind "Ctrl b" { Write 2; SwitchToMode "normal"; } - bind "c" { NewTab; SwitchToMode "normal"; } - bind "h" { MoveFocus "left"; SwitchToMode "normal"; } - bind "j" { MoveFocus "down"; SwitchToMode "normal"; } - bind "k" { MoveFocus "up"; SwitchToMode "normal"; } - bind "l" { MoveFocus "right"; SwitchToMode "normal"; } - bind "n" { GoToNextTab; SwitchToMode "normal"; } - bind "o" { FocusNextPane; } - bind "p" { GoToPreviousTab; SwitchToMode "normal"; } - bind "z" { ToggleFocusFullscreen; SwitchToMode "normal"; } - } -} - -// Plugin aliases - can be used to change the implementation of Zellij -// changing these requires a restart to take effect -plugins { - about location="zellij:about" - compact-bar location="zellij:compact-bar" - configuration location="zellij:configuration" - filepicker location="zellij:strider" { - cwd "/" - } - plugin-manager location="zellij:plugin-manager" - session-manager location="zellij:session-manager" - status-bar location="zellij:status-bar" - strider location="zellij:strider" - tab-bar location="zellij:tab-bar" - welcome-screen location="zellij:session-manager" { - welcome_screen true - } -} - -// Plugins to load in the background when a new session starts -// eg. "file:/path/to/my-plugin.wasm" -// eg. "https://example.com/my-plugin.wasm" -load_plugins { -} - -// Use a simplified UI without special fonts (arrow glyphs) -// Options: -// - true -// - false (Default) -// -// simplified_ui true - -// Choose the theme that is specified in the themes section. -// Default: default -// -// theme "dracula" - -// Choose the base input mode of zellij. -// Default: normal -// -// default_mode "locked" - -// Choose the path to the default shell that zellij will use for opening new panes -// Default: $SHELL -// -// default_shell "fish" - -// Choose the path to override cwd that zellij will use for opening new panes -// -// default_cwd "/tmp" - -// The name of the default layout to load on startup -// Default: "default" -// -// default_layout "compact" - -// The folder in which Zellij will look for layouts -// (Requires restart) -// -// layout_dir "/tmp" - -// The folder in which Zellij will look for themes -// (Requires restart) -// -// theme_dir "/tmp" - -// Toggle enabling the mouse mode. -// On certain configurations, or terminals this could -// potentially interfere with copying text. -// Options: -// - true (default) -// - false -// -// mouse_mode false - -// Toggle having pane frames around the panes -// Options: -// - true (default, enabled) -// - false -// -// pane_frames false - -// When attaching to an existing session with other users, -// should the session be mirrored (true) -// or should each user have their own cursor (false) -// (Requires restart) -// Default: false -// -// mirror_session true - -// Choose what to do when zellij receives SIGTERM, SIGINT, SIGQUIT or SIGHUP -// eg. when terminal window with an active zellij session is closed -// (Requires restart) -// Options: -// - detach (Default) -// - quit -// -// on_force_close "quit" - -// Configure the scroll back buffer size -// This is the number of lines zellij stores for each pane in the scroll back -// buffer. Excess number of lines are discarded in a FIFO fashion. -// (Requires restart) -// Valid values: positive integers -// Default value: 10000 -// -// scroll_buffer_size 10000 - -// Provide a command to execute when copying text. The text will be piped to -// the stdin of the program to perform the copy. This can be used with -// terminal emulators which do not support the OSC 52 ANSI control sequence -// that will be used by default if this option is not set. -// Examples: -// -// copy_command "xclip -selection clipboard" // x11 -// copy_command "wl-copy" // wayland -// copy_command "pbcopy" // osx -// -// copy_command "pbcopy" - -// Choose the destination for copied text -// Allows using the primary selection buffer (on x11/wayland) instead of the system clipboard. -// Does not apply when using copy_command. -// Options: -// - system (default) -// - primary -// -// copy_clipboard "primary" - -// Enable automatic copying (and clearing) of selection when releasing mouse -// Default: true -// -// copy_on_select true - -// Path to the default editor to use to edit pane scrollbuffer -// Default: $EDITOR or $VISUAL -// scrollback_editor "/usr/bin/vim" - -// A fixed name to always give the Zellij session. -// Consider also setting `attach_to_session true,` -// otherwise this will error if such a session exists. -// Default: -// -// session_name "My singleton session" - -// When `session_name` is provided, attaches to that session -// if it is already running or creates it otherwise. -// Default: false -// -// attach_to_session true - -// Toggle between having Zellij lay out panes according to a predefined set of layouts whenever possible -// Options: -// - true (default) -// - false -// -// auto_layout false - -// Whether sessions should be serialized to the cache folder (including their tabs/panes, cwds and running commands) so that they can later be resurrected -// Options: -// - true (default) -// - false -// -// session_serialization false - -// Whether pane viewports are serialized along with the session, default is false -// Options: -// - true -// - false (default) -// -// serialize_pane_viewport false - -// Scrollback lines to serialize along with the pane viewport when serializing sessions, 0 -// defaults to the scrollback size. If this number is higher than the scrollback size, it will -// also default to the scrollback size. This does nothing if `serialize_pane_viewport` is not true. -// -// scrollback_lines_to_serialize 10000 - -// Enable or disable the rendering of styled and colored underlines (undercurl). -// May need to be disabled for certain unsupported terminals -// (Requires restart) -// Default: true -// -// styled_underlines false - -// How often in seconds sessions are serialized -// -// serialization_interval 10000 - -// Enable or disable writing of session metadata to disk (if disabled, other sessions might not know -// metadata info on this session) -// (Requires restart) -// Default: false -// -// disable_session_metadata false - -// Enable or disable support for the enhanced Kitty Keyboard Protocol (the host terminal must also support it) -// (Requires restart) -// Default: true (if the host terminal supports it) -// -// support_kitty_keyboard_protocol false - -// Whether to stack panes when resizing beyond a certain size -// Default: true -// -// stacked_resize false - -// Whether to show tips on startup -// Default: true -// -// show_startup_tips false - -// Whether to show release notes on first version run -// Default: true -// -// show_release_notes false diff --git a/home_config/zellij/config.kdl.bak.1 b/home_config/zellij/config.kdl.bak.1 deleted file mode 100644 index b980257..0000000 --- a/home_config/zellij/config.kdl.bak.1 +++ /dev/null @@ -1,598 +0,0 @@ -// -// THIS FILE WAS AUTOGENERATED BY ZELLIJ, THE PREVIOUS FILE AT THIS LOCATION WAS COPIED TO: /home/lkraven/.config/zellij/config.kdl.bak -// - -keybinds clear-defaults=true { - locked { - bind "Ctrl g" { SwitchToMode "normal"; } - } - pane { - bind "left" { MoveFocus "left"; } - bind "down" { MoveFocus "down"; } - bind "up" { MoveFocus "up"; } - bind "right" { MoveFocus "right"; } - bind "c" { SwitchToMode "renamepane"; PaneNameInput 0; } - bind "d" { NewPane "down"; SwitchToMode "normal"; } - bind "e" { TogglePaneEmbedOrFloating; SwitchToMode "normal"; } - bind "f" { ToggleFocusFullscreen; SwitchToMode "normal"; } - bind "h" { MoveFocus "left"; } - bind "i" { TogglePanePinned; SwitchToMode "normal"; } - bind "j" { MoveFocus "down"; } - bind "k" { MoveFocus "up"; } - bind "l" { MoveFocus "right"; } - bind "n" { NewPane; SwitchToMode "normal"; } - bind "p" { SwitchFocus; } - bind "Ctrl p" { SwitchToMode "normal"; } - bind "r" { NewPane "right"; SwitchToMode "normal"; } - bind "w" { ToggleFloatingPanes; SwitchToMode "normal"; } - bind "z" { TogglePaneFrames; SwitchToMode "normal"; } - } - tab { - bind "left" { GoToPreviousTab; } - bind "down" { GoToNextTab; } - bind "up" { GoToPreviousTab; } - bind "right" { GoToNextTab; } - bind "1" { GoToTab 1; SwitchToMode "normal"; } - bind "2" { GoToTab 2; SwitchToMode "normal"; } - bind "3" { GoToTab 3; SwitchToMode "normal"; } - bind "4" { GoToTab 4; SwitchToMode "normal"; } - bind "5" { GoToTab 5; SwitchToMode "normal"; } - bind "6" { GoToTab 6; SwitchToMode "normal"; } - bind "7" { GoToTab 7; SwitchToMode "normal"; } - bind "8" { GoToTab 8; SwitchToMode "normal"; } - bind "9" { GoToTab 9; SwitchToMode "normal"; } - bind "[" { BreakPaneLeft; SwitchToMode "normal"; } - bind "]" { BreakPaneRight; SwitchToMode "normal"; } - bind "b" { BreakPane; SwitchToMode "normal"; } - bind "h" { GoToPreviousTab; } - bind "j" { GoToNextTab; } - bind "k" { GoToPreviousTab; } - bind "l" { GoToNextTab; } - bind "n" { NewTab; SwitchToMode "normal"; } - bind "r" { SwitchToMode "renametab"; TabNameInput 0; } - bind "s" { ToggleActiveSyncTab; SwitchToMode "normal"; } - bind "Ctrl t" { SwitchToMode "normal"; } - bind "x" { CloseTab; SwitchToMode "normal"; } - bind "tab" { ToggleTab; } - } - resize { - bind "left" { Resize "Increase left"; } - bind "down" { Resize "Increase down"; } - bind "up" { Resize "Increase up"; } - bind "right" { Resize "Increase right"; } - bind "+" { Resize "Increase"; } - bind "-" { Resize "Decrease"; } - bind "=" { Resize "Increase"; } - bind "H" { Resize "Decrease left"; } - bind "J" { Resize "Decrease down"; } - bind "K" { Resize "Decrease up"; } - bind "L" { Resize "Decrease right"; } - bind "h" { Resize "Increase left"; } - bind "j" { Resize "Increase down"; } - bind "k" { Resize "Increase up"; } - bind "l" { Resize "Increase right"; } - bind "Ctrl n" { SwitchToMode "normal"; } - } - move { - bind "left" { MovePane "left"; } - bind "down" { MovePane "down"; } - bind "up" { MovePane "up"; } - bind "right" { MovePane "right"; } - bind "h" { MovePane "left"; } - bind "Ctrl h" { SwitchToMode "normal"; } - bind "j" { MovePane "down"; } - bind "k" { MovePane "up"; } - bind "l" { MovePane "right"; } - bind "n" { MovePane; } - bind "p" { MovePaneBackwards; } - bind "tab" { MovePane; } - } - scroll { - bind "Alt left" { MoveFocusOrTab "left"; SwitchToMode "normal"; } - bind "Alt down" { MoveFocus "down"; SwitchToMode "normal"; } - bind "Alt up" { MoveFocus "up"; SwitchToMode "normal"; } - bind "Alt right" { MoveFocusOrTab "right"; SwitchToMode "normal"; } - bind "e" { EditScrollback; SwitchToMode "normal"; } - bind "Alt h" { MoveFocusOrTab "left"; SwitchToMode "normal"; } - bind "Alt j" { MoveFocus "down"; SwitchToMode "normal"; } - bind "Alt k" { MoveFocus "up"; SwitchToMode "normal"; } - bind "Alt l" { MoveFocusOrTab "right"; SwitchToMode "normal"; } - bind "s" { SwitchToMode "entersearch"; SearchInput 0; } - } - search { - bind "c" { SearchToggleOption "CaseSensitivity"; } - bind "n" { Search "down"; } - bind "o" { SearchToggleOption "WholeWord"; } - bind "p" { Search "up"; } - bind "w" { SearchToggleOption "Wrap"; } - } - session { - bind "a" { - LaunchOrFocusPlugin "zellij:about" { - floating true - move_to_focused_tab true - } - SwitchToMode "normal" - } - bind "c" { - LaunchOrFocusPlugin "configuration" { - floating true - move_to_focused_tab true - } - SwitchToMode "normal" - } - bind "Ctrl o" { SwitchToMode "normal"; } - bind "p" { - LaunchOrFocusPlugin "plugin-manager" { - floating true - move_to_focused_tab true - } - SwitchToMode "normal" - } - bind "w" { - LaunchOrFocusPlugin "session-manager" { - floating true - move_to_focused_tab true - } - SwitchToMode "normal" - } - } - shared_except "locked" { - bind "Alt +" { Resize "Increase"; } - bind "Alt -" { Resize "Decrease"; } - bind "Alt =" { Resize "Increase"; } - bind "Alt [" { PreviousSwapLayout; } - bind "Alt ]" { NextSwapLayout; } - bind "Alt f" { ToggleFloatingPanes; } - bind "Ctrl g" { SwitchToMode "locked"; } - bind "Alt i" { MoveTab "left"; } - bind "Alt n" { NewPane; } - bind "Alt o" { MoveTab "right"; } - bind "Ctrl q" { Quit; } - } - shared_except "locked" "move" { - bind "Ctrl h" { SwitchToMode "move"; } - } - shared_except "locked" "session" { - bind "Ctrl o" { SwitchToMode "session"; } - } - shared_except "locked" "scroll" { - bind "Alt left" { MoveFocusOrTab "left"; } - bind "Alt down" { MoveFocus "down"; } - bind "Alt up" { MoveFocus "up"; } - bind "Alt right" { MoveFocusOrTab "right"; } - bind "Alt h" { MoveFocusOrTab "left"; } - bind "Alt j" { MoveFocus "down"; } - bind "Alt k" { MoveFocus "up"; } - bind "Alt l" { MoveFocusOrTab "right"; } - } - shared_except "locked" "scroll" "search" "tmux" { - bind "Ctrl b" { SwitchToMode "tmux"; } - } - shared_except "locked" "scroll" "search" { - bind "Ctrl s" { SwitchToMode "scroll"; } - } - shared_except "locked" "tab" { - bind "Ctrl t" { SwitchToMode "tab"; } - } - shared_except "locked" "pane" { - bind "Ctrl p" { SwitchToMode "pane"; } - } - shared_except "locked" "resize" { - bind "Ctrl n" { SwitchToMode "resize"; } - } - shared_except "normal" "locked" "entersearch" { - bind "enter" { SwitchToMode "normal"; } - } - shared_except "normal" "locked" "entersearch" "renametab" "renamepane" { - bind "esc" { SwitchToMode "normal"; } - } - shared_among "pane" "tmux" { - bind "x" { CloseFocus; SwitchToMode "normal"; } - } - shared_among "scroll" "search" { - bind "PageDown" { PageScrollDown; } - bind "PageUp" { PageScrollUp; } - bind "left" { PageScrollUp; } - bind "down" { ScrollDown; } - bind "up" { ScrollUp; } - bind "right" { PageScrollDown; } - bind "Ctrl b" { PageScrollUp; } - bind "Ctrl c" { ScrollToBottom; SwitchToMode "normal"; } - bind "d" { HalfPageScrollDown; } - bind "Ctrl f" { PageScrollDown; } - bind "h" { PageScrollUp; } - bind "j" { ScrollDown; } - bind "k" { ScrollUp; } - bind "l" { PageScrollDown; } - bind "Ctrl s" { SwitchToMode "normal"; } - bind "u" { HalfPageScrollUp; } - } - entersearch { - bind "Ctrl c" { SwitchToMode "scroll"; } - bind "esc" { SwitchToMode "scroll"; } - bind "enter" { SwitchToMode "search"; } - } - renametab { - bind "esc" { UndoRenameTab; SwitchToMode "tab"; } - } - shared_among "renametab" "renamepane" { - bind "Ctrl c" { SwitchToMode "normal"; } - } - renamepane { - bind "esc" { UndoRenamePane; SwitchToMode "pane"; } - } - shared_among "session" "tmux" { - bind "d" { Detach; } - } - tmux { - bind "left" { MoveFocus "left"; SwitchToMode "normal"; } - bind "down" { MoveFocus "down"; SwitchToMode "normal"; } - bind "up" { MoveFocus "up"; SwitchToMode "normal"; } - bind "right" { MoveFocus "right"; SwitchToMode "normal"; } - bind "space" { NextSwapLayout; } - bind "\"" { NewPane "down"; SwitchToMode "normal"; } - bind "%" { NewPane "right"; SwitchToMode "normal"; } - bind "," { SwitchToMode "renametab"; } - bind "[" { SwitchToMode "scroll"; } - bind "Ctrl b" { Write 2; SwitchToMode "normal"; } - bind "c" { NewTab; SwitchToMode "normal"; } - bind "h" { MoveFocus "left"; SwitchToMode "normal"; } - bind "j" { MoveFocus "down"; SwitchToMode "normal"; } - bind "k" { MoveFocus "up"; SwitchToMode "normal"; } - bind "l" { MoveFocus "right"; SwitchToMode "normal"; } - bind "n" { GoToNextTab; SwitchToMode "normal"; } - bind "o" { FocusNextPane; } - bind "p" { GoToPreviousTab; SwitchToMode "normal"; } - bind "z" { ToggleFocusFullscreen; SwitchToMode "normal"; } - } -} - -// Plugin aliases - can be used to change the implementation of Zellij -// changing these requires a restart to take effect -plugins { - about location="zellij:about" - compact-bar location="zellij:compact-bar" - configuration location="zellij:configuration" - filepicker location="zellij:strider" { - cwd "/" - } - plugin-manager location="zellij:plugin-manager" - session-manager location="zellij:session-manager" - status-bar location="zellij:status-bar" - strider location="zellij:strider" - tab-bar location="zellij:tab-bar" - welcome-screen location="zellij:session-manager" { - welcome_screen true - } -} - -// Plugins to load in the background when a new session starts -// eg. "file:/path/to/my-plugin.wasm" -// eg. "https://example.com/my-plugin.wasm" -themes { - australis { - - text_unselected { - base 204 231 236 // #CCE7EC - Bright text - background 65 71 81 // #414751 - Dark 30 - emphasis_0 164 196 255 // #A4C4FF - Bright blue - emphasis_1 22 184 102 // #16B866 - Green - emphasis_2 99 136 216 // #6388D8 - Blue - emphasis_3 66 220 209 // #42DCD1 - Bright cyan (was 255 133 79 - Bright red) - } - - text_selected { - base 230 250 255 // #E6FAFF - Brighter white (was 204 231 236) - background 99 136 216 // #6388D8 - Blue - emphasis_0 255 225 78 // #FFE14E - Bright yellow - emphasis_1 22 184 102 // #16B866 - Green - emphasis_2 99 136 216 // #6388D8 - Blue - emphasis_3 255 133 79 // #FF854F - Bright red - } - - ribbon_unselected { - base 204 231 236 // #CCE7EC - Bright white - background 86 95 105 // #565f69 - Dark 40 (was 65 71 81 - Dark 30) - emphasis_0 81 224 138 // #51E08A - Bright green - emphasis_1 22 184 102 // #16B866 - Green - emphasis_2 99 136 216 // #6388D8 - Blue - emphasis_3 255 133 79 // #FF854F - Bright red - } - - ribbon_selected { - base 65 71 81 // #414751 - Dark 30 - background 99 136 216 // #6388D8 - Blue - emphasis_0 81 224 138 // #51E08A - Bright green - emphasis_1 22 184 102 // #16B866 - Green - emphasis_2 225 198 49 // #E1C631 - Yellow - emphasis_3 255 133 79 // #FF854F - Bright red - } - - table_title { - base 169 188 195 // #A9BCC3 - White - background 34 37 49 // #222531 - Black - emphasis_0 255 133 79 // #FF854F - Bright red - emphasis_1 22 184 102 // #16B866 - Green - emphasis_2 99 136 216 // #6388D8 - Blue - emphasis_3 255 73 26 // #FF491A - Red - } - - table_cell_unselected { - base 169 188 195 // #A9BCC3 - White - background 34 37 49 // #222531 - Black - emphasis_0 255 73 26 // #FF491A - Red - emphasis_1 22 184 102 // #16B866 - Green - emphasis_2 99 136 216 // #6388D8 - Blue - emphasis_3 255 133 79 // #FF854F - Bright red - } - - table_cell_selected { - base 204 231 236 // #CCE7EC - Bright white - background 65 71 81 // #414751 - Dark 30 - emphasis_0 255 225 78 // #FFE14E - Bright yellow - emphasis_1 22 184 102 // #16B866 - Green - emphasis_2 99 136 216 // #6388D8 - Blue - emphasis_3 255 133 79 // #FF854F - Bright red - } - - list_unselected { - base 169 188 195 // #A9BCC3 - White - background 34 37 49 // #222531 - Black - emphasis_0 225 198 49 // #E1C631 - Yellow - emphasis_1 22 184 102 // #16B866 - Green - emphasis_2 99 136 216 // #6388D8 - Blue - emphasis_3 255 133 79 // #FF854F - Bright red - } - - list_selected { - base 204 231 236 // #CCE7EC - Bright white - background 65 71 81 // #414751 - Dark 30 - emphasis_0 255 225 78 // #FFE14E - Bright yellow - emphasis_1 22 184 102 // #16B866 - Green - emphasis_2 99 136 216 // #6388D8 - Blue - emphasis_3 255 133 79 // #FF854F - Bright red - } - - frame_selected { - base 99 136 216 // #6388D8 - Blue - background 34 37 49 // #222531 - Black - emphasis_0 255 73 26 // #FF491A - Red - emphasis_1 22 184 102 // #16B866 - Green - emphasis_2 225 198 49 // #E1C631 - Yellow - emphasis_3 255 133 79 // #FF854F - Bright red - } - - frame_highlight { - base 81 224 138 // #51E08A - Bright green - background 34 37 49 // #222531 - Black - emphasis_0 255 133 79 // #FF854F - Bright red - emphasis_1 99 136 216 // #6388D8 - Blue - emphasis_2 225 198 49 // #E1C631 - Yellow - emphasis_3 255 73 26 // #FF491A - Red - } - - exit_code_success { - base 22 184 102 // #16B866 - Green - emphasis_0 255 73 26 // #FF491A - Red - emphasis_1 99 136 216 // #6388D8 - Blue - emphasis_2 225 198 49 // #E1C631 - Yellow - emphasis_3 255 133 79 // #FF854F - Bright red - } - - exit_code_error { - base 255 73 26 // #FF491A - Red - emphasis_0 22 184 102 // #16B866 - Green - emphasis_1 99 136 216 // #6388D8 - Blue - emphasis_2 225 198 49 // #E1C631 - Yellow - emphasis_3 255 133 79 // #FF854F - Bright red - } - - multiplayer_user_colors { - player_1 255 73 26 // #FF491A - Red - player_2 255 133 79 // #FF854F - Bright red - player_3 225 198 49 // #E1C631 - Yellow - player_4 255 225 78 // #FFE14E - Bright yellow - player_5 157 120 255 // #9D78FF - Magenta - player_6 216 173 255 // #D8ADFF - Bright magenta - player_7 99 136 216 // #6388D8 - Blue - player_8 0 177 168 // #00B1A8 - Cyan - player_9 66 220 209 // #42DCD1 - Bright cyan - player_10 164 196 255 // #A4C4FF - Bright blue - } - } -} -load_plugins { -} - -// Use a simplified UI without special fonts (arrow glyphs) -// Options: -// - true -// - false (Default) -// -// simplified_ui true - -// Choose the theme that is specified in the themes section. -// Default: default - -theme "australis" - -// Choose the base input mode of zellij. -// Default: normal -// -default_mode "normal" - -// Choose the path to the default shell that zellij will use for opening new panes -// Default: $SHELL -// -// default_shell "fish" - -// Choose the path to override cwd that zellij will use for opening new panes -// -// default_cwd "/tmp" - -// The name of the default layout to load on startup -// Default: "default" -// -// default_layout "compact" - -// The folder in which Zellij will look for layouts -// (Requires restart) -// -// layout_dir "/tmp" - -// The folder in which Zellij will look for themes -// (Requires restart) -// -// theme_dir "/tmp" - -// Toggle enabling the mouse mode. -// On certain configurations, or terminals this could -// potentially interfere with copying text. -// Options: -// - true (default) -// - false -// -// mouse_mode false - -// Toggle having pane frames around the panes -// Options: -// - true (default, enabled) -// - false -// -// pane_frames false - -// When attaching to an existing session with other users, -// should the session be mirrored (true) -// or should each user have their own cursor (false) -// (Requires restart) -// Default: false -// -// mirror_session true - -// Choose what to do when zellij receives SIGTERM, SIGINT, SIGQUIT or SIGHUP -// eg. when terminal window with an active zellij session is closed -// (Requires restart) -// Options: -// - detach (Default) -// - quit -// -// on_force_close "quit" - -// Configure the scroll back buffer size -// This is the number of lines zellij stores for each pane in the scroll back -// buffer. Excess number of lines are discarded in a FIFO fashion. -// (Requires restart) -// Valid values: positive integers -// Default value: 10000 -// -// scroll_buffer_size 10000 - -// Provide a command to execute when copying text. The text will be piped to -// the stdin of the program to perform the copy. This can be used with -// terminal emulators which do not support the OSC 52 ANSI control sequence -// that will be used by default if this option is not set. -// Examples: -// -// copy_command "xclip -selection clipboard" // x11 -// copy_command "wl-copy" // wayland -// copy_command "pbcopy" // osx -// -// copy_command "pbcopy" - -// Choose the destination for copied text -// Allows using the primary selection buffer (on x11/wayland) instead of the system clipboard. -// Does not apply when using copy_command. -// Options: -// - system (default) -// - primary -// -// copy_clipboard "primary" - -// Enable automatic copying (and clearing) of selection when releasing mouse -// Default: true -// -// copy_on_select true - -// Path to the default editor to use to edit pane scrollbuffer -// Default: $EDITOR or $VISUAL -// scrollback_editor "/usr/bin/vim" - -// A fixed name to always give the Zellij session. -// Consider also setting `attach_to_session true,` -// otherwise this will error if such a session exists. -// Default: -// -// session_name "My singleton session" - -// When `session_name` is provided, attaches to that session -// if it is already running or creates it otherwise. -// Default: false -// -// attach_to_session true - -// Toggle between having Zellij lay out panes according to a predefined set of layouts whenever possible -// Options: -// - true (default) -// - false -// -// auto_layout false - -// Whether sessions should be serialized to the cache folder (including their tabs/panes, cwds and running commands) so that they can later be resurrected -// Options: -// - true (default) -// - false -// -// session_serialization false - -// Whether pane viewports are serialized along with the session, default is false -// Options: -// - true -// - false (default) -// -// serialize_pane_viewport false - -// Scrollback lines to serialize along with the pane viewport when serializing sessions, 0 -// defaults to the scrollback size. If this number is higher than the scrollback size, it will -// also default to the scrollback size. This does nothing if `serialize_pane_viewport` is not true. -// -// scrollback_lines_to_serialize 10000 - -// Enable or disable the rendering of styled and colored underlines (undercurl). -// May need to be disabled for certain unsupported terminals -// (Requires restart) -// Default: true -// -// styled_underlines false - -// How often in seconds sessions are serialized -// -// serialization_interval 10000 - -// Enable or disable writing of session metadata to disk (if disabled, other sessions might not know -// metadata info on this session) -// (Requires restart) -// Default: false -// -// disable_session_metadata false - -// Enable or disable support for the enhanced Kitty Keyboard Protocol (the host terminal must also support it) -// (Requires restart) -// Default: true (if the host terminal supports it) -// -// support_kitty_keyboard_protocol false - -// Whether to stack panes when resizing beyond a certain size -// Default: true -// -// stacked_resize false - -// Whether to show tips on startup -// Default: true -// -// show_startup_tips false - -// Whether to show release notes on first version run -// Default: true -// -// show_release_notes false From 898047b2eb0d6b5f878bfe5ce5521f44c2089a37 Mon Sep 17 00:00:00 2001 From: Vuong Hoang Date: Fri, 26 Jun 2026 09:28:02 -0700 Subject: [PATCH 16/22] feat(p10k): nerd-font glyphs for git status segment Replace the ASCII git VCS markers with Nerd Font glyphs: branch , detached-HEAD commit , and a distinct staged / unstaged / untracked breakdown (each with its count) in place of the single '*' dirty marker; behind/ahead use / arrows. Drop the old CONTENT_EXPANSION (hard-coded the literal arrows and stripped all spacing for the collapsed design) and the ahead/behind MAX_NUM=1 cap so real commit counts show. Glyphs use \uXXXX escapes beside naming comments for auditability; all sit in the core Nerd Font range covered by VictorMono Nerd Font Mono. --- home_root/.p10k.zsh | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/home_root/.p10k.zsh b/home_root/.p10k.zsh index a289c59..f98ef80 100644 --- a/home_root/.p10k.zsh +++ b/home_root/.p10k.zsh @@ -142,22 +142,21 @@ typeset -g POWERLEVEL9K_VCS_{INCOMING,OUTGOING}_CHANGESFORMAT_FOREGROUND=$cyan # Don't show remote branch, current tag or stashes. typeset -g POWERLEVEL9K_VCS_GIT_HOOKS=(vcs-detect-changes git-untracked git-aheadbehind) - # Don't show the branch icon. - typeset -g POWERLEVEL9K_VCS_BRANCH_ICON= - # When in detached HEAD state, show @commit where branch normally goes. - typeset -g POWERLEVEL9K_VCS_COMMIT_ICON='@' - # Don't show staged, unstaged, untracked indicators. - typeset -g POWERLEVEL9K_VCS_{STAGED,UNSTAGED,UNTRACKED}_ICON= - # Show '*' when there are staged, unstaged or untracked files. - typeset -g POWERLEVEL9K_VCS_DIRTY_ICON='*' - # Show '⇣' if local branch is behind remote. - typeset -g POWERLEVEL9K_VCS_INCOMING_CHANGES_ICON=':⇣' - # Show '⇡' if local branch is ahead of remote. - typeset -g POWERLEVEL9K_VCS_OUTGOING_CHANGES_ICON=':⇡' - # Don't show the number of commits next to the ahead/behind arrows. - typeset -g POWERLEVEL9K_VCS_{COMMITS_AHEAD,COMMITS_BEHIND}_MAX_NUM=1 - # Remove space between '⇣' and '⇡' and all trailing spaces. - typeset -g POWERLEVEL9K_VCS_CONTENT_EXPANSION='${${${P9K_CONTENT/⇣* :⇡/⇣⇡}// }//:/ }' + # Nerd Font branch glyph () before the branch name. + typeset -g POWERLEVEL9K_VCS_BRANCH_ICON=$' ' + # Detached HEAD: git-commit glyph () where the branch name normally goes. + typeset -g POWERLEVEL9K_VCS_COMMIT_ICON=$' ' + # Distinct Nerd Font glyphs, each followed by its count, for the working-tree state: + # staged · unstaged (modified, not staged) · untracked. + # A category only renders when its count is non-zero. + typeset -g POWERLEVEL9K_VCS_STAGED_ICON=$' ' + typeset -g POWERLEVEL9K_VCS_UNSTAGED_ICON=$' ' + typeset -g POWERLEVEL9K_VCS_UNTRACKED_ICON=$' ' + # No separate catch-all dirty marker — the three glyphs above are the breakdown. + typeset -g POWERLEVEL9K_VCS_DIRTY_ICON= + # Nerd Font behind/ahead arrows (/), each followed by the commit count. + typeset -g POWERLEVEL9K_VCS_INCOMING_CHANGES_ICON=$' ' + typeset -g POWERLEVEL9K_VCS_OUTGOING_CHANGES_ICON=$' ' # Grey current time. typeset -g POWERLEVEL9K_TIME_FOREGROUND=$grey From 26143c4a74f97f11042d27b4b1bb85605d764e75 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 2 Jul 2026 13:37:44 -0700 Subject: [PATCH 17/22] claude: point SemVer etiquette at canonical VERSIONING-POLICY.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Global versioning questions now resolve against corviduo-project-template/docs/VERSIONING-POLICY.md (self-pinned versioning-policy-v1); the SemVer etiquette section is declared as the Corviduo cadence layer on top — it wins on cadence/tier choice, the policy wins on format, contract semantics, pre-release staging, and release mechanics. --- home_root/.claude/CLAUDE.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/home_root/.claude/CLAUDE.md b/home_root/.claude/CLAUDE.md index 45b925c..bdd6e35 100644 --- a/home_root/.claude/CLAUDE.md +++ b/home_root/.claude/CLAUDE.md @@ -374,6 +374,26 @@ Specifically, never append: ## SemVer etiquette +**Canonical policy reference:** the formal versioning policy for ALL +projects lives at +`~/development/corviduo-project-template/docs/VERSIONING-POLICY.md` +(canonical, self-pinned as `versioning-policy-v1`). It governs version +format (SemVer 2.0.0), the public-contract declaration each project +must make, pre-1.0 semantics, pre-release staging (`-alpha.N` / +`-beta.N` / `-rc.N`, the same-commit rc discipline), dev/in-progress +labeling per ecosystem, commit conventions, the release process, and +special cases (hotfix, deprecation, breaking security fix, build +metadata). Consult it for any versioning question this section doesn't +answer — especially pre-releases and release staging, which this +section doesn't cover. + +This section is Corviduo's **operational cadence layer on top of that +policy**: which commits become releases and at what tier (tier-bar +test, patch-default, operator approval for non-patch). Where the two +differ on cadence or tier choice, this section governs; for format, +contract semantics, pre-release staging, and release mechanics, the +policy governs. + Each code-bearing or substantive-artifact commit bumps a version in the project's `pyproject.toml` (or equivalent), refreshes the lockfile, gets a `vX.Y.Z` git tag. Establishes a fine-grained From 1a2aa4f444772d4bdea0f2aca55d1002342c0da3 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 2 Jul 2026 13:45:11 -0700 Subject: [PATCH 18/22] =?UTF-8?q?claude:=20record=20operator=20ruling=20?= =?UTF-8?q?=E2=80=94=20pre-1.0=20milestone=20minors=20stay=20legal?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The tier-bar's non-breaking milestone-minor examples override VERSIONING-POLICY.md § 4's strict reading (pre-1.0 minor = breaking only). Ruled 2026-07-02; settled. --- home_root/.claude/CLAUDE.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/home_root/.claude/CLAUDE.md b/home_root/.claude/CLAUDE.md index bdd6e35..4e2563e 100644 --- a/home_root/.claude/CLAUDE.md +++ b/home_root/.claude/CLAUDE.md @@ -392,7 +392,10 @@ policy**: which commits become releases and at what tier (tier-bar test, patch-default, operator approval for non-patch). Where the two differ on cadence or tier choice, this section governs; for format, contract semantics, pre-release staging, and release mechanics, the -policy governs. +policy governs. Operator ruling (2026-07-02): pre-1.0 **milestone +minors stay legal** — this section's non-breaking milestone-minor +examples override the policy's § 4 strict reading (pre-1.0 minor = +breaking changes only). Settled; do not re-litigate. Each code-bearing or substantive-artifact commit bumps a version in the project's `pyproject.toml` (or equivalent), refreshes the From 10c424927a68a02add3963886cee70046fc3101e Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 2 Jul 2026 13:51:44 -0700 Subject: [PATCH 19/22] chore(shell): interactive_comments, bun and grok installer blocks - setopt interactive_comments: inline `#` comments at the prompt, so pasted commands with comment tails don't error (matches script mode) - bun: completions + BUN_INSTALL bin on PATH (installer-appended) - grok: bin on PATH + zsh completions fpath (installer-appended) --- home_root/.zshrc | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/home_root/.zshrc b/home_root/.zshrc index c933994..33aaee2 100644 --- a/home_root/.zshrc +++ b/home_root/.zshrc @@ -60,6 +60,10 @@ setopt hist_ignore_dups setopt hist_find_no_dups setopt hist_verify +# allow inline `#` comments at the interactive prompt (paste-friendly; +# matches non-interactive/script behavior so pasted commands don't fail) +setopt interactive_comments + # completion styling zstyle ':completion:*' matcher-list 'm:{a-z}={A-Za-z}' zstyle ':completion:*' list-colors "${(s.:.)LS_COLORS}" @@ -114,3 +118,16 @@ if [[ $(uname) == "Linux" ]]; then bindkey "${terminfo[kcud1]}" history-search-forward fi + +# bun completions +[ -s "/home/lkraven/.bun/_bun" ] && source "/home/lkraven/.bun/_bun" + +# bun +export BUN_INSTALL="$HOME/.bun" +export PATH="$BUN_INSTALL/bin:$PATH" + +# >>> grok installer >>> +export PATH="$HOME/.grok/bin:$PATH" +fpath=(~/.grok/completions/zsh $fpath) +autoload -Uz compinit && compinit -C +# <<< grok installer <<< From ac84ebde4c1a594c6b3c4b38cac89d894d0e3e1f Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 2 Jul 2026 13:51:44 -0700 Subject: [PATCH 20/22] =?UTF-8?q?feat(zellij):=20web-client=20font=20?= =?UTF-8?q?=E2=80=94=20VictorMono=20Nerd=20Font?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Forces the web pilot to VictorMono NF for ligatures. Resolves against the client device's installed fonts (no @font-face serving like the ttyd seat), so each device needs the font installed locally. --- home_config/zellij/config.kdl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/home_config/zellij/config.kdl b/home_config/zellij/config.kdl index db9ae32..d9ea728 100644 --- a/home_config/zellij/config.kdl +++ b/home_config/zellij/config.kdl @@ -584,3 +584,10 @@ show_startup_tips false // Default: true // // show_release_notes false + +// Web-client (zellij web pilot) — force VictorMono Nerd Font for ligatures. +// NOTE: resolves against the CLIENT device's installed fonts (no @font-face +// serving like the ttyd seat); each device needs the font installed. +web_client { + font "VictorMono Nerd Font" +} From 0f06e29f30ab9ff01b23e068beeae20a49829cce Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 2 Jul 2026 14:03:33 -0700 Subject: [PATCH 21/22] chore: gitignore zellij web-pilot tokens (credentials) --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 55f015b..2da5536 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ home_config/nvim/lazy-lock.json __pycache__/ *.bak +# zellij web-pilot auth tokens — credentials, never commit +home_config/zellij/pilot-tokens/ From d1a1090517bce8194b9fb036b4f649c312f53889 Mon Sep 17 00:00:00 2001 From: Vuong Hoang Date: Thu, 9 Jul 2026 10:27:54 -0700 Subject: [PATCH 22/22] wezterm: raise macOS/Linux window opacity 0.85 -> 0.95 --- home_root/.wezterm.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/home_root/.wezterm.lua b/home_root/.wezterm.lua index 7206e34..d680ee4 100644 --- a/home_root/.wezterm.lua +++ b/home_root/.wezterm.lua @@ -110,7 +110,7 @@ config.colors = { config.window_decorations = "RESIZE" config.default_prog = { 'pwsh' } else - config.window_background_opacity = 0.85 + config.window_background_opacity = 0.95 config.macos_window_background_blur = 40 config.enable_tab_bar = false config.window_decorations = "RESIZE"