From 43fe707bfe0ec2607a7e65f960bbd1f1578e8644 Mon Sep 17 00:00:00 2001 From: princejoogie Date: Tue, 10 Feb 2026 14:14:08 +0800 Subject: [PATCH 01/44] feat: migrate to kojarchy automated installer Replace stow-based setup with omarchy-style automated installer. - Two-layer config system: config/ (user-editable, copied to ~/.config/) and default/ (sourced at runtime, updated via git pull) - Replace hyprpaper with swaybg, fnm with mise, remove eww - Full install pipeline: preflight, packaging, config, services, post-install - Package lists in install/ (kojarchy-base/optional/cargo.packages) - lib/ helpers: presentation (gum TUI), logging, error handling - Fix all hardcoded stow paths in waybar, wofi, and custom scripts - Move .luarc.json and .stylua.toml into config/nvim/ - Remove arch-post.sh, config.rayconfig, old sddm helpers - Add boot.sh entry point, install.sh orchestrator, logo.txt --- .gitignore | 13 +- arch-post.sh | 73 ----- {shell/.local/custom/bin => bin}/_wt | 0 {shell/.local/custom/bin => bin}/claude-usage | 0 {shell/.local/custom/bin => bin}/clone | 0 {shell/.local/custom/bin => bin}/commit | 0 {shell/.local/custom/bin => bin}/gh-comments | 0 {shell/.local/custom/bin => bin}/lsort | 0 .../.local/custom/bin => bin}/scyrox-battery | 0 {shell/.local/custom/bin => bin}/summarize | 0 boot.sh | 27 ++ config.rayconfig | Bin 36496 -> 0 bytes config/btop/btop.conf | 272 ++++++++++++++++++ {hyprland/.config => config}/dunst/dunstrc | 0 config/hypr/hyprland.conf | 17 ++ .../kitty/current-theme.conf | 0 {shell/.config => config}/kitty/kitty.conf | 0 .luarc.json => config/nvim/.luarc.json | 0 .stylua.toml => config/nvim/.stylua.toml | 0 .../nvim/after/ftplugin/oil.lua | 0 .../nvim/after/ftplugin/qf.lua | 0 .../nvim/after/lsp/.gitkeep | 0 .../after/queries/javascript/injections.scm | 0 .../queries/javascriptreact/injections.scm | 0 .../after/queries/typescript/injections.scm | 0 .../queries/typescriptreact/injections.scm | 0 {nvim/.config => config}/nvim/init.lua | 0 {nvim/.config => config}/nvim/lazy-lock.json | 0 .../nvim/lua/joogie/autocmds/init.lua | 0 .../nvim/lua/joogie/autocmds/node-exec.lua | 0 .../nvim/lua/joogie/autocmds/opencode.lua | 0 .../nvim/lua/joogie/autocmds/super-zen.lua | 0 .../nvim/lua/joogie/init.lua | 0 .../nvim/lua/joogie/keymaps/init.lua | 0 .../nvim/lua/joogie/options/init.lua | 0 .../nvim/lua/joogie/plugins/diffview.lua | 0 .../nvim/lua/joogie/plugins/formatter.lua | 0 .../nvim/lua/joogie/plugins/gitsigns.lua | 0 .../nvim/lua/joogie/plugins/init.lua | 0 .../nvim/lua/joogie/plugins/local.lua | 0 .../nvim/lua/joogie/plugins/lsp.lua | 0 .../nvim/lua/joogie/plugins/neo-test.lua | 0 .../nvim/lua/joogie/plugins/nvim-cmp.lua | 0 .../nvim/lua/joogie/plugins/snacks.lua | 0 .../nvim/lua/joogie/plugins/theme.lua | 0 .../nvim/lua/joogie/plugins/treesitter.lua | 0 .../nvim/lua/joogie/utils/init.lua | 0 .../.config => config}/opencode/opencode.json | 0 .../skills/frontend-design/LICENSE.txt | 0 .../opencode/skills/frontend-design/SKILL.md | 0 .../skills/remotion-best-practices/SKILL.md | 0 .../remotion-best-practices/rules/3d.md | 0 .../rules/animations.md | 0 .../remotion-best-practices/rules/assets.md | 0 .../rules/assets/charts-bar-chart.tsx | 0 .../assets/text-animations-typewriter.tsx | 0 .../assets/text-animations-word-highlight.tsx | 0 .../remotion-best-practices/rules/audio.md | 0 .../rules/calculate-metadata.md | 0 .../rules/can-decode.md | 0 .../remotion-best-practices/rules/charts.md | 0 .../rules/compositions.md | 0 .../rules/display-captions.md | 0 .../rules/extract-frames.md | 0 .../remotion-best-practices/rules/fonts.md | 0 .../rules/get-audio-duration.md | 0 .../rules/get-video-dimensions.md | 0 .../rules/get-video-duration.md | 0 .../remotion-best-practices/rules/gifs.md | 0 .../remotion-best-practices/rules/images.md | 0 .../rules/import-srt-captions.md | 0 .../remotion-best-practices/rules/lottie.md | 0 .../remotion-best-practices/rules/maps.md | 0 .../rules/measuring-dom-nodes.md | 0 .../rules/measuring-text.md | 0 .../rules/parameters.md | 0 .../rules/sequencing.md | 0 .../remotion-best-practices/rules/tailwind.md | 0 .../rules/text-animations.md | 0 .../remotion-best-practices/rules/timing.md | 0 .../rules/transcribe-captions.md | 0 .../rules/transitions.md | 0 .../remotion-best-practices/rules/trimming.md | 0 .../remotion-best-practices/rules/videos.md | 0 .../opencode/skills/turborepo/SKILL.md | 0 .../skills/turborepo/command/turborepo.md | 0 .../references/best-practices/dependencies.md | 0 .../references/best-practices/packages.md | 0 .../references/best-practices/structure.md | 0 .../turborepo/references/caching/gotchas.md | 0 .../references/caching/remote-cache.md | 0 .../turborepo/references/ci/github-actions.md | 0 .../turborepo/references/ci/patterns.md | 0 .../skills/turborepo/references/ci/vercel.md | 0 .../turborepo/references/cli/commands.md | 0 .../configuration/global-options.md | 0 .../references/configuration/gotchas.md | 0 .../references/configuration/tasks.md | 0 .../references/environment/gotchas.md | 0 .../turborepo/references/environment/modes.md | 0 .../references/filtering/patterns.md | 0 .../vercel-composition-patterns/AGENTS.md | 0 .../vercel-composition-patterns/SKILL.md | 0 .../rules/architecture-avoid-boolean-props.md | 0 .../rules/architecture-compound-components.md | 0 .../patterns-children-over-render-props.md | 0 .../rules/patterns-explicit-variants.md | 0 .../rules/react19-no-forwardref.md | 0 .../rules/state-context-interface.md | 0 .../rules/state-decouple-implementation.md | 0 .../rules/state-lift-state.md | 0 .../vercel-react-best-practices/AGENTS.md | 0 .../vercel-react-best-practices/SKILL.md | 0 .../rules/advanced-event-handler-refs.md | 0 .../rules/advanced-init-once.md | 0 .../rules/advanced-use-latest.md | 0 .../rules/async-api-routes.md | 0 .../rules/async-defer-await.md | 0 .../rules/async-dependencies.md | 0 .../rules/async-parallel.md | 0 .../rules/async-suspense-boundaries.md | 0 .../rules/bundle-barrel-imports.md | 0 .../rules/bundle-conditional.md | 0 .../rules/bundle-defer-third-party.md | 0 .../rules/bundle-dynamic-imports.md | 0 .../rules/bundle-preload.md | 0 .../rules/client-event-listeners.md | 0 .../rules/client-localstorage-schema.md | 0 .../rules/client-passive-event-listeners.md | 0 .../rules/client-swr-dedup.md | 0 .../rules/js-batch-dom-css.md | 0 .../rules/js-cache-function-results.md | 0 .../rules/js-cache-property-access.md | 0 .../rules/js-cache-storage.md | 0 .../rules/js-combine-iterations.md | 0 .../rules/js-early-exit.md | 0 .../rules/js-hoist-regexp.md | 0 .../rules/js-index-maps.md | 0 .../rules/js-length-check-first.md | 0 .../rules/js-min-max-loop.md | 0 .../rules/js-set-map-lookups.md | 0 .../rules/js-tosorted-immutable.md | 0 .../rules/rendering-activity.md | 0 .../rules/rendering-animate-svg-wrapper.md | 0 .../rules/rendering-conditional-render.md | 0 .../rules/rendering-content-visibility.md | 0 .../rules/rendering-hoist-jsx.md | 0 .../rules/rendering-hydration-no-flicker.md | 0 .../rendering-hydration-suppress-warning.md | 0 .../rules/rendering-svg-precision.md | 0 .../rules/rendering-usetransition-loading.md | 0 .../rules/rerender-defer-reads.md | 0 .../rules/rerender-dependencies.md | 0 .../rules/rerender-derived-state-no-effect.md | 0 .../rules/rerender-derived-state.md | 0 .../rules/rerender-functional-setstate.md | 0 .../rules/rerender-lazy-state-init.md | 0 .../rules/rerender-memo-with-default-value.md | 0 .../rules/rerender-memo.md | 0 .../rules/rerender-move-effect-to-event.md | 0 .../rerender-simple-expression-in-memo.md | 0 .../rules/rerender-transitions.md | 0 .../rerender-use-ref-transient-values.md | 0 .../rules/server-after-nonblocking.md | 0 .../rules/server-auth-actions.md | 0 .../rules/server-cache-lru.md | 0 .../rules/server-cache-react.md | 0 .../rules/server-dedup-props.md | 0 .../rules/server-parallel-fetching.md | 0 .../rules/server-serialization.md | 0 .../vercel-react-native-skills/AGENTS.md | 0 .../vercel-react-native-skills/SKILL.md | 0 .../rules/animation-derived-value.md | 0 .../rules/animation-gesture-detector-press.md | 0 .../rules/animation-gpu-properties.md | 0 .../design-system-compound-components.md | 0 .../rules/fonts-config-plugin.md | 0 .../rules/imports-design-system-folder.md | 0 .../rules/js-hoist-intl.md | 0 .../rules/list-performance-callbacks.md | 0 .../list-performance-function-references.md | 0 .../rules/list-performance-images.md | 0 .../rules/list-performance-inline-objects.md | 0 .../rules/list-performance-item-expensive.md | 0 .../rules/list-performance-item-memo.md | 0 .../rules/list-performance-item-types.md | 0 .../rules/list-performance-virtualize.md | 0 .../rules/monorepo-native-deps-in-app.md | 0 .../monorepo-single-dependency-versions.md | 0 .../rules/navigation-native-navigators.md | 0 .../react-compiler-destructure-functions.md | 0 ...react-compiler-reanimated-shared-values.md | 0 .../rules/react-state-dispatcher.md | 0 .../rules/react-state-fallback.md | 0 .../rules/react-state-minimize.md | 0 .../rules/rendering-no-falsy-and.md | 0 .../rules/rendering-text-in-text-component.md | 0 .../rules/scroll-position-no-state.md | 0 .../rules/state-ground-truth.md | 0 .../rules/ui-expo-image.md | 0 .../rules/ui-image-gallery.md | 0 .../rules/ui-measure-views.md | 0 .../rules/ui-menus.md | 0 .../rules/ui-native-modals.md | 0 .../rules/ui-pressable.md | 0 .../rules/ui-safe-area-scroll.md | 0 .../rules/ui-scrollview-content-inset.md | 0 .../rules/ui-styling.md | 0 .../web-animation-design/PRACTICAL-TIPS.md | 0 .../skills/web-animation-design/SKILL.md | 0 .../skills/web-design-guidelines/SKILL.md | 0 .../opencode/themes/opencode-black.json | 0 {shell/.config => config}/starship.toml | 0 shell/.tmux.conf => config/tmux/tmux.conf | 0 .../.config => config}/waybar/config.jsonc | 24 +- .../waybar/custom/focus_class.sh | 0 .../waybar/custom/mouse-battery.sh | 2 +- .../waybar/custom/spotify/mediaplayer.py | 0 .../waybar/custom/tailscale/check_status.sh | 0 .../tailscale/inverted-tailscale-icon.png | Bin .../custom/tailscale/tailscale-icon.png | Bin .../waybar/custom/tailscale/tailscale-icon.sh | 10 + .../waybar/custom/tailscale/toggle.sh | 0 .../waybar/custom/tunnelbear/check_status.sh | 0 .../waybar/custom/tunnelbear/toggle.sh | 0 .../custom/tunnelbear/tunnelbear-icon.sh | 9 + .../custom/tunnelbear/tunnelbear-logo-off.png | Bin .../custom/tunnelbear/tunnelbear-logo.png | Bin .../waybar/hyprwhspr-module.jsonc | 0 {hyprland/.config => config}/waybar/mocha.css | 0 {hyprland/.config => config}/waybar/style.css | 0 {hyprland/.config => config}/wofi/config | 0 .../.config => config}/wofi/dmenu/launcher.sh | 2 +- .../wofi/dmenu/scripts/calculator | 0 .../wofi/dmenu/scripts/camera | 0 .../wofi/dmenu/scripts/close-all | 0 .../wofi/dmenu/scripts/kill-port | 0 .../wofi/dmenu/scripts/kill-process | 0 .../wofi/dmenu/scripts/open-file | 0 .../wofi/dmenu/scripts/reboot | 0 .../wofi/dmenu/scripts/shutdown | 0 .../wofi/dmenu/scripts/toggle-black | 22 +- .../wofi/dmenu/scripts/toggle-hyprsunset | 0 .../wofi/dmenu/scripts/toggle-rgb | 0 .../wofi/dmenu/scripts/toggle-waybar | 0 {hyprland/.config => config}/wofi/style.css | 0 .../xdg-desktop-portal/hyprland-portals.conf | 0 .../xdg-desktop-portal/portals.conf | 0 {hyprland/.config => config}/yazi/theme.toml | 0 default/hypr/autostart.conf | 5 + default/hypr/bindings.conf | 89 ++++++ default/hypr/envs.conf | 4 + default/hypr/input.conf | 27 ++ default/hypr/looknfeel.conf | 72 +++++ default/hypr/windows.conf | 15 + default/zsh/aliases | 11 + default/zsh/envs | 12 + default/zsh/functions | 1 + default/zsh/init | 25 ++ default/zsh/rc | 5 + default/zsh/shell | 30 ++ default/zshrc | 7 + hyprland/.config/dolphinrc | 28 -- hyprland/.config/eww/eww.yuck | 1 - hyprland/.config/eww/widgets/calendar.yuck | 14 - hyprland/.config/hypr/_black.conf | 10 - hyprland/.config/hypr/hyprland.conf | 224 --------------- hyprland/.config/hypr/hyprpaper.conf | 10 - hyprland/.config/ncspot/config.toml | 21 -- .../waybar/custom/tailscale/tailscale-icon.sh | 10 - .../custom/tunnelbear/tunnelbear-icon.sh | 9 - install.sh | 18 ++ install/config/all.sh | 10 + install/config/bin.sh | 9 + install/config/cargo.sh | 12 + install/config/config.sh | 8 + install/config/docker.sh | 16 ++ install/config/git.sh | 16 ++ install/config/gtk.sh | 7 + install/config/mise.sh | 6 + install/config/neovim.sh | 11 + install/config/shell.sh | 26 ++ install/config/tmux.sh | 11 + install/kojarchy-base.packages | 182 ++++++++++++ install/kojarchy-cargo.packages | 8 + install/kojarchy-optional.packages | 61 ++++ install/packaging/all.sh | 4 + install/packaging/aur-helper.sh | 13 + install/packaging/base.sh | 3 + install/packaging/fonts.sh | 2 + install/packaging/optional.sh | 5 + install/post-install/all.sh | 1 + install/post-install/finished.sh | 25 ++ install/preflight/all.sh | 2 + install/preflight/begin.sh | 4 + install/preflight/guard.sh | 22 ++ install/services/all.sh | 3 + install/services/sddm.sh | 21 ++ install/services/systemd.sh | 18 ++ install/services/udev.sh | 8 + lib/errors.sh | 111 +++++++ lib/helpers.sh | 8 + lib/logging.sh | 103 +++++++ lib/packages.sh | 34 +++ lib/presentation.sh | 50 ++++ logo.txt | 9 + sddm/etc/sddm.conf | 2 - sddm/install-dependencies.sh | 3 - sddm/link.sh | 5 - shell/.gitconfig | 64 ----- shell/.zshrc | 108 ------- 311 files changed, 1507 insertions(+), 623 deletions(-) delete mode 100755 arch-post.sh rename {shell/.local/custom/bin => bin}/_wt (100%) rename {shell/.local/custom/bin => bin}/claude-usage (100%) rename {shell/.local/custom/bin => bin}/clone (100%) rename {shell/.local/custom/bin => bin}/commit (100%) rename {shell/.local/custom/bin => bin}/gh-comments (100%) rename {shell/.local/custom/bin => bin}/lsort (100%) rename {shell/.local/custom/bin => bin}/scyrox-battery (100%) rename {shell/.local/custom/bin => bin}/summarize (100%) create mode 100755 boot.sh delete mode 100644 config.rayconfig create mode 100644 config/btop/btop.conf rename {hyprland/.config => config}/dunst/dunstrc (100%) create mode 100644 config/hypr/hyprland.conf rename {shell/.config => config}/kitty/current-theme.conf (100%) rename {shell/.config => config}/kitty/kitty.conf (100%) rename .luarc.json => config/nvim/.luarc.json (100%) rename .stylua.toml => config/nvim/.stylua.toml (100%) rename {nvim/.config => config}/nvim/after/ftplugin/oil.lua (100%) rename {nvim/.config => config}/nvim/after/ftplugin/qf.lua (100%) rename {nvim/.config => config}/nvim/after/lsp/.gitkeep (100%) rename {nvim/.config => config}/nvim/after/queries/javascript/injections.scm (100%) rename {nvim/.config => config}/nvim/after/queries/javascriptreact/injections.scm (100%) rename {nvim/.config => config}/nvim/after/queries/typescript/injections.scm (100%) rename {nvim/.config => config}/nvim/after/queries/typescriptreact/injections.scm (100%) rename {nvim/.config => config}/nvim/init.lua (100%) rename {nvim/.config => config}/nvim/lazy-lock.json (100%) rename {nvim/.config => config}/nvim/lua/joogie/autocmds/init.lua (100%) rename {nvim/.config => config}/nvim/lua/joogie/autocmds/node-exec.lua (100%) rename {nvim/.config => config}/nvim/lua/joogie/autocmds/opencode.lua (100%) rename {nvim/.config => config}/nvim/lua/joogie/autocmds/super-zen.lua (100%) rename {nvim/.config => config}/nvim/lua/joogie/init.lua (100%) rename {nvim/.config => config}/nvim/lua/joogie/keymaps/init.lua (100%) rename {nvim/.config => config}/nvim/lua/joogie/options/init.lua (100%) rename {nvim/.config => config}/nvim/lua/joogie/plugins/diffview.lua (100%) rename {nvim/.config => config}/nvim/lua/joogie/plugins/formatter.lua (100%) rename {nvim/.config => config}/nvim/lua/joogie/plugins/gitsigns.lua (100%) rename {nvim/.config => config}/nvim/lua/joogie/plugins/init.lua (100%) rename {nvim/.config => config}/nvim/lua/joogie/plugins/local.lua (100%) rename {nvim/.config => config}/nvim/lua/joogie/plugins/lsp.lua (100%) rename {nvim/.config => config}/nvim/lua/joogie/plugins/neo-test.lua (100%) rename {nvim/.config => config}/nvim/lua/joogie/plugins/nvim-cmp.lua (100%) rename {nvim/.config => config}/nvim/lua/joogie/plugins/snacks.lua (100%) rename {nvim/.config => config}/nvim/lua/joogie/plugins/theme.lua (100%) rename {nvim/.config => config}/nvim/lua/joogie/plugins/treesitter.lua (100%) rename {nvim/.config => config}/nvim/lua/joogie/utils/init.lua (100%) rename {opencode/.config => config}/opencode/opencode.json (100%) rename {opencode/.config => config}/opencode/skills/frontend-design/LICENSE.txt (100%) rename {opencode/.config => config}/opencode/skills/frontend-design/SKILL.md (100%) rename {opencode/.config => config}/opencode/skills/remotion-best-practices/SKILL.md (100%) rename {opencode/.config => config}/opencode/skills/remotion-best-practices/rules/3d.md (100%) rename {opencode/.config => config}/opencode/skills/remotion-best-practices/rules/animations.md (100%) rename {opencode/.config => config}/opencode/skills/remotion-best-practices/rules/assets.md (100%) rename {opencode/.config => config}/opencode/skills/remotion-best-practices/rules/assets/charts-bar-chart.tsx (100%) rename {opencode/.config => config}/opencode/skills/remotion-best-practices/rules/assets/text-animations-typewriter.tsx (100%) rename {opencode/.config => config}/opencode/skills/remotion-best-practices/rules/assets/text-animations-word-highlight.tsx (100%) rename {opencode/.config => config}/opencode/skills/remotion-best-practices/rules/audio.md (100%) rename {opencode/.config => config}/opencode/skills/remotion-best-practices/rules/calculate-metadata.md (100%) rename {opencode/.config => config}/opencode/skills/remotion-best-practices/rules/can-decode.md (100%) rename {opencode/.config => config}/opencode/skills/remotion-best-practices/rules/charts.md (100%) rename {opencode/.config => config}/opencode/skills/remotion-best-practices/rules/compositions.md (100%) rename {opencode/.config => config}/opencode/skills/remotion-best-practices/rules/display-captions.md (100%) rename {opencode/.config => config}/opencode/skills/remotion-best-practices/rules/extract-frames.md (100%) rename {opencode/.config => config}/opencode/skills/remotion-best-practices/rules/fonts.md (100%) rename {opencode/.config => config}/opencode/skills/remotion-best-practices/rules/get-audio-duration.md (100%) rename {opencode/.config => config}/opencode/skills/remotion-best-practices/rules/get-video-dimensions.md (100%) rename {opencode/.config => config}/opencode/skills/remotion-best-practices/rules/get-video-duration.md (100%) rename {opencode/.config => config}/opencode/skills/remotion-best-practices/rules/gifs.md (100%) rename {opencode/.config => config}/opencode/skills/remotion-best-practices/rules/images.md (100%) rename {opencode/.config => config}/opencode/skills/remotion-best-practices/rules/import-srt-captions.md (100%) rename {opencode/.config => config}/opencode/skills/remotion-best-practices/rules/lottie.md (100%) rename {opencode/.config => config}/opencode/skills/remotion-best-practices/rules/maps.md (100%) rename {opencode/.config => config}/opencode/skills/remotion-best-practices/rules/measuring-dom-nodes.md (100%) rename {opencode/.config => config}/opencode/skills/remotion-best-practices/rules/measuring-text.md (100%) rename {opencode/.config => config}/opencode/skills/remotion-best-practices/rules/parameters.md (100%) rename {opencode/.config => config}/opencode/skills/remotion-best-practices/rules/sequencing.md (100%) rename {opencode/.config => config}/opencode/skills/remotion-best-practices/rules/tailwind.md (100%) rename {opencode/.config => config}/opencode/skills/remotion-best-practices/rules/text-animations.md (100%) rename {opencode/.config => config}/opencode/skills/remotion-best-practices/rules/timing.md (100%) rename {opencode/.config => config}/opencode/skills/remotion-best-practices/rules/transcribe-captions.md (100%) rename {opencode/.config => config}/opencode/skills/remotion-best-practices/rules/transitions.md (100%) rename {opencode/.config => config}/opencode/skills/remotion-best-practices/rules/trimming.md (100%) rename {opencode/.config => config}/opencode/skills/remotion-best-practices/rules/videos.md (100%) rename {opencode/.config => config}/opencode/skills/turborepo/SKILL.md (100%) rename {opencode/.config => config}/opencode/skills/turborepo/command/turborepo.md (100%) rename {opencode/.config => config}/opencode/skills/turborepo/references/best-practices/dependencies.md (100%) rename {opencode/.config => config}/opencode/skills/turborepo/references/best-practices/packages.md (100%) rename {opencode/.config => config}/opencode/skills/turborepo/references/best-practices/structure.md (100%) rename {opencode/.config => config}/opencode/skills/turborepo/references/caching/gotchas.md (100%) rename {opencode/.config => config}/opencode/skills/turborepo/references/caching/remote-cache.md (100%) rename {opencode/.config => config}/opencode/skills/turborepo/references/ci/github-actions.md (100%) rename {opencode/.config => config}/opencode/skills/turborepo/references/ci/patterns.md (100%) rename {opencode/.config => config}/opencode/skills/turborepo/references/ci/vercel.md (100%) rename {opencode/.config => config}/opencode/skills/turborepo/references/cli/commands.md (100%) rename {opencode/.config => config}/opencode/skills/turborepo/references/configuration/global-options.md (100%) rename {opencode/.config => config}/opencode/skills/turborepo/references/configuration/gotchas.md (100%) rename {opencode/.config => config}/opencode/skills/turborepo/references/configuration/tasks.md (100%) rename {opencode/.config => config}/opencode/skills/turborepo/references/environment/gotchas.md (100%) rename {opencode/.config => config}/opencode/skills/turborepo/references/environment/modes.md (100%) rename {opencode/.config => config}/opencode/skills/turborepo/references/filtering/patterns.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-composition-patterns/AGENTS.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-composition-patterns/SKILL.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-composition-patterns/rules/architecture-avoid-boolean-props.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-composition-patterns/rules/architecture-compound-components.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-composition-patterns/rules/patterns-children-over-render-props.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-composition-patterns/rules/patterns-explicit-variants.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-composition-patterns/rules/react19-no-forwardref.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-composition-patterns/rules/state-context-interface.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-composition-patterns/rules/state-decouple-implementation.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-composition-patterns/rules/state-lift-state.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/AGENTS.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/SKILL.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/advanced-init-once.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/advanced-use-latest.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/async-api-routes.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/async-defer-await.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/async-dependencies.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/async-parallel.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/bundle-conditional.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/bundle-preload.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/client-event-listeners.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/client-localstorage-schema.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/client-swr-dedup.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/js-batch-dom-css.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/js-cache-function-results.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/js-cache-property-access.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/js-cache-storage.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/js-combine-iterations.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/js-early-exit.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/js-hoist-regexp.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/js-index-maps.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/js-length-check-first.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/js-min-max-loop.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/js-set-map-lookups.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/rendering-activity.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/rendering-conditional-render.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/rendering-content-visibility.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/rendering-svg-precision.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/rerender-defer-reads.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/rerender-dependencies.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/rerender-derived-state.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/rerender-memo.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/rerender-transitions.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/server-after-nonblocking.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/server-auth-actions.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/server-cache-lru.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/server-cache-react.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/server-dedup-props.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/server-parallel-fetching.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-best-practices/rules/server-serialization.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/AGENTS.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/SKILL.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/rules/animation-derived-value.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/rules/animation-gesture-detector-press.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/rules/animation-gpu-properties.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/rules/design-system-compound-components.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/rules/fonts-config-plugin.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/rules/imports-design-system-folder.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/rules/js-hoist-intl.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/rules/list-performance-callbacks.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/rules/list-performance-function-references.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/rules/list-performance-images.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/rules/list-performance-inline-objects.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/rules/list-performance-item-expensive.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/rules/list-performance-item-memo.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/rules/list-performance-item-types.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/rules/list-performance-virtualize.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/rules/monorepo-native-deps-in-app.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/rules/monorepo-single-dependency-versions.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/rules/navigation-native-navigators.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/rules/react-compiler-destructure-functions.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/rules/react-compiler-reanimated-shared-values.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/rules/react-state-dispatcher.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/rules/react-state-fallback.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/rules/react-state-minimize.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/rules/rendering-no-falsy-and.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/rules/rendering-text-in-text-component.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/rules/scroll-position-no-state.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/rules/state-ground-truth.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/rules/ui-expo-image.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/rules/ui-image-gallery.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/rules/ui-measure-views.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/rules/ui-menus.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/rules/ui-native-modals.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/rules/ui-pressable.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/rules/ui-safe-area-scroll.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/rules/ui-scrollview-content-inset.md (100%) rename {opencode/.config => config}/opencode/skills/vercel-react-native-skills/rules/ui-styling.md (100%) rename {opencode/.config => config}/opencode/skills/web-animation-design/PRACTICAL-TIPS.md (100%) rename {opencode/.config => config}/opencode/skills/web-animation-design/SKILL.md (100%) rename {opencode/.config => config}/opencode/skills/web-design-guidelines/SKILL.md (100%) rename {opencode/.config => config}/opencode/themes/opencode-black.json (100%) rename {shell/.config => config}/starship.toml (100%) rename shell/.tmux.conf => config/tmux/tmux.conf (100%) rename {hyprland/.config => config}/waybar/config.jsonc (81%) rename {hyprland/.config => config}/waybar/custom/focus_class.sh (100%) rename {hyprland/.config => config}/waybar/custom/mouse-battery.sh (93%) rename {hyprland/.config => config}/waybar/custom/spotify/mediaplayer.py (100%) rename {hyprland/.config => config}/waybar/custom/tailscale/check_status.sh (100%) rename {hyprland/.config => config}/waybar/custom/tailscale/inverted-tailscale-icon.png (100%) rename {hyprland/.config => config}/waybar/custom/tailscale/tailscale-icon.png (100%) create mode 100755 config/waybar/custom/tailscale/tailscale-icon.sh rename {hyprland/.config => config}/waybar/custom/tailscale/toggle.sh (100%) rename {hyprland/.config => config}/waybar/custom/tunnelbear/check_status.sh (100%) rename {hyprland/.config => config}/waybar/custom/tunnelbear/toggle.sh (100%) create mode 100755 config/waybar/custom/tunnelbear/tunnelbear-icon.sh rename {hyprland/.config => config}/waybar/custom/tunnelbear/tunnelbear-logo-off.png (100%) rename {hyprland/.config => config}/waybar/custom/tunnelbear/tunnelbear-logo.png (100%) rename {hyprland/.config => config}/waybar/hyprwhspr-module.jsonc (100%) rename {hyprland/.config => config}/waybar/mocha.css (100%) rename {hyprland/.config => config}/waybar/style.css (100%) rename {hyprland/.config => config}/wofi/config (100%) rename {hyprland/.config => config}/wofi/dmenu/launcher.sh (86%) rename {hyprland/.config => config}/wofi/dmenu/scripts/calculator (100%) rename {hyprland/.config => config}/wofi/dmenu/scripts/camera (100%) rename {hyprland/.config => config}/wofi/dmenu/scripts/close-all (100%) rename {hyprland/.config => config}/wofi/dmenu/scripts/kill-port (100%) rename {hyprland/.config => config}/wofi/dmenu/scripts/kill-process (100%) rename {hyprland/.config => config}/wofi/dmenu/scripts/open-file (100%) rename {hyprland/.config => config}/wofi/dmenu/scripts/reboot (100%) rename {hyprland/.config => config}/wofi/dmenu/scripts/shutdown (100%) rename {hyprland/.config => config}/wofi/dmenu/scripts/toggle-black (79%) rename {hyprland/.config => config}/wofi/dmenu/scripts/toggle-hyprsunset (100%) rename {hyprland/.config => config}/wofi/dmenu/scripts/toggle-rgb (100%) rename {hyprland/.config => config}/wofi/dmenu/scripts/toggle-waybar (100%) rename {hyprland/.config => config}/wofi/style.css (100%) rename {hyprland/.config => config}/xdg-desktop-portal/hyprland-portals.conf (100%) rename {hyprland/.config => config}/xdg-desktop-portal/portals.conf (100%) rename {hyprland/.config => config}/yazi/theme.toml (100%) create mode 100644 default/hypr/autostart.conf create mode 100644 default/hypr/bindings.conf create mode 100644 default/hypr/envs.conf create mode 100644 default/hypr/input.conf create mode 100644 default/hypr/looknfeel.conf create mode 100644 default/hypr/windows.conf create mode 100644 default/zsh/aliases create mode 100644 default/zsh/envs create mode 100644 default/zsh/functions create mode 100644 default/zsh/init create mode 100644 default/zsh/rc create mode 100644 default/zsh/shell create mode 100644 default/zshrc delete mode 100644 hyprland/.config/dolphinrc delete mode 100644 hyprland/.config/eww/eww.yuck delete mode 100644 hyprland/.config/eww/widgets/calendar.yuck delete mode 100644 hyprland/.config/hypr/_black.conf delete mode 100644 hyprland/.config/hypr/hyprland.conf delete mode 100644 hyprland/.config/hypr/hyprpaper.conf delete mode 100644 hyprland/.config/ncspot/config.toml delete mode 100755 hyprland/.config/waybar/custom/tailscale/tailscale-icon.sh delete mode 100755 hyprland/.config/waybar/custom/tunnelbear/tunnelbear-icon.sh create mode 100755 install.sh create mode 100644 install/config/all.sh create mode 100644 install/config/bin.sh create mode 100644 install/config/cargo.sh create mode 100644 install/config/config.sh create mode 100644 install/config/docker.sh create mode 100644 install/config/git.sh create mode 100644 install/config/gtk.sh create mode 100644 install/config/mise.sh create mode 100644 install/config/neovim.sh create mode 100644 install/config/shell.sh create mode 100644 install/config/tmux.sh create mode 100644 install/kojarchy-base.packages create mode 100644 install/kojarchy-cargo.packages create mode 100644 install/kojarchy-optional.packages create mode 100644 install/packaging/all.sh create mode 100644 install/packaging/aur-helper.sh create mode 100644 install/packaging/base.sh create mode 100644 install/packaging/fonts.sh create mode 100644 install/packaging/optional.sh create mode 100644 install/post-install/all.sh create mode 100644 install/post-install/finished.sh create mode 100644 install/preflight/all.sh create mode 100644 install/preflight/begin.sh create mode 100644 install/preflight/guard.sh create mode 100644 install/services/all.sh create mode 100644 install/services/sddm.sh create mode 100644 install/services/systemd.sh create mode 100644 install/services/udev.sh create mode 100644 lib/errors.sh create mode 100644 lib/helpers.sh create mode 100644 lib/logging.sh create mode 100644 lib/packages.sh create mode 100644 lib/presentation.sh create mode 100644 logo.txt delete mode 100644 sddm/etc/sddm.conf delete mode 100755 sddm/install-dependencies.sh delete mode 100755 sddm/link.sh delete mode 100644 shell/.gitconfig delete mode 100644 shell/.zshrc diff --git a/.gitignore b/.gitignore index 85c55fb1..bd61f9b0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,4 @@ -nvim/.config/nvm/ -nvim/.config/gh/ -nvim/.config/devcert/ -nvim/.config/zsh/ -nvim/.config/github-copilot/ -nvim/.config/nextjs-nodejs/ -nvim/.config/wslu/ -nvim/.config/nvim/plugin/ -shell/.local/share -shell/.local/state -shell/.local/bin -claude/.claude/ +config/nvim/plugin/ .private.sh diff --git a/arch-post.sh b/arch-post.sh deleted file mode 100755 index be8230f7..00000000 --- a/arch-post.sh +++ /dev/null @@ -1,73 +0,0 @@ -#!/bin/bash - -install_git() { - echo "" - if [[ -x "$(command -v git)" ]]; then - echo "'git' is already installed" - else - echo "Installing 'git'" - pacman -S --noconfirm git - fi -} - -install_yay() { - echo "" - if [[ -x "$(command -v yay)" ]]; then - echo "'yay' is already installed" - else - echo "Installing 'yay'" - git clone https://aur.archlinux.org/yay-bin.git - cd yay-bin || exit - makepkg -si - cd .. || exit - rm -rf yay-bin - fi - - declare -A packages=( - ["stow"]=stow - ["tmux"]=tmux - ["git-delta"]=delta - ["ripgrep"]=rg - ) - - for pkg in "${!packages[@]}"; do - bin="${packages[$pkg]}" - if [[ -x "$(command -v "$bin")" ]]; then - echo "$pkg (binary: $bin) is already installed" - else - echo "Installing $pkg" - yay -S --noconfirm "$pkg" - fi - done -} - -install_cargo() { - echo "" - if [[ -x "$(command -v cargo)" ]]; then - echo "'cargo' is already installed" - else - echo "Installing cargo" - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh - fi - - declare -A packages=( - ["bob-nvim"]=bob - ["tmux-sessionizer"]=tms - ["fnm"]=fnm - ["tree-sitter-cli"]=tree-sitter - ) - - for pkg in "${!packages[@]}"; do - bin="${packages[$pkg]}" - if [[ -x "$(command -v "$bin")" ]]; then - echo "$pkg (binary: $bin) is already installed" - else - echo "Installing $pkg" - cargo install "$pkg" - fi - done -} - -install_git -install_yay -install_cargo diff --git a/shell/.local/custom/bin/_wt b/bin/_wt similarity index 100% rename from shell/.local/custom/bin/_wt rename to bin/_wt diff --git a/shell/.local/custom/bin/claude-usage b/bin/claude-usage similarity index 100% rename from shell/.local/custom/bin/claude-usage rename to bin/claude-usage diff --git a/shell/.local/custom/bin/clone b/bin/clone similarity index 100% rename from shell/.local/custom/bin/clone rename to bin/clone diff --git a/shell/.local/custom/bin/commit b/bin/commit similarity index 100% rename from shell/.local/custom/bin/commit rename to bin/commit diff --git a/shell/.local/custom/bin/gh-comments b/bin/gh-comments similarity index 100% rename from shell/.local/custom/bin/gh-comments rename to bin/gh-comments diff --git a/shell/.local/custom/bin/lsort b/bin/lsort similarity index 100% rename from shell/.local/custom/bin/lsort rename to bin/lsort diff --git a/shell/.local/custom/bin/scyrox-battery b/bin/scyrox-battery similarity index 100% rename from shell/.local/custom/bin/scyrox-battery rename to bin/scyrox-battery diff --git a/shell/.local/custom/bin/summarize b/bin/summarize similarity index 100% rename from shell/.local/custom/bin/summarize rename to bin/summarize diff --git a/boot.sh b/boot.sh new file mode 100755 index 00000000..7befe90a --- /dev/null +++ b/boot.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +# Kojarchy bootstrap - curl-pipe-bash entry point +# Usage: curl -fsSL https://raw.githubusercontent.com/princejoogie/dotfiles/refs/heads/automated-installer/boot.sh | bash + +sudo pacman -Syu --noconfirm --needed git + +KOJARCHY_REPO="${KOJARCHY_REPO:-princejoogie/dotfiles}" +KOJARCHY_DIR="$HOME/dotfiles" + +if [[ -d "$KOJARCHY_DIR/.git" ]]; then + echo "Updating existing dotfiles..." + git -C "$KOJARCHY_DIR" pull +else + echo "Cloning dotfiles from: https://github.com/${KOJARCHY_REPO}.git" + rm -rf "$KOJARCHY_DIR" + git clone "https://github.com/${KOJARCHY_REPO}.git" "$KOJARCHY_DIR" +fi + +KOJARCHY_REF="${KOJARCHY_REF:-automated-installer}" +echo -e "\e[32mUsing branch: $KOJARCHY_REF\e[0m" +cd "$KOJARCHY_DIR" +git fetch origin "$KOJARCHY_REF" && git checkout "$KOJARCHY_REF" +cd - + +echo -e "\nInstallation starting..." +source "$KOJARCHY_DIR/install.sh" diff --git a/config.rayconfig b/config.rayconfig deleted file mode 100644 index 761e21bd5190df0fc6aa0cf938ec9c298613324d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36496 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/dev/null 2>&1; then exit 0 fi -raw=$(/home/joogie/dotfiles/shell/.local/custom/bin/scyrox-battery --device=scyrox --json --no-sudo 2>&1 || true) +raw=$("$HOME/.local/custom/bin/scyrox-battery" --device=scyrox --json --no-sudo 2>&1 || true) if [[ -z "$raw" ]]; then printf '{"text":"mouse --","tooltip":"Mouse battery unavailable"}\n' diff --git a/hyprland/.config/waybar/custom/spotify/mediaplayer.py b/config/waybar/custom/spotify/mediaplayer.py similarity index 100% rename from hyprland/.config/waybar/custom/spotify/mediaplayer.py rename to config/waybar/custom/spotify/mediaplayer.py diff --git a/hyprland/.config/waybar/custom/tailscale/check_status.sh b/config/waybar/custom/tailscale/check_status.sh similarity index 100% rename from hyprland/.config/waybar/custom/tailscale/check_status.sh rename to config/waybar/custom/tailscale/check_status.sh diff --git a/hyprland/.config/waybar/custom/tailscale/inverted-tailscale-icon.png b/config/waybar/custom/tailscale/inverted-tailscale-icon.png similarity index 100% rename from hyprland/.config/waybar/custom/tailscale/inverted-tailscale-icon.png rename to config/waybar/custom/tailscale/inverted-tailscale-icon.png diff --git a/hyprland/.config/waybar/custom/tailscale/tailscale-icon.png b/config/waybar/custom/tailscale/tailscale-icon.png similarity index 100% rename from hyprland/.config/waybar/custom/tailscale/tailscale-icon.png rename to config/waybar/custom/tailscale/tailscale-icon.png diff --git a/config/waybar/custom/tailscale/tailscale-icon.sh b/config/waybar/custom/tailscale/tailscale-icon.sh new file mode 100755 index 00000000..86bb607c --- /dev/null +++ b/config/waybar/custom/tailscale/tailscale-icon.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +STATE=$(tailscale status --json | jq -r '.BackendState') + +if [[ "$STATE" == "Running" ]]; then + echo "$HOME/.config/waybar/custom/tailscale/inverted-tailscale-icon.png" + exit 0 +fi + +echo "$HOME/.config/waybar/custom/tailscale/tailscale-icon.png" diff --git a/hyprland/.config/waybar/custom/tailscale/toggle.sh b/config/waybar/custom/tailscale/toggle.sh similarity index 100% rename from hyprland/.config/waybar/custom/tailscale/toggle.sh rename to config/waybar/custom/tailscale/toggle.sh diff --git a/hyprland/.config/waybar/custom/tunnelbear/check_status.sh b/config/waybar/custom/tunnelbear/check_status.sh similarity index 100% rename from hyprland/.config/waybar/custom/tunnelbear/check_status.sh rename to config/waybar/custom/tunnelbear/check_status.sh diff --git a/hyprland/.config/waybar/custom/tunnelbear/toggle.sh b/config/waybar/custom/tunnelbear/toggle.sh similarity index 100% rename from hyprland/.config/waybar/custom/tunnelbear/toggle.sh rename to config/waybar/custom/tunnelbear/toggle.sh diff --git a/config/waybar/custom/tunnelbear/tunnelbear-icon.sh b/config/waybar/custom/tunnelbear/tunnelbear-icon.sh new file mode 100755 index 00000000..f468f88d --- /dev/null +++ b/config/waybar/custom/tunnelbear/tunnelbear-icon.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +# Check if TunnelBear Japan connection is active +if nmcli connection show --active | grep -q "TunnelBear Japan"; then + echo "$HOME/.config/waybar/custom/tunnelbear/tunnelbear-logo.png" + exit 0 +fi + +echo "$HOME/.config/waybar/custom/tunnelbear/tunnelbear-logo-off.png" \ No newline at end of file diff --git a/hyprland/.config/waybar/custom/tunnelbear/tunnelbear-logo-off.png b/config/waybar/custom/tunnelbear/tunnelbear-logo-off.png similarity index 100% rename from hyprland/.config/waybar/custom/tunnelbear/tunnelbear-logo-off.png rename to config/waybar/custom/tunnelbear/tunnelbear-logo-off.png diff --git a/hyprland/.config/waybar/custom/tunnelbear/tunnelbear-logo.png b/config/waybar/custom/tunnelbear/tunnelbear-logo.png similarity index 100% rename from hyprland/.config/waybar/custom/tunnelbear/tunnelbear-logo.png rename to config/waybar/custom/tunnelbear/tunnelbear-logo.png diff --git a/hyprland/.config/waybar/hyprwhspr-module.jsonc b/config/waybar/hyprwhspr-module.jsonc similarity index 100% rename from hyprland/.config/waybar/hyprwhspr-module.jsonc rename to config/waybar/hyprwhspr-module.jsonc diff --git a/hyprland/.config/waybar/mocha.css b/config/waybar/mocha.css similarity index 100% rename from hyprland/.config/waybar/mocha.css rename to config/waybar/mocha.css diff --git a/hyprland/.config/waybar/style.css b/config/waybar/style.css similarity index 100% rename from hyprland/.config/waybar/style.css rename to config/waybar/style.css diff --git a/hyprland/.config/wofi/config b/config/wofi/config similarity index 100% rename from hyprland/.config/wofi/config rename to config/wofi/config diff --git a/hyprland/.config/wofi/dmenu/launcher.sh b/config/wofi/dmenu/launcher.sh similarity index 86% rename from hyprland/.config/wofi/dmenu/launcher.sh rename to config/wofi/dmenu/launcher.sh index 9091fa87..9c10a3d3 100755 --- a/hyprland/.config/wofi/dmenu/launcher.sh +++ b/config/wofi/dmenu/launcher.sh @@ -1,6 +1,6 @@ #!/bin/bash -SCRIPT_DIR="$HOME/dotfiles/hyprland/.config/wofi/dmenu/scripts" +SCRIPT_DIR="$HOME/.config/wofi/dmenu/scripts" SCRIPTS=$(ls "$SCRIPT_DIR") selected=$(printf "%s\n" "$SCRIPTS" | wofi --dmenu -p "Run script or Search web" --matching fuzzy) diff --git a/hyprland/.config/wofi/dmenu/scripts/calculator b/config/wofi/dmenu/scripts/calculator similarity index 100% rename from hyprland/.config/wofi/dmenu/scripts/calculator rename to config/wofi/dmenu/scripts/calculator diff --git a/hyprland/.config/wofi/dmenu/scripts/camera b/config/wofi/dmenu/scripts/camera similarity index 100% rename from hyprland/.config/wofi/dmenu/scripts/camera rename to config/wofi/dmenu/scripts/camera diff --git a/hyprland/.config/wofi/dmenu/scripts/close-all b/config/wofi/dmenu/scripts/close-all similarity index 100% rename from hyprland/.config/wofi/dmenu/scripts/close-all rename to config/wofi/dmenu/scripts/close-all diff --git a/hyprland/.config/wofi/dmenu/scripts/kill-port b/config/wofi/dmenu/scripts/kill-port similarity index 100% rename from hyprland/.config/wofi/dmenu/scripts/kill-port rename to config/wofi/dmenu/scripts/kill-port diff --git a/hyprland/.config/wofi/dmenu/scripts/kill-process b/config/wofi/dmenu/scripts/kill-process similarity index 100% rename from hyprland/.config/wofi/dmenu/scripts/kill-process rename to config/wofi/dmenu/scripts/kill-process diff --git a/hyprland/.config/wofi/dmenu/scripts/open-file b/config/wofi/dmenu/scripts/open-file similarity index 100% rename from hyprland/.config/wofi/dmenu/scripts/open-file rename to config/wofi/dmenu/scripts/open-file diff --git a/hyprland/.config/wofi/dmenu/scripts/reboot b/config/wofi/dmenu/scripts/reboot similarity index 100% rename from hyprland/.config/wofi/dmenu/scripts/reboot rename to config/wofi/dmenu/scripts/reboot diff --git a/hyprland/.config/wofi/dmenu/scripts/shutdown b/config/wofi/dmenu/scripts/shutdown similarity index 100% rename from hyprland/.config/wofi/dmenu/scripts/shutdown rename to config/wofi/dmenu/scripts/shutdown diff --git a/hyprland/.config/wofi/dmenu/scripts/toggle-black b/config/wofi/dmenu/scripts/toggle-black similarity index 79% rename from hyprland/.config/wofi/dmenu/scripts/toggle-black rename to config/wofi/dmenu/scripts/toggle-black index d12a42a7..8d3e1ce3 100755 --- a/hyprland/.config/wofi/dmenu/scripts/toggle-black +++ b/config/wofi/dmenu/scripts/toggle-black @@ -3,7 +3,8 @@ set -euo pipefail STATE_FILE="${XDG_CACHE_HOME:-$HOME/.cache}/toggle-black" -HYPRPAPER_CONFIG="$HOME/dotfiles/hyprland/.config/hypr/_black.conf" +BLACK_WALLPAPER="$HOME/dotfiles/wallpapers/black.png" +DEFAULT_WALLPAPER="$HOME/dotfiles/wallpapers/pallete.png" CACHE_SEPARATOR=$'\t' DEFAULT_CURSOR_TIMEOUT=10 @@ -12,21 +13,12 @@ get_option() { hyprctl -j getoption "$option" | jq -r '(.custom // .int)' } -stop_process() { - local name="$1" - local pid - pid=$(pgrep -x "$name" || true) - if [ -n "$pid" ]; then - kill "$pid" - fi -} - if [ -f "$STATE_FILE" ]; then IFS=$'\t' read -r waybar_was_running cursor_timeout previous_workspace < "$STATE_FILE" rm -f "$STATE_FILE" - stop_process hyprpaper - hyprpaper & + pkill -x swaybg || true + swaybg -i "$DEFAULT_WALLPAPER" -m fill & if [ -z "$cursor_timeout" ] || [ "$cursor_timeout" = "null" ]; then cursor_timeout=$DEFAULT_CURSOR_TIMEOUT @@ -52,9 +44,9 @@ else previous_workspace=$(hyprctl -j activeworkspace | jq -r '.id') printf "%s%s%s%s%s\n" "$waybar_was_running" "$CACHE_SEPARATOR" "$cursor_timeout" "$CACHE_SEPARATOR" "$previous_workspace" > "$STATE_FILE" - stop_process waybar - stop_process hyprpaper - hyprpaper -c "$HYPRPAPER_CONFIG" & + pkill -x waybar || true + pkill -x swaybg || true + swaybg -i "$BLACK_WALLPAPER" -m fill & hyprctl dispatch workspace 10 hyprctl keyword cursor:inactive_timeout 1 diff --git a/hyprland/.config/wofi/dmenu/scripts/toggle-hyprsunset b/config/wofi/dmenu/scripts/toggle-hyprsunset similarity index 100% rename from hyprland/.config/wofi/dmenu/scripts/toggle-hyprsunset rename to config/wofi/dmenu/scripts/toggle-hyprsunset diff --git a/hyprland/.config/wofi/dmenu/scripts/toggle-rgb b/config/wofi/dmenu/scripts/toggle-rgb similarity index 100% rename from hyprland/.config/wofi/dmenu/scripts/toggle-rgb rename to config/wofi/dmenu/scripts/toggle-rgb diff --git a/hyprland/.config/wofi/dmenu/scripts/toggle-waybar b/config/wofi/dmenu/scripts/toggle-waybar similarity index 100% rename from hyprland/.config/wofi/dmenu/scripts/toggle-waybar rename to config/wofi/dmenu/scripts/toggle-waybar diff --git a/hyprland/.config/wofi/style.css b/config/wofi/style.css similarity index 100% rename from hyprland/.config/wofi/style.css rename to config/wofi/style.css diff --git a/hyprland/.config/xdg-desktop-portal/hyprland-portals.conf b/config/xdg-desktop-portal/hyprland-portals.conf similarity index 100% rename from hyprland/.config/xdg-desktop-portal/hyprland-portals.conf rename to config/xdg-desktop-portal/hyprland-portals.conf diff --git a/hyprland/.config/xdg-desktop-portal/portals.conf b/config/xdg-desktop-portal/portals.conf similarity index 100% rename from hyprland/.config/xdg-desktop-portal/portals.conf rename to config/xdg-desktop-portal/portals.conf diff --git a/hyprland/.config/yazi/theme.toml b/config/yazi/theme.toml similarity index 100% rename from hyprland/.config/yazi/theme.toml rename to config/yazi/theme.toml diff --git a/default/hypr/autostart.conf b/default/hypr/autostart.conf new file mode 100644 index 00000000..ad8f15c7 --- /dev/null +++ b/default/hypr/autostart.conf @@ -0,0 +1,5 @@ +exec-once = systemctl --user start hyprpolkitagent +exec-once = waybar & dunst +exec-once = swaybg -i ~/dotfiles/wallpapers/pallete.png -m fill +exec-once = [workspace 1 silent] kitty +exec-once = [workspace 2 silent] flatpak run app.zen_browser.zen diff --git a/default/hypr/bindings.conf b/default/hypr/bindings.conf new file mode 100644 index 00000000..bfbf1229 --- /dev/null +++ b/default/hypr/bindings.conf @@ -0,0 +1,89 @@ +$mainMod = ALT + +# App launchers +bind = $mainMod, RETURN, exec, $terminal +bind = $mainMod, Q, killactive, +bind = $mainMod, F, fullscreen, +bind = $mainMod, M, exit, +bind = $mainMod, E, exec, $fileManager +bind = $mainMod, W, exec, ~/.config/wofi/dmenu/scripts/toggle-waybar +bind = $mainMod, V, togglefloating, +bind = $mainMod, SPACE, exec, $menu +bind = $mainMod CTRL, SPACE, exec, ~/.config/wofi/dmenu/launcher.sh +bind = $mainMod, P, pseudo, +bind = $mainMod SHIFT, J, togglesplit, +bind = $mainMod SHIFT, C, exec, hyprpicker | { read color; trimmed=$(printf "%s" "$color"); printf "%s" "$trimmed" | wl-copy; notify-send "Copied $color to clipboard"; } + +# Focus movement (vim-style) +bind = $mainMod, H, movefocus, l +bind = $mainMod, L, movefocus, r +bind = $mainMod, K, movefocus, u +bind = $mainMod, J, movefocus, d + +# Window movement +bind = $mainMod CTRL, H, movewindow, l +bind = $mainMod CTRL, J, movewindow, d +bind = $mainMod CTRL, K, movewindow, u +bind = $mainMod CTRL, L, movewindow, r + +# Window resize +bind = $mainMod CTRL SHIFT, H, resizeactive, -40 0 +bind = $mainMod CTRL SHIFT, L, resizeactive, 40 0 +bind = $mainMod CTRL SHIFT, K, resizeactive, 0 -40 +bind = $mainMod CTRL SHIFT, J, resizeactive, 0 40 + +# Workspaces +bind = $mainMod, 1, workspace, 1 +bind = $mainMod, 2, workspace, 2 +bind = $mainMod, 3, workspace, 3 +bind = $mainMod, 4, workspace, 4 +bind = $mainMod, 5, workspace, 5 +bind = $mainMod, 6, workspace, 6 +bind = $mainMod, 7, workspace, 7 +bind = $mainMod, 8, workspace, 8 +bind = $mainMod, 9, workspace, 9 +bind = $mainMod, 0, workspace, 10 + +# Move to workspace +bind = $mainMod SHIFT, 1, movetoworkspace, 1 +bind = $mainMod SHIFT, 2, movetoworkspace, 2 +bind = $mainMod SHIFT, 3, movetoworkspace, 3 +bind = $mainMod SHIFT, 4, movetoworkspace, 4 +bind = $mainMod SHIFT, 5, movetoworkspace, 5 +bind = $mainMod SHIFT, 6, movetoworkspace, 6 +bind = $mainMod SHIFT, 7, movetoworkspace, 7 +bind = $mainMod SHIFT, 8, movetoworkspace, 8 +bind = $mainMod SHIFT, 9, movetoworkspace, 9 +bind = $mainMod SHIFT, 0, movetoworkspace, 10 + +# Notifications +bind = $mainMod Shift, N, exec, dunstctl history-pop + +# Special workspace +bind = $mainMod, S, togglespecialworkspace, magic +bind = $mainMod SHIFT, S, movetoworkspace, special:magic + +# Mouse bindings +bindm = $mainMod, mouse:272, movewindow +bindm = $mainMod, mouse:273, resizewindow + +# Screenshots +bind = $mainMod, PRINT, exec, hyprshot -m window +bind = , PRINT, exec, hyprshot -m region + +# Media keys +bindel = ,XF86AudioRaiseVolume, exec, wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+ +bindel = ,XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%- +bindel = ,XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle +bindel = ,XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle +bindel = ,XF86MonBrightnessUp, exec, brightnessctl s 10%+ +bindel = ,XF86MonBrightnessDown, exec, brightnessctl s 10%- + +# Player controls +bindl = , XF86AudioNext, exec, playerctl next +bindl = , XF86AudioPause, exec, playerctl play-pause +bindl = , XF86AudioPlay, exec, playerctl play-pause +bindl = , XF86AudioPrev, exec, playerctl previous + +# hyprwhspr +bindd = $mainMod SHIFT, D, Speech-to-text, exec, /usr/lib/hyprwhspr/config/hyprland/hyprwhspr-tray.sh record diff --git a/default/hypr/envs.conf b/default/hypr/envs.conf new file mode 100644 index 00000000..4b161917 --- /dev/null +++ b/default/hypr/envs.conf @@ -0,0 +1,4 @@ +env = XCURSOR_SIZE,24 +env = HYPRCURSOR_SIZE,24 +env = QT_QPA_PLATFORMTHEME,qt6ct +env = XDG_MENU_PREFIX,arch- diff --git a/default/hypr/input.conf b/default/hypr/input.conf new file mode 100644 index 00000000..57f9e675 --- /dev/null +++ b/default/hypr/input.conf @@ -0,0 +1,27 @@ +input { + kb_layout = us + kb_variant = + kb_model = + kb_options = + kb_rules = + + repeat_delay = 300 + repeat_rate = 50 + + follow_mouse = 1 + + sensitivity = -0.7 # -1.0 - 1.0, 0 means no modification. + + touchpad { + natural_scroll = false + } +} + +cursor { + inactive_timeout = 10 +} + +device { + name = epic-mouse-v1 + sensitivity = -0.5 +} diff --git a/default/hypr/looknfeel.conf b/default/hypr/looknfeel.conf new file mode 100644 index 00000000..c60d7b72 --- /dev/null +++ b/default/hypr/looknfeel.conf @@ -0,0 +1,72 @@ +general { + gaps_in = 2 + gaps_out = 4 + + border_size = 1 + + col.active_border = rgba(b4befeFF) rgba(89b4faFF) 45deg + col.inactive_border = rgba(45475aAA) + + resize_on_border = false + allow_tearing = false + layout = dwindle +} + +decoration { + rounding = 10 + rounding_power = 2 + + shadow { + enabled = true + range = 4 + render_power = 3 + color = rgba(11111bAA) + } + + blur { + enabled = true + size = 4 + passes = 4 + vibrancy = 0.1696 + } +} + +animations { + enabled = yes, please :) + + bezier = easeOutQuint,0.23,1,0.32,1 + bezier = easeInOutCubic,0.65,0.05,0.36,1 + bezier = linear,0,0,1,1 + bezier = almostLinear,0.5,0.5,0.75,1.0 + bezier = quick,0.15,0,0.1,1 + + animation = global, 1, 5, default + animation = border, 1, 2.5, easeOutQuint + animation = windows, 1, 2.5, easeOutQuint + animation = windowsIn, 1, 2, easeOutQuint, popin 87% + animation = windowsOut, 1, 1, linear, popin 87% + animation = fadeIn, 1, 1, almostLinear + animation = fadeOut, 1, 1, almostLinear + animation = fade, 1, 1.5, quick + animation = layersOut, 1, 1, linear, fade + animation = fadeLayersIn, 1, 1, almostLinear + animation = fadeLayersOut, 1, 1, almostLinear + animation = workspaces, 1, 1.5, almostLinear, fade + animation = workspacesIn, 1, 3, easeOutQuint, slide + animation = workspacesOut, 1, 3, easeOutQuint, slide +} + +dwindle { + pseudotile = true + preserve_split = true +} + +master { + new_status = master +} + +misc { + focus_on_activate = true + force_default_wallpaper = -1 + disable_hyprland_logo = false +} diff --git a/default/hypr/windows.conf b/default/hypr/windows.conf new file mode 100644 index 00000000..124f6f09 --- /dev/null +++ b/default/hypr/windows.conf @@ -0,0 +1,15 @@ +windowrule = match:class .*, suppress_event maximize + +windowrule = match:class ^$, match:title ^$, match:xwayland 1, match:float on, match:fullscreen 0, match:pin 0, stay_focused on + +# xwaylandvideobridge +windowrule = match:class ^(xwaylandvideobridge)$, opacity 0.0 override +windowrule = match:class ^(xwaylandvideobridge)$, no_anim on +windowrule = match:class ^(xwaylandvideobridge)$, stay_focused on +windowrule = match:class ^(xwaylandvideobridge)$, no_max_size on +windowrule = match:class ^(xwaylandvideobridge)$, no_blur on + +windowrule = match:workspace w[t1], border_size 0 + +windowrule = match:class ^(org\.freedesktop\.impl\.portal\.desktop\.kde)$, float on +windowrule = match:class ^(org\.freedesktop\.impl\.portal\.desktop\.kde)$, size 900 600 diff --git a/default/zsh/aliases b/default/zsh/aliases new file mode 100644 index 00000000..51a70287 --- /dev/null +++ b/default/zsh/aliases @@ -0,0 +1,11 @@ +alias cls=clear +alias sl="eza --group-directories-first --icons --time-style=long-iso -la" +alias so=source +alias x=exit +alias G=git +alias t=tmux +alias lta="ls -ltar --human-readable | grep -vE '^\.| \.$| \.\.$'" +alias pip=pip3 +alias wt=". _wt" +alias ai="noglob opencode run --model \"opencode/gemini-3-flash\"" +alias open=xdg-open diff --git a/default/zsh/envs b/default/zsh/envs new file mode 100644 index 00000000..432c4b66 --- /dev/null +++ b/default/zsh/envs @@ -0,0 +1,12 @@ +export EDITOR=nvim +export MANPAGER='nvim +Man!' +export PATH=$PATH:$HOME/.cargo/bin +export PATH=$PATH:$HOME/.local/bin +export PATH=$PATH:$HOME/.local/custom/bin +export PATH=$PATH:$HOME/.local/share/bob/nvim-bin +export PATH=$PATH:$HOME/.duckdb/cli/latest +export PATH=$PATH:$HOME/.opencode/bin +export PATH=$PATH:$HOME/.lmstudio/bin +export PATH=$PATH:$HOME/go/bin +export BUN_INSTALL="$HOME/.bun" +export PATH=$PATH:$BUN_INSTALL/bin diff --git a/default/zsh/functions b/default/zsh/functions new file mode 100644 index 00000000..ee11f849 --- /dev/null +++ b/default/zsh/functions @@ -0,0 +1 @@ +# Add custom shell functions here diff --git a/default/zsh/init b/default/zsh/init new file mode 100644 index 00000000..8ebf16f0 --- /dev/null +++ b/default/zsh/init @@ -0,0 +1,25 @@ +# starship +if [[ -x "$(command -v starship)" ]]; then + eval "$(starship init zsh)" +fi + +# mise (replaces fnm) +if command -v mise &>/dev/null; then + eval "$(mise activate zsh)" +fi + +# uv +if [[ -x "$(command -v uv)" ]]; then + eval "$(uv generate-shell-completion zsh)" +fi +if [[ -x "$(command -v uvx)" ]]; then + eval "$(uvx --generate-shell-completion zsh)" +fi + +# direnv +if [[ -x "$(command -v direnv)" ]]; then + eval "$(direnv hook zsh)" +fi + +# bun +[ -s "$HOME/.bun/_bun" ] && source "$HOME/.bun/_bun" diff --git a/default/zsh/rc b/default/zsh/rc new file mode 100644 index 00000000..65ac45a2 --- /dev/null +++ b/default/zsh/rc @@ -0,0 +1,5 @@ +source ~/dotfiles/default/zsh/shell +source ~/dotfiles/default/zsh/aliases +source ~/dotfiles/default/zsh/functions +source ~/dotfiles/default/zsh/init +source ~/dotfiles/default/zsh/envs diff --git a/default/zsh/shell b/default/zsh/shell new file mode 100644 index 00000000..17fce882 --- /dev/null +++ b/default/zsh/shell @@ -0,0 +1,30 @@ +autoload -U compinit +compinit + +export DISABLE_AUTO_UPDATE="true" +export ZSH="$HOME/.oh-my-zsh" + +plugins=( + z + gh + aws + git + tmux + docker + vi-mode + zsh-autosuggestions + zsh-syntax-highlighting + fast-syntax-highlighting +) + +bindkey -M viins jj vi-cmd-mode +export VI_MODE_SET_CURSOR=true + +# History options +setopt HIST_IGNORE_ALL_DUPS +setopt HIST_FIND_NO_DUPS +setopt HIST_SAVE_NO_DUPS +setopt SHARE_HISTORY +setopt INC_APPEND_HISTORY + +source $ZSH/oh-my-zsh.sh diff --git a/default/zshrc b/default/zshrc new file mode 100644 index 00000000..c0eca6da --- /dev/null +++ b/default/zshrc @@ -0,0 +1,7 @@ +# Source defaults from dotfiles (updated via git pull) +source ~/dotfiles/default/zsh/rc + +# Add your own customizations below: +if [[ -f "$HOME/.private.sh" ]]; then + source "$HOME/.private.sh" +fi diff --git a/hyprland/.config/dolphinrc b/hyprland/.config/dolphinrc deleted file mode 100644 index 59b9f950..00000000 --- a/hyprland/.config/dolphinrc +++ /dev/null @@ -1,28 +0,0 @@ -[CompactMode] -PreviewSize=96 - -[DetailsMode] -PreviewSize=112 - -[General] -Version=202 -ViewPropsTimestamp=2025,5,3,1,9,35.934 - -[IconsMode] -PreviewSize=256 - -[KFileDialog Settings] -Places Icons Auto-resize=false -Places Icons Static Size=48 - -[MainWindow] -MenuBar=Disabled - -[PlacesPanel] -IconSize=48 - -[PreviewSettings] -Plugins=appimagethumbnail,audiothumbnail,comicbookthumbnail,cursorthumbnail,djvuthumbnail,ebookthumbnail,exrthumbnail,directorythumbnail,imagethumbnail,jpegthumbnail,kraorathumbnail,windowsexethumbnail,windowsimagethumbnail,opendocumentthumbnail,svgthumbnail,ffmpegthumbs,gdk-pixbuf-thumbnailer - -[UiSettings] -ColorScheme=catpuccin-mocha-blue diff --git a/hyprland/.config/eww/eww.yuck b/hyprland/.config/eww/eww.yuck deleted file mode 100644 index 63ff0cfb..00000000 --- a/hyprland/.config/eww/eww.yuck +++ /dev/null @@ -1 +0,0 @@ -(include "widgets/calendar.yuck") diff --git a/hyprland/.config/eww/widgets/calendar.yuck b/hyprland/.config/eww/widgets/calendar.yuck deleted file mode 100644 index fad10443..00000000 --- a/hyprland/.config/eww/widgets/calendar.yuck +++ /dev/null @@ -1,14 +0,0 @@ -(defwindow calendar - :monitor 0 - :geometry (geometry :x 1160 :y 0 :width 240 :height 200) - :stacking "fg" - :focusable true - :on-lost-focus "eww close calendar" - :visible false - (calendar - :show-heading true - :show-day-names true - :show-week-numbers false - ) -) - diff --git a/hyprland/.config/hypr/_black.conf b/hyprland/.config/hypr/_black.conf deleted file mode 100644 index ffa972df..00000000 --- a/hyprland/.config/hypr/_black.conf +++ /dev/null @@ -1,10 +0,0 @@ -# preload = ~/dotfiles/wallpapers/macos11-night.jpg -# wallpaper = ,~/dotfiles/wallpapers/macos11-night.jpg - -splash = false - -wallpaper { - monitor = DP-1 - path = ~/dotfiles/wallpapers/black.png - fit_mode = cover -} diff --git a/hyprland/.config/hypr/hyprland.conf b/hyprland/.config/hypr/hyprland.conf deleted file mode 100644 index 9c7b5b53..00000000 --- a/hyprland/.config/hypr/hyprland.conf +++ /dev/null @@ -1,224 +0,0 @@ -monitor=,2560x1440@240,auto,1 - -$terminal = kitty -$fileManager = dolphin -$menu = wofi --show drun --matching startswith -$toggleWaybar = ~/dotfiles/hyprland/.config/wofi/dmenu/scripts/toggle-waybar -$menuScripts = ~/dotfiles/hyprland/.config/wofi/dmenu/launcher.sh - -exec-once = systemctl --user start hyprpolkitagent -exec-once = waybar & hyprpaper & eww daemon & dunst -exec-once = [workspace 1 silent] kitty -exec-once = [workspace 2 silent] flatpak run app.zen_browser.zen - -env = XCURSOR_SIZE,24 -env = HYPRCURSOR_SIZE,24 -env = QT_QPA_PLATFORMTHEME,qt5ct -env = QT_QPA_PLATFORMTHEME,qt6ct -env = XDG_MENU_PREFIX,arch- - -general { - gaps_in = 2 - gaps_out = 4 - - border_size = 1 - - col.active_border = rgba(b4befeFF) rgba(89b4faFF) 45deg - col.inactive_border = rgba(45475aAA) - - resize_on_border = false - allow_tearing = false - layout = dwindle -} - -decoration { - rounding = 10 - rounding_power = 2 - - shadow { - enabled = true - range = 4 - render_power = 3 - color = rgba(11111bAA) - } - - blur { - enabled = true - size = 4 - passes = 4 - vibrancy = 0.1696 - } -} - -animations { - enabled = yes, please :) - - bezier = easeOutQuint,0.23,1,0.32,1 - bezier = easeInOutCubic,0.65,0.05,0.36,1 - bezier = linear,0,0,1,1 - bezier = almostLinear,0.5,0.5,0.75,1.0 - bezier = quick,0.15,0,0.1,1 - - animation = global, 1, 5, default - animation = border, 1, 2.5, easeOutQuint - animation = windows, 1, 2.5, easeOutQuint - animation = windowsIn, 1, 2, easeOutQuint, popin 87% - animation = windowsOut, 1, 1, linear, popin 87% - animation = fadeIn, 1, 1, almostLinear - animation = fadeOut, 1, 1, almostLinear - animation = fade, 1, 1.5, quick - animation = layersOut, 1, 1, linear, fade - animation = fadeLayersIn, 1, 1, almostLinear - animation = fadeLayersOut, 1, 1, almostLinear - animation = workspaces, 1, 1.5, almostLinear, fade - animation = workspacesIn, 1, 3, easeOutQuint, slide - animation = workspacesOut, 1, 3, easeOutQuint, slide -} - -dwindle { - pseudotile = true - preserve_split = true -} - -master { - new_status = master -} - -misc { - focus_on_activate = true - force_default_wallpaper = -1 - disable_hyprland_logo = false -} - -input { - kb_layout = us - kb_variant = - kb_model = - kb_options = ctrl:nocaps - kb_rules = - - repeat_delay = 300 - repeat_rate = 50 - - follow_mouse = 1 - - sensitivity = -0.7 # -1.0 - 1.0, 0 means no modification. - - touchpad { - natural_scroll = false - } -} - -cursor { - inactive_timeout = 10 -} - -device { - name = epic-mouse-v1 - sensitivity = -0.5 -} - - -$mainMod = ALT - -bind = $mainMod, RETURN, exec, $terminal -bind = $mainMod, Q, killactive, -bind = $mainMod, F, fullscreen, -bind = $mainMod, M, exit, -bind = $mainMod, E, exec, $fileManager -bind = $mainMod, W, exec, $toggleWaybar -bind = $mainMod, V, togglefloating, -bind = $mainMod, SPACE, exec, $menu -bind = $mainMod CTRL, SPACE, exec, $menuScripts -bind = $mainMod, P, pseudo, # dwindle -bind = $mainMod SHIFT, J, togglesplit, # dwindle -bind = $mainMod SHIFT, C, exec, hyprpicker | { read color; trimmed=$(printf "%s" "$color"); printf "%s" "$trimmed" | wl-copy; notify-send "Copied $color to clipboard"; } - -bind = $mainMod, H, movefocus, l -bind = $mainMod, L, movefocus, r -bind = $mainMod, K, movefocus, u -bind = $mainMod, J, movefocus, d - -bind = $mainMod CTRL, H, movewindow, l -bind = $mainMod CTRL, J, movewindow, d -bind = $mainMod CTRL, K, movewindow, u -bind = $mainMod CTRL, L, movewindow, r - -bind = $mainMod CTRL SHIFT, H, resizeactive, -40 0 -bind = $mainMod CTRL SHIFT, L, resizeactive, 40 0 -bind = $mainMod CTRL SHIFT, K, resizeactive, 0 -40 -bind = $mainMod CTRL SHIFT, J, resizeactive, 0 40 - -bind = $mainMod, 1, workspace, 1 -bind = $mainMod, 2, workspace, 2 -bind = $mainMod, 3, workspace, 3 -bind = $mainMod, 4, workspace, 4 -bind = $mainMod, 5, workspace, 5 -bind = $mainMod, 6, workspace, 6 -bind = $mainMod, 7, workspace, 7 -bind = $mainMod, 8, workspace, 8 -bind = $mainMod, 9, workspace, 9 -bind = $mainMod, 0, workspace, 10 - -bind = $mainMod SHIFT, 1, movetoworkspace, 1 -bind = $mainMod SHIFT, 2, movetoworkspace, 2 -bind = $mainMod SHIFT, 3, movetoworkspace, 3 -bind = $mainMod SHIFT, 4, movetoworkspace, 4 -bind = $mainMod SHIFT, 5, movetoworkspace, 5 -bind = $mainMod SHIFT, 6, movetoworkspace, 6 -bind = $mainMod SHIFT, 7, movetoworkspace, 7 -bind = $mainMod SHIFT, 8, movetoworkspace, 8 -bind = $mainMod SHIFT, 9, movetoworkspace, 9 -bind = $mainMod SHIFT, 0, movetoworkspace, 10 - -bind = $mainMod Shift, N, exec, dunstctl history-pop - -bind = $mainMod, S, togglespecialworkspace, magic -bind = $mainMod SHIFT, S, movetoworkspace, special:magic - -# bind = $mainMod, mouse_down, workspace, e+1 -# bind = $mainMod, mouse_up, workspace, e-1 - -bindm = $mainMod, mouse:272, movewindow -bindm = $mainMod, mouse:273, resizewindow - -bind = $mainMod, PRINT, exec, hyprshot -m window -bind = $mainMod SHIFT, P, exec, hyprshot -m region -bind = , PRINT, exec, hyprshot -m region - -bindel = ,XF86AudioRaiseVolume, exec, wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+ -bindel = ,XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%- -bindel = ,XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle -bindel = ,XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle -bindel = ,XF86MonBrightnessUp, exec, brightnessctl s 10%+ -bindel = ,XF86MonBrightnessDown, exec, brightnessctl s 10%- - -bindl = , XF86AudioNext, exec, playerctl next -bindl = , XF86AudioPause, exec, playerctl play-pause -bindl = , XF86AudioPlay, exec, playerctl play-pause -bindl = , XF86AudioPrev, exec, playerctl previous - -windowrule = match:class .*, suppress_event maximize - -windowrule = match:class ^$, match:title ^$, match:xwayland 1, match:float on, match:fullscreen 0, match:pin 0, stay_focused on - -windowrule = match:class ^(xwaylandvideobridge)$, opacity 0.0 override -windowrule = match:class ^(xwaylandvideobridge)$, no_anim on -windowrule = match:class ^(xwaylandvideobridge)$, stay_focused on -windowrule = match:class ^(xwaylandvideobridge)$, no_max_size on -windowrule = match:class ^(xwaylandvideobridge)$, no_blur on -windowrule = match:class ^(xwaylandvideobridge)$, stay_focused on - -windowrule = match:class ^(eww)$, float on -windowrule = match:class ^(eww)$, stay_focused on -windowrule = match:class ^(eww)$, border_size 0 -windowrule = match:class ^(eww)$, stay_focused on -windowrule = match:class ^(eww)$, workspace special silent -windowrule = match:workspace w[t1], border_size 0 - -windowrule = match:class ^(org\.freedesktop\.impl\.portal\.desktop\.kde)$, float on -windowrule = match:class ^(org\.freedesktop\.impl\.portal\.desktop\.kde)$, size 900 600 - -# hyprwhspr - Toggle mode (added by hyprwhspr setup) -# Press once to start, press again to stop -bindd = $mainMod SHIFT, D, Speech-to-text, exec, /usr/lib/hyprwhspr/config/hyprland/hyprwhspr-tray.sh record diff --git a/hyprland/.config/hypr/hyprpaper.conf b/hyprland/.config/hypr/hyprpaper.conf deleted file mode 100644 index f46b3e21..00000000 --- a/hyprland/.config/hypr/hyprpaper.conf +++ /dev/null @@ -1,10 +0,0 @@ -# preload = ~/dotfiles/wallpapers/macos11-night.jpg -# wallpaper = ,~/dotfiles/wallpapers/macos11-night.jpg - -splash = false - -wallpaper { - monitor = DP-1 - path = ~/dotfiles/wallpapers/pallete.png - fit_mode = cover -} diff --git a/hyprland/.config/ncspot/config.toml b/hyprland/.config/ncspot/config.toml deleted file mode 100644 index c83fe268..00000000 --- a/hyprland/.config/ncspot/config.toml +++ /dev/null @@ -1,21 +0,0 @@ -[bindings] -"g" = "move_top" -"G" = "move_bottom" - -[theme] -background = "#1e1e2e" -primary = "#cdd6f4" -secondary = "#94e2d5" -title = "#89b4fa" -playing = "#a6e3a1" -playing_bg = "#1e1e2e" -highlight = "#cdd6f4" -highlight_bg = "#536994" -playing_selected = "#a6e3a1" -error = "#1e1e2e" -error_bg = "#f38ba8" -statusbar = "#89b4fa" -statusbar_bg = "#313244" -statusbar_progress = "#89b4fa" -cmdline = "#89b4fa" -cmdline_bg = "#181825" diff --git a/hyprland/.config/waybar/custom/tailscale/tailscale-icon.sh b/hyprland/.config/waybar/custom/tailscale/tailscale-icon.sh deleted file mode 100755 index af9319e9..00000000 --- a/hyprland/.config/waybar/custom/tailscale/tailscale-icon.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -STATE=$(tailscale status --json | jq -r '.BackendState') - -if [[ "$STATE" == "Running" ]]; then - echo "/home/joogie/dotfiles/hyprland/.config/waybar/custom/tailscale/inverted-tailscale-icon.png" - exit 0 -fi - -echo "/home/joogie/dotfiles/hyprland/.config/waybar/custom/tailscale/tailscale-icon.png" diff --git a/hyprland/.config/waybar/custom/tunnelbear/tunnelbear-icon.sh b/hyprland/.config/waybar/custom/tunnelbear/tunnelbear-icon.sh deleted file mode 100755 index 2450b019..00000000 --- a/hyprland/.config/waybar/custom/tunnelbear/tunnelbear-icon.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -# Check if TunnelBear Japan connection is active -if nmcli connection show --active | grep -q "TunnelBear Japan"; then - echo "/home/joogie/dotfiles/hyprland/.config/waybar/custom/tunnelbear/tunnelbear-logo.png" - exit 0 -fi - -echo "/home/joogie/dotfiles/hyprland/.config/waybar/custom/tunnelbear/tunnelbear-logo-off.png" \ No newline at end of file diff --git a/install.sh b/install.sh new file mode 100755 index 00000000..efc5d933 --- /dev/null +++ b/install.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +# Exit immediately if a command exits with a non-zero status +set -eEo pipefail + +# Define Kojarchy locations +export KOJARCHY_DIR="$HOME/dotfiles" +export KOJARCHY_INSTALL="$KOJARCHY_DIR/install" +export KOJARCHY_LOG="/var/log/kojarchy-install.log" +export PATH="$KOJARCHY_DIR/bin:$PATH" + +# Install +source "$KOJARCHY_DIR/lib/helpers.sh" +source "$KOJARCHY_INSTALL/preflight/all.sh" +source "$KOJARCHY_INSTALL/packaging/all.sh" +source "$KOJARCHY_INSTALL/config/all.sh" +source "$KOJARCHY_INSTALL/services/all.sh" +source "$KOJARCHY_INSTALL/post-install/all.sh" diff --git a/install/config/all.sh b/install/config/all.sh new file mode 100644 index 00000000..797f3868 --- /dev/null +++ b/install/config/all.sh @@ -0,0 +1,10 @@ +run_logged $KOJARCHY_INSTALL/config/config.sh +run_logged $KOJARCHY_INSTALL/config/bin.sh +run_logged $KOJARCHY_INSTALL/config/shell.sh +run_logged $KOJARCHY_INSTALL/config/tmux.sh +run_logged $KOJARCHY_INSTALL/config/cargo.sh +run_logged $KOJARCHY_INSTALL/config/neovim.sh +run_logged $KOJARCHY_INSTALL/config/mise.sh +run_logged $KOJARCHY_INSTALL/config/git.sh +run_logged $KOJARCHY_INSTALL/config/docker.sh +run_logged $KOJARCHY_INSTALL/config/gtk.sh diff --git a/install/config/bin.sh b/install/config/bin.sh new file mode 100644 index 00000000..16c01f1f --- /dev/null +++ b/install/config/bin.sh @@ -0,0 +1,9 @@ +# Symlink bin scripts to ~/.local/custom/bin/ +mkdir -p ~/.local/custom/bin + +for script in "$KOJARCHY_DIR"/bin/*; do + local_name="$HOME/.local/custom/bin/$(basename "$script")" + ln -sf "$script" "$local_name" +done + +echo "Bin scripts linked to ~/.local/custom/bin/" diff --git a/install/config/cargo.sh b/install/config/cargo.sh new file mode 100644 index 00000000..02b30f9a --- /dev/null +++ b/install/config/cargo.sh @@ -0,0 +1,12 @@ +# Ensure rust toolchain is set up +if ! command -v cargo &>/dev/null; then + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y + source "$HOME/.cargo/env" +fi + +rustup default stable + +# Install cargo packages +install_cargo_packages "$KOJARCHY_INSTALL/kojarchy-cargo.packages" + +echo "Cargo: OK" diff --git a/install/config/config.sh b/install/config/config.sh new file mode 100644 index 00000000..495c854b --- /dev/null +++ b/install/config/config.sh @@ -0,0 +1,8 @@ +# Copy over Kojarchy configs to ~/.config/ +mkdir -p ~/.config +cp -R "$KOJARCHY_DIR/config/"* ~/.config/ + +# Use default zshrc from Kojarchy +cp "$KOJARCHY_DIR/default/zshrc" ~/.zshrc + +echo "Configs deployed to ~/.config/" diff --git a/install/config/docker.sh b/install/config/docker.sh new file mode 100644 index 00000000..27dc7acc --- /dev/null +++ b/install/config/docker.sh @@ -0,0 +1,16 @@ +# Configure Docker daemon +sudo mkdir -p /etc/docker +sudo tee /etc/docker/daemon.json >/dev/null <<'EOF' +{ + "log-driver": "json-file", + "log-opts": { "max-size": "10m", "max-file": "5" } +} +EOF + +# Start Docker automatically +sudo systemctl enable docker + +# Give this user privileged Docker access +sudo usermod -aG docker ${USER} + +echo "Docker: OK" diff --git a/install/config/git.sh b/install/config/git.sh new file mode 100644 index 00000000..cefc6152 --- /dev/null +++ b/install/config/git.sh @@ -0,0 +1,16 @@ +# Prompt for git identity if not already set +if [[ -z "$(git config --global user.name)" ]]; then + name=$(gum input --placeholder "Your full name" --header "Git user.name:" /dev/null; then + gsettings set org.gnome.desktop.interface gtk-theme "Adwaita-dark" 2>/dev/null || true + gsettings set org.gnome.desktop.interface color-scheme "prefer-dark" 2>/dev/null || true +fi + +echo "GTK theme: OK" diff --git a/install/config/mise.sh b/install/config/mise.sh new file mode 100644 index 00000000..febe175b --- /dev/null +++ b/install/config/mise.sh @@ -0,0 +1,6 @@ +# Set up mise global tools (replaces fnm) +if command -v mise &>/dev/null; then + mise use -g node@latest +fi + +echo "Mise: OK" diff --git a/install/config/neovim.sh b/install/config/neovim.sh new file mode 100644 index 00000000..acec4085 --- /dev/null +++ b/install/config/neovim.sh @@ -0,0 +1,11 @@ +# Install neovim via bob +if command -v bob &>/dev/null; then + bob use stable +fi + +# Run lazy.nvim sync headlessly +if command -v nvim &>/dev/null; then + nvim --headless "+Lazy! sync" +qa 2>/dev/null || true +fi + +echo "Neovim: OK" diff --git a/install/config/shell.sh b/install/config/shell.sh new file mode 100644 index 00000000..6fbdc00e --- /dev/null +++ b/install/config/shell.sh @@ -0,0 +1,26 @@ +# Install oh-my-zsh (unattended) +if [[ ! -d "$HOME/.oh-my-zsh" ]]; then + RUNZSH=no KEEP_ZSHRC=yes sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" +fi + +# Install zsh plugins +ZSH_CUSTOM="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}" + +if [[ ! -d "$ZSH_CUSTOM/plugins/zsh-autosuggestions" ]]; then + git clone https://github.com/zsh-users/zsh-autosuggestions "$ZSH_CUSTOM/plugins/zsh-autosuggestions" +fi + +if [[ ! -d "$ZSH_CUSTOM/plugins/zsh-syntax-highlighting" ]]; then + git clone https://github.com/zsh-users/zsh-syntax-highlighting "$ZSH_CUSTOM/plugins/zsh-syntax-highlighting" +fi + +if [[ ! -d "$ZSH_CUSTOM/plugins/fast-syntax-highlighting" ]]; then + git clone https://github.com/zdharma-continuum/fast-syntax-highlighting "$ZSH_CUSTOM/plugins/fast-syntax-highlighting" +fi + +# Set zsh as default shell +if [[ "$SHELL" != *"zsh"* ]]; then + chsh -s /usr/bin/zsh +fi + +echo "Shell: OK" diff --git a/install/config/tmux.sh b/install/config/tmux.sh new file mode 100644 index 00000000..25fcca84 --- /dev/null +++ b/install/config/tmux.sh @@ -0,0 +1,11 @@ +# Install TPM (Tmux Plugin Manager) +TPM_DIR="$HOME/.tmux/plugins/tpm" + +if [[ ! -d "$TPM_DIR" ]]; then + git clone https://github.com/tmux-plugins/tpm "$TPM_DIR" +fi + +# Install tmux plugins +"$TPM_DIR/bin/install_plugins" || true + +echo "Tmux: OK" diff --git a/install/kojarchy-base.packages b/install/kojarchy-base.packages new file mode 100644 index 00000000..e2b57730 --- /dev/null +++ b/install/kojarchy-base.packages @@ -0,0 +1,182 @@ +# Kojarchy core package list installed via install/packaging/base.sh +# One per line, # for comments, blank lines ignored + +# === System === +base +base-devel +linux +linux-firmware +linux-headers +amd-ucode +btrfs-progs +dkms +efibootmgr +efitools +less +man-db +nano +sbctl +sbsigntools +smartmontools +unzip +zip +7zip + +# === Networking === +bind +iwd +netctl +net-tools +networkmanager +network-manager-applet +openvpn +sshfs +systemd-resolvconf +tailscale +traceroute +wget +wireguard-tools +wireless_tools + +# === GPU (NVIDIA) === +nvidia-open-dkms +lib32-nvidia-utils +libva-nvidia-driver +mesa-utils +clinfo + +# === Hyprland & Desktop === +hyprland +hypridle +hyprlock +hyprpicker +hyprpolkitagent +hyprsunset +hyprshot-git +hyprmon-bin +hyprwhspr +swaybg +waybar +dunst +wofi +wofi-calc +xdg-desktop-portal-gtk +xdg-desktop-portal-hyprland +xdg-desktop-portal-kde +xdg-utils +xorg-server +xorg-xhost +xorg-xinit +xwaylandvideobridge +sddm + +# === Terminal & Shell === +kitty +tmux +zsh +zoxide +fzf +starship +btop +htop +fastfetch +direnv +yad + +# === Development === +git +git-delta +github-cli +docker +docker-compose +mise +bun +uv +postgresql + +# === File Management === +dolphin +yazi +fd +gdu +ncdu +tree + +# === Media & Graphics === +pipewire +pipewire-alsa +pipewire-jack +pipewire-pulse +gst-plugin-pipewire +libpulse +wireplumber +pavucontrol +imagemagick +graphicsmagick +grim +slurp +wl-clipboard +ffmpegthumbs +chafa +yt-dlp + +# === Fonts === +otf-geist-mono-nerd +ttf-firacode-nerd +ttf-nerd-fonts-symbols +noto-fonts-cjk +noto-color-emoji-fontconfig +woff2-font-awesome +apple-fonts +font-manager + +# === Qt/GTK Theming === +qt5ct +qt6ct +qt5-wayland +qt6-wayland +qt5-quickcontrols2 +kvantum-qt5 +kvantum-git +adwaita-qt5-git +adwaita-qt6-git +nwg-look +breeze +sassc + +# === Firewall === +ufw + +# === AUR Helper === +yay-bin + +# === Misc Tools === +expac +flatpak +gum +jq +hyperfine-git +tesseract-data-eng +hunspell-en_us +bc +lshw +v4l2loopback-dkms +speedtest-cli + +# === Virtualization === +qemu-full +libvirt +virt-manager +virt-install +virt-viewer +libosinfo +guestfs-tools +swtpm +dnsmasq + +# === Document & Image Viewing === +zathura +zathura-pdf-mupdf +mupdf-git +qview +ocrmypdf diff --git a/install/kojarchy-cargo.packages b/install/kojarchy-cargo.packages new file mode 100644 index 00000000..6fd1f587 --- /dev/null +++ b/install/kojarchy-cargo.packages @@ -0,0 +1,8 @@ +# Kojarchy cargo packages (format: crate=binary) +# If binary name matches crate name, just use the crate name +# Installed via install/config/cargo.sh + +bob-nvim=bob +tmux-sessionizer=tms +tree-sitter-cli=tree-sitter +cargo-update=cargo-install-update diff --git a/install/kojarchy-optional.packages b/install/kojarchy-optional.packages new file mode 100644 index 00000000..4320a7e5 --- /dev/null +++ b/install/kojarchy-optional.packages @@ -0,0 +1,61 @@ +# Kojarchy optional packages - prompted during install (gum confirm) +# One per line, # for comments, blank lines ignored + +# === Gaming === +steam +prismlauncher +protonup-qt +protontricks +goverlay +tetrio-desktop + +# === Communication === +discord +vesktop +legcord +slack-desktop +telegram-desktop-bin + +# === Productivity === +notion-calendar-electron +obs-studio +obs-backgroundremoval +audacity +blender-bin + +# === Video Calling === +zoom +uxplay + +# === Browsers === +chromium +helium-browser-bin + +# === Remote === +rustdesk-bin +localsend-bin +ngrok +rcon-cli + +# === Torrents === +qbittorrent +qbittorrent-nox + +# === Music === +spotify + +# === RGB & Hardware === +openrgb + +# === Other === +kdeconnect +video-trimmer +spacedrive-bin +cmatrix +pipes.sh +qalculate-qt +ollama +cuda +cudnn +onnxruntime-cuda +nvidia-container-toolkit diff --git a/install/packaging/all.sh b/install/packaging/all.sh new file mode 100644 index 00000000..35ec2d99 --- /dev/null +++ b/install/packaging/all.sh @@ -0,0 +1,4 @@ +run_logged $KOJARCHY_INSTALL/packaging/aur-helper.sh +run_logged $KOJARCHY_INSTALL/packaging/base.sh +run_logged $KOJARCHY_INSTALL/packaging/optional.sh +run_logged $KOJARCHY_INSTALL/packaging/fonts.sh diff --git a/install/packaging/aur-helper.sh b/install/packaging/aur-helper.sh new file mode 100644 index 00000000..dcad2132 --- /dev/null +++ b/install/packaging/aur-helper.sh @@ -0,0 +1,13 @@ +# Install yay if not present +if ! command -v yay &>/dev/null; then + echo "Installing yay AUR helper..." + sudo pacman -S --needed --noconfirm git base-devel + tmpdir=$(mktemp -d) + git clone https://aur.archlinux.org/yay-bin.git "$tmpdir/yay-bin" + cd "$tmpdir/yay-bin" + makepkg -si --noconfirm + cd - + rm -rf "$tmpdir" +fi + +echo "yay: OK" diff --git a/install/packaging/base.sh b/install/packaging/base.sh new file mode 100644 index 00000000..d19eee97 --- /dev/null +++ b/install/packaging/base.sh @@ -0,0 +1,3 @@ +# Install all base packages (pacman + AUR via yay) +mapfile -t packages < <(grep -v '^#' "$KOJARCHY_INSTALL/kojarchy-base.packages" | grep -v '^$') +yay -S --noconfirm --needed "${packages[@]}" diff --git a/install/packaging/fonts.sh b/install/packaging/fonts.sh new file mode 100644 index 00000000..df872dc5 --- /dev/null +++ b/install/packaging/fonts.sh @@ -0,0 +1,2 @@ +# Rebuild font cache after package installation +fc-cache -fv diff --git a/install/packaging/optional.sh b/install/packaging/optional.sh new file mode 100644 index 00000000..307a6108 --- /dev/null +++ b/install/packaging/optional.sh @@ -0,0 +1,5 @@ +# Prompt user for optional packages +if gum confirm "Install optional packages? (gaming, comms, productivity, etc.)" /dev/null; then + abort "Internet connection" +fi + +echo "Guards: OK" diff --git a/install/services/all.sh b/install/services/all.sh new file mode 100644 index 00000000..9f27962a --- /dev/null +++ b/install/services/all.sh @@ -0,0 +1,3 @@ +run_logged $KOJARCHY_INSTALL/services/systemd.sh +run_logged $KOJARCHY_INSTALL/services/sddm.sh +run_logged $KOJARCHY_INSTALL/services/udev.sh diff --git a/install/services/sddm.sh b/install/services/sddm.sh new file mode 100644 index 00000000..be08eb91 --- /dev/null +++ b/install/services/sddm.sh @@ -0,0 +1,21 @@ +# Install SDDM with custom macOS theme + autologin + +# Copy macOS theme to SDDM themes directory +sudo mkdir -p /usr/share/sddm/themes/macos +sudo cp -R "$KOJARCHY_DIR/sddm/macos/"* /usr/share/sddm/themes/macos/ + +# Configure SDDM: macOS theme + autologin +sudo mkdir -p /etc/sddm.conf.d +sudo tee /etc/sddm.conf.d/kojarchy.conf >/dev/null </dev/null || true + sudo udevadm control --reload-rules + sudo udevadm trigger +fi + +echo "Udev: OK" diff --git a/lib/errors.sh b/lib/errors.sh new file mode 100644 index 00000000..4cc52c2d --- /dev/null +++ b/lib/errors.sh @@ -0,0 +1,111 @@ +#!/bin/bash + +# Kojarchy error handling - traps, recovery menu + +# Track if we're already handling an error to prevent double-trapping +ERROR_HANDLING=false + +show_cursor() { + printf "\033[?25h" +} + +show_log_tail() { + if [[ -f $KOJARCHY_LOG ]]; then + local log_lines=$(($TERM_HEIGHT - $LOGO_HEIGHT - 20)) + local max_line_width=$((LOGO_WIDTH - 4)) + + tail -n $log_lines "$KOJARCHY_LOG" | while IFS= read -r line; do + if ((${#line} > max_line_width)); then + local truncated_line="${line:0:$max_line_width}..." + else + local truncated_line="$line" + fi + gum style "$truncated_line" + done + echo + fi +} + +show_failed_script_or_command() { + if [[ -n ${CURRENT_SCRIPT:-} ]]; then + gum style "Failed script: $CURRENT_SCRIPT" + else + local cmd="$BASH_COMMAND" + local max_cmd_width=$((LOGO_WIDTH - 4)) + if ((${#cmd} > max_cmd_width)); then + cmd="${cmd:0:$max_cmd_width}..." + fi + gum style "$cmd" + fi +} + +# Save original stdout and stderr for trap to use +save_original_outputs() { + exec 3>&1 4>&2 +} + +restore_outputs() { + if [ -e /proc/self/fd/3 ] && [ -e /proc/self/fd/4 ]; then + exec 1>&3 2>&4 + fi +} + +catch_errors() { + if [[ $ERROR_HANDLING == true ]]; then + return + else + ERROR_HANDLING=true + fi + + local exit_code=$? + + stop_log_output + restore_outputs + + clear_logo + show_cursor + + gum style --foreground 1 --padding "1 0 1 $PADDING_LEFT" "Kojarchy installation stopped!" + show_log_tail + + gum style "This command halted with exit code $exit_code:" + show_failed_script_or_command + + while true; do + options=("Retry installation" "View full log" "Exit") + + choice=$(gum choose "${options[@]}" --header "What would you like to do?" --height 5 --padding "1 $PADDING_LEFT") + + case "$choice" in + "Retry installation") + bash "$KOJARCHY_DIR/install.sh" + break + ;; + "View full log") + if command -v less &>/dev/null; then + less "$KOJARCHY_LOG" + else + tail "$KOJARCHY_LOG" + fi + ;; + "Exit" | "") + exit 1 + ;; + esac + done +} + +exit_handler() { + local exit_code=$? + if [[ $exit_code -ne 0 && $ERROR_HANDLING != true ]]; then + catch_errors + else + stop_log_output + show_cursor + fi +} + +trap catch_errors ERR INT TERM +trap exit_handler EXIT + +save_original_outputs diff --git a/lib/helpers.sh b/lib/helpers.sh new file mode 100644 index 00000000..4f7d6783 --- /dev/null +++ b/lib/helpers.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# Kojarchy install helpers - sourced by install.sh + +source "$KOJARCHY_DIR/lib/presentation.sh" +source "$KOJARCHY_DIR/lib/errors.sh" +source "$KOJARCHY_DIR/lib/logging.sh" +source "$KOJARCHY_DIR/lib/packages.sh" diff --git a/lib/logging.sh b/lib/logging.sh new file mode 100644 index 00000000..58dc031d --- /dev/null +++ b/lib/logging.sh @@ -0,0 +1,103 @@ +#!/bin/bash + +# Kojarchy logging - install log, live tail display + +start_log_output() { + local ANSI_SAVE_CURSOR="\033[s" + local ANSI_RESTORE_CURSOR="\033[u" + local ANSI_CLEAR_LINE="\033[2K" + local ANSI_HIDE_CURSOR="\033[?25l" + local ANSI_RESET="\033[0m" + local ANSI_GRAY="\033[90m" + + printf $ANSI_SAVE_CURSOR + printf $ANSI_HIDE_CURSOR + + ( + local log_lines=20 + local max_line_width=$((LOGO_WIDTH - 4)) + + while true; do + mapfile -t current_lines < <(tail -n $log_lines "$KOJARCHY_LOG" 2>/dev/null) + + output="" + for ((i = 0; i < log_lines; i++)); do + line="${current_lines[i]:-}" + if [ ${#line} -gt $max_line_width ]; then + line="${line:0:$max_line_width}..." + fi + if [ -n "$line" ]; then + output+="${ANSI_CLEAR_LINE}${ANSI_GRAY}${PADDING_LEFT_SPACES} → ${line}${ANSI_RESET}\n" + else + output+="${ANSI_CLEAR_LINE}${PADDING_LEFT_SPACES}\n" + fi + done + + printf "${ANSI_RESTORE_CURSOR}%b" "$output" + sleep 0.1 + done + ) & + monitor_pid=$! +} + +stop_log_output() { + if [ -n "${monitor_pid:-}" ]; then + kill $monitor_pid 2>/dev/null || true + wait $monitor_pid 2>/dev/null || true + unset monitor_pid + fi +} + +start_install_log() { + sudo touch "$KOJARCHY_LOG" + sudo chmod 666 "$KOJARCHY_LOG" + + export KOJARCHY_START_TIME=$(date '+%Y-%m-%d %H:%M:%S') + echo "=== Kojarchy Installation Started: $KOJARCHY_START_TIME ===" >>"$KOJARCHY_LOG" + start_log_output +} + +stop_install_log() { + stop_log_output + show_cursor + + if [[ -n ${KOJARCHY_LOG:-} ]]; then + KOJARCHY_END_TIME=$(date '+%Y-%m-%d %H:%M:%S') + echo "=== Kojarchy Installation Completed: $KOJARCHY_END_TIME ===" >>"$KOJARCHY_LOG" + echo "" >>"$KOJARCHY_LOG" + + echo "=== Installation Time Summary ===" >>"$KOJARCHY_LOG" + + if [ -n "$KOJARCHY_START_TIME" ]; then + KOJARCHY_START_EPOCH=$(date -d "$KOJARCHY_START_TIME" +%s) + KOJARCHY_END_EPOCH=$(date -d "$KOJARCHY_END_TIME" +%s) + KOJARCHY_DURATION=$((KOJARCHY_END_EPOCH - KOJARCHY_START_EPOCH)) + + KOJARCHY_MINS=$((KOJARCHY_DURATION / 60)) + KOJARCHY_SECS=$((KOJARCHY_DURATION % 60)) + + echo "Kojarchy: ${KOJARCHY_MINS}m ${KOJARCHY_SECS}s" >>"$KOJARCHY_LOG" + fi + echo "=================================" >>"$KOJARCHY_LOG" + fi +} + +run_logged() { + local script="$1" + export CURRENT_SCRIPT="$script" + + echo "[$(date '+%Y-%m-%d %H:%M:%S')] Starting: $script" >>"$KOJARCHY_LOG" + + bash -c "source '$KOJARCHY_DIR/lib/helpers.sh'; source '$script'" >"$KOJARCHY_LOG" 2>&1 + + local exit_code=$? + + if [ $exit_code -eq 0 ]; then + echo "[$(date '+%Y-%m-%d %H:%M:%S')] Completed: $script" >>"$KOJARCHY_LOG" + unset CURRENT_SCRIPT + else + echo "[$(date '+%Y-%m-%d %H:%M:%S')] Failed: $script (exit code: $exit_code)" >>"$KOJARCHY_LOG" + fi + + return $exit_code +} diff --git a/lib/packages.sh b/lib/packages.sh new file mode 100644 index 00000000..54b0b101 --- /dev/null +++ b/lib/packages.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +# Kojarchy package install helpers + +install_packages() { + local packages_file="$1" + mapfile -t packages < <(grep -v '^#' "$packages_file" | grep -v '^$') + if [ ${#packages[@]} -gt 0 ]; then + sudo pacman -S --noconfirm --needed "${packages[@]}" + fi +} + +install_aur_packages() { + local packages_file="$1" + mapfile -t packages < <(grep -v '^#' "$packages_file" | grep -v '^$') + if [ ${#packages[@]} -gt 0 ]; then + yay -S --noconfirm --needed "${packages[@]}" + fi +} + +install_cargo_packages() { + local packages_file="$1" + + while IFS= read -r line; do + [[ -z "$line" || "$line" =~ ^# ]] && continue + + local crate="${line%%=*}" + local binary="${line##*=}" + + if ! command -v "$binary" &>/dev/null; then + cargo install "$crate" + fi + done <"$packages_file" +} diff --git a/lib/presentation.sh b/lib/presentation.sh new file mode 100644 index 00000000..fe832592 --- /dev/null +++ b/lib/presentation.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +# Kojarchy presentation helpers - gum TUI, logo display + +# Ensure we have gum available +if ! command -v gum &>/dev/null; then + sudo pacman -S --needed --noconfirm gum +fi + +# Get terminal size from /dev/tty (works in all scenarios: direct, sourced, or piped) +if [ -e /dev/tty ]; then + TERM_SIZE=$(stty size 2>/dev/null max) max = length } END { print max+0 }' "$LOGO_PATH" 2>/dev/null || echo 0) +export LOGO_HEIGHT=$(wc -l <"$LOGO_PATH" 2>/dev/null || echo 0) + +export PADDING_LEFT=$((($TERM_WIDTH - $LOGO_WIDTH) / 2)) +export PADDING_LEFT_SPACES=$(printf "%*s" $PADDING_LEFT "") + +# Gum style padding +export PADDING="0 0 0 $PADDING_LEFT" +export GUM_CONFIRM_PROMPT_FOREGROUND="6" +export GUM_CONFIRM_SELECTED_FOREGROUND="0" +export GUM_CONFIRM_SELECTED_BACKGROUND="2" +export GUM_CONFIRM_UNSELECTED_FOREGROUND="7" +export GUM_CONFIRM_UNSELECTED_BACKGROUND="0" +export GUM_CHOOSE_PADDING="$PADDING" +export GUM_FILTER_PADDING="$PADDING" +export GUM_INPUT_PADDING="$PADDING" +export GUM_SPIN_PADDING="$PADDING" +export GUM_TABLE_PADDING="$PADDING" +export GUM_CONFIRM_PADDING="$PADDING" + +clear_logo() { + printf "\033[H\033[2J" + gum style --foreground 2 --padding "1 0 0 $PADDING_LEFT" "$(<"$LOGO_PATH")" +} diff --git a/logo.txt b/logo.txt new file mode 100644 index 00000000..defeba99 --- /dev/null +++ b/logo.txt @@ -0,0 +1,9 @@ + + ▄█ ▄█▀ ▄██████▄ ▄█ ▄█████▄ ▄███████ ▄███████ ▄█ █▄ ▄█ █▄ + ██ ▄█▀ ███ ███ ██ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ + ███▀ ███ ███ ██ ███ ███ ███ ███ ███ █▀ ███ ███ ███ ███ + ██▀ ███ ███ ██ ▄███▄▄▄███ ▄███▄▄▄██▀ ███ ▄███▄▄▄███▄ ███▄▄▄███ + ██▄ ███ ███ ██ ▀███▀▀▀███ ▀███▀▀▀▀ ███ ▀▀███▀▀▀███ ▀▀▀▀▀▀███ + ██ ▀█▄ ███ █████ ██ ███ ███ ██████████ ███ █▄ ███ ███ ▄██ ███ + ██ ▀█▄ ███ ███ ██ ██ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ + ██ ▀█ ▀██████▀ ████ ███ █▀ ███ ███ ███████▀ ███ █▀ ▀█████▀ diff --git a/sddm/etc/sddm.conf b/sddm/etc/sddm.conf deleted file mode 100644 index 3686c096..00000000 --- a/sddm/etc/sddm.conf +++ /dev/null @@ -1,2 +0,0 @@ -[Theme] -Current=macos diff --git a/sddm/install-dependencies.sh b/sddm/install-dependencies.sh deleted file mode 100755 index 54542a98..00000000 --- a/sddm/install-dependencies.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -sudo pacman -Syu qt6-svg qt6-declarative qt5-quickcontrols2 diff --git a/sddm/link.sh b/sddm/link.sh deleted file mode 100755 index f7013765..00000000 --- a/sddm/link.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -sudo mkdir -p /usr/share/sddm/themes/macos -sudo cp -r sddm/macos/* /usr/share/sddm/themes/macos -sudo cp sddm/etc/sddm.conf /etc/sddm.conf diff --git a/shell/.gitconfig b/shell/.gitconfig deleted file mode 100644 index 567a7b38..00000000 --- a/shell/.gitconfig +++ /dev/null @@ -1,64 +0,0 @@ -[credential] - helper = store -[alias] - co = "!f() { git branch -a | awk '{gsub(\"remotes/origin/\", \"\", $1); print $1}' | sort -u | fzf-tmux -p --reverse | xargs git checkout; }; f" - col = "!f() { git branch | awk '{gsub(\"remotes/origin/\", \"\", $1); print $1}' | sort -u | fzf-tmux -p --reverse | xargs git checkout; }; f" - squash = "!f(){ git reset --soft HEAD~${1} && git commit --edit -m\"$(git log --format=%B --reverse HEAD..HEAD@{1})\"; }; f" - gone = "!f() { git fetch --all --prune; git branch -vv | awk '/: gone]/{print $1}' | xargs git branch -D; }; f" - ll = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(auto)%d%C(reset)' - root = rev-parse --show-toplevel -[core] - pager = delta -[interactive] - diffFilter = delta --color-only -[add.interactive] - useBuiltin = false -[delta] - navigate = true - light = false - side-by-side = false - - blame-palette = "#1e1e2e #181825 #11111b #313244 #45475a" - commit-decoration-style = "#6c7086" bold box ul - dark = true - file-decoration-style = "#6c7086" - file-style = "#cdd6f4" - hunk-header-decoration-style = "#6c7086" box ul - hunk-header-file-style = bold - hunk-header-line-number-style = bold "#a6adc8" - hunk-header-style = file line-number syntax - line-numbers-left-style = "#6c7086" - line-numbers-minus-style = bold "#f38ba8" - line-numbers-plus-style = bold "#a6e3a1" - line-numbers-right-style = "#6c7086" - line-numbers-zero-style = "#6c7086" - minus-emph-style = bold syntax "#53394c" - minus-style = syntax "#34293a" - plus-emph-style = bold syntax "#404f4a" - plus-style = syntax "#2c3239" - map-styles = \ - bold purple => syntax "#494060", \ - bold blue => syntax "#384361", \ - bold cyan => syntax "#384d5d", \ - bold yellow => syntax "#544f4e" -[merge] - conflictstyle = diff3 -[diff] - colorMoved = default -[init] - defaultBranch = main -[push] - autoSetupRemote = true -[rerere] - enabled = true -[credential "https://github.com"] - helper = - helper = !/opt/homebrew/bin/gh auth git-credential -[credential "https://gist.github.com"] - helper = - helper = !/opt/homebrew/bin/gh auth git-credential -[user] - name = princejoogie - email = princejoogie@gmail.com -[pull] - rebase = true diff --git a/shell/.zshrc b/shell/.zshrc deleted file mode 100644 index a4ea8ce8..00000000 --- a/shell/.zshrc +++ /dev/null @@ -1,108 +0,0 @@ -# oh-my-zsh -autoload -U compinit -compinit - -export DISABLE_AUTO_UPDATE="true" - -export ZSH="$HOME/.oh-my-zsh" - -plugins=( - z - gh - aws - fnm - git - tmux - docker - vi-mode - zsh-autosuggestions - zsh-syntax-highlighting - fast-syntax-highlighting -) - -bindkey -M viins jj vi-cmd-mode -export VI_MODE_SET_CURSOR=true -# oh-my-zsh end - -# options -setopt HIST_IGNORE_ALL_DUPS -setopt HIST_FIND_NO_DUPS -setopt HIST_SAVE_NO_DUPS -setopt SHARE_HISTORY -setopt INC_APPEND_HISTORY -# options end - -# aliases -alias cls=clear -alias sl="exa --group-directories-first --icons --time-style=long-iso -la" -alias so=source -alias x=exit -alias G=git -alias t=tmux -alias lta="ls -ltar --human-readable | grep -vE '^\.| \.$| \.\.$'" -alias pip=pip3 -alias wt=". _wt" -alias ai="noglob opencode run --model \"opencode/gemini-3-flash\"" -alias open=xdg-open -alias claude="claude --dangerously-skip-permissions" -# alises end - -# variables -export EDITOR=nvim -export MANPAGER='nvim +Man!' -export PATH=$PATH:/opt/homebrew/bin -export PATH=$PATH:$HOME/.cargo/bin -export PATH=$PATH:$HOME/.local/bin -export PATH=$PATH:$HOME/.local/share/fnm -export PATH=$PATH:$HOME/.local/custom/bin -export PATH=$PATH:$HOME/.local/share/bob/nvim-bin -export PATH=$PATH:$HOME/.duckdb/cli/latest -export PATH=$PATH:$HOME/.opencode/bin -export PATH=$PATH:$HOME/.lmstudio/bin -export PATH=$PATH:$HOME/go/bin - -if [[ -f "$HOME/.private.sh" ]]; then - source "$HOME/.private.sh" -fi -# variables end - -# starship -if [[ -x "$(command -v starship)" ]]; then - eval "$(starship init zsh)" -fi -# starship end - -# fnm -if [[ -x "$(command -v fnm)" ]]; then - eval "$(fnm env --use-on-cd --shell zsh)" -fi -# fnm end - -# uv -if [[ -x "$(command -v uv)" ]]; then - eval "$(uv generate-shell-completion zsh)" -fi - -if [[ -x "$(command -v uvx)" ]]; then - eval "$(uvx --generate-shell-completion zsh)" -fi -# uv end - -# direnv -if [[ -x "$(command -v direnv)" ]]; then - eval "$(direnv hook zsh)" -fi -# direnv end - -# bun -[ -s "$HOME/.bun/_bun" ] && source "$HOME/.bun/_bun" -export BUN_INSTALL="$HOME/.bun" -export PATH="$BUN_INSTALL/bin:$PATH" -# bun end - -source $ZSH/oh-my-zsh.sh -# The following lines have been added by Docker Desktop to enable Docker CLI completions. -fpath=(/Users/pjuguilon/.docker/completions $fpath) -autoload -Uz compinit -compinit -# End of Docker CLI completions From 29f31b544102f1d4d8cfd2a44f09b934efe50f8d Mon Sep 17 00:00:00 2001 From: princejoogie Date: Tue, 10 Feb 2026 14:16:47 +0800 Subject: [PATCH 02/44] docs: rewrite README for kojarchy installer, fix yazi hyprpaper reference --- README.md | 182 ++++++++++++++++++++++++++--------------- config/yazi/theme.toml | 2 +- 2 files changed, 115 insertions(+), 69 deletions(-) diff --git a/README.md b/README.md index 69e5c2ab..b36e5c23 100644 --- a/README.md +++ b/README.md @@ -1,103 +1,149 @@ -# dotfiles +# Kojarchy -Personal configuration for a productive and aesthetic development environment, focused on Linux (Hyprland) and macOS. +Personal Hyprland desktop environment for Arch Linux, automated from a fresh `archinstall` to a fully configured system in one command. ![demo_1](.github/assets/demo_1.png) ![demo_2](.github/assets/demo_2.png) ![demo_3](.github/assets/demo_3.png) -## ✨ Highlights +## Install -### 🖥️ Desktop (Linux) +After a fresh Arch Linux install via `archinstall`, reboot and run: -- **Window Manager**: [Hyprland](https://hyprland.org/) - A dynamic tiling Wayland compositor. -- **Status Bar**: [Waybar](https://github.com/Alexays/Waybar) with custom modules for Spotify, Tailscale, and Tunnelbear. -- **Widgets**: [Eww](https://github.com/elkowar/eww) for interactive desktop elements like calendars. -- **Launcher**: [Wofi](https://hg.sr.ht/~scoopta/wofi) with a collection of custom utility scripts. -- **Notifications**: [Dunst](https://dunst-project.org/) for lightweight system alerts. +```bash +curl -fsSL https://raw.githubusercontent.com/princejoogie/dotfiles/refs/heads/main/boot.sh | bash +``` -### ⌨️ Editor +The installer handles everything: packages, configs, services, shell setup, and post-install. -- **Neovim**: A modern Lua-based configuration using [lazy.nvim](https://github.com/folke/lazy.nvim). - - Built-in LSP, Treesitter, and snacks.nvim integration. - - Optimized for performance and a seamless coding experience. - - Custom UI components and statuslines. +## What's Included -### 🛠️ Shell & Tools +| Component | Tool | +|:----------|:-----| +| Window Manager | [Hyprland](https://hyprland.org/) | +| Status Bar | [Waybar](https://github.com/Alexays/Waybar) with Spotify, Tailscale, Tunnelbear modules | +| Launcher | [Wofi](https://hg.sr.ht/~scoopta/wofi) with custom utility scripts | +| Notifications | [Dunst](https://dunst-project.org/) | +| Wallpaper | [swaybg](https://github.com/swaywm/swaybg) | +| Terminal | [Kitty](https://sw.kovidgoyal.net/kitty/) | +| Shell | Zsh + [oh-my-zsh](https://ohmyz.sh/) + [Starship](https://starship.rs/) | +| Editor | [Neovim](https://neovim.io/) (Lua config, lazy.nvim) | +| File Manager | [yazi](https://github.com/sxyazi/yazi) | +| Multiplexer | [Tmux](https://github.com/tmux/tmux) | +| Version Manager | [mise](https://mise.jdx.dev/) (node, go, python) | +| Display Manager | [SDDM](https://github.com/sddm/sddm) with macOS theme + autologin | +| Theme | Adwaita-dark via gsettings, Catppuccin Mocha accents | -- **Terminal**: [Kitty](https://sw.kovidgoyal.net/kitty/) and [Alacritty](https://alacritty.org/) support. -- **Shell**: Zsh with [Starship](https://starship.rs/) prompt. -- **File Manager**: [yazi](https://github.com/sxyazi/yazi) - Blazing fast terminal file manager. -- **Multiplexer**: [Tmux](https://github.com/tmux/tmux) for robust session management. -- **Productivity**: Raycast scripts for macOS automation. +## Project Structure -## 📂 Structure +``` +~/dotfiles/ +├── boot.sh # Bootstrap (curl-pipe-bash entry point) +├── install.sh # Main orchestrator +├── lib/ # Helpers (presentation, logging, errors, packages) +├── install/ +│ ├── preflight/ # Guard checks, install log setup +│ ├── packaging/ # AUR helper, base/optional packages, fonts +│ ├── config/ # Config deploy, shell, tmux, cargo, neovim, mise, git, docker, gtk +│ ├── services/ # systemd, SDDM, udev +│ ├── post-install/ # Summary, reboot prompt +│ ├── kojarchy-base.packages +│ ├── kojarchy-optional.packages +│ └── kojarchy-cargo.packages +├── config/ # Copied to ~/.config/ on install (user-editable) +│ ├── hypr/ # Hyprland (sources defaults, user overrides) +│ ├── waybar/ # Waybar + custom modules +│ ├── wofi/ # Wofi + dmenu scripts +│ ├── dunst/ # Notification config +│ ├── kitty/ # Terminal config +│ ├── nvim/ # Neovim (lazy.nvim, LSP, treesitter) +│ ├── tmux/ # Tmux config +│ ├── yazi/ # File manager theme +│ ├── opencode/ # OpenCode AI config + skills +│ ├── btop/ # System monitor config +│ ├── starship.toml # Prompt config +│ └── xdg-desktop-portal/ # Portal configs +├── default/ # Stays in repo, sourced at runtime (updated via git pull) +│ ├── hypr/ # autostart, bindings, envs, looknfeel, input, windows +│ └── zsh/ # aliases, envs, init, functions, shell, rc +├── bin/ # CLI utilities -> ~/.local/custom/bin/ +├── sddm/macos/ # SDDM macOS theme +├── wallpapers/ # Wallpaper collection +├── system/udev/ # udev rules +└── logo.txt # ASCII art for installer TUI +``` -| Folder | Description | -| :------------ | :-------------------------------------------------- | -| `hyprland/` | Hyprland, Waybar, Wofi, and Eww configurations | -| `nvim/` | Neovim configuration (Lua) | -| `shell/` | Shell environment (Zsh, Starship, Tmux, Git) | -| `sddm/` | macOS-inspired login theme | -| `wallpapers/` | A collection of curated high-resolution backgrounds | +## Two-Layer Config System -## 🚀 Setup +Configs are split into two layers: -### 1. Clone the repository +1. **`config/`** -- Copied to `~/.config/` on fresh install. These are your files to customize. They are never overwritten on updates. -```bash -git clone https://github.com/princejoogie/dotfiles.git ~/dotfiles -cd ~/dotfiles -``` - -### 2. Install GNU Stow +2. **`default/`** -- Stays in `~/dotfiles/default/` and is `source`d from the config files at runtime. Updated automatically when you `git pull`. -Ensure `stow` is installed on your system: +This means defaults can be improved upstream without overwriting your personal tweaks. -- **Arch Linux**: `sudo pacman -S stow` -- **macOS**: `brew install stow` +### Example: Hyprland -### 3. Symlink configurations +```conf +# ~/.config/hypr/hyprland.conf -Use `stow` to link the configurations to your home directory: +# Source defaults (updated via git pull) +source = ~/dotfiles/default/hypr/autostart.conf +source = ~/dotfiles/default/hypr/bindings.conf +source = ~/dotfiles/default/hypr/envs.conf -```bash -# Link core configurations -stow hyprland -stow nvim -stow shell +# Your overrides below: +monitor=,2560x1440@240,auto,1 ``` -> [!NOTE] -> For SDDM theme installation, refer to the scripts within the `sddm/` directory. +### Example: Zsh -## 🖱️ Scyrox Mouse Battery (Waybar) +```bash +# ~/.zshrc sources ~/dotfiles/default/zsh/rc +# which loads: aliases, envs, init, functions, shell -This Waybar module reads the Scyrox mouse battery via HID and displays it with a custom icon. +# Add your own customizations at the bottom of ~/.zshrc +``` -### 1. Install dependencies +## Customization -- `bun` (runtime for the script) -- `node-hid` (HID access) +1. **Edit configs**: Modify files in `~/.config/` directly. They're yours. +2. **Update defaults**: `cd ~/dotfiles && git pull` -- changes propagate automatically since configs source the defaults. +3. **Add overrides**: Uncomment or create override files referenced in the configs (e.g., `~/.config/hypr/overrides.conf`). +4. **Private config**: Add secrets/tokens to `~/.private.sh` (sourced by `~/.zshrc`, gitignored). -```bash -bun add -g node-hid -``` +## Key Bindings -### 2. Allow user access to the HID device +All bindings use `ALT` as the main modifier. -```bash -sudo cp ~/dotfiles/system/udev/99-scyrox-hidraw.rules /etc/udev/rules.d/ -sudo udevadm control --reload-rules && sudo udevadm trigger -sudo usermod -aG input $USER -``` +| Binding | Action | +|:--------|:-------| +| `ALT + Return` | Open terminal | +| `ALT + Space` | App launcher (wofi drun) | +| `ALT + CTRL + Space` | Dmenu scripts launcher | +| `ALT + Q` | Kill active window | +| `ALT + F` | Fullscreen | +| `ALT + V` | Toggle floating | +| `ALT + H/J/K/L` | Focus left/down/up/right | +| `ALT + CTRL + H/J/K/L` | Move window | +| `ALT + CTRL + SHIFT + H/J/K/L` | Resize window | +| `ALT + 1-0` | Switch workspace | +| `ALT + SHIFT + 1-0` | Move to workspace | +| `ALT + W` | Toggle waybar | +| `ALT + SHIFT + C` | Color picker | +| `Print` | Screenshot region | +| `ALT + Print` | Screenshot window | -Log out and back in (or reboot) so the group change takes effect. +## Optional Packages -### 3. Verify +During install, you're prompted to install optional packages including: -```bash -scyrox-battery --device=scyrox --json --no-sudo -``` +- Gaming (Steam, Prismlauncher, Proton) +- Communication (Discord, Slack, Telegram) +- Productivity (OBS, Blender, Audacity) +- And more + +## Credits -If that returns JSON, restart Waybar and the module will appear between the mic input and Tailscale. +Installer architecture inspired by [omarchy](https://github.com/basecamp/omarchy). diff --git a/config/yazi/theme.toml b/config/yazi/theme.toml index 55622092..a3c5e594 100644 --- a/config/yazi/theme.toml +++ b/config/yazi/theme.toml @@ -137,7 +137,7 @@ files = [ { name = "dockerfile", text = "󰡨", fg = "#89b4fa" }, { name = ".git-blame-ignore-revs", text = "", fg = "#fab387" }, { name = ".nvmrc", text = "", fg = "#a6e3a1" }, - { name = "hyprpaper.conf", text = "", fg = "#74c7ec" }, + { name = "hyprland.conf", text = "", fg = "#74c7ec" }, { name = ".prettierignore", text = "", fg = "#89b4fa" }, { name = "rakefile", text = "", fg = "#313244" }, { name = "code_of_conduct", text = "", fg = "#f38ba8" }, From ac42b4f1ad2335802db2cfdfb40f909f647059a2 Mon Sep 17 00:00:00 2001 From: princejoogie Date: Tue, 10 Feb 2026 14:47:20 +0800 Subject: [PATCH 03/44] feat: add update.sh for reloading configs and document update workflow --- README.md | 28 +++++++++++++++++++ update.sh | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100755 update.sh diff --git a/README.md b/README.md index b36e5c23..9185678d 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ The installer handles everything: packages, configs, services, shell setup, and ~/dotfiles/ ├── boot.sh # Bootstrap (curl-pipe-bash entry point) ├── install.sh # Main orchestrator +├── update.sh # Interactive updater (re-deploy configs, packages, etc.) ├── lib/ # Helpers (presentation, logging, errors, packages) ├── install/ │ ├── preflight/ # Guard checks, install log setup @@ -106,6 +107,33 @@ monitor=,2560x1440@240,auto,1 # Add your own customizations at the bottom of ~/.zshrc ``` +## Updating + +After changing configs or pulling new updates from the repo: + +```bash +# Quick: defaults (hypr, zsh) update automatically — just git pull +cd ~/dotfiles && git pull + +# Interactive: choose what to re-deploy +~/dotfiles/update.sh +``` + +`update.sh` lets you pick what to reload: + +| Option | What it does | +|:-------|:-------------| +| Packages | Installs new/missing packages from package lists | +| Configs | Re-copies `config/` to `~/.config/` (overwrites local changes) | +| Bin scripts | Re-links `bin/` to `~/.local/custom/bin/` | +| Shell | Re-deploys `~/.zshrc` from `default/zshrc` | +| SDDM theme | Re-copies theme to `/usr/share/sddm/themes/macos/` | +| Cargo packages | Installs any missing cargo tools | +| Neovim plugins | Syncs lazy.nvim plugins | +| Everything | All of the above | + +> **Note**: For most day-to-day changes, `git pull` is enough. The two-layer system means `default/` changes (keybindings, autostart, shell aliases, etc.) take effect immediately since they're sourced at runtime. Only use `update.sh` when you need to re-deploy `config/` files or install new packages. + ## Customization 1. **Edit configs**: Modify files in `~/.config/` directly. They're yours. diff --git a/update.sh b/update.sh new file mode 100755 index 00000000..2c399320 --- /dev/null +++ b/update.sh @@ -0,0 +1,84 @@ +#!/bin/bash +set -euo pipefail + +KOJARCHY_DIR="$HOME/dotfiles" + +if [[ ! -d "$KOJARCHY_DIR/.git" ]]; then + echo "Error: $KOJARCHY_DIR is not a git repo. Run the installer first." + exit 1 +fi + +if ! command -v gum &>/dev/null; then + sudo pacman -S --needed --noconfirm gum +fi + +echo "Pulling latest changes..." +git -C "$KOJARCHY_DIR" pull + +ACTIONS=$(gum choose --no-limit --header "What do you want to update?" \ + "Packages (install new/missing packages from package lists)" \ + "Configs (re-deploy config/ to ~/.config/ — overwrites local changes)" \ + "Bin scripts (re-link bin/ to ~/.local/custom/bin/)" \ + "Shell (re-deploy ~/.zshrc from default/zshrc)" \ + "SDDM theme (re-copy sddm/macos/ to system theme dir)" \ + "Cargo packages (install missing cargo tools)" \ + "Neovim plugins (sync lazy.nvim)" \ + "Everything") + +if echo "$ACTIONS" | grep -q "Everything"; then + ACTIONS="Packages +Configs +Bin scripts +Shell +SDDM theme +Cargo packages +Neovim plugins" +fi + +while IFS= read -r action; do + case "$action" in + "Packages"*) + echo "Installing packages..." + mapfile -t packages < <(grep -v '^#' "$KOJARCHY_DIR/install/kojarchy-base.packages" | grep -v '^$') + yay -S --noconfirm --needed "${packages[@]}" + echo "Packages: OK" + ;; + "Configs"*) + echo "Deploying configs to ~/.config/..." + cp -R "$KOJARCHY_DIR/config/"* ~/.config/ + echo "Configs: OK" + ;; + "Bin scripts"*) + echo "Linking bin scripts..." + mkdir -p ~/.local/custom/bin + for script in "$KOJARCHY_DIR"/bin/*; do + ln -sf "$script" "$HOME/.local/custom/bin/$(basename "$script")" + done + echo "Bin scripts: OK" + ;; + "Shell"*) + echo "Deploying ~/.zshrc..." + cp "$KOJARCHY_DIR/default/zshrc" ~/.zshrc + echo "Shell: OK (restart your shell or run: source ~/.zshrc)" + ;; + "SDDM theme"*) + echo "Deploying SDDM theme..." + sudo cp -R "$KOJARCHY_DIR/sddm/macos/"* /usr/share/sddm/themes/macos/ + echo "SDDM: OK" + ;; + "Cargo packages"*) + echo "Installing cargo packages..." + source "$KOJARCHY_DIR/lib/packages.sh" + install_cargo_packages "$KOJARCHY_DIR/install/kojarchy-cargo.packages" + echo "Cargo: OK" + ;; + "Neovim plugins"*) + echo "Syncing neovim plugins..." + nvim --headless "+Lazy! sync" +qa 2>/dev/null || true + echo "Neovim: OK" + ;; + esac +done <<< "$ACTIONS" + +echo "" +echo "Update complete!" From 2858187f42e78cfa326c994ee33dc5dd59c4a1b3 Mon Sep 17 00:00:00 2001 From: princejoogie Date: Tue, 10 Feb 2026 14:48:53 +0800 Subject: [PATCH 04/44] chore: update base packages --- install/kojarchy-base.packages | 2 -- 1 file changed, 2 deletions(-) diff --git a/install/kojarchy-base.packages b/install/kojarchy-base.packages index e2b57730..a3828274 100644 --- a/install/kojarchy-base.packages +++ b/install/kojarchy-base.packages @@ -92,7 +92,6 @@ docker-compose mise bun uv -postgresql # === File Management === dolphin @@ -117,7 +116,6 @@ grim slurp wl-clipboard ffmpegthumbs -chafa yt-dlp # === Fonts === From cc66c3d0e81e7fa5335d95db8cd6cb21a2354961 Mon Sep 17 00:00:00 2001 From: princejoogie Date: Tue, 10 Feb 2026 14:57:54 +0800 Subject: [PATCH 05/44] feat: add check-upstream.sh to track omarchy changes via opencode Clones/updates omarchy, diffs against baseline commit ffafe172, and runs opencode to analyze what needs syncing to kojarchy. --- check-upstream.sh | 95 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100755 check-upstream.sh diff --git a/check-upstream.sh b/check-upstream.sh new file mode 100755 index 00000000..adb43333 --- /dev/null +++ b/check-upstream.sh @@ -0,0 +1,95 @@ +#!/bin/bash +set -euo pipefail + +# Kojarchy upstream sync checker +# Compares omarchy changes since our last-known commit and uses opencode +# to analyze what needs syncing to our repo. + +KOJARCHY_DIR="$(cd "$(dirname "$0")" && pwd)" +OMARCHY_REPO="https://github.com/basecamp/omarchy.git" +OMARCHY_LOCAL="/tmp/kojarchy-omarchy-upstream" + +# Last omarchy commit hash we synced against +OMARCHY_BASELINE="ffafe1727e32c38ba5a291bf3a12d5995a01fda0" + +echo "=== Kojarchy Upstream Sync Check ===" +echo "Baseline: $OMARCHY_BASELINE" +echo "" + +# Clone or update omarchy +if [[ -d "$OMARCHY_LOCAL/.git" ]]; then + echo "Updating omarchy clone..." + git -C "$OMARCHY_LOCAL" fetch origin main + git -C "$OMARCHY_LOCAL" reset --hard origin/main +else + echo "Cloning omarchy..." + git clone --single-branch --branch main "$OMARCHY_REPO" "$OMARCHY_LOCAL" +fi + +OMARCHY_LATEST=$(git -C "$OMARCHY_LOCAL" rev-parse HEAD) + +if [[ "$OMARCHY_BASELINE" == "$OMARCHY_LATEST" ]]; then + echo "" + echo "No new changes in omarchy since baseline." + echo "Baseline: $OMARCHY_BASELINE" + exit 0 +fi + +echo "" +echo "Latest: $OMARCHY_LATEST" +echo "" + +# Get the commit log +echo "=== New commits since baseline ===" +COMMIT_LOG=$(git -C "$OMARCHY_LOCAL" log --oneline "$OMARCHY_BASELINE..$OMARCHY_LATEST") +echo "$COMMIT_LOG" +echo "" + +# Get the diff (stat + full) +DIFF_STAT=$(git -C "$OMARCHY_LOCAL" diff --stat "$OMARCHY_BASELINE..$OMARCHY_LATEST") +DIFF_FULL=$(git -C "$OMARCHY_LOCAL" diff "$OMARCHY_BASELINE..$OMARCHY_LATEST") + +echo "=== Changed files ===" +echo "$DIFF_STAT" +echo "" + +# Write diff to a temp file for opencode to reference +DIFF_FILE="/tmp/kojarchy-omarchy-diff.patch" +echo "$DIFF_FULL" > "$DIFF_FILE" + +PROMPT="I need you to analyze upstream changes from omarchy (https://github.com/basecamp/omarchy) and determine what we should sync to our kojarchy dotfiles repo. + +## Context +- Our repo is at: $KOJARCHY_DIR +- We are based on omarchy's architecture (install scripts, two-layer config, lib helpers, etc.) +- Our last sync was at omarchy commit: $OMARCHY_BASELINE +- Omarchy is now at: $OMARCHY_LATEST + +## New omarchy commits since our baseline: +$COMMIT_LOG + +## Changed files summary: +$DIFF_STAT + +## Full diff is at: $DIFF_FILE + +## Instructions +1. Read the full diff at $DIFF_FILE +2. For each change, determine if it's relevant to our kojarchy setup +3. Categorize changes as: + - **SYNC**: We should port this change (explain what and why) + - **SKIP**: Not relevant to us (explain why — e.g., we don't use that tool, different approach) + - **REVIEW**: Needs manual review (explain the tradeoff) +4. For SYNC items, describe exactly what files in our repo need changing +5. Do NOT make any changes — this is analysis only + +Focus on: install scripts, lib helpers, boot.sh/install.sh patterns, config deployment logic, service setup, and any new best practices." + +echo "Running opencode analysis..." +echo "" + +opencode run "$PROMPT" + +# Remind to update baseline after syncing +echo "" +echo "=== After syncing, update OMARCHY_BASELINE in this script to: $OMARCHY_LATEST ===" From 2c5f204d770ac4fe2b727417b2ac993b44ada610 Mon Sep 17 00:00:00 2001 From: princejoogie Date: Tue, 10 Feb 2026 15:01:53 +0800 Subject: [PATCH 06/44] fix: error handling in run_logged, guard.sh, and optional packages - run_logged: only source packages.sh in subshell, not full helpers (avoids re-registering traps and breaking fd redirects) - guard.sh: use /dev/tty for gum confirm, add fallback ping to 8.8.8.8 - begin.sh: cache sudo before starting install log - optional.sh: split into prompt (main shell) + install (run_logged) so gum can access tty for user interaction --- install/packaging/all.sh | 5 ++++- install/packaging/optional-install.sh | 3 +++ install/packaging/optional.sh | 7 +++---- install/preflight/begin.sh | 4 ++++ install/preflight/guard.sh | 6 ++++-- lib/logging.sh | 10 +++++++++- 6 files changed, 27 insertions(+), 8 deletions(-) create mode 100644 install/packaging/optional-install.sh diff --git a/install/packaging/all.sh b/install/packaging/all.sh index 35ec2d99..235d30cf 100644 --- a/install/packaging/all.sh +++ b/install/packaging/all.sh @@ -1,4 +1,7 @@ run_logged $KOJARCHY_INSTALL/packaging/aur-helper.sh run_logged $KOJARCHY_INSTALL/packaging/base.sh -run_logged $KOJARCHY_INSTALL/packaging/optional.sh + +# Optional packages prompt must run in the main shell (needs tty for gum) +source $KOJARCHY_INSTALL/packaging/optional.sh + run_logged $KOJARCHY_INSTALL/packaging/fonts.sh diff --git a/install/packaging/optional-install.sh b/install/packaging/optional-install.sh new file mode 100644 index 00000000..ae57959b --- /dev/null +++ b/install/packaging/optional-install.sh @@ -0,0 +1,3 @@ +# Install optional packages (called from optional.sh after user confirms) +mapfile -t packages < <(grep -v '^#' "$KOJARCHY_INSTALL/kojarchy-optional.packages" | grep -v '^$') +yay -S --noconfirm --needed "${packages[@]}" diff --git a/install/packaging/optional.sh b/install/packaging/optional.sh index 307a6108..d33a4138 100644 --- a/install/packaging/optional.sh +++ b/install/packaging/optional.sh @@ -1,5 +1,4 @@ -# Prompt user for optional packages -if gum confirm "Install optional packages? (gaming, comms, productivity, etc.)" /dev/tty 2>/dev/tty; then + run_logged $KOJARCHY_INSTALL/packaging/optional-install.sh fi diff --git a/install/preflight/begin.sh b/install/preflight/begin.sh index f83a7c38..013a70be 100644 --- a/install/preflight/begin.sh +++ b/install/preflight/begin.sh @@ -1,4 +1,8 @@ clear_logo gum style --foreground 3 --padding "1 0 0 $PADDING_LEFT" "Installing..." echo + +# Ensure sudo is cached before starting the log (needs tty for password prompt) +sudo -v /dev/null; then +if ! ping -c 1 -W 3 1.1.1.1 &>/dev/null && ! ping -c 1 -W 3 8.8.8.8 &>/dev/null; then abort "Internet connection" fi diff --git a/lib/logging.sh b/lib/logging.sh index 58dc031d..d7c85209 100644 --- a/lib/logging.sh +++ b/lib/logging.sh @@ -88,7 +88,15 @@ run_logged() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] Starting: $script" >>"$KOJARCHY_LOG" - bash -c "source '$KOJARCHY_DIR/lib/helpers.sh'; source '$script'" >"$KOJARCHY_LOG" 2>&1 + # Only source packages.sh for install helpers — NOT errors.sh/presentation.sh + # which would re-register traps and break fd redirects inside the subshell + bash -c " + export KOJARCHY_DIR='$KOJARCHY_DIR' + export KOJARCHY_INSTALL='$KOJARCHY_INSTALL' + export KOJARCHY_LOG='$KOJARCHY_LOG' + source '$KOJARCHY_DIR/lib/packages.sh' + source '$script' + " >"$KOJARCHY_LOG" 2>&1 local exit_code=$? From 5faad413321d11d80a45488b359cc4bb0c60b330 Mon Sep 17 00:00:00 2001 From: princejoogie Date: Tue, 10 Feb 2026 15:04:44 +0800 Subject: [PATCH 07/44] fix: split NVIDIA/virtualization out of base packages, add GPU detection - Move NVIDIA packages to kojarchy-nvidia.packages (prompted via lspci detection) - Move virtualization packages to optional - Remove packages already provided by archinstall (base, linux, firmware, etc.) - Remove duplicate yay-bin from base (already installed by aur-helper.sh) - Add nvidia.sh prompt with lspci detection --- install/kojarchy-base.packages | 38 ++--------------------------- install/kojarchy-nvidia.packages | 6 +++++ install/kojarchy-optional.packages | 12 +++++++++ install/packaging/all.sh | 3 ++- install/packaging/nvidia-install.sh | 3 +++ install/packaging/nvidia.sh | 6 +++++ 6 files changed, 31 insertions(+), 37 deletions(-) create mode 100644 install/kojarchy-nvidia.packages create mode 100644 install/packaging/nvidia-install.sh create mode 100644 install/packaging/nvidia.sh diff --git a/install/kojarchy-base.packages b/install/kojarchy-base.packages index a3828274..bcff78d6 100644 --- a/install/kojarchy-base.packages +++ b/install/kojarchy-base.packages @@ -1,22 +1,11 @@ # Kojarchy core package list installed via install/packaging/base.sh # One per line, # for comments, blank lines ignored -# === System === -base +# === System (supplements archinstall base) === base-devel -linux -linux-firmware -linux-headers -amd-ucode -btrfs-progs dkms -efibootmgr -efitools less man-db -nano -sbctl -sbsigntools smartmontools unzip zip @@ -24,26 +13,18 @@ zip # === Networking === bind -iwd -netctl net-tools networkmanager network-manager-applet openvpn sshfs -systemd-resolvconf tailscale traceroute wget wireguard-tools -wireless_tools -# === GPU (NVIDIA) === -nvidia-open-dkms -lib32-nvidia-utils -libva-nvidia-driver +# === Graphics (generic) === mesa-utils -clinfo # === Hyprland & Desktop === hyprland @@ -145,9 +126,6 @@ sassc # === Firewall === ufw -# === AUR Helper === -yay-bin - # === Misc Tools === expac flatpak @@ -158,20 +136,8 @@ tesseract-data-eng hunspell-en_us bc lshw -v4l2loopback-dkms speedtest-cli -# === Virtualization === -qemu-full -libvirt -virt-manager -virt-install -virt-viewer -libosinfo -guestfs-tools -swtpm -dnsmasq - # === Document & Image Viewing === zathura zathura-pdf-mupdf diff --git a/install/kojarchy-nvidia.packages b/install/kojarchy-nvidia.packages new file mode 100644 index 00000000..f90f0438 --- /dev/null +++ b/install/kojarchy-nvidia.packages @@ -0,0 +1,6 @@ +# Kojarchy NVIDIA GPU packages - prompted during install +# Only install these on systems with NVIDIA GPUs + +nvidia-open-dkms +lib32-nvidia-utils +libva-nvidia-driver diff --git a/install/kojarchy-optional.packages b/install/kojarchy-optional.packages index 4320a7e5..e0ff87cf 100644 --- a/install/kojarchy-optional.packages +++ b/install/kojarchy-optional.packages @@ -47,6 +47,18 @@ spotify # === RGB & Hardware === openrgb +# === Virtualization === +qemu-full +libvirt +virt-manager +virt-install +virt-viewer +libosinfo +guestfs-tools +swtpm +dnsmasq +v4l2loopback-dkms + # === Other === kdeconnect video-trimmer diff --git a/install/packaging/all.sh b/install/packaging/all.sh index 235d30cf..51dba05e 100644 --- a/install/packaging/all.sh +++ b/install/packaging/all.sh @@ -1,7 +1,8 @@ run_logged $KOJARCHY_INSTALL/packaging/aur-helper.sh run_logged $KOJARCHY_INSTALL/packaging/base.sh -# Optional packages prompt must run in the main shell (needs tty for gum) +# Interactive prompts must run in the main shell (needs tty for gum) +source $KOJARCHY_INSTALL/packaging/nvidia.sh source $KOJARCHY_INSTALL/packaging/optional.sh run_logged $KOJARCHY_INSTALL/packaging/fonts.sh diff --git a/install/packaging/nvidia-install.sh b/install/packaging/nvidia-install.sh new file mode 100644 index 00000000..8aabc4fe --- /dev/null +++ b/install/packaging/nvidia-install.sh @@ -0,0 +1,3 @@ +# Install NVIDIA packages +mapfile -t packages < <(grep -v '^#' "$KOJARCHY_INSTALL/kojarchy-nvidia.packages" | grep -v '^$') +yay -S --noconfirm --needed "${packages[@]}" diff --git a/install/packaging/nvidia.sh b/install/packaging/nvidia.sh new file mode 100644 index 00000000..12d9dfc1 --- /dev/null +++ b/install/packaging/nvidia.sh @@ -0,0 +1,6 @@ +# Detect NVIDIA GPU and prompt for driver installation +if lspci | grep -qi nvidia; then + if gum confirm "NVIDIA GPU detected. Install NVIDIA drivers?" /dev/tty 2>/dev/tty; then + run_logged $KOJARCHY_INSTALL/packaging/nvidia-install.sh + fi +fi From b79ef79ac72fab8a37751ebb7adfdc90b780a9f8 Mon Sep 17 00:00:00 2001 From: princejoogie Date: Tue, 10 Feb 2026 15:05:20 +0800 Subject: [PATCH 08/44] fix: enable multilib repo before package install (needed for lib32-* deps) --- install/packaging/aur-helper.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/install/packaging/aur-helper.sh b/install/packaging/aur-helper.sh index dcad2132..6ce7f162 100644 --- a/install/packaging/aur-helper.sh +++ b/install/packaging/aur-helper.sh @@ -1,3 +1,14 @@ +# Enable multilib repo (needed for lib32-* packages like lib32-nvidia-utils) +if ! grep -q '^\[multilib\]' /etc/pacman.conf; then + echo "Enabling multilib repository..." + sudo tee -a /etc/pacman.conf >/dev/null <<'EOF' + +[multilib] +Include = /etc/pacman.d/mirrorlist +EOF + sudo pacman -Sy +fi + # Install yay if not present if ! command -v yay &>/dev/null; then echo "Installing yay AUR helper..." From 99807dcb06ba4a8450047aa7eff5e2e32531839e Mon Sep 17 00:00:00 2001 From: princejoogie Date: Tue, 10 Feb 2026 15:22:22 +0800 Subject: [PATCH 09/44] feat: add interactive 4-phase workflow to check-upstream.sh Phase 1: opencode analyzes diff and writes analysis to file Phase 2: user reviews analysis, can edit before proceeding Phase 3: opencode applies only SYNC items from the analysis Phase 4: prompt to update baseline commit hash --- check-upstream.sh | 140 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 128 insertions(+), 12 deletions(-) diff --git a/check-upstream.sh b/check-upstream.sh index adb43333..3655e347 100755 --- a/check-upstream.sh +++ b/check-upstream.sh @@ -3,11 +3,13 @@ set -euo pipefail # Kojarchy upstream sync checker # Compares omarchy changes since our last-known commit and uses opencode -# to analyze what needs syncing to our repo. +# to analyze and optionally apply changes to our repo. KOJARCHY_DIR="$(cd "$(dirname "$0")" && pwd)" OMARCHY_REPO="https://github.com/basecamp/omarchy.git" OMARCHY_LOCAL="/tmp/kojarchy-omarchy-upstream" +ANALYSIS_FILE="/tmp/kojarchy-upstream-analysis.md" +DIFF_FILE="/tmp/kojarchy-omarchy-diff.patch" # Last omarchy commit hash we synced against OMARCHY_BASELINE="ffafe1727e32c38ba5a291bf3a12d5995a01fda0" @@ -53,17 +55,21 @@ echo "=== Changed files ===" echo "$DIFF_STAT" echo "" -# Write diff to a temp file for opencode to reference -DIFF_FILE="/tmp/kojarchy-omarchy-diff.patch" +# Write diff to temp file echo "$DIFF_FULL" > "$DIFF_FILE" -PROMPT="I need you to analyze upstream changes from omarchy (https://github.com/basecamp/omarchy) and determine what we should sync to our kojarchy dotfiles repo. +# ────────────────────────────────────────── +# Phase 1: Analysis +# ────────────────────────────────────────── + +ANALYSIS_PROMPT="I need you to analyze upstream changes from omarchy (https://github.com/basecamp/omarchy) and determine what we should sync to our kojarchy dotfiles repo. ## Context - Our repo is at: $KOJARCHY_DIR - We are based on omarchy's architecture (install scripts, two-layer config, lib helpers, etc.) - Our last sync was at omarchy commit: $OMARCHY_BASELINE - Omarchy is now at: $OMARCHY_LATEST +- The omarchy repo is cloned at: $OMARCHY_LOCAL ## New omarchy commits since our baseline: $COMMIT_LOG @@ -75,21 +81,131 @@ $DIFF_STAT ## Instructions 1. Read the full diff at $DIFF_FILE -2. For each change, determine if it's relevant to our kojarchy setup -3. Categorize changes as: +2. Read our current repo files at $KOJARCHY_DIR as needed for comparison +3. For each change, determine if it's relevant to our kojarchy setup +4. Categorize changes as: - **SYNC**: We should port this change (explain what and why) - **SKIP**: Not relevant to us (explain why — e.g., we don't use that tool, different approach) - **REVIEW**: Needs manual review (explain the tradeoff) -4. For SYNC items, describe exactly what files in our repo need changing -5. Do NOT make any changes — this is analysis only +5. For SYNC items, describe exactly what files in our repo need changing and what the change should be +6. Do NOT make any changes — this is analysis only +7. Write your full analysis to: $ANALYSIS_FILE + +Use this exact format in $ANALYSIS_FILE: + +\`\`\` +# Upstream Sync Analysis +Baseline: $OMARCHY_BASELINE +Latest: $OMARCHY_LATEST + +## SYNC +### 1. +- **Omarchy file**: +- **Kojarchy file**: +- **Change**: + +## SKIP +### 1. +- **Reason**: + +## REVIEW +### 1. +- **Tradeoff**: +\`\`\` Focus on: install scripts, lib helpers, boot.sh/install.sh patterns, config deployment logic, service setup, and any new best practices." -echo "Running opencode analysis..." +echo "Phase 1: Running analysis..." +echo "" + +opencode run "$ANALYSIS_PROMPT" + +# ────────────────────────────────────────── +# Phase 2: User review +# ────────────────────────────────────────── + +if [[ ! -f "$ANALYSIS_FILE" ]]; then + echo "" + echo "Analysis file not found at $ANALYSIS_FILE" + echo "opencode may have printed the analysis to stdout instead. Re-run or apply manually." + exit 1 +fi + +echo "" +echo "=== Analysis Complete ===" +echo "" +cat "$ANALYSIS_FILE" +echo "" + +if ! command -v gum &>/dev/null; then + echo "Install gum to use interactive mode: sudo pacman -S gum" + echo "Analysis saved to: $ANALYSIS_FILE" + exit 0 +fi + +echo "" +CHOICE=$(gum choose \ + "Apply SYNC changes (let opencode make the changes)" \ + "Edit analysis first (open in \$EDITOR)" \ + "Skip for now (analysis saved to $ANALYSIS_FILE)") + +case "$CHOICE" in +"Edit analysis first"*) + ${EDITOR:-nvim} "$ANALYSIS_FILE" + echo "" + if ! gum confirm "Apply changes from the edited analysis?"; then + echo "Skipped. Analysis at: $ANALYSIS_FILE" + exit 0 + fi + ;; +"Skip for now"*) + echo "Analysis saved to: $ANALYSIS_FILE" + exit 0 + ;; +esac + +# ────────────────────────────────────────── +# Phase 3: Apply changes +# ────────────────────────────────────────── + +ANALYSIS_CONTENT=$(<"$ANALYSIS_FILE") + +APPLY_PROMPT="Apply the following upstream sync changes to our kojarchy repo at $KOJARCHY_DIR. + +## Analysis +$ANALYSIS_CONTENT + +## Full omarchy diff is at: $DIFF_FILE +## The omarchy repo is cloned at: $OMARCHY_LOCAL (use this to read full file contents if needed) + +## Instructions +1. Only apply changes marked as **SYNC** in the analysis above +2. For each SYNC item, make the corresponding change in our repo +3. Adapt the changes to our kojarchy naming/structure (not copy-paste from omarchy) +4. Do NOT commit — just make the file changes +5. After all changes, print a summary of what was modified" + echo "" +echo "Phase 3: Applying SYNC changes..." +echo "" + +opencode run "$APPLY_PROMPT" -opencode run "$PROMPT" +# ────────────────────────────────────────── +# Phase 4: Review and update baseline +# ────────────────────────────────────────── -# Remind to update baseline after syncing echo "" -echo "=== After syncing, update OMARCHY_BASELINE in this script to: $OMARCHY_LATEST ===" +echo "=== Changes applied. Review with: git diff ===" +echo "" + +if gum confirm "Update baseline to $OMARCHY_LATEST?"; then + sed -i "s/^OMARCHY_BASELINE=.*/OMARCHY_BASELINE=\"$OMARCHY_LATEST\"/" "$KOJARCHY_DIR/check-upstream.sh" + echo "Baseline updated to: $OMARCHY_LATEST" + echo "" + echo "Don't forget to commit when you're happy with the changes:" + echo " cd $KOJARCHY_DIR && git add -A && git commit -m 'sync: upstream omarchy changes to $OMARCHY_LATEST'" +else + echo "Baseline NOT updated. Update manually after reviewing:" + echo " OMARCHY_BASELINE in $KOJARCHY_DIR/check-upstream.sh" +fi From 026bf5f70d4b9ec91310ef65f8b1dc671d84a091 Mon Sep 17 00:00:00 2001 From: princejoogie Date: Tue, 10 Feb 2026 15:23:06 +0800 Subject: [PATCH 10/44] refactor: simplify check-upstream to single interactive opencode session Instead of multi-phase file-based workflow, uses one opencode run that walks through each change item-by-item, asking the user to confirm or skip before applying. --- check-upstream.sh | 191 +++++++++------------------------------------- 1 file changed, 37 insertions(+), 154 deletions(-) diff --git a/check-upstream.sh b/check-upstream.sh index 3655e347..1d18911e 100755 --- a/check-upstream.sh +++ b/check-upstream.sh @@ -3,12 +3,11 @@ set -euo pipefail # Kojarchy upstream sync checker # Compares omarchy changes since our last-known commit and uses opencode -# to analyze and optionally apply changes to our repo. +# to interactively walk through each change with the user. KOJARCHY_DIR="$(cd "$(dirname "$0")" && pwd)" OMARCHY_REPO="https://github.com/basecamp/omarchy.git" OMARCHY_LOCAL="/tmp/kojarchy-omarchy-upstream" -ANALYSIS_FILE="/tmp/kojarchy-upstream-analysis.md" DIFF_FILE="/tmp/kojarchy-omarchy-diff.patch" # Last omarchy commit hash we synced against @@ -41,171 +40,55 @@ echo "" echo "Latest: $OMARCHY_LATEST" echo "" -# Get the commit log -echo "=== New commits since baseline ===" +# Get the commit log and diff COMMIT_LOG=$(git -C "$OMARCHY_LOCAL" log --oneline "$OMARCHY_BASELINE..$OMARCHY_LATEST") -echo "$COMMIT_LOG" -echo "" - -# Get the diff (stat + full) DIFF_STAT=$(git -C "$OMARCHY_LOCAL" diff --stat "$OMARCHY_BASELINE..$OMARCHY_LATEST") -DIFF_FULL=$(git -C "$OMARCHY_LOCAL" diff "$OMARCHY_BASELINE..$OMARCHY_LATEST") +git -C "$OMARCHY_LOCAL" diff "$OMARCHY_BASELINE..$OMARCHY_LATEST" > "$DIFF_FILE" +echo "=== New commits ===" +echo "$COMMIT_LOG" +echo "" echo "=== Changed files ===" echo "$DIFF_STAT" echo "" +echo "Handing off to opencode..." +echo "" -# Write diff to temp file -echo "$DIFF_FULL" > "$DIFF_FILE" - -# ────────────────────────────────────────── -# Phase 1: Analysis -# ────────────────────────────────────────── - -ANALYSIS_PROMPT="I need you to analyze upstream changes from omarchy (https://github.com/basecamp/omarchy) and determine what we should sync to our kojarchy dotfiles repo. +# Single interactive opencode session that analyzes, asks, and applies +opencode run "You are reviewing upstream changes from omarchy to sync into our kojarchy dotfiles repo. ## Context -- Our repo is at: $KOJARCHY_DIR -- We are based on omarchy's architecture (install scripts, two-layer config, lib helpers, etc.) -- Our last sync was at omarchy commit: $OMARCHY_BASELINE -- Omarchy is now at: $OMARCHY_LATEST -- The omarchy repo is cloned at: $OMARCHY_LOCAL +- Our kojarchy repo: $KOJARCHY_DIR +- Omarchy repo clone: $OMARCHY_LOCAL +- Full diff file: $DIFF_FILE +- Baseline commit: $OMARCHY_BASELINE +- Latest commit: $OMARCHY_LATEST -## New omarchy commits since our baseline: +## Commits since baseline: $COMMIT_LOG -## Changed files summary: +## Changed files: $DIFF_STAT -## Full diff is at: $DIFF_FILE +## Your workflow -## Instructions 1. Read the full diff at $DIFF_FILE -2. Read our current repo files at $KOJARCHY_DIR as needed for comparison -3. For each change, determine if it's relevant to our kojarchy setup -4. Categorize changes as: - - **SYNC**: We should port this change (explain what and why) - - **SKIP**: Not relevant to us (explain why — e.g., we don't use that tool, different approach) - - **REVIEW**: Needs manual review (explain the tradeoff) -5. For SYNC items, describe exactly what files in our repo need changing and what the change should be -6. Do NOT make any changes — this is analysis only -7. Write your full analysis to: $ANALYSIS_FILE - -Use this exact format in $ANALYSIS_FILE: - -\`\`\` -# Upstream Sync Analysis -Baseline: $OMARCHY_BASELINE -Latest: $OMARCHY_LATEST - -## SYNC -### 1. -- **Omarchy file**: -- **Kojarchy file**: -- **Change**: - -## SKIP -### 1. -- **Reason**: - -## REVIEW -### 1. -- **Tradeoff**: -\`\`\` - -Focus on: install scripts, lib helpers, boot.sh/install.sh patterns, config deployment logic, service setup, and any new best practices." - -echo "Phase 1: Running analysis..." -echo "" - -opencode run "$ANALYSIS_PROMPT" - -# ────────────────────────────────────────── -# Phase 2: User review -# ────────────────────────────────────────── - -if [[ ! -f "$ANALYSIS_FILE" ]]; then - echo "" - echo "Analysis file not found at $ANALYSIS_FILE" - echo "opencode may have printed the analysis to stdout instead. Re-run or apply manually." - exit 1 -fi - -echo "" -echo "=== Analysis Complete ===" -echo "" -cat "$ANALYSIS_FILE" -echo "" - -if ! command -v gum &>/dev/null; then - echo "Install gum to use interactive mode: sudo pacman -S gum" - echo "Analysis saved to: $ANALYSIS_FILE" - exit 0 -fi - -echo "" -CHOICE=$(gum choose \ - "Apply SYNC changes (let opencode make the changes)" \ - "Edit analysis first (open in \$EDITOR)" \ - "Skip for now (analysis saved to $ANALYSIS_FILE)") - -case "$CHOICE" in -"Edit analysis first"*) - ${EDITOR:-nvim} "$ANALYSIS_FILE" - echo "" - if ! gum confirm "Apply changes from the edited analysis?"; then - echo "Skipped. Analysis at: $ANALYSIS_FILE" - exit 0 - fi - ;; -"Skip for now"*) - echo "Analysis saved to: $ANALYSIS_FILE" - exit 0 - ;; -esac - -# ────────────────────────────────────────── -# Phase 3: Apply changes -# ────────────────────────────────────────── - -ANALYSIS_CONTENT=$(<"$ANALYSIS_FILE") - -APPLY_PROMPT="Apply the following upstream sync changes to our kojarchy repo at $KOJARCHY_DIR. - -## Analysis -$ANALYSIS_CONTENT - -## Full omarchy diff is at: $DIFF_FILE -## The omarchy repo is cloned at: $OMARCHY_LOCAL (use this to read full file contents if needed) - -## Instructions -1. Only apply changes marked as **SYNC** in the analysis above -2. For each SYNC item, make the corresponding change in our repo -3. Adapt the changes to our kojarchy naming/structure (not copy-paste from omarchy) -4. Do NOT commit — just make the file changes -5. After all changes, print a summary of what was modified" - -echo "" -echo "Phase 3: Applying SYNC changes..." -echo "" - -opencode run "$APPLY_PROMPT" - -# ────────────────────────────────────────── -# Phase 4: Review and update baseline -# ────────────────────────────────────────── - -echo "" -echo "=== Changes applied. Review with: git diff ===" -echo "" - -if gum confirm "Update baseline to $OMARCHY_LATEST?"; then - sed -i "s/^OMARCHY_BASELINE=.*/OMARCHY_BASELINE=\"$OMARCHY_LATEST\"/" "$KOJARCHY_DIR/check-upstream.sh" - echo "Baseline updated to: $OMARCHY_LATEST" - echo "" - echo "Don't forget to commit when you're happy with the changes:" - echo " cd $KOJARCHY_DIR && git add -A && git commit -m 'sync: upstream omarchy changes to $OMARCHY_LATEST'" -else - echo "Baseline NOT updated. Update manually after reviewing:" - echo " OMARCHY_BASELINE in $KOJARCHY_DIR/check-upstream.sh" -fi +2. Read our repo files at $KOJARCHY_DIR as needed for comparison +3. Group related changes together into discrete sync items +4. For each item, **ask me** whether to sync it or skip it. Present each item like this: + + **[1/N] ** + Omarchy changed: + What changed: <1-2 sentence summary of what the change does> + Our equivalent: + Recommendation: SYNC / SKIP / REVIEW (with brief reason) + + Then wait for my response before moving to the next item. + +5. After going through all items, apply ONLY the changes I confirmed +6. Adapt all changes to kojarchy naming/structure — do not copy omarchy references verbatim +7. Do NOT commit — just make the file changes +8. After applying, print a summary of what was changed and remind me to: + - Review with: git diff + - Update baseline: sed -i 's/^OMARCHY_BASELINE=.*/OMARCHY_BASELINE=\"$OMARCHY_LATEST\"/' $KOJARCHY_DIR/check-upstream.sh + - Commit when ready" From d7d0a1235b6efe5cb88110ba9bedb4433f8522c1 Mon Sep 17 00:00:00 2001 From: princejoogie Date: Tue, 10 Feb 2026 15:24:48 +0800 Subject: [PATCH 11/44] fix: use dev branch for omarchy upstream in check-upstream.sh --- check-upstream.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/check-upstream.sh b/check-upstream.sh index 1d18911e..b4d18883 100755 --- a/check-upstream.sh +++ b/check-upstream.sh @@ -20,11 +20,11 @@ echo "" # Clone or update omarchy if [[ -d "$OMARCHY_LOCAL/.git" ]]; then echo "Updating omarchy clone..." - git -C "$OMARCHY_LOCAL" fetch origin main - git -C "$OMARCHY_LOCAL" reset --hard origin/main + git -C "$OMARCHY_LOCAL" fetch origin dev + git -C "$OMARCHY_LOCAL" reset --hard origin/dev else echo "Cloning omarchy..." - git clone --single-branch --branch main "$OMARCHY_REPO" "$OMARCHY_LOCAL" + git clone --single-branch --branch dev "$OMARCHY_REPO" "$OMARCHY_LOCAL" fi OMARCHY_LATEST=$(git -C "$OMARCHY_LOCAL" rev-parse HEAD) From 2c81bcc8914fb845517de7b9407ac58e8392a1c4 Mon Sep 17 00:00:00 2001 From: princejoogie Date: Tue, 10 Feb 2026 15:25:47 +0800 Subject: [PATCH 12/44] fix: have opencode auto-update baseline hash in check-upstream.sh --- check-upstream.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/check-upstream.sh b/check-upstream.sh index b4d18883..7a412b70 100755 --- a/check-upstream.sh +++ b/check-upstream.sh @@ -88,7 +88,5 @@ $DIFF_STAT 5. After going through all items, apply ONLY the changes I confirmed 6. Adapt all changes to kojarchy naming/structure — do not copy omarchy references verbatim 7. Do NOT commit — just make the file changes -8. After applying, print a summary of what was changed and remind me to: - - Review with: git diff - - Update baseline: sed -i 's/^OMARCHY_BASELINE=.*/OMARCHY_BASELINE=\"$OMARCHY_LATEST\"/' $KOJARCHY_DIR/check-upstream.sh - - Commit when ready" +8. After applying, print a summary of what was changed and remind me to review with git diff and commit when ready +9. Then update the OMARCHY_BASELINE variable in $KOJARCHY_DIR/check-upstream.sh from \"$OMARCHY_BASELINE\" to \"$OMARCHY_LATEST\" by editing the file directly" From 7404db7881dccdb72a33dd887a03cc9bcafac8fa Mon Sep 17 00:00:00 2001 From: princejoogie Date: Tue, 10 Feb 2026 15:31:34 +0800 Subject: [PATCH 13/44] feat: add mac/ helper scripts for macOS config deployment - mac/deps.sh: install shared tooling via Homebrew (nvim, tmux, starship, etc.) - mac/setup.sh: copy shared configs (nvim, opencode, kitty, shell, tmux, yazi) - mac/update.sh: interactive updater to re-deploy configs after git pull --- mac/deps.sh | 77 +++++++++++++++++++++++++++++++++++++++++++++++++ mac/setup.sh | 49 ++++++++++++++++++++++++++++++++ mac/update.sh | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 205 insertions(+) create mode 100755 mac/deps.sh create mode 100755 mac/setup.sh create mode 100755 mac/update.sh diff --git a/mac/deps.sh b/mac/deps.sh new file mode 100755 index 00000000..15faa286 --- /dev/null +++ b/mac/deps.sh @@ -0,0 +1,77 @@ +#!/bin/bash +set -euo pipefail + +# Kojarchy macOS dependencies — installs shared tooling via Homebrew +# Usage: bash ~/dotfiles/mac/deps.sh + +if ! command -v brew &>/dev/null; then + echo "Installing Homebrew..." + /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" +fi + +echo "Installing packages..." + +brew install \ + neovim \ + tmux \ + starship \ + zoxide \ + fzf \ + fd \ + yazi \ + jq \ + git-delta \ + gh \ + direnv \ + mise \ + uv \ + bun \ + btop \ + gum \ + kitty + +# Oh-my-zsh +if [[ ! -d "$HOME/.oh-my-zsh" ]]; then + echo "Installing oh-my-zsh..." + RUNZSH=no KEEP_ZSHRC=yes sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" +fi + +# Zsh plugins +ZSH_CUSTOM="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}" + +[[ ! -d "$ZSH_CUSTOM/plugins/zsh-autosuggestions" ]] && \ + git clone https://github.com/zsh-users/zsh-autosuggestions "$ZSH_CUSTOM/plugins/zsh-autosuggestions" + +[[ ! -d "$ZSH_CUSTOM/plugins/zsh-syntax-highlighting" ]] && \ + git clone https://github.com/zsh-users/zsh-syntax-highlighting "$ZSH_CUSTOM/plugins/zsh-syntax-highlighting" + +[[ ! -d "$ZSH_CUSTOM/plugins/fast-syntax-highlighting" ]] && \ + git clone https://github.com/zdharma-continuum/fast-syntax-highlighting "$ZSH_CUSTOM/plugins/fast-syntax-highlighting" + +# TPM +TPM_DIR="$HOME/.tmux/plugins/tpm" +if [[ ! -d "$TPM_DIR" ]]; then + echo "Installing TPM..." + git clone https://github.com/tmux-plugins/tpm "$TPM_DIR" +fi + +# Rust + cargo tools +if ! command -v cargo &>/dev/null; then + echo "Installing Rust..." + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y + source "$HOME/.cargo/env" +fi + +# Bob (neovim version manager) +if ! command -v bob &>/dev/null; then + cargo install bob-nvim +fi +bob use stable + +# TMS +if ! command -v tms &>/dev/null; then + cargo install tmux-sessionizer +fi + +echo "" +echo "Done! Run 'mac/setup.sh' to deploy configs." diff --git a/mac/setup.sh b/mac/setup.sh new file mode 100755 index 00000000..a3240e83 --- /dev/null +++ b/mac/setup.sh @@ -0,0 +1,49 @@ +#!/bin/bash +set -euo pipefail + +# Kojarchy macOS setup — copies shared configs (nvim, opencode, shell, tmux, git) +# Usage: bash ~/dotfiles/mac/setup.sh + +DOTFILES_DIR="$(cd "$(dirname "$0")/.." && pwd)" + +echo "=== Kojarchy macOS Setup ===" +echo "Dotfiles: $DOTFILES_DIR" +echo "" + +# Nvim +echo "Deploying nvim config..." +mkdir -p ~/.config/nvim +cp -R "$DOTFILES_DIR/config/nvim/"* ~/.config/nvim/ + +# OpenCode +echo "Deploying opencode config..." +mkdir -p ~/.config/opencode +cp -R "$DOTFILES_DIR/config/opencode/"* ~/.config/opencode/ + +# Kitty +echo "Deploying kitty config..." +mkdir -p ~/.config/kitty +cp -R "$DOTFILES_DIR/config/kitty/"* ~/.config/kitty/ + +# Starship +echo "Deploying starship config..." +cp "$DOTFILES_DIR/config/starship.toml" ~/.config/starship.toml + +# Tmux +echo "Deploying tmux config..." +mkdir -p ~/.config/tmux +cp "$DOTFILES_DIR/config/tmux/tmux.conf" ~/.config/tmux/tmux.conf + +# Zsh +echo "Deploying zshrc..." +cp "$DOTFILES_DIR/default/zshrc" ~/.zshrc + +# Yazi +echo "Deploying yazi config..." +mkdir -p ~/.config/yazi +cp -R "$DOTFILES_DIR/config/yazi/"* ~/.config/yazi/ + +echo "" +echo "Done! You may need to:" +echo " - Restart your shell: source ~/.zshrc" +echo " - Install dependencies: see mac/deps.sh" diff --git a/mac/update.sh b/mac/update.sh new file mode 100755 index 00000000..9f3f174f --- /dev/null +++ b/mac/update.sh @@ -0,0 +1,79 @@ +#!/bin/bash +set -euo pipefail + +# Kojarchy macOS update — re-deploys configs from repo +# Usage: bash ~/dotfiles/mac/update.sh + +DOTFILES_DIR="$(cd "$(dirname "$0")/.." && pwd)" + +echo "Pulling latest..." +git -C "$DOTFILES_DIR" pull + +echo "" + +if command -v gum &>/dev/null; then + ACTIONS=$(gum choose --no-limit --header "What do you want to update?" \ + "Nvim" \ + "OpenCode" \ + "Kitty" \ + "Shell (zshrc)" \ + "Tmux" \ + "Starship" \ + "Yazi" \ + "Neovim plugins (lazy sync)" \ + "Everything") + + if echo "$ACTIONS" | grep -q "Everything"; then + ACTIONS="Nvim +OpenCode +Kitty +Shell (zshrc) +Tmux +Starship +Yazi +Neovim plugins (lazy sync)" + fi +else + ACTIONS="Everything" +fi + +while IFS= read -r action; do + case "$action" in + "Nvim"*|"Everything") + echo "Deploying nvim..." + cp -R "$DOTFILES_DIR/config/nvim/"* ~/.config/nvim/ + ;;& + "OpenCode"*|"Everything") + echo "Deploying opencode..." + cp -R "$DOTFILES_DIR/config/opencode/"* ~/.config/opencode/ + ;;& + "Kitty"*|"Everything") + echo "Deploying kitty..." + cp -R "$DOTFILES_DIR/config/kitty/"* ~/.config/kitty/ + ;;& + "Shell"*|"Everything") + echo "Deploying zshrc..." + cp "$DOTFILES_DIR/default/zshrc" ~/.zshrc + ;;& + "Tmux"*|"Everything") + echo "Deploying tmux..." + cp "$DOTFILES_DIR/config/tmux/tmux.conf" ~/.config/tmux/tmux.conf + ;;& + "Starship"*|"Everything") + echo "Deploying starship..." + cp "$DOTFILES_DIR/config/starship.toml" ~/.config/starship.toml + ;;& + "Yazi"*|"Everything") + echo "Deploying yazi..." + cp -R "$DOTFILES_DIR/config/yazi/"* ~/.config/yazi/ + ;;& + "Neovim plugins"*|"Everything") + echo "Syncing neovim plugins..." + nvim --headless "+Lazy! sync" +qa 2>/dev/null || true + ;;& + esac + break +done <<< "$ACTIONS" + +echo "" +echo "Update complete!" From 8f1eae8e0ae4e65659ef9ac2e570da4ae93246cf Mon Sep 17 00:00:00 2001 From: princejoogie Date: Tue, 10 Feb 2026 16:05:11 +0800 Subject: [PATCH 14/44] fix: clear stale pacman db lock in preflight guard --- install/preflight/guard.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/install/preflight/guard.sh b/install/preflight/guard.sh index a64c3b33..2a359c64 100644 --- a/install/preflight/guard.sh +++ b/install/preflight/guard.sh @@ -21,4 +21,9 @@ if ! ping -c 1 -W 3 1.1.1.1 &>/dev/null && ! ping -c 1 -W 3 8.8.8.8 &>/dev/null; abort "Internet connection" fi +# Clear stale pacman lock from previous interrupted runs +if [[ -f /var/lib/pacman/db.lck ]]; then + sudo rm -f /var/lib/pacman/db.lck +fi + echo "Guards: OK" From f303308a253d20187cc805cac66c3cb93def5bb8 Mon Sep 17 00:00:00 2001 From: princejoogie Date: Tue, 10 Feb 2026 16:30:13 +0800 Subject: [PATCH 15/44] feat: add 11 omarchy-inspired system tweaks and utilities Add system hardening, quality-of-life improvements, and utility scripts adapted from omarchy to kojarchy branding and tooling preferences: - Fast systemd shutdown (5s timeout) - Graceful reboot/shutdown (close Hyprland windows first) - SSH MTU probing fix for flaky connections - Sudo 10-attempt limit and PAM faillock (deny=10, unlock 2min) - Default mimetypes (dolphin, qview, zathura, mpv, nvim) - USB autosuspend disable - Audio output switcher (pactl cycle + notify-send) - Screen recording (gpu-screen-recorder with wf-recorder fallback) - GPG keyserver config (5 fallback servers) - Fontconfig fonts.conf (Liberation Sans/Serif, JetBrainsMono NF) - Debug info dump script (system info, dmesg, journal, packages) --- bin/kojarchy-cmd-audio-switch | 38 ++++++++++ bin/kojarchy-cmd-reboot | 7 ++ bin/kojarchy-cmd-screenrecord | 89 ++++++++++++++++++++++ bin/kojarchy-cmd-shutdown | 7 ++ bin/kojarchy-debug | 96 ++++++++++++++++++++++++ bin/kojarchy-hyprland-window-close-all | 9 +++ config/fontconfig/fonts.conf | 58 ++++++++++++++ default/gpg/dirmngr.conf | 7 ++ default/systemd/faster-shutdown.conf | 2 + install/config/all.sh | 7 ++ install/config/gpg.sh | 7 ++ install/config/increase-lockout-limit.sh | 11 +++ install/config/increase-sudo-tries.sh | 8 ++ install/config/mimetypes.sh | 30 ++++++++ install/config/ssh-flakiness.sh | 7 ++ install/config/systemd-tweaks.sh | 5 ++ install/config/usb-autosuspend.sh | 6 ++ 17 files changed, 394 insertions(+) create mode 100755 bin/kojarchy-cmd-audio-switch create mode 100755 bin/kojarchy-cmd-reboot create mode 100755 bin/kojarchy-cmd-screenrecord create mode 100755 bin/kojarchy-cmd-shutdown create mode 100755 bin/kojarchy-debug create mode 100755 bin/kojarchy-hyprland-window-close-all create mode 100644 config/fontconfig/fonts.conf create mode 100644 default/gpg/dirmngr.conf create mode 100644 default/systemd/faster-shutdown.conf create mode 100644 install/config/gpg.sh create mode 100644 install/config/increase-lockout-limit.sh create mode 100644 install/config/increase-sudo-tries.sh create mode 100644 install/config/mimetypes.sh create mode 100644 install/config/ssh-flakiness.sh create mode 100644 install/config/systemd-tweaks.sh create mode 100644 install/config/usb-autosuspend.sh diff --git a/bin/kojarchy-cmd-audio-switch b/bin/kojarchy-cmd-audio-switch new file mode 100755 index 00000000..25746afa --- /dev/null +++ b/bin/kojarchy-cmd-audio-switch @@ -0,0 +1,38 @@ +#!/bin/bash + +# Switch between audio outputs while preserving the mute status. +# By default mapped to Super + Mute. + +focused_monitor="$(hyprctl monitors -j | jq -r '.[] | select(.focused == true).name')" + +sinks=$(pactl -f json list sinks | jq '[.[] | select((.ports | length == 0) or ([.ports[]? | .availability != "not available"] | any))]') +sinks_count=$(echo "$sinks" | jq '. | length') + +if [ "$sinks_count" -eq 0 ]; then + notify-send "No audio devices found" -u critical -t 3000 + exit 1 +fi + +current_sink_name=$(pactl get-default-sink) +current_sink_index=$(echo "$sinks" | jq -r --arg name "$current_sink_name" 'map(.name) | index($name)') + +if [ "$current_sink_index" != "null" ]; then + next_sink_index=$(((current_sink_index + 1) % sinks_count)) +else + next_sink_index=0 +fi + +next_sink=$(echo "$sinks" | jq -r ".[$next_sink_index]") +next_sink_name=$(echo "$next_sink" | jq -r '.name') + +next_sink_description=$(echo "$next_sink" | jq -r '.description') +if [ "$next_sink_description" = "(null)" ] || [ "$next_sink_description" = "null" ] || [ -z "$next_sink_description" ]; then + sink_id=$(echo "$next_sink" | jq -r '.properties."object.id"') + next_sink_description=$(wpctl status | grep -E "\s+\*?\s+${sink_id}\." | sed -E 's/^.*[0-9]+\.\s+//' | sed -E 's/\s+\[.*$//') +fi + +if [ "$next_sink_name" != "$current_sink_name" ]; then + pactl set-default-sink "$next_sink_name" +fi + +notify-send "Audio Output" "$next_sink_description" -t 2000 diff --git a/bin/kojarchy-cmd-reboot b/bin/kojarchy-cmd-reboot new file mode 100755 index 00000000..16902416 --- /dev/null +++ b/bin/kojarchy-cmd-reboot @@ -0,0 +1,7 @@ +#!/bin/bash + +# Gracefully close all Hyprland windows before rebooting. +# Schedules reboot, then closes windows to give apps time to save state. + +sudo shutdown -r +0 & +kojarchy-hyprland-window-close-all diff --git a/bin/kojarchy-cmd-screenrecord b/bin/kojarchy-cmd-screenrecord new file mode 100755 index 00000000..2185a153 --- /dev/null +++ b/bin/kojarchy-cmd-screenrecord @@ -0,0 +1,89 @@ +#!/bin/bash + +# Start and stop a screen recording, saved to ~/Videos by default. +# Alternative location can be set via KOJARCHY_SCREENRECORD_DIR or XDG_VIDEOS_DIR. + +[[ -f ~/.config/user-dirs.dirs ]] && source ~/.config/user-dirs.dirs +OUTPUT_DIR="${KOJARCHY_SCREENRECORD_DIR:-${XDG_VIDEOS_DIR:-$HOME/Videos}}" + +if [[ ! -d "$OUTPUT_DIR" ]]; then + mkdir -p "$OUTPUT_DIR" || { + notify-send "Screen recording directory does not exist: $OUTPUT_DIR" -u critical -t 3000 + exit 1 + } +fi + +DESKTOP_AUDIO="false" +MICROPHONE_AUDIO="false" +STOP_RECORDING="false" + +for arg in "$@"; do + case "$arg" in + --with-desktop-audio) DESKTOP_AUDIO="true" ;; + --with-microphone-audio) MICROPHONE_AUDIO="true" ;; + --stop-recording) STOP_RECORDING="true" ;; + esac +done + +start_screenrecording() { + local filename="$OUTPUT_DIR/screenrecording-$(date +'%Y-%m-%d_%H-%M-%S').mp4" + local audio_args="" + + if [[ "$DESKTOP_AUDIO" == "true" ]] || [[ "$MICROPHONE_AUDIO" == "true" ]]; then + local audio_devices="" + [[ "$DESKTOP_AUDIO" == "true" ]] && audio_devices+="default_output" + if [[ "$MICROPHONE_AUDIO" == "true" ]]; then + [[ -n "$audio_devices" ]] && audio_devices+="|" + audio_devices+="default_input" + fi + audio_args="-a $audio_devices" + fi + + if command -v gpu-screen-recorder &>/dev/null; then + gpu-screen-recorder -w portal -f 60 -fallback-cpu-encoding yes -o "$filename" $audio_args -ac aac & + elif command -v wf-recorder &>/dev/null; then + local wf_audio="" + [[ "$DESKTOP_AUDIO" == "true" ]] && wf_audio="--audio" + wf-recorder $wf_audio -f "$filename" & + else + notify-send "No screen recorder found" "Install gpu-screen-recorder or wf-recorder" -u critical -t 3000 + exit 1 + fi + + notify-send "Screen recording started" -t 2000 +} + +stop_screenrecording() { + if pgrep -f "^gpu-screen-recorder" >/dev/null; then + pkill -SIGINT -f "^gpu-screen-recorder" + elif pgrep -f "^wf-recorder" >/dev/null; then + pkill -SIGINT -f "^wf-recorder" + fi + + # Wait up to 5 seconds for clean exit + local count=0 + while (pgrep -f "^gpu-screen-recorder" >/dev/null || pgrep -f "^wf-recorder" >/dev/null) && [ $count -lt 50 ]; do + sleep 0.1 + count=$((count + 1)) + done + + if pgrep -f "^gpu-screen-recorder" >/dev/null || pgrep -f "^wf-recorder" >/dev/null; then + pkill -9 -f "^gpu-screen-recorder" 2>/dev/null + pkill -9 -f "^wf-recorder" 2>/dev/null + notify-send "Screen recording error" "Recording had to be force-killed. Video may be corrupted." -u critical -t 5000 + else + notify-send "Screen recording saved to $OUTPUT_DIR" -t 2000 + fi +} + +screenrecording_active() { + pgrep -f "^gpu-screen-recorder" >/dev/null || pgrep -f "^wf-recorder" >/dev/null +} + +if screenrecording_active; then + stop_screenrecording +elif [[ "$STOP_RECORDING" == "false" ]]; then + start_screenrecording +else + exit 1 +fi diff --git a/bin/kojarchy-cmd-shutdown b/bin/kojarchy-cmd-shutdown new file mode 100755 index 00000000..38d7c842 --- /dev/null +++ b/bin/kojarchy-cmd-shutdown @@ -0,0 +1,7 @@ +#!/bin/bash + +# Gracefully close all Hyprland windows before shutting down. +# Schedules poweroff, then closes windows to give apps time to save state. + +sudo shutdown -P +0 & +kojarchy-hyprland-window-close-all diff --git a/bin/kojarchy-debug b/bin/kojarchy-debug new file mode 100755 index 00000000..daa503e8 --- /dev/null +++ b/bin/kojarchy-debug @@ -0,0 +1,96 @@ +#!/bin/bash + +# Return exhaustive debugging information about the system to help diagnose problems. + +NO_SUDO=false +PRINT_ONLY=false + +while [[ $# -gt 0 ]]; do + case "$1" in + --no-sudo) + NO_SUDO=true + shift + ;; + --print) + PRINT_ONLY=true + shift + ;; + *) + echo "Unknown option: $1" + echo "Usage: kojarchy-debug [--no-sudo] [--print]" + exit 1 + ;; + esac +done + +KOJARCHY_PATH="${KOJARCHY_PATH:-$HOME/dotfiles}" +LOG_FILE="/tmp/kojarchy-debug.log" + +if [ "$NO_SUDO" = true ]; then + DMESG_OUTPUT="(skipped - --no-sudo flag used)" +else + DMESG_OUTPUT="$(sudo dmesg)" +fi + +cat > "$LOG_FILE" </dev/null || echo "unknown") + +========================================= +SYSTEM INFORMATION +========================================= +$(inxi -Farz 2>/dev/null || echo "inxi not installed") + +========================================= +DMESG +========================================= +$DMESG_OUTPUT + +========================================= +JOURNALCTL (CURRENT BOOT, ERRORS ONLY) +========================================= +$(journalctl -b -p 4..1 2>/dev/null || echo "journalctl unavailable") + +========================================= +INSTALLED PACKAGES +========================================= +$({ expac -S '%n %v (%r)' $(pacman -Qqe) 2>/dev/null; comm -13 <(pacman -Sql | sort) <(pacman -Qqe | sort) | xargs -r expac -Q '%n %v (AUR)'; } | sort 2>/dev/null || echo "package list unavailable") +EOF + +if [ "$PRINT_ONLY" = true ]; then + cat "$LOG_FILE" + exit 0 +fi + +OPTIONS=("View log" "Save in current directory") +if ping -c 1 -W 2 8.8.8.8 >/dev/null 2>&1; then + OPTIONS=("Upload log" "${OPTIONS[@]}") +fi + +ACTION=$(gum choose "${OPTIONS[@]}") + +case "$ACTION" in + "Upload log") + echo "Uploading debug log to 0x0.st..." + URL=$(curl -sF "file=@$LOG_FILE" -Fexpires=24 https://0x0.st) + if [ $? -eq 0 ] && [ -n "$URL" ]; then + echo "Log uploaded successfully!" + echo "Share this URL:" + echo "" + echo " $URL" + echo "" + echo "This link will expire in 24 hours." + else + echo "Error: Failed to upload log file" + exit 1 + fi + ;; + "View log") + less "$LOG_FILE" + ;; + "Save in current directory") + cp "$LOG_FILE" "./kojarchy-debug.log" + echo "Log saved to $(pwd)/kojarchy-debug.log" + ;; +esac diff --git a/bin/kojarchy-hyprland-window-close-all b/bin/kojarchy-hyprland-window-close-all new file mode 100755 index 00000000..abe9c03a --- /dev/null +++ b/bin/kojarchy-hyprland-window-close-all @@ -0,0 +1,9 @@ +#!/bin/bash + +# Close all open Hyprland windows gracefully +hyprctl clients -j | \ + jq -r ".[].address" | \ + xargs -I{} hyprctl dispatch closewindow address:{} + +# Move to first workspace +hyprctl dispatch workspace 1 diff --git a/config/fontconfig/fonts.conf b/config/fontconfig/fonts.conf new file mode 100644 index 00000000..5463ba30 --- /dev/null +++ b/config/fontconfig/fonts.conf @@ -0,0 +1,58 @@ + + + + + + sans-serif + + + Liberation Sans + + + + + + serif + + + Liberation Serif + + + + + + monospace + + + JetBrainsMono Nerd Font + + + + + system-ui + + Liberation Sans + + + + + ui-monospace + + monospace + + + + + -apple-system + + Liberation Sans + + + + + BlinkMacSystemFont + + Liberation Sans + + + diff --git a/default/gpg/dirmngr.conf b/default/gpg/dirmngr.conf new file mode 100644 index 00000000..8d327907 --- /dev/null +++ b/default/gpg/dirmngr.conf @@ -0,0 +1,7 @@ +keyserver hkps://keyserver.ubuntu.com +keyserver hkps://pgp.surfnet.nl +keyserver hkps://keys.mailvelope.com +keyserver hkps://keyring.debian.org +keyserver hkps://pgp.mit.edu + +connect-quick-timeout 4 diff --git a/default/systemd/faster-shutdown.conf b/default/systemd/faster-shutdown.conf new file mode 100644 index 00000000..90dce4f6 --- /dev/null +++ b/default/systemd/faster-shutdown.conf @@ -0,0 +1,2 @@ +[Manager] +DefaultTimeoutStopSec=5s diff --git a/install/config/all.sh b/install/config/all.sh index 797f3868..35248003 100644 --- a/install/config/all.sh +++ b/install/config/all.sh @@ -8,3 +8,10 @@ run_logged $KOJARCHY_INSTALL/config/mise.sh run_logged $KOJARCHY_INSTALL/config/git.sh run_logged $KOJARCHY_INSTALL/config/docker.sh run_logged $KOJARCHY_INSTALL/config/gtk.sh +run_logged $KOJARCHY_INSTALL/config/gpg.sh +run_logged $KOJARCHY_INSTALL/config/mimetypes.sh +run_logged $KOJARCHY_INSTALL/config/ssh-flakiness.sh +run_logged $KOJARCHY_INSTALL/config/increase-sudo-tries.sh +run_logged $KOJARCHY_INSTALL/config/increase-lockout-limit.sh +run_logged $KOJARCHY_INSTALL/config/usb-autosuspend.sh +run_logged $KOJARCHY_INSTALL/config/systemd-tweaks.sh diff --git a/install/config/gpg.sh b/install/config/gpg.sh new file mode 100644 index 00000000..7f80c64a --- /dev/null +++ b/install/config/gpg.sh @@ -0,0 +1,7 @@ +# Deploy GPG keyserver configuration with multiple fallbacks +mkdir -p "$HOME/.gnupg" +cp "$KOJARCHY_DIR/default/gpg/dirmngr.conf" "$HOME/.gnupg/dirmngr.conf" +chmod 700 "$HOME/.gnupg" +chmod 600 "$HOME/.gnupg/dirmngr.conf" + +echo "GPG keyserver config: OK" diff --git a/install/config/increase-lockout-limit.sh b/install/config/increase-lockout-limit.sh new file mode 100644 index 00000000..db0f5926 --- /dev/null +++ b/install/config/increase-lockout-limit.sh @@ -0,0 +1,11 @@ +# Increase PAM faillock limit to 10 attempts with 2min unlock timeout +# This prevents permanent lockout from typos while still protecting against brute force + +FAILLOCK_CONF="/etc/security/faillock.conf" + +if [[ -f "$FAILLOCK_CONF" ]]; then + sudo sed -i 's/^#\?\s*deny\s*=.*/deny = 10/' "$FAILLOCK_CONF" + sudo sed -i 's/^#\?\s*unlock_time\s*=.*/unlock_time = 120/' "$FAILLOCK_CONF" +fi + +echo "PAM lockout limit: OK" diff --git a/install/config/increase-sudo-tries.sh b/install/config/increase-sudo-tries.sh new file mode 100644 index 00000000..f9a8b6c7 --- /dev/null +++ b/install/config/increase-sudo-tries.sh @@ -0,0 +1,8 @@ +# Increase sudo password attempts from default 3 to 10 +SUDOERS_FILE="/etc/sudoers.d/99-kojarchy-passwd-tries" +if [[ ! -f "$SUDOERS_FILE" ]]; then + echo 'Defaults passwd_tries=10' | sudo tee "$SUDOERS_FILE" + sudo chmod 440 "$SUDOERS_FILE" +fi + +echo "Sudo password tries: OK" diff --git a/install/config/mimetypes.sh b/install/config/mimetypes.sh new file mode 100644 index 00000000..ab25f7af --- /dev/null +++ b/install/config/mimetypes.sh @@ -0,0 +1,30 @@ +# Set default applications for common file types + +update-desktop-database ~/.local/share/applications 2>/dev/null || true + +# Open directories in file manager (dolphin) +xdg-mime default org.kde.dolphin.desktop inode/directory 2>/dev/null || true + +# Open images with qview +for mime in image/png image/jpeg image/gif image/webp image/bmp image/tiff; do + xdg-mime default com.interversehq.qView.desktop "$mime" 2>/dev/null || true +done + +# Open PDFs with zathura +xdg-mime default org.pwmt.zathura.desktop application/pdf 2>/dev/null || true + +# Open video files with mpv +for mime in video/mp4 video/x-msvideo video/x-matroska video/x-flv video/x-ms-wmv \ + video/mpeg video/ogg video/webm video/quicktime video/3gpp video/3gpp2 \ + video/x-ms-asf video/x-ogm+ogg video/x-theora+ogg application/ogg; do + xdg-mime default mpv.desktop "$mime" 2>/dev/null || true +done + +# Open text files with nvim +for mime in text/plain text/english text/x-makefile text/x-c++hdr text/x-c++src \ + text/x-chdr text/x-csrc text/x-java text/x-moc text/x-pascal text/x-tcl \ + text/x-tex application/x-shellscript text/x-c text/x-c++ application/xml text/xml; do + xdg-mime default nvim.desktop "$mime" 2>/dev/null || true +done + +echo "Default mimetypes: OK" diff --git a/install/config/ssh-flakiness.sh b/install/config/ssh-flakiness.sh new file mode 100644 index 00000000..e67d145e --- /dev/null +++ b/install/config/ssh-flakiness.sh @@ -0,0 +1,7 @@ +# Fix SSH connection flakiness by enabling MTU probing +if ! grep -q "tcp_mtu_probing" /etc/sysctl.d/99-sysctl.conf 2>/dev/null; then + echo "net.ipv4.tcp_mtu_probing=1" | sudo tee -a /etc/sysctl.d/99-sysctl.conf + sudo sysctl -p /etc/sysctl.d/99-sysctl.conf +fi + +echo "SSH MTU probing fix: OK" diff --git a/install/config/systemd-tweaks.sh b/install/config/systemd-tweaks.sh new file mode 100644 index 00000000..468a03db --- /dev/null +++ b/install/config/systemd-tweaks.sh @@ -0,0 +1,5 @@ +# Apply systemd tweaks (faster shutdown timeout) +sudo mkdir -p /etc/systemd/system.conf.d +sudo cp "$KOJARCHY_DIR/default/systemd/faster-shutdown.conf" /etc/systemd/system.conf.d/faster-shutdown.conf + +echo "Systemd tweaks: OK" diff --git a/install/config/usb-autosuspend.sh b/install/config/usb-autosuspend.sh new file mode 100644 index 00000000..03d7314c --- /dev/null +++ b/install/config/usb-autosuspend.sh @@ -0,0 +1,6 @@ +# Disable USB autosuspend to prevent peripheral disconnection issues +if [[ ! -f /etc/modprobe.d/disable-usb-autosuspend.conf ]]; then + echo "options usbcore autosuspend=-1" | sudo tee /etc/modprobe.d/disable-usb-autosuspend.conf +fi + +echo "USB autosuspend disabled: OK" From 9f1d0d2fe6017cadc96098527817df83788ab08e Mon Sep 17 00:00:00 2001 From: princejoogie Date: Tue, 10 Feb 2026 16:50:37 +0800 Subject: [PATCH 16/44] fix: replace -git packages with official repo equivalents MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Swap 6 -git AUR packages for their prebuilt counterparts to avoid long compile times during install: - hyprshot-git → hyprshot (extra) - kvantum-git → kvantum (extra) - adwaita-qt5-git → adwaita-qt5 (AUR release) - adwaita-qt6-git → adwaita-qt6 (AUR release) - hyperfine-git → hyperfine (extra) - mupdf-git → mupdf (extra) --- install/kojarchy-base.packages | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/install/kojarchy-base.packages b/install/kojarchy-base.packages index bcff78d6..8706f40b 100644 --- a/install/kojarchy-base.packages +++ b/install/kojarchy-base.packages @@ -33,7 +33,7 @@ hyprlock hyprpicker hyprpolkitagent hyprsunset -hyprshot-git +hyprshot hyprmon-bin hyprwhspr swaybg @@ -116,9 +116,9 @@ qt5-wayland qt6-wayland qt5-quickcontrols2 kvantum-qt5 -kvantum-git -adwaita-qt5-git -adwaita-qt6-git +kvantum +adwaita-qt5 +adwaita-qt6 nwg-look breeze sassc @@ -131,7 +131,7 @@ expac flatpak gum jq -hyperfine-git +hyperfine tesseract-data-eng hunspell-en_us bc @@ -141,6 +141,6 @@ speedtest-cli # === Document & Image Viewing === zathura zathura-pdf-mupdf -mupdf-git +mupdf qview ocrmypdf From 43a195ac12e77c29a02b43d1a7595ab73a3d32ba Mon Sep 17 00:00:00 2001 From: princejoogie Date: Tue, 10 Feb 2026 17:27:04 +0800 Subject: [PATCH 17/44] feat: add omarchy-inspired system utilities, update system, and hardware detection Major feature batch adding comprehensive system management adapted from omarchy with kojarchy branding and ALT-based keybindings: Update system (replaces update.sh): - kojarchy-update orchestrator with git pull, package updates, migrations - kojarchy-migrate for timestamped incremental system changes - kojarchy-update-restart for kernel update detection + reboot prompt Package management: - pkg-add/drop/missing/present helpers for scripting - pkg-install/remove interactive TUI pickers (fzf-based) - pkg-aur-add/aur-accessible for AUR support Hardware detection (install/config/hardware/): - Network (iwd, disable networkd-wait-online) - Bluetooth auto-enable - Intel GPU video acceleration - Wireless regulatory domain from timezone - F-key fix for Apple-like keyboards - Synaptics touchpad InterTouch - Power profile auto-switch on AC/battery System hardening & config: - Default GNOME keyring (prevents unlock popup) - UFW firewall (deny in, allow LocalSend + Docker DNS) - DNS resolver (systemd-resolved symlink) - Input group for game controllers - Keyboard layout detection from vconsole.conf - mkinitcpio disable during install (speed optimization) - Hidden .desktop files (29 entries for cleaner app launcher) Hyprland enhancements: - App window rules (browser, terminal, PiP, Steam, Bitwarden, system dialogs) - hypridle.conf (5min lock, 10min DPMS off) - hyprlock.conf (styled lock screen) - hyprsunset.conf (night light placeholder) - Updated keybindings: screenshot via satty, notification dismiss, power menu (ALT+ESC), lock (ALT+CTRL+L), keybind viewer (ALT+/) Browser Wayland flags: - chromium-flags.conf, brave-flags.conf, helium-flags.conf - MOZ_ENABLE_WAYLAND=1 for Firefox/Zen Utility scripts: - Restart helpers (waybar, pipewire, bluetooth, hypridle, wifi, btop) - Refresh scripts (reset individual configs to defaults with backup) - Font management (set/list/current system monospace font) - Lock screen, screenshot, keybindings viewer - Version tracking, state management, hook system Updated README with new workflows, commands, and project structure. --- README.md | 140 ++++++++++++++---- applications/hidden/avahi-discover.desktop | 2 + applications/hidden/bssh.desktop | 2 + applications/hidden/btop.desktop | 2 + applications/hidden/bvnc.desktop | 2 + applications/hidden/cmake-gui.desktop | 2 + applications/hidden/cups.desktop | 2 + applications/hidden/electron34.desktop | 2 + applications/hidden/electron36.desktop | 2 + applications/hidden/electron37.desktop | 2 + applications/hidden/fcitx5-configtool.desktop | 2 + .../hidden/fcitx5-wayland-launcher.desktop | 2 + applications/hidden/java-java-openjdk.desktop | 2 + .../hidden/jconsole-java-openjdk.desktop | 2 + .../hidden/jshell-java-openjdk.desktop | 2 + .../hidden/kbd-layout-viewer5.desktop | 2 + applications/hidden/kcm_fcitx5.desktop | 2 + applications/hidden/kcm_kaccounts.desktop | 2 + applications/hidden/kvantummanager.desktop | 2 + applications/hidden/org.fcitx.Fcitx5.desktop | 2 + .../hidden/org.fcitx.fcitx5-config-qt.desktop | 2 + .../hidden/org.fcitx.fcitx5-migrator.desktop | 2 + .../org.fcitx.fcitx5-qt5-gui-wrapper.desktop | 2 + .../org.fcitx.fcitx5-qt6-gui-wrapper.desktop | 2 + applications/hidden/qv4l2.desktop | 2 + applications/hidden/qvidcap.desktop | 2 + applications/hidden/uuctl.desktop | 2 + applications/hidden/xgps.desktop | 2 + applications/hidden/xgpsspeed.desktop | 2 + bin/kojarchy-cmd-screenshot | 57 +++++++ bin/kojarchy-font-current | 5 + bin/kojarchy-font-list | 5 + bin/kojarchy-font-set | 41 +++++ bin/kojarchy-hook | 18 +++ bin/kojarchy-lock-screen | 8 + bin/kojarchy-menu-keybindings | 51 +++++++ bin/kojarchy-migrate | 27 ++++ bin/kojarchy-pkg-add | 16 ++ bin/kojarchy-pkg-aur-accessible | 6 + bin/kojarchy-pkg-aur-add | 16 ++ bin/kojarchy-pkg-drop | 9 ++ bin/kojarchy-pkg-install | 21 +++ bin/kojarchy-pkg-missing | 11 ++ bin/kojarchy-pkg-present | 9 ++ bin/kojarchy-pkg-remove | 21 +++ bin/kojarchy-powerprofiles-list | 7 + bin/kojarchy-refresh-config | 39 +++++ bin/kojarchy-refresh-hypridle | 3 + bin/kojarchy-refresh-hyprland | 3 + bin/kojarchy-refresh-hyprlock | 2 + bin/kojarchy-refresh-hyprsunset | 3 + bin/kojarchy-refresh-waybar | 5 + bin/kojarchy-restart-app | 8 + bin/kojarchy-restart-bluetooth | 4 + bin/kojarchy-restart-btop | 2 + bin/kojarchy-restart-hypridle | 2 + bin/kojarchy-restart-hyprsunset | 2 + bin/kojarchy-restart-pipewire | 3 + bin/kojarchy-restart-waybar | 2 + bin/kojarchy-restart-wifi | 4 + bin/kojarchy-state | 20 +++ bin/kojarchy-update | 12 ++ bin/kojarchy-update-aur-pkgs | 13 ++ bin/kojarchy-update-confirm | 14 ++ bin/kojarchy-update-git | 9 ++ bin/kojarchy-update-orphan-pkgs | 10 ++ bin/kojarchy-update-perform | 15 ++ bin/kojarchy-update-restart | 19 +++ bin/kojarchy-update-system-pkgs | 6 + bin/kojarchy-update-time | 3 + bin/kojarchy-version | 2 + bin/kojarchy-version-branch | 2 + bin/kojarchy-version-pkgs | 2 + config/brave-flags.conf | 3 + config/chromium-flags.conf | 3 + config/helium-flags.conf | 3 + config/hypr/hypridle.conf | 16 ++ config/hypr/hyprlock.conf | 37 +++++ config/hypr/hyprsunset.conf | 14 ++ config/kojarchy/hooks/font-set.sample | 7 + config/kojarchy/hooks/post-update.sample | 6 + default/hypr/apps.conf | 7 + default/hypr/apps/bitwarden.conf | 7 + default/hypr/apps/browser.conf | 10 ++ default/hypr/apps/pip.conf | 9 ++ default/hypr/apps/steam.conf | 7 + default/hypr/apps/system.conf | 14 ++ default/hypr/apps/terminals.conf | 3 + default/hypr/bindings.conf | 18 ++- default/hypr/envs.conf | 3 + default/hypr/windows.conf | 3 + install/config/all.sh | 13 ++ install/config/default-keyring.sh | 25 ++++ install/config/detect-keyboard-layout.sh | 20 +++ install/config/dns-resolver.sh | 10 ++ install/config/firewall.sh | 15 ++ install/config/hardware/bluetooth.sh | 4 + install/config/hardware/fix-fkeys.sh | 6 + .../config/hardware/fix-synaptic-touchpad.sh | 7 + install/config/hardware/intel.sh | 11 ++ install/config/hardware/network.sh | 8 + install/config/hardware/powerprofiles.sh | 26 ++++ .../config/hardware/set-wireless-regdom.sh | 27 ++++ install/config/hidden-apps.sh | 8 + install/config/input-group.sh | 4 + install/post-install/all.sh | 1 + install/post-install/reenable-mkinitcpio.sh | 15 ++ install/preflight/all.sh | 1 + install/preflight/disable-mkinitcpio.sh | 14 ++ update.sh | 84 ----------- version | 1 + 111 files changed, 1088 insertions(+), 115 deletions(-) create mode 100644 applications/hidden/avahi-discover.desktop create mode 100644 applications/hidden/bssh.desktop create mode 100644 applications/hidden/btop.desktop create mode 100644 applications/hidden/bvnc.desktop create mode 100644 applications/hidden/cmake-gui.desktop create mode 100644 applications/hidden/cups.desktop create mode 100644 applications/hidden/electron34.desktop create mode 100644 applications/hidden/electron36.desktop create mode 100644 applications/hidden/electron37.desktop create mode 100644 applications/hidden/fcitx5-configtool.desktop create mode 100644 applications/hidden/fcitx5-wayland-launcher.desktop create mode 100644 applications/hidden/java-java-openjdk.desktop create mode 100644 applications/hidden/jconsole-java-openjdk.desktop create mode 100644 applications/hidden/jshell-java-openjdk.desktop create mode 100644 applications/hidden/kbd-layout-viewer5.desktop create mode 100644 applications/hidden/kcm_fcitx5.desktop create mode 100644 applications/hidden/kcm_kaccounts.desktop create mode 100644 applications/hidden/kvantummanager.desktop create mode 100644 applications/hidden/org.fcitx.Fcitx5.desktop create mode 100644 applications/hidden/org.fcitx.fcitx5-config-qt.desktop create mode 100644 applications/hidden/org.fcitx.fcitx5-migrator.desktop create mode 100644 applications/hidden/org.fcitx.fcitx5-qt5-gui-wrapper.desktop create mode 100644 applications/hidden/org.fcitx.fcitx5-qt6-gui-wrapper.desktop create mode 100644 applications/hidden/qv4l2.desktop create mode 100644 applications/hidden/qvidcap.desktop create mode 100644 applications/hidden/uuctl.desktop create mode 100644 applications/hidden/xgps.desktop create mode 100644 applications/hidden/xgpsspeed.desktop create mode 100755 bin/kojarchy-cmd-screenshot create mode 100755 bin/kojarchy-font-current create mode 100755 bin/kojarchy-font-list create mode 100755 bin/kojarchy-font-set create mode 100755 bin/kojarchy-hook create mode 100755 bin/kojarchy-lock-screen create mode 100755 bin/kojarchy-menu-keybindings create mode 100755 bin/kojarchy-migrate create mode 100755 bin/kojarchy-pkg-add create mode 100755 bin/kojarchy-pkg-aur-accessible create mode 100755 bin/kojarchy-pkg-aur-add create mode 100755 bin/kojarchy-pkg-drop create mode 100755 bin/kojarchy-pkg-install create mode 100755 bin/kojarchy-pkg-missing create mode 100755 bin/kojarchy-pkg-present create mode 100755 bin/kojarchy-pkg-remove create mode 100755 bin/kojarchy-powerprofiles-list create mode 100755 bin/kojarchy-refresh-config create mode 100755 bin/kojarchy-refresh-hypridle create mode 100755 bin/kojarchy-refresh-hyprland create mode 100755 bin/kojarchy-refresh-hyprlock create mode 100755 bin/kojarchy-refresh-hyprsunset create mode 100755 bin/kojarchy-refresh-waybar create mode 100755 bin/kojarchy-restart-app create mode 100755 bin/kojarchy-restart-bluetooth create mode 100755 bin/kojarchy-restart-btop create mode 100755 bin/kojarchy-restart-hypridle create mode 100755 bin/kojarchy-restart-hyprsunset create mode 100755 bin/kojarchy-restart-pipewire create mode 100755 bin/kojarchy-restart-waybar create mode 100755 bin/kojarchy-restart-wifi create mode 100755 bin/kojarchy-state create mode 100755 bin/kojarchy-update create mode 100755 bin/kojarchy-update-aur-pkgs create mode 100755 bin/kojarchy-update-confirm create mode 100755 bin/kojarchy-update-git create mode 100755 bin/kojarchy-update-orphan-pkgs create mode 100755 bin/kojarchy-update-perform create mode 100755 bin/kojarchy-update-restart create mode 100755 bin/kojarchy-update-system-pkgs create mode 100755 bin/kojarchy-update-time create mode 100755 bin/kojarchy-version create mode 100755 bin/kojarchy-version-branch create mode 100755 bin/kojarchy-version-pkgs create mode 100644 config/brave-flags.conf create mode 100644 config/chromium-flags.conf create mode 100644 config/helium-flags.conf create mode 100644 config/hypr/hypridle.conf create mode 100644 config/hypr/hyprlock.conf create mode 100644 config/hypr/hyprsunset.conf create mode 100644 config/kojarchy/hooks/font-set.sample create mode 100644 config/kojarchy/hooks/post-update.sample create mode 100644 default/hypr/apps.conf create mode 100644 default/hypr/apps/bitwarden.conf create mode 100644 default/hypr/apps/browser.conf create mode 100644 default/hypr/apps/pip.conf create mode 100644 default/hypr/apps/steam.conf create mode 100644 default/hypr/apps/system.conf create mode 100644 default/hypr/apps/terminals.conf create mode 100644 install/config/default-keyring.sh create mode 100644 install/config/detect-keyboard-layout.sh create mode 100644 install/config/dns-resolver.sh create mode 100644 install/config/firewall.sh create mode 100644 install/config/hardware/bluetooth.sh create mode 100644 install/config/hardware/fix-fkeys.sh create mode 100644 install/config/hardware/fix-synaptic-touchpad.sh create mode 100644 install/config/hardware/intel.sh create mode 100644 install/config/hardware/network.sh create mode 100644 install/config/hardware/powerprofiles.sh create mode 100644 install/config/hardware/set-wireless-regdom.sh create mode 100644 install/config/hidden-apps.sh create mode 100644 install/config/input-group.sh create mode 100644 install/post-install/reenable-mkinitcpio.sh create mode 100644 install/preflight/disable-mkinitcpio.sh delete mode 100755 update.sh create mode 100644 version diff --git a/README.md b/README.md index 9185678d..6ed15ead 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ The installer handles everything: packages, configs, services, shell setup, and | Terminal | [Kitty](https://sw.kovidgoyal.net/kitty/) | | Shell | Zsh + [oh-my-zsh](https://ohmyz.sh/) + [Starship](https://starship.rs/) | | Editor | [Neovim](https://neovim.io/) (Lua config, lazy.nvim) | -| File Manager | [yazi](https://github.com/sxyazi/yazi) | +| File Manager | [yazi](https://github.com/sxyazi/yazi) / [Dolphin](https://apps.kde.org/dolphin/) | | Multiplexer | [Tmux](https://github.com/tmux/tmux) | | Version Manager | [mise](https://mise.jdx.dev/) (node, go, python) | | Display Manager | [SDDM](https://github.com/sddm/sddm) with macOS theme + autologin | @@ -40,19 +40,22 @@ The installer handles everything: packages, configs, services, shell setup, and ~/dotfiles/ ├── boot.sh # Bootstrap (curl-pipe-bash entry point) ├── install.sh # Main orchestrator -├── update.sh # Interactive updater (re-deploy configs, packages, etc.) +├── version # Version file (semver) ├── lib/ # Helpers (presentation, logging, errors, packages) ├── install/ -│ ├── preflight/ # Guard checks, install log setup +│ ├── preflight/ # Guard checks, mkinitcpio disable, install log setup │ ├── packaging/ # AUR helper, base/optional packages, fonts -│ ├── config/ # Config deploy, shell, tmux, cargo, neovim, mise, git, docker, gtk +│ ├── config/ # Config deploy, shell, tmux, cargo, neovim, mise, git, +│ │ │ # docker, gtk, gpg, firewall, dns, hardware detection +│ │ └── hardware/ # Network, bluetooth, Intel GPU, wireless regdom, F-keys, +│ │ # touchpad, power profiles │ ├── services/ # systemd, SDDM, udev -│ ├── post-install/ # Summary, reboot prompt +│ ├── post-install/ # Re-enable mkinitcpio, summary, reboot prompt │ ├── kojarchy-base.packages │ ├── kojarchy-optional.packages │ └── kojarchy-cargo.packages ├── config/ # Copied to ~/.config/ on install (user-editable) -│ ├── hypr/ # Hyprland (sources defaults, user overrides) +│ ├── hypr/ # hyprland.conf, hypridle.conf, hyprlock.conf, hyprsunset.conf │ ├── waybar/ # Waybar + custom modules │ ├── wofi/ # Wofi + dmenu scripts │ ├── dunst/ # Notification config @@ -62,13 +65,36 @@ The installer handles everything: packages, configs, services, shell setup, and │ ├── yazi/ # File manager theme │ ├── opencode/ # OpenCode AI config + skills │ ├── btop/ # System monitor config +│ ├── fontconfig/ # Font rendering (Liberation Sans, JetBrainsMono NF) +│ ├── kojarchy/hooks/ # User-extensible hooks (post-update, font-set) │ ├── starship.toml # Prompt config +│ ├── chromium-flags.conf # Wayland flags for Chromium +│ ├── brave-flags.conf # Wayland flags for Brave +│ ├── helium-flags.conf # Wayland flags for Helium │ └── xdg-desktop-portal/ # Portal configs ├── default/ # Stays in repo, sourced at runtime (updated via git pull) │ ├── hypr/ # autostart, bindings, envs, looknfeel, input, windows -│ └── zsh/ # aliases, envs, init, functions, shell, rc +│ │ └── apps/ # App-specific window rules (browser, PiP, Steam, etc.) +│ ├── zsh/ # aliases, envs, init, functions, shell, rc +│ ├── gpg/ # GPG keyserver config (multiple fallbacks) +│ └── systemd/ # Faster shutdown timeout ├── bin/ # CLI utilities -> ~/.local/custom/bin/ -├── sddm/macos/ # SDDM macOS theme +│ ├── kojarchy-update # Update system (git pull + packages + migrations) +│ ├── kojarchy-migrate # Run pending migrations +│ ├── kojarchy-pkg-* # Package management helpers (add, drop, install TUI) +│ ├── kojarchy-cmd-* # Commands (screenshot, screenrecord, audio-switch, reboot, shutdown) +│ ├── kojarchy-restart-* # Restart individual services (waybar, pipewire, bluetooth, etc.) +│ ├── kojarchy-refresh-* # Reset individual configs to defaults +│ ├── kojarchy-font-* # Font management (set, list, current) +│ ├── kojarchy-lock-screen # Lock screen via hyprlock +│ ├── kojarchy-debug # System debug info dump +│ ├── kojarchy-version # Show version, branch, last package update +│ ├── kojarchy-hook # Run user hooks +│ ├── kojarchy-state # Persistent state management for toggles +│ └── kojarchy-menu-keybindings # Interactive keybinding search (wofi) +├── migrations/ # Timestamped incremental update scripts +├── applications/hidden/ # .desktop files to hide unwanted app launcher entries +├── sddm/macos/ # SDDM macOS theme ├── wallpapers/ # Wallpaper collection ├── system/udev/ # udev rules └── logo.txt # ASCII art for installer TUI @@ -109,30 +135,59 @@ monitor=,2560x1440@240,auto,1 ## Updating -After changing configs or pulling new updates from the repo: +Kojarchy uses a multi-step update system inspired by omarchy: ```bash -# Quick: defaults (hypr, zsh) update automatically — just git pull -cd ~/dotfiles && git pull +# Full update: pull repo, update packages, run migrations +kojarchy-update -# Interactive: choose what to re-deploy -~/dotfiles/update.sh +# Skip confirmation prompt +kojarchy-update -y ``` -`update.sh` lets you pick what to reload: +The update process runs these steps in order: -| Option | What it does | -|:-------|:-------------| -| Packages | Installs new/missing packages from package lists | -| Configs | Re-copies `config/` to `~/.config/` (overwrites local changes) | -| Bin scripts | Re-links `bin/` to `~/.local/custom/bin/` | -| Shell | Re-deploys `~/.zshrc` from `default/zshrc` | -| SDDM theme | Re-copies theme to `/usr/share/sddm/themes/macos/` | -| Cargo packages | Installs any missing cargo tools | -| Neovim plugins | Syncs lazy.nvim plugins | -| Everything | All of the above | +1. **`kojarchy-update-git`** -- Pull latest changes from the repo +2. **`kojarchy-update-time`** -- Sync system clock +3. **`kojarchy-update-system-pkgs`** -- Update official packages (`pacman -Syyu`) +4. **`kojarchy-migrate`** -- Run any pending migrations (incremental system changes) +5. **`kojarchy-update-aur-pkgs`** -- Update AUR packages (via yay) +6. **`kojarchy-update-orphan-pkgs`** -- Remove orphaned packages +7. **`kojarchy-hook post-update`** -- Run user post-update hook +8. **`kojarchy-update-restart`** -- Offer reboot if kernel updated -> **Note**: For most day-to-day changes, `git pull` is enough. The two-layer system means `default/` changes (keybindings, autostart, shell aliases, etc.) take effect immediately since they're sourced at runtime. Only use `update.sh` when you need to re-deploy `config/` files or install new packages. +For most day-to-day changes, `git pull` is enough. The two-layer system means `default/` changes (keybindings, autostart, shell aliases, etc.) take effect immediately since they're sourced at runtime. + +### Migrations + +Migrations are timestamped shell scripts in `migrations/` that apply one-time system changes during updates. They ensure users who installed earlier get new fixes/features automatically. Each migration runs once and is tracked in `~/.local/state/kojarchy/migrations/`. + +### Refreshing Configs + +If you break a config, reset it to the Kojarchy default: + +```bash +kojarchy-refresh-hyprland # Reset all Hyprland configs +kojarchy-refresh-waybar # Reset Waybar config + restart +kojarchy-refresh-hyprlock # Reset lock screen config +kojarchy-refresh-hypridle # Reset idle config + restart +kojarchy-refresh-hyprsunset # Reset night light config + restart +kojarchy-refresh-config waybar/style.css # Reset any specific config file +``` + +A timestamped backup is created before overwriting. + +## Package Management + +```bash +kojarchy-pkg-add # Install if missing (pacman) +kojarchy-pkg-drop # Remove if installed +kojarchy-pkg-aur-add # Install from AUR (yay) +kojarchy-pkg-install # Interactive TUI for browsing/installing packages +kojarchy-pkg-remove # Interactive TUI for removing packages +kojarchy-pkg-missing # Check: exit 0 if any are missing +kojarchy-pkg-present # Check: exit 0 if all installed +``` ## Customization @@ -140,10 +195,12 @@ cd ~/dotfiles && git pull 2. **Update defaults**: `cd ~/dotfiles && git pull` -- changes propagate automatically since configs source the defaults. 3. **Add overrides**: Uncomment or create override files referenced in the configs (e.g., `~/.config/hypr/overrides.conf`). 4. **Private config**: Add secrets/tokens to `~/.private.sh` (sourced by `~/.zshrc`, gitignored). +5. **Hooks**: Add custom scripts to `~/.config/kojarchy/hooks/` (see `.sample` files). +6. **Font**: Change system-wide monospace font with `kojarchy-font-set ` (list available: `kojarchy-font-list`). ## Key Bindings -All bindings use `ALT` as the main modifier. +All bindings use `ALT` as the main modifier. Press `ALT + /` to search all keybindings interactively. | Binding | Action | |:--------|:-------| @@ -158,10 +215,37 @@ All bindings use `ALT` as the main modifier. | `ALT + CTRL + SHIFT + H/J/K/L` | Resize window | | `ALT + 1-0` | Switch workspace | | `ALT + SHIFT + 1-0` | Move to workspace | +| `ALT + S` | Toggle scratchpad | | `ALT + W` | Toggle waybar | +| `ALT + E` | File manager | | `ALT + SHIFT + C` | Color picker | -| `Print` | Screenshot region | -| `ALT + Print` | Screenshot window | +| `ALT + CTRL + L` | Lock screen | +| `ALT + ESCAPE` | Power menu (lock/reboot/shutdown) | +| `ALT + /` | Search keybindings | +| `ALT + ,` | Dismiss notification | +| `ALT + SHIFT + ,` | Dismiss all notifications | +| `ALT + SHIFT + N` | Notification history | +| `Print` | Screenshot (region, edit with satty) | +| `SHIFT + Print` | Screenshot to clipboard | +| `ALT + Print` | Screen recording toggle | +| `ALT + SHIFT + D` | Speech-to-text (hyprwhspr) | + +## Utility Commands + +| Command | Description | +|:--------|:------------| +| `kojarchy-update` | Full system update | +| `kojarchy-version` | Show version | +| `kojarchy-debug` | System debug info dump | +| `kojarchy-cmd-screenshot` | Take screenshot (region/window/fullscreen) | +| `kojarchy-cmd-screenrecord` | Start/stop screen recording | +| `kojarchy-cmd-audio-switch` | Cycle audio outputs | +| `kojarchy-cmd-reboot` | Graceful reboot (closes windows first) | +| `kojarchy-cmd-shutdown` | Graceful shutdown (closes windows first) | +| `kojarchy-lock-screen` | Lock screen via hyprlock | +| `kojarchy-font-set` | Change system monospace font | +| `kojarchy-menu-keybindings` | Interactive keybinding search | +| `kojarchy-pkg-install` | TUI package browser | ## Optional Packages diff --git a/applications/hidden/avahi-discover.desktop b/applications/hidden/avahi-discover.desktop new file mode 100644 index 00000000..e1e3e173 --- /dev/null +++ b/applications/hidden/avahi-discover.desktop @@ -0,0 +1,2 @@ +[Desktop Entry] +Hidden=true diff --git a/applications/hidden/bssh.desktop b/applications/hidden/bssh.desktop new file mode 100644 index 00000000..e1e3e173 --- /dev/null +++ b/applications/hidden/bssh.desktop @@ -0,0 +1,2 @@ +[Desktop Entry] +Hidden=true diff --git a/applications/hidden/btop.desktop b/applications/hidden/btop.desktop new file mode 100644 index 00000000..e1e3e173 --- /dev/null +++ b/applications/hidden/btop.desktop @@ -0,0 +1,2 @@ +[Desktop Entry] +Hidden=true diff --git a/applications/hidden/bvnc.desktop b/applications/hidden/bvnc.desktop new file mode 100644 index 00000000..e1e3e173 --- /dev/null +++ b/applications/hidden/bvnc.desktop @@ -0,0 +1,2 @@ +[Desktop Entry] +Hidden=true diff --git a/applications/hidden/cmake-gui.desktop b/applications/hidden/cmake-gui.desktop new file mode 100644 index 00000000..e1e3e173 --- /dev/null +++ b/applications/hidden/cmake-gui.desktop @@ -0,0 +1,2 @@ +[Desktop Entry] +Hidden=true diff --git a/applications/hidden/cups.desktop b/applications/hidden/cups.desktop new file mode 100644 index 00000000..e1e3e173 --- /dev/null +++ b/applications/hidden/cups.desktop @@ -0,0 +1,2 @@ +[Desktop Entry] +Hidden=true diff --git a/applications/hidden/electron34.desktop b/applications/hidden/electron34.desktop new file mode 100644 index 00000000..e1e3e173 --- /dev/null +++ b/applications/hidden/electron34.desktop @@ -0,0 +1,2 @@ +[Desktop Entry] +Hidden=true diff --git a/applications/hidden/electron36.desktop b/applications/hidden/electron36.desktop new file mode 100644 index 00000000..e1e3e173 --- /dev/null +++ b/applications/hidden/electron36.desktop @@ -0,0 +1,2 @@ +[Desktop Entry] +Hidden=true diff --git a/applications/hidden/electron37.desktop b/applications/hidden/electron37.desktop new file mode 100644 index 00000000..e1e3e173 --- /dev/null +++ b/applications/hidden/electron37.desktop @@ -0,0 +1,2 @@ +[Desktop Entry] +Hidden=true diff --git a/applications/hidden/fcitx5-configtool.desktop b/applications/hidden/fcitx5-configtool.desktop new file mode 100644 index 00000000..e1e3e173 --- /dev/null +++ b/applications/hidden/fcitx5-configtool.desktop @@ -0,0 +1,2 @@ +[Desktop Entry] +Hidden=true diff --git a/applications/hidden/fcitx5-wayland-launcher.desktop b/applications/hidden/fcitx5-wayland-launcher.desktop new file mode 100644 index 00000000..e1e3e173 --- /dev/null +++ b/applications/hidden/fcitx5-wayland-launcher.desktop @@ -0,0 +1,2 @@ +[Desktop Entry] +Hidden=true diff --git a/applications/hidden/java-java-openjdk.desktop b/applications/hidden/java-java-openjdk.desktop new file mode 100644 index 00000000..e1e3e173 --- /dev/null +++ b/applications/hidden/java-java-openjdk.desktop @@ -0,0 +1,2 @@ +[Desktop Entry] +Hidden=true diff --git a/applications/hidden/jconsole-java-openjdk.desktop b/applications/hidden/jconsole-java-openjdk.desktop new file mode 100644 index 00000000..e1e3e173 --- /dev/null +++ b/applications/hidden/jconsole-java-openjdk.desktop @@ -0,0 +1,2 @@ +[Desktop Entry] +Hidden=true diff --git a/applications/hidden/jshell-java-openjdk.desktop b/applications/hidden/jshell-java-openjdk.desktop new file mode 100644 index 00000000..e1e3e173 --- /dev/null +++ b/applications/hidden/jshell-java-openjdk.desktop @@ -0,0 +1,2 @@ +[Desktop Entry] +Hidden=true diff --git a/applications/hidden/kbd-layout-viewer5.desktop b/applications/hidden/kbd-layout-viewer5.desktop new file mode 100644 index 00000000..e1e3e173 --- /dev/null +++ b/applications/hidden/kbd-layout-viewer5.desktop @@ -0,0 +1,2 @@ +[Desktop Entry] +Hidden=true diff --git a/applications/hidden/kcm_fcitx5.desktop b/applications/hidden/kcm_fcitx5.desktop new file mode 100644 index 00000000..e1e3e173 --- /dev/null +++ b/applications/hidden/kcm_fcitx5.desktop @@ -0,0 +1,2 @@ +[Desktop Entry] +Hidden=true diff --git a/applications/hidden/kcm_kaccounts.desktop b/applications/hidden/kcm_kaccounts.desktop new file mode 100644 index 00000000..e1e3e173 --- /dev/null +++ b/applications/hidden/kcm_kaccounts.desktop @@ -0,0 +1,2 @@ +[Desktop Entry] +Hidden=true diff --git a/applications/hidden/kvantummanager.desktop b/applications/hidden/kvantummanager.desktop new file mode 100644 index 00000000..e1e3e173 --- /dev/null +++ b/applications/hidden/kvantummanager.desktop @@ -0,0 +1,2 @@ +[Desktop Entry] +Hidden=true diff --git a/applications/hidden/org.fcitx.Fcitx5.desktop b/applications/hidden/org.fcitx.Fcitx5.desktop new file mode 100644 index 00000000..e1e3e173 --- /dev/null +++ b/applications/hidden/org.fcitx.Fcitx5.desktop @@ -0,0 +1,2 @@ +[Desktop Entry] +Hidden=true diff --git a/applications/hidden/org.fcitx.fcitx5-config-qt.desktop b/applications/hidden/org.fcitx.fcitx5-config-qt.desktop new file mode 100644 index 00000000..e1e3e173 --- /dev/null +++ b/applications/hidden/org.fcitx.fcitx5-config-qt.desktop @@ -0,0 +1,2 @@ +[Desktop Entry] +Hidden=true diff --git a/applications/hidden/org.fcitx.fcitx5-migrator.desktop b/applications/hidden/org.fcitx.fcitx5-migrator.desktop new file mode 100644 index 00000000..e1e3e173 --- /dev/null +++ b/applications/hidden/org.fcitx.fcitx5-migrator.desktop @@ -0,0 +1,2 @@ +[Desktop Entry] +Hidden=true diff --git a/applications/hidden/org.fcitx.fcitx5-qt5-gui-wrapper.desktop b/applications/hidden/org.fcitx.fcitx5-qt5-gui-wrapper.desktop new file mode 100644 index 00000000..e1e3e173 --- /dev/null +++ b/applications/hidden/org.fcitx.fcitx5-qt5-gui-wrapper.desktop @@ -0,0 +1,2 @@ +[Desktop Entry] +Hidden=true diff --git a/applications/hidden/org.fcitx.fcitx5-qt6-gui-wrapper.desktop b/applications/hidden/org.fcitx.fcitx5-qt6-gui-wrapper.desktop new file mode 100644 index 00000000..e1e3e173 --- /dev/null +++ b/applications/hidden/org.fcitx.fcitx5-qt6-gui-wrapper.desktop @@ -0,0 +1,2 @@ +[Desktop Entry] +Hidden=true diff --git a/applications/hidden/qv4l2.desktop b/applications/hidden/qv4l2.desktop new file mode 100644 index 00000000..e1e3e173 --- /dev/null +++ b/applications/hidden/qv4l2.desktop @@ -0,0 +1,2 @@ +[Desktop Entry] +Hidden=true diff --git a/applications/hidden/qvidcap.desktop b/applications/hidden/qvidcap.desktop new file mode 100644 index 00000000..e1e3e173 --- /dev/null +++ b/applications/hidden/qvidcap.desktop @@ -0,0 +1,2 @@ +[Desktop Entry] +Hidden=true diff --git a/applications/hidden/uuctl.desktop b/applications/hidden/uuctl.desktop new file mode 100644 index 00000000..e1e3e173 --- /dev/null +++ b/applications/hidden/uuctl.desktop @@ -0,0 +1,2 @@ +[Desktop Entry] +Hidden=true diff --git a/applications/hidden/xgps.desktop b/applications/hidden/xgps.desktop new file mode 100644 index 00000000..e1e3e173 --- /dev/null +++ b/applications/hidden/xgps.desktop @@ -0,0 +1,2 @@ +[Desktop Entry] +Hidden=true diff --git a/applications/hidden/xgpsspeed.desktop b/applications/hidden/xgpsspeed.desktop new file mode 100644 index 00000000..e1e3e173 --- /dev/null +++ b/applications/hidden/xgpsspeed.desktop @@ -0,0 +1,2 @@ +[Desktop Entry] +Hidden=true diff --git a/bin/kojarchy-cmd-screenshot b/bin/kojarchy-cmd-screenshot new file mode 100755 index 00000000..4c47c209 --- /dev/null +++ b/bin/kojarchy-cmd-screenshot @@ -0,0 +1,57 @@ +#!/bin/bash + +# Take a screenshot of the whole screen, a specific window, or a user-drawn region. +# Saves to ~/Pictures by default. Change via KOJARCHY_SCREENSHOT_DIR or XDG_PICTURES_DIR. + +[[ -f ~/.config/user-dirs.dirs ]] && source ~/.config/user-dirs.dirs +OUTPUT_DIR="${KOJARCHY_SCREENSHOT_DIR:-${XDG_PICTURES_DIR:-$HOME/Pictures}}" + +if [[ ! -d "$OUTPUT_DIR" ]]; then + mkdir -p "$OUTPUT_DIR" || { + notify-send "Screenshot directory does not exist: $OUTPUT_DIR" -u critical -t 3000 + exit 1 + } +fi + +pkill slurp && exit 0 + +MODE="${1:-region}" +PROCESSING="${2:-edit}" + +get_rectangles() { + local active_workspace=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true) | .activeWorkspace.id') + hyprctl monitors -j | jq -r --arg ws "$active_workspace" '.[] | select(.activeWorkspace.id == ($ws | tonumber)) | "\(.x),\(.y) \((.width / .scale) | floor)x\((.height / .scale) | floor)"' + hyprctl clients -j | jq -r --arg ws "$active_workspace" '.[] | select(.workspace.id == ($ws | tonumber)) | "\(.at[0]),\(.at[1]) \(.size[0])x\(.size[1])"' +} + +case "$MODE" in + region) + SELECTION=$(slurp 2>/dev/null) + ;; + window) + SELECTION=$(get_rectangles | slurp -r 2>/dev/null) + ;; + fullscreen) + SELECTION=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true) | "\(.x),\(.y) \((.width / .scale) | floor)x\((.height / .scale) | floor)"') + ;; +esac + +[ -z "$SELECTION" ] && exit 0 + +FILENAME="$OUTPUT_DIR/screenshot-$(date +'%Y-%m-%d_%H-%M-%S').png" + +if [[ "$PROCESSING" == "edit" ]] && command -v satty &>/dev/null; then + grim -g "$SELECTION" - | + satty --filename - \ + --output-filename "$FILENAME" \ + --early-exit \ + --actions-on-enter save-to-clipboard \ + --save-after-copy \ + --copy-command 'wl-copy' +elif [[ "$PROCESSING" == "clipboard" ]]; then + grim -g "$SELECTION" - | wl-copy + notify-send "Screenshot copied to clipboard" -t 2000 +else + grim -g "$SELECTION" "$FILENAME" + notify-send "Screenshot saved to $FILENAME" -t 2000 +fi diff --git a/bin/kojarchy-font-current b/bin/kojarchy-font-current new file mode 100755 index 00000000..d1b3918c --- /dev/null +++ b/bin/kojarchy-font-current @@ -0,0 +1,5 @@ +#!/bin/bash + +# Returns the current monospace font from the Waybar stylesheet. + +grep -oP 'font-family:\s*["'\''"]?\K[^;"'\'']+' ~/.config/waybar/style.css | head -n1 diff --git a/bin/kojarchy-font-list b/bin/kojarchy-font-list new file mode 100755 index 00000000..bbbe4931 --- /dev/null +++ b/bin/kojarchy-font-list @@ -0,0 +1,5 @@ +#!/bin/bash + +# List all monospace fonts available on the system. + +fc-list :spacing=100 -f "%{family[0]}\n" | grep -v -i -E 'emoji|signwriting' | sort -u diff --git a/bin/kojarchy-font-set b/bin/kojarchy-font-set new file mode 100755 index 00000000..8a93ae86 --- /dev/null +++ b/bin/kojarchy-font-set @@ -0,0 +1,41 @@ +#!/bin/bash + +# Set the system-wide monospace font (terminal, hyprlock, waybar, fontconfig). + +font_name="$1" + +if [[ -z "$font_name" ]]; then + echo "Usage: kojarchy-font-set " + echo "Available fonts: kojarchy-font-list" + exit 1 +fi + +if ! fc-list | grep -iq "$font_name"; then + echo "Font '$font_name' not found." + exit 1 +fi + +if [[ -f ~/.config/kitty/kitty.conf ]]; then + sed -i "s/^font_family .*/font_family $font_name/g" ~/.config/kitty/kitty.conf + pkill -USR1 kitty 2>/dev/null || true +fi + +if [[ -f ~/.config/hypr/hyprlock.conf ]]; then + sed -i "s/font_family = .*/font_family = $font_name/g" ~/.config/hypr/hyprlock.conf +fi + +if [[ -f ~/.config/waybar/style.css ]]; then + sed -i "s/font-family: .*/font-family: '$font_name';/g" ~/.config/waybar/style.css + kojarchy-restart-waybar 2>/dev/null || true +fi + +if [[ -f ~/.config/fontconfig/fonts.conf ]] && command -v xmlstarlet &>/dev/null; then + xmlstarlet ed -L \ + -u '//match[@target="pattern"][test/string="monospace"]/edit[@name="family"]/string' \ + -v "$font_name" \ + ~/.config/fontconfig/fonts.conf +fi + +kojarchy-hook font-set "$font_name" 2>/dev/null || true + +echo "Font set to: $font_name" diff --git a/bin/kojarchy-hook b/bin/kojarchy-hook new file mode 100755 index 00000000..0bc8f30e --- /dev/null +++ b/bin/kojarchy-hook @@ -0,0 +1,18 @@ +#!/bin/bash + +# Run a named hook (e.g. post-update, font-set). +# Hooks live in ~/.config/kojarchy/hooks/ + +set -e + +if [[ $# -lt 1 ]]; then + echo "Usage: kojarchy-hook [name] [args...]" + exit 1 +fi + +HOOK_PATH="$HOME/.config/kojarchy/hooks/$1" +shift + +if [[ -f "$HOOK_PATH" ]]; then + bash "$HOOK_PATH" "$@" +fi diff --git a/bin/kojarchy-lock-screen b/bin/kojarchy-lock-screen new file mode 100755 index 00000000..7413a3aa --- /dev/null +++ b/bin/kojarchy-lock-screen @@ -0,0 +1,8 @@ +#!/bin/bash + +# Lock the screen using hyprlock. + +pidof hyprlock || hyprlock & + +# Reset keyboard layout to default +hyprctl switchxkblayout all 0 > /dev/null 2>&1 diff --git a/bin/kojarchy-menu-keybindings b/bin/kojarchy-menu-keybindings new file mode 100755 index 00000000..6ef8b2c5 --- /dev/null +++ b/bin/kojarchy-menu-keybindings @@ -0,0 +1,51 @@ +#!/bin/bash + +# Display Hyprland keybindings in an interactive search using wofi. + +output_keybindings() { + hyprctl -j binds | + jq -r '.[] | {modmask, key, keycode, description, dispatcher, arg} | "\(.modmask),\(.key)@\(.keycode),\(.description),\(.dispatcher),\(.arg)"' | + sed -r \ + -e 's/null//' \ + -e 's/@0//' \ + -e 's/,@/,code:/' \ + -e 's/^0,/,/' \ + -e 's/^1,/SHIFT,/' \ + -e 's/^4,/CTRL,/' \ + -e 's/^5,/SHIFT CTRL,/' \ + -e 's/^8,/ALT,/' \ + -e 's/^9,/SHIFT ALT,/' \ + -e 's/^12,/CTRL ALT,/' \ + -e 's/^13,/SHIFT CTRL ALT,/' \ + -e 's/^64,/SUPER,/' \ + -e 's/^65,/SUPER SHIFT,/' \ + -e 's/^68,/SUPER CTRL,/' \ + -e 's/^69,/SUPER SHIFT CTRL,/' \ + -e 's/^72,/SUPER ALT,/' \ + -e 's/^73,/SUPER SHIFT ALT,/' \ + -e 's/^76,/SUPER CTRL ALT,/' \ + -e 's/^77,/SUPER SHIFT CTRL ALT,/' | + awk -F, '{ + key_combo = $1 " + " $2; + gsub(/^[ \t]*\+?[ \t]*/, "", key_combo); + gsub(/[ \t]+$/, "", key_combo); + action = $3; + if (action == "") { + for (i = 4; i <= NF; i++) { + action = action $i (i < NF ? "," : ""); + } + sub(/,$/, "", action); + gsub(/(^|,)[[:space:]]*exec[[:space:]]*,?/, "", action); + gsub(/^[ \t]+|[ \t]+$/, "", action); + } + if (action != "") { + printf "%-35s %s\n", key_combo, action; + } + }' +} + +if [[ "$1" == "--print" || "$1" == "-p" ]]; then + output_keybindings +else + output_keybindings | wofi --show dmenu -p 'Keybindings' --width 800 --height 600 +fi diff --git a/bin/kojarchy-migrate b/bin/kojarchy-migrate new file mode 100755 index 00000000..1b541a10 --- /dev/null +++ b/bin/kojarchy-migrate @@ -0,0 +1,27 @@ +#!/bin/bash + +# Run all pending migrations to bring the system in line with the installed version. + +KOJARCHY_PATH="${KOJARCHY_PATH:-$HOME/dotfiles}" +STATE_DIR="$HOME/.local/state/kojarchy/migrations" +mkdir -p "$STATE_DIR" +mkdir -p "$STATE_DIR/skipped" + +for file in "$KOJARCHY_PATH"/migrations/*.sh; do + [[ -f "$file" ]] || continue + filename=$(basename "$file") + + if [[ ! -f "$STATE_DIR/$filename" && ! -f "$STATE_DIR/skipped/$filename" ]]; then + echo -e "\e[32m\nRunning migration (${filename%.sh})\e[0m" + + if bash "$file"; then + touch "$STATE_DIR/$filename" + else + if command -v gum &>/dev/null && gum confirm "Migration ${filename%.sh} failed. Skip and continue?"; then + touch "$STATE_DIR/skipped/$filename" + else + exit 1 + fi + fi + fi +done diff --git a/bin/kojarchy-pkg-add b/bin/kojarchy-pkg-add new file mode 100755 index 00000000..b1a4e774 --- /dev/null +++ b/bin/kojarchy-pkg-add @@ -0,0 +1,16 @@ +#!/bin/bash + +# Add named packages if missing. Returns false if it couldn't be done. + +if kojarchy-pkg-missing "$@"; then + sudo pacman -S --noconfirm --needed "$@" || exit 1 +fi + +for pkg in "$@"; do + if ! pacman -Q "$pkg" &>/dev/null; then + echo -e "\033[31mError: Package '$pkg' did not install\033[0m" >&2 + exit 1 + fi +done + +exit 0 diff --git a/bin/kojarchy-pkg-aur-accessible b/bin/kojarchy-pkg-aur-accessible new file mode 100755 index 00000000..e4f08e1f --- /dev/null +++ b/bin/kojarchy-pkg-aur-accessible @@ -0,0 +1,6 @@ +#!/bin/bash + +# Returns true if the AUR is up and available. + +curl -sf --connect-timeout 30 --retry 3 --retry-delay 3 -A "kojarchy-update" \ + "https://aur.archlinux.org/rpc/?v=5&type=info&arg=base" >/dev/null diff --git a/bin/kojarchy-pkg-aur-add b/bin/kojarchy-pkg-aur-add new file mode 100755 index 00000000..54349365 --- /dev/null +++ b/bin/kojarchy-pkg-aur-add @@ -0,0 +1,16 @@ +#!/bin/bash + +# Add named AUR packages if missing. + +if kojarchy-pkg-missing "$@"; then + yay -S --noconfirm --needed "$@" || exit 1 +fi + +for pkg in "$@"; do + if ! pacman -Q "$pkg" &>/dev/null; then + echo -e "\033[31mError: Package '$pkg' did not install\033[0m" >&2 + exit 1 + fi +done + +exit 0 diff --git a/bin/kojarchy-pkg-drop b/bin/kojarchy-pkg-drop new file mode 100755 index 00000000..a33a02f7 --- /dev/null +++ b/bin/kojarchy-pkg-drop @@ -0,0 +1,9 @@ +#!/bin/bash + +# Remove named packages if installed (otherwise ignore). + +for pkg in "$@"; do + if pacman -Q "$pkg" &>/dev/null; then + sudo pacman -Rns --noconfirm "$pkg" + fi +done diff --git a/bin/kojarchy-pkg-install b/bin/kojarchy-pkg-install new file mode 100755 index 00000000..c2f70da2 --- /dev/null +++ b/bin/kojarchy-pkg-install @@ -0,0 +1,21 @@ +#!/bin/bash + +# Interactive fuzzy-finder TUI for picking new packages to install. + +fzf_args=( + --multi + --preview 'pacman -Sii {1}' + --preview-label='alt-p: toggle preview, alt-j/k: scroll, tab: multi-select' + --preview-label-pos='bottom' + --preview-window 'down:65%:wrap' + --bind 'alt-p:toggle-preview' + --bind 'alt-d:preview-half-page-down,alt-u:preview-half-page-up' + --bind 'alt-k:preview-up,alt-j:preview-down' + --color 'pointer:green,marker:green' +) + +pkg_names=$(pacman -Slq | fzf "${fzf_args[@]}") + +if [[ -n "$pkg_names" ]]; then + echo "$pkg_names" | tr '\n' ' ' | xargs sudo pacman -S --noconfirm +fi diff --git a/bin/kojarchy-pkg-missing b/bin/kojarchy-pkg-missing new file mode 100755 index 00000000..62e4bd00 --- /dev/null +++ b/bin/kojarchy-pkg-missing @@ -0,0 +1,11 @@ +#!/bin/bash + +# Returns true (exit 0) if any named packages are missing. + +for pkg in "$@"; do + if ! pacman -Q "$pkg" &>/dev/null; then + exit 0 + fi +done + +exit 1 diff --git a/bin/kojarchy-pkg-present b/bin/kojarchy-pkg-present new file mode 100755 index 00000000..8bebc077 --- /dev/null +++ b/bin/kojarchy-pkg-present @@ -0,0 +1,9 @@ +#!/bin/bash + +# Returns true (exit 0) if all named packages are installed. + +for pkg in "$@"; do + pacman -Q "$pkg" &>/dev/null || exit 1 +done + +exit 0 diff --git a/bin/kojarchy-pkg-remove b/bin/kojarchy-pkg-remove new file mode 100755 index 00000000..8d6c02c3 --- /dev/null +++ b/bin/kojarchy-pkg-remove @@ -0,0 +1,21 @@ +#!/bin/bash + +# Interactive fuzzy-finder TUI for removing installed packages. + +fzf_args=( + --multi + --preview 'pacman -Qi {1}' + --preview-label='alt-p: toggle preview, alt-j/k: scroll, tab: multi-select' + --preview-label-pos='bottom' + --preview-window 'down:65%:wrap' + --bind 'alt-p:toggle-preview' + --bind 'alt-d:preview-half-page-down,alt-u:preview-half-page-up' + --bind 'alt-k:preview-up,alt-j:preview-down' + --color 'pointer:red,marker:red' +) + +pkg_names=$(pacman -Qqe | fzf "${fzf_args[@]}") + +if [[ -n "$pkg_names" ]]; then + echo "$pkg_names" | tr '\n' ' ' | xargs sudo pacman -Rns --noconfirm +fi diff --git a/bin/kojarchy-powerprofiles-list b/bin/kojarchy-powerprofiles-list new file mode 100755 index 00000000..eb7ca11d --- /dev/null +++ b/bin/kojarchy-powerprofiles-list @@ -0,0 +1,7 @@ +#!/bin/bash + +# List available power profiles on the system. + +powerprofilesctl list | + awk '/^\s*[* ]\s*[a-zA-Z0-9\-]+:$/ { gsub(/^[*[:space:]]+|:$/,""); print }' | + tac diff --git a/bin/kojarchy-refresh-config b/bin/kojarchy-refresh-config new file mode 100755 index 00000000..f195b69b --- /dev/null +++ b/bin/kojarchy-refresh-config @@ -0,0 +1,39 @@ +#!/bin/bash + +# Refresh a config file from defaults. Takes a backup if file exists and differs. +# Usage: kojarchy-refresh-config +# Example: kojarchy-refresh-config hypr/hyprlock.conf + +KOJARCHY_PATH="${KOJARCHY_PATH:-$HOME/dotfiles}" + +config_file=$1 + +if [[ -z "$config_file" ]]; then + echo "Usage: $0 " + echo "Example: $0 hypr/hyprlock.conf" + exit 1 +fi + +user_config_file="${HOME}/.config/$config_file" +default_config_file="${KOJARCHY_PATH}/config/$config_file" +backup_config_file="$user_config_file.bak.$(date +%s)" + +if [[ ! -f "$default_config_file" ]]; then + echo "Default config not found: $default_config_file" + exit 1 +fi + +if [[ -f "$user_config_file" ]]; then + cp -f "$user_config_file" "$backup_config_file" 2>/dev/null + cp -f "$default_config_file" "$user_config_file" 2>/dev/null + + if cmp -s "$user_config_file" "$backup_config_file"; then + rm "$backup_config_file" + else + echo -e "\e[31mReplaced $user_config_file with Kojarchy default.\nBackup saved as ${backup_config_file}.\n\n\e[32mChanges:\e[0m" + diff "$user_config_file" "$backup_config_file" || true + fi +else + mkdir -p "$(dirname "$user_config_file")" + cp -f "$default_config_file" "$user_config_file" 2>/dev/null +fi diff --git a/bin/kojarchy-refresh-hypridle b/bin/kojarchy-refresh-hypridle new file mode 100755 index 00000000..630b1cb7 --- /dev/null +++ b/bin/kojarchy-refresh-hypridle @@ -0,0 +1,3 @@ +#!/bin/bash +kojarchy-refresh-config hypr/hypridle.conf +kojarchy-restart-hypridle diff --git a/bin/kojarchy-refresh-hyprland b/bin/kojarchy-refresh-hyprland new file mode 100755 index 00000000..d7e624d5 --- /dev/null +++ b/bin/kojarchy-refresh-hyprland @@ -0,0 +1,3 @@ +#!/bin/bash +# Reset all Hyprland user configs to Kojarchy defaults. +kojarchy-refresh-config hypr/hyprland.conf diff --git a/bin/kojarchy-refresh-hyprlock b/bin/kojarchy-refresh-hyprlock new file mode 100755 index 00000000..c9b6d07c --- /dev/null +++ b/bin/kojarchy-refresh-hyprlock @@ -0,0 +1,2 @@ +#!/bin/bash +kojarchy-refresh-config hypr/hyprlock.conf diff --git a/bin/kojarchy-refresh-hyprsunset b/bin/kojarchy-refresh-hyprsunset new file mode 100755 index 00000000..b9703f65 --- /dev/null +++ b/bin/kojarchy-refresh-hyprsunset @@ -0,0 +1,3 @@ +#!/bin/bash +kojarchy-refresh-config hypr/hyprsunset.conf +kojarchy-restart-hyprsunset diff --git a/bin/kojarchy-refresh-waybar b/bin/kojarchy-refresh-waybar new file mode 100755 index 00000000..5c35e801 --- /dev/null +++ b/bin/kojarchy-refresh-waybar @@ -0,0 +1,5 @@ +#!/bin/bash +# Reset Waybar config to Kojarchy defaults and restart. +kojarchy-refresh-config waybar/config.jsonc +kojarchy-refresh-config waybar/style.css +kojarchy-restart-waybar diff --git a/bin/kojarchy-restart-app b/bin/kojarchy-restart-app new file mode 100755 index 00000000..f3aea655 --- /dev/null +++ b/bin/kojarchy-restart-app @@ -0,0 +1,8 @@ +#!/bin/bash + +# Restart an application by killing it and relaunching. +# Usage: kojarchy-restart-app + +pkill -x "$1" 2>/dev/null +sleep 0.5 +setsid "$1" >/dev/null 2>&1 & diff --git a/bin/kojarchy-restart-bluetooth b/bin/kojarchy-restart-bluetooth new file mode 100755 index 00000000..fe33707d --- /dev/null +++ b/bin/kojarchy-restart-bluetooth @@ -0,0 +1,4 @@ +#!/bin/bash +echo "Unblocking bluetooth..." +rfkill unblock bluetooth +rfkill list bluetooth diff --git a/bin/kojarchy-restart-btop b/bin/kojarchy-restart-btop new file mode 100755 index 00000000..f3023b43 --- /dev/null +++ b/bin/kojarchy-restart-btop @@ -0,0 +1,2 @@ +#!/bin/bash +pkill -SIGUSR2 btop diff --git a/bin/kojarchy-restart-hypridle b/bin/kojarchy-restart-hypridle new file mode 100755 index 00000000..a5e8682a --- /dev/null +++ b/bin/kojarchy-restart-hypridle @@ -0,0 +1,2 @@ +#!/bin/bash +kojarchy-restart-app hypridle diff --git a/bin/kojarchy-restart-hyprsunset b/bin/kojarchy-restart-hyprsunset new file mode 100755 index 00000000..7b1ddb21 --- /dev/null +++ b/bin/kojarchy-restart-hyprsunset @@ -0,0 +1,2 @@ +#!/bin/bash +kojarchy-restart-app hyprsunset diff --git a/bin/kojarchy-restart-pipewire b/bin/kojarchy-restart-pipewire new file mode 100755 index 00000000..1385ebe9 --- /dev/null +++ b/bin/kojarchy-restart-pipewire @@ -0,0 +1,3 @@ +#!/bin/bash +echo "Restarting pipewire audio service..." +systemctl --user restart pipewire.service diff --git a/bin/kojarchy-restart-waybar b/bin/kojarchy-restart-waybar new file mode 100755 index 00000000..76e7ed14 --- /dev/null +++ b/bin/kojarchy-restart-waybar @@ -0,0 +1,2 @@ +#!/bin/bash +kojarchy-restart-app waybar diff --git a/bin/kojarchy-restart-wifi b/bin/kojarchy-restart-wifi new file mode 100755 index 00000000..6119725d --- /dev/null +++ b/bin/kojarchy-restart-wifi @@ -0,0 +1,4 @@ +#!/bin/bash +echo "Unblocking wifi..." +rfkill unblock wifi +rfkill list wifi diff --git a/bin/kojarchy-state b/bin/kojarchy-state new file mode 100755 index 00000000..fcb6bde8 --- /dev/null +++ b/bin/kojarchy-state @@ -0,0 +1,20 @@ +#!/bin/bash + +# Manage persistent state files for toggles and settings. +# Usage: kojarchy-state + +STATE_DIR="$HOME/.local/state/kojarchy" +mkdir -p "$STATE_DIR" + +COMMAND="$1" +STATE_NAME="$2" + +if [[ -z "$COMMAND" || -z "$STATE_NAME" ]]; then + echo "Usage: kojarchy-state " + exit 1 +fi + +case "$COMMAND" in + set) touch "$STATE_DIR/$STATE_NAME" ;; + clear) find "$STATE_DIR" -maxdepth 1 -type f -name "$STATE_NAME" -delete ;; +esac diff --git a/bin/kojarchy-update b/bin/kojarchy-update new file mode 100755 index 00000000..e0176cd8 --- /dev/null +++ b/bin/kojarchy-update @@ -0,0 +1,12 @@ +#!/bin/bash + +set -e + +KOJARCHY_PATH="${KOJARCHY_PATH:-$HOME/dotfiles}" + +trap 'echo ""; echo -e "\033[0;31mSomething went wrong during the update!\n\nPlease review the output above carefully, correct the error, and retry the update.\033[0m"' ERR + +if [[ $1 == "-y" ]] || kojarchy-update-confirm; then + kojarchy-update-git + kojarchy-update-perform +fi diff --git a/bin/kojarchy-update-aur-pkgs b/bin/kojarchy-update-aur-pkgs new file mode 100755 index 00000000..ec892a9c --- /dev/null +++ b/bin/kojarchy-update-aur-pkgs @@ -0,0 +1,13 @@ +#!/bin/bash + +# Update AUR packages if any are installed +if pacman -Qem >/dev/null 2>&1; then + if kojarchy-pkg-aur-accessible; then + echo -e "\e[32m\nUpdate AUR packages\e[0m" + yay -Sua --noconfirm --cleanafter + echo + else + echo -e "\e[31m\nAUR is unavailable (skipping updates)\e[0m" + echo + fi +fi diff --git a/bin/kojarchy-update-confirm b/bin/kojarchy-update-confirm new file mode 100755 index 00000000..a17d3540 --- /dev/null +++ b/bin/kojarchy-update-confirm @@ -0,0 +1,14 @@ +#!/bin/bash + +gum style --border normal --border-foreground 6 --padding "1 2" \ + "Ready to update?" \ + "" \ + " You cannot stop the update once you start!" \ + " Make sure you're connected to power or have a full battery" + +echo + +if ! gum confirm "Continue with update?"; then + echo "Update cancelled" + exit 1 +fi diff --git a/bin/kojarchy-update-git b/bin/kojarchy-update-git new file mode 100755 index 00000000..f44b8e38 --- /dev/null +++ b/bin/kojarchy-update-git @@ -0,0 +1,9 @@ +#!/bin/bash + +set -e + +KOJARCHY_PATH="${KOJARCHY_PATH:-$HOME/dotfiles}" + +echo -e "\e[32mUpdate Kojarchy\e[0m" +git -C "$KOJARCHY_PATH" pull --autostash +git -C "$KOJARCHY_PATH" --no-pager diff --check || git -C "$KOJARCHY_PATH" reset --merge diff --git a/bin/kojarchy-update-orphan-pkgs b/bin/kojarchy-update-orphan-pkgs new file mode 100755 index 00000000..c1754c90 --- /dev/null +++ b/bin/kojarchy-update-orphan-pkgs @@ -0,0 +1,10 @@ +#!/bin/bash + +orphans=$(pacman -Qtdq 2>/dev/null || true) +if [[ -n $orphans ]]; then + echo -e "\e[32m\nRemove orphan system packages\e[0m" + for pkg in $orphans; do + sudo pacman -Rs --noconfirm "$pkg" || true + done + echo +fi diff --git a/bin/kojarchy-update-perform b/bin/kojarchy-update-perform new file mode 100755 index 00000000..7a81a060 --- /dev/null +++ b/bin/kojarchy-update-perform @@ -0,0 +1,15 @@ +#!/bin/bash + +set -e + +# Capture update logs +exec > >(tee "/tmp/kojarchy-update.log") 2>&1 + +# Perform all update steps +kojarchy-update-time +kojarchy-update-system-pkgs +kojarchy-migrate +kojarchy-update-aur-pkgs +kojarchy-update-orphan-pkgs +kojarchy-hook post-update +kojarchy-update-restart diff --git a/bin/kojarchy-update-restart b/bin/kojarchy-update-restart new file mode 100755 index 00000000..f905e3c7 --- /dev/null +++ b/bin/kojarchy-update-restart @@ -0,0 +1,19 @@ +#!/bin/bash + +# Check if kernel was updated and offer reboot +if [ "$(uname -r | sed 's/-arch/\.arch/')" != "$(pacman -Q linux | awk '{print $2}')" ]; then + gum confirm "Linux kernel has been updated. Reboot?" && kojarchy-cmd-reboot +elif [ -f "$HOME/.local/state/kojarchy/reboot-required" ]; then + gum confirm "Updates require reboot. Ready?" && kojarchy-cmd-reboot +fi + +# Restart any services that flagged themselves +for file in "$HOME"/.local/state/kojarchy/restart-*-required; do + if [ -f "$file" ]; then + filename=$(basename "$file") + service=$(echo "$filename" | sed 's/restart-\(.*\)-required/\1/') + echo "Restarting $service" + kojarchy-state clear "$filename" + kojarchy-restart-"$service" 2>/dev/null || true + fi +done diff --git a/bin/kojarchy-update-system-pkgs b/bin/kojarchy-update-system-pkgs new file mode 100755 index 00000000..36a78418 --- /dev/null +++ b/bin/kojarchy-update-system-pkgs @@ -0,0 +1,6 @@ +#!/bin/bash + +set -e + +echo -e "\e[32m\nUpdate system packages\e[0m" +sudo pacman -Syyu --noconfirm diff --git a/bin/kojarchy-update-time b/bin/kojarchy-update-time new file mode 100755 index 00000000..4c08caf4 --- /dev/null +++ b/bin/kojarchy-update-time @@ -0,0 +1,3 @@ +#!/bin/bash +echo "Updating time..." +sudo systemctl restart systemd-timesyncd diff --git a/bin/kojarchy-version b/bin/kojarchy-version new file mode 100755 index 00000000..c8f7f821 --- /dev/null +++ b/bin/kojarchy-version @@ -0,0 +1,2 @@ +#!/bin/bash +cat "${KOJARCHY_PATH:-$HOME/dotfiles}/version" diff --git a/bin/kojarchy-version-branch b/bin/kojarchy-version-branch new file mode 100755 index 00000000..60cd2028 --- /dev/null +++ b/bin/kojarchy-version-branch @@ -0,0 +1,2 @@ +#!/bin/bash +git -C "${KOJARCHY_PATH:-$HOME/dotfiles}" rev-parse --abbrev-ref HEAD diff --git a/bin/kojarchy-version-pkgs b/bin/kojarchy-version-pkgs new file mode 100755 index 00000000..e4d6b427 --- /dev/null +++ b/bin/kojarchy-version-pkgs @@ -0,0 +1,2 @@ +#!/bin/bash +date -d "$(grep upgraded /var/log/pacman.log | tail -1 | sed -E 's/\[([^]]+)\].*/\1/')" "+%A, %B %d %Y at %H:%M" 2>/dev/null || echo "unknown" diff --git a/config/brave-flags.conf b/config/brave-flags.conf new file mode 100644 index 00000000..c009930b --- /dev/null +++ b/config/brave-flags.conf @@ -0,0 +1,3 @@ +--ozone-platform-hint=auto +--enable-features=WaylandWindowDecorations +--enable-gpu-rasterization diff --git a/config/chromium-flags.conf b/config/chromium-flags.conf new file mode 100644 index 00000000..c009930b --- /dev/null +++ b/config/chromium-flags.conf @@ -0,0 +1,3 @@ +--ozone-platform-hint=auto +--enable-features=WaylandWindowDecorations +--enable-gpu-rasterization diff --git a/config/helium-flags.conf b/config/helium-flags.conf new file mode 100644 index 00000000..c009930b --- /dev/null +++ b/config/helium-flags.conf @@ -0,0 +1,3 @@ +--ozone-platform-hint=auto +--enable-features=WaylandWindowDecorations +--enable-gpu-rasterization diff --git a/config/hypr/hypridle.conf b/config/hypr/hypridle.conf new file mode 100644 index 00000000..1926319d --- /dev/null +++ b/config/hypr/hypridle.conf @@ -0,0 +1,16 @@ +general { + lock_cmd = kojarchy-lock-screen + before_sleep_cmd = loginctl lock-session + after_sleep_cmd = hyprctl dispatch dpms on +} + +listener { + timeout = 300 # 5min + on-timeout = loginctl lock-session # lock screen +} + +listener { + timeout = 600 # 10min + on-timeout = hyprctl dispatch dpms off # screen off + on-resume = hyprctl dispatch dpms on # screen on when activity detected +} diff --git a/config/hypr/hyprlock.conf b/config/hypr/hyprlock.conf new file mode 100644 index 00000000..5b3e0ca8 --- /dev/null +++ b/config/hypr/hyprlock.conf @@ -0,0 +1,37 @@ +general { + ignore_empty_input = true +} + +background { + monitor = + color = rgb(1a1b26) + path = ~/dotfiles/wallpapers/pallete.png + blur_passes = 3 +} + +animations { + enabled = false +} + +input-field { + monitor = + size = 650, 100 + position = 0, 0 + halign = center + valign = center + + inner_color = rgb(1a1b26) + outer_color = rgb(7aa2f7) + outline_thickness = 4 + + font_family = JetBrainsMono Nerd Font + font_color = rgb(c0caf5) + + placeholder_text = Enter Password + check_color = rgb(9ece6a) + fail_text = $FAIL ($ATTEMPTS) + + rounding = 0 + shadow_passes = 0 + fade_on_empty = false +} diff --git a/config/hypr/hyprsunset.conf b/config/hypr/hyprsunset.conf new file mode 100644 index 00000000..9617c754 --- /dev/null +++ b/config/hypr/hyprsunset.conf @@ -0,0 +1,14 @@ +# Default: no color temperature change +# To enable auto night light, add to your autostart.conf: +# exec-once = hyprsunset +# and uncomment the profile below: + +profile { + time = 07:00 + identity = true +} + +# profile { +# time = 20:00 +# temperature = 4000 +# } diff --git a/config/kojarchy/hooks/font-set.sample b/config/kojarchy/hooks/font-set.sample new file mode 100644 index 00000000..b0f2dcaf --- /dev/null +++ b/config/kojarchy/hooks/font-set.sample @@ -0,0 +1,7 @@ +#!/bin/bash +# This hook runs after kojarchy-font-set changes the font. +# The new font name is passed as $1. +# Rename this file to 'font-set' (remove .sample) to activate. +# +# Example: notify about font change +# notify-send "Font changed to $1" diff --git a/config/kojarchy/hooks/post-update.sample b/config/kojarchy/hooks/post-update.sample new file mode 100644 index 00000000..14dce3ba --- /dev/null +++ b/config/kojarchy/hooks/post-update.sample @@ -0,0 +1,6 @@ +#!/bin/bash +# This hook runs after kojarchy-update completes. +# Rename this file to 'post-update' (remove .sample) to activate. +# +# Example: restart waybar after update +# kojarchy-restart-waybar diff --git a/default/hypr/apps.conf b/default/hypr/apps.conf new file mode 100644 index 00000000..1b718a41 --- /dev/null +++ b/default/hypr/apps.conf @@ -0,0 +1,7 @@ +# App-specific window tweaks +source = ~/dotfiles/default/hypr/apps/browser.conf +source = ~/dotfiles/default/hypr/apps/terminals.conf +source = ~/dotfiles/default/hypr/apps/system.conf +source = ~/dotfiles/default/hypr/apps/pip.conf +source = ~/dotfiles/default/hypr/apps/bitwarden.conf +source = ~/dotfiles/default/hypr/apps/steam.conf diff --git a/default/hypr/apps/bitwarden.conf b/default/hypr/apps/bitwarden.conf new file mode 100644 index 00000000..97772d31 --- /dev/null +++ b/default/hypr/apps/bitwarden.conf @@ -0,0 +1,7 @@ +# Bitwarden: floating + no screen share +windowrule = no_screen_share on, match:class ^(Bitwarden)$ +windowrule = tag +floating-window, match:class ^(Bitwarden)$ + +# Bitwarden Chrome Extension +windowrule = no_screen_share on, match:class chrome-nngceckbapebfimnlniiiahkandclblb-Default +windowrule = tag +floating-window, match:class chrome-nngceckbapebfimnlniiiahkandclblb-Default diff --git a/default/hypr/apps/browser.conf b/default/hypr/apps/browser.conf new file mode 100644 index 00000000..e536bed4 --- /dev/null +++ b/default/hypr/apps/browser.conf @@ -0,0 +1,10 @@ +# Browser window rules +windowrule = tag +chromium-based-browser, match:class ((google-)?[cC]hrom(e|ium)|[bB]rave-browser|[mM]icrosoft-edge|Vivaldi-stable|helium) +windowrule = tag +firefox-based-browser, match:class ([fF]irefox|zen|librewolf) + +# Force chromium-based browsers into a tile (--app bug workaround) +windowrule = tile on, match:tag chromium-based-browser + +# Subtle opacity when unfocused +windowrule = opacity 1.0 0.97, match:tag chromium-based-browser +windowrule = opacity 1.0 0.97, match:tag firefox-based-browser diff --git a/default/hypr/apps/pip.conf b/default/hypr/apps/pip.conf new file mode 100644 index 00000000..e5b45d56 --- /dev/null +++ b/default/hypr/apps/pip.conf @@ -0,0 +1,9 @@ +# Picture-in-picture overlays +windowrule = tag +pip, match:title (Picture.?in.?[Pp]icture) +windowrule = float on, match:tag pip +windowrule = pin on, match:tag pip +windowrule = size 600 338, match:tag pip +windowrule = keep_aspect_ratio on, match:tag pip +windowrule = border_size 0, match:tag pip +windowrule = opacity 1 1, match:tag pip +windowrule = move (monitor_w-window_w-40) (monitor_h*0.04), match:tag pip diff --git a/default/hypr/apps/steam.conf b/default/hypr/apps/steam.conf new file mode 100644 index 00000000..f1693f9d --- /dev/null +++ b/default/hypr/apps/steam.conf @@ -0,0 +1,7 @@ +# Steam: float all windows, no transparency +windowrule = float on, match:class steam +windowrule = center on, match:class steam, match:title Steam +windowrule = opacity 1 1, match:class steam.* +windowrule = size 1100 700, match:class steam, match:title Steam +windowrule = size 460 800, match:class steam, match:title Friends List +windowrule = idle_inhibit fullscreen, match:class steam diff --git a/default/hypr/apps/system.conf b/default/hypr/apps/system.conf new file mode 100644 index 00000000..2ae894f0 --- /dev/null +++ b/default/hypr/apps/system.conf @@ -0,0 +1,14 @@ +# System dialog floating rules +windowrule = float on, match:tag floating-window +windowrule = center on, match:tag floating-window +windowrule = size 875 600, match:tag floating-window + +windowrule = tag +floating-window, match:class (com.gabm.satty|imv|mpv) +windowrule = tag +floating-window, match:class (xdg-desktop-portal-gtk|org.kde.dolphin), match:title ^(Open.*Files?|Open [F|f]older.*|Save.*Files?|Save.*As|Save|All Files|[C|c]hoose.*) +windowrule = float on, match:class org.gnome.Calculator + +# No transparency on media windows +windowrule = opacity 1 1, match:class ^(vlc|mpv|imv|qview)$ + +# Prevent idle while media is open +windowrule = idle_inhibit always, match:tag noidle diff --git a/default/hypr/apps/terminals.conf b/default/hypr/apps/terminals.conf new file mode 100644 index 00000000..61bb0141 --- /dev/null +++ b/default/hypr/apps/terminals.conf @@ -0,0 +1,3 @@ +# Terminal window rules +windowrule = tag +terminal, match:class (Alacritty|kitty|com.mitchellh.ghostty) +windowrule = opacity 0.97 0.9, match:tag terminal diff --git a/default/hypr/bindings.conf b/default/hypr/bindings.conf index bfbf1229..5cfdde08 100644 --- a/default/hypr/bindings.conf +++ b/default/hypr/bindings.conf @@ -58,6 +58,8 @@ bind = $mainMod SHIFT, 0, movetoworkspace, 10 # Notifications bind = $mainMod Shift, N, exec, dunstctl history-pop +bind = $mainMod, COMMA, exec, dunstctl close +bind = $mainMod SHIFT, COMMA, exec, dunstctl close-all # Special workspace bind = $mainMod, S, togglespecialworkspace, magic @@ -67,9 +69,10 @@ bind = $mainMod SHIFT, S, movetoworkspace, special:magic bindm = $mainMod, mouse:272, movewindow bindm = $mainMod, mouse:273, resizewindow -# Screenshots -bind = $mainMod, PRINT, exec, hyprshot -m window -bind = , PRINT, exec, hyprshot -m region +# Screenshots & screen recording +bind = , PRINT, exec, kojarchy-cmd-screenshot region edit +bind = SHIFT, PRINT, exec, kojarchy-cmd-screenshot region clipboard +bind = $mainMod, PRINT, exec, kojarchy-cmd-screenrecord # Media keys bindel = ,XF86AudioRaiseVolume, exec, wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+ @@ -85,5 +88,14 @@ bindl = , XF86AudioPause, exec, playerctl play-pause bindl = , XF86AudioPlay, exec, playerctl play-pause bindl = , XF86AudioPrev, exec, playerctl previous +# Lock screen +bind = $mainMod CTRL, L, exec, kojarchy-lock-screen + +# Power menu +bind = $mainMod, ESCAPE, exec, gum choose "Lock" "Reboot" "Shutdown" "Cancel" | xargs -I{} sh -c 'case "{}" in Lock) kojarchy-lock-screen;; Reboot) kojarchy-cmd-reboot;; Shutdown) kojarchy-cmd-shutdown;; esac' + +# Keybindings viewer +bind = $mainMod, SLASH, exec, kojarchy-menu-keybindings + # hyprwhspr bindd = $mainMod SHIFT, D, Speech-to-text, exec, /usr/lib/hyprwhspr/config/hyprland/hyprwhspr-tray.sh record diff --git a/default/hypr/envs.conf b/default/hypr/envs.conf index 4b161917..2cd293ab 100644 --- a/default/hypr/envs.conf +++ b/default/hypr/envs.conf @@ -2,3 +2,6 @@ env = XCURSOR_SIZE,24 env = HYPRCURSOR_SIZE,24 env = QT_QPA_PLATFORMTHEME,qt6ct env = XDG_MENU_PREFIX,arch- + +# Firefox/Zen native Wayland +env = MOZ_ENABLE_WAYLAND,1 diff --git a/default/hypr/windows.conf b/default/hypr/windows.conf index 124f6f09..d4e5b787 100644 --- a/default/hypr/windows.conf +++ b/default/hypr/windows.conf @@ -13,3 +13,6 @@ windowrule = match:workspace w[t1], border_size 0 windowrule = match:class ^(org\.freedesktop\.impl\.portal\.desktop\.kde)$, float on windowrule = match:class ^(org\.freedesktop\.impl\.portal\.desktop\.kde)$, size 900 600 + +# App-specific rules +source = ~/dotfiles/default/hypr/apps.conf diff --git a/install/config/all.sh b/install/config/all.sh index 35248003..abe57772 100644 --- a/install/config/all.sh +++ b/install/config/all.sh @@ -15,3 +15,16 @@ run_logged $KOJARCHY_INSTALL/config/increase-sudo-tries.sh run_logged $KOJARCHY_INSTALL/config/increase-lockout-limit.sh run_logged $KOJARCHY_INSTALL/config/usb-autosuspend.sh run_logged $KOJARCHY_INSTALL/config/systemd-tweaks.sh +run_logged $KOJARCHY_INSTALL/config/default-keyring.sh +run_logged $KOJARCHY_INSTALL/config/firewall.sh +run_logged $KOJARCHY_INSTALL/config/dns-resolver.sh +run_logged $KOJARCHY_INSTALL/config/input-group.sh +run_logged $KOJARCHY_INSTALL/config/detect-keyboard-layout.sh +run_logged $KOJARCHY_INSTALL/config/hardware/network.sh +run_logged $KOJARCHY_INSTALL/config/hardware/bluetooth.sh +run_logged $KOJARCHY_INSTALL/config/hardware/intel.sh +run_logged $KOJARCHY_INSTALL/config/hardware/set-wireless-regdom.sh +run_logged $KOJARCHY_INSTALL/config/hardware/fix-fkeys.sh +run_logged $KOJARCHY_INSTALL/config/hardware/fix-synaptic-touchpad.sh +run_logged $KOJARCHY_INSTALL/config/hardware/powerprofiles.sh +run_logged $KOJARCHY_INSTALL/config/hidden-apps.sh diff --git a/install/config/default-keyring.sh b/install/config/default-keyring.sh new file mode 100644 index 00000000..38140e4b --- /dev/null +++ b/install/config/default-keyring.sh @@ -0,0 +1,25 @@ +# Create default GNOME keyring that doesn't prompt on login +KEYRING_DIR="$HOME/.local/share/keyrings" +KEYRING_FILE="$KEYRING_DIR/Default_keyring.keyring" +DEFAULT_FILE="$KEYRING_DIR/default" + +mkdir -p "$KEYRING_DIR" + +cat << EOF | tee "$KEYRING_FILE" +[keyring] +display-name=Default keyring +ctime=$(date +%s) +mtime=0 +lock-on-idle=false +lock-after=false +EOF + +cat << EOF | tee "$DEFAULT_FILE" +Default_keyring +EOF + +chmod 700 "$KEYRING_DIR" +chmod 600 "$KEYRING_FILE" +chmod 644 "$DEFAULT_FILE" + +echo "Default keyring: OK" diff --git a/install/config/detect-keyboard-layout.sh b/install/config/detect-keyboard-layout.sh new file mode 100644 index 00000000..28a83d74 --- /dev/null +++ b/install/config/detect-keyboard-layout.sh @@ -0,0 +1,20 @@ +# Copy keyboard layout from /etc/vconsole.conf (set during archinstall) to Hyprland +conf="/etc/vconsole.conf" +hyprconf="$HOME/.config/hypr/input.conf" + +if [[ ! -f "$conf" ]] || [[ ! -f "$hyprconf" ]]; then + echo "Keyboard layout detection: skipped (missing files)" + exit 0 +fi + +if grep -q '^XKBLAYOUT=' "$conf"; then + layout=$(grep '^XKBLAYOUT=' "$conf" | cut -d= -f2 | tr -d '"') + sed -i "/^[[:space:]]*kb_options *=/i\ kb_layout = $layout" "$hyprconf" +fi + +if grep -q '^XKBVARIANT=' "$conf"; then + variant=$(grep '^XKBVARIANT=' "$conf" | cut -d= -f2 | tr -d '"') + sed -i "/^[[:space:]]*kb_options *=/i\ kb_variant = $variant" "$hyprconf" +fi + +echo "Keyboard layout detection: OK" diff --git a/install/config/dns-resolver.sh b/install/config/dns-resolver.sh new file mode 100644 index 00000000..67d1787d --- /dev/null +++ b/install/config/dns-resolver.sh @@ -0,0 +1,10 @@ +# Symlink systemd-resolved stub to /etc/resolv.conf +# This ensures DNS works reliably with NetworkManager + systemd-resolved +sudo systemctl enable --now systemd-resolved.service 2>/dev/null || true + +if [[ -L /etc/resolv.conf ]]; then + echo "DNS resolver: already symlinked" +else + sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf + echo "DNS resolver: OK" +fi diff --git a/install/config/firewall.sh b/install/config/firewall.sh new file mode 100644 index 00000000..884c2041 --- /dev/null +++ b/install/config/firewall.sh @@ -0,0 +1,15 @@ +# Configure UFW firewall +sudo ufw default deny incoming +sudo ufw default allow outgoing + +# Allow LocalSend file sharing +sudo ufw allow 53317/tcp comment 'LocalSend' +sudo ufw allow 53317/udp comment 'LocalSend' + +# Allow Docker DNS +sudo ufw allow in on docker0 to any port 53 proto udp comment 'Docker DNS' + +sudo ufw --force enable +sudo systemctl enable --now ufw.service + +echo "Firewall: OK" diff --git a/install/config/hardware/bluetooth.sh b/install/config/hardware/bluetooth.sh new file mode 100644 index 00000000..71a63760 --- /dev/null +++ b/install/config/hardware/bluetooth.sh @@ -0,0 +1,4 @@ +# Turn on bluetooth by default +sudo systemctl enable bluetooth.service 2>/dev/null || true + +echo "Bluetooth: OK" diff --git a/install/config/hardware/fix-fkeys.sh b/install/config/hardware/fix-fkeys.sh new file mode 100644 index 00000000..5584c1bd --- /dev/null +++ b/install/config/hardware/fix-fkeys.sh @@ -0,0 +1,6 @@ +# Ensure F-keys on Apple-like keyboards (such as Lofree Flow84) are always F-keys +if [[ ! -f /etc/modprobe.d/hid_apple.conf ]]; then + echo "options hid_apple fnmode=2" | sudo tee /etc/modprobe.d/hid_apple.conf +fi + +echo "F-keys fix: OK" diff --git a/install/config/hardware/fix-synaptic-touchpad.sh b/install/config/hardware/fix-synaptic-touchpad.sh new file mode 100644 index 00000000..64e691fb --- /dev/null +++ b/install/config/hardware/fix-synaptic-touchpad.sh @@ -0,0 +1,7 @@ +# Enable Synaptics InterTouch for confirmed touchpads +if grep -qi synaptics /proc/bus/input/devices 2>/dev/null \ + && ! lsmod | grep -q '^psmouse'; then + modprobe psmouse synaptics_intertouch=1 2>/dev/null || true +fi + +echo "Synaptics touchpad: OK" diff --git a/install/config/hardware/intel.sh b/install/config/hardware/intel.sh new file mode 100644 index 00000000..46730859 --- /dev/null +++ b/install/config/hardware/intel.sh @@ -0,0 +1,11 @@ +# Install hardware video acceleration for Intel GPUs +if INTEL_GPU=$(lspci | grep -iE 'vga|3d|display' | grep -i 'intel'); then + if [[ "${INTEL_GPU,,}" =~ "hd graphics"|"xe"|"iris" ]]; then + sudo pacman -S --needed --noconfirm intel-media-driver + elif [[ "${INTEL_GPU,,}" =~ "gma" ]]; then + sudo pacman -S --needed --noconfirm libva-intel-driver + fi + echo "Intel GPU acceleration: OK" +else + echo "No Intel GPU detected, skipping" +fi diff --git a/install/config/hardware/network.sh b/install/config/hardware/network.sh new file mode 100644 index 00000000..af1cb419 --- /dev/null +++ b/install/config/hardware/network.sh @@ -0,0 +1,8 @@ +# Ensure iwd service will be started +sudo systemctl enable iwd.service 2>/dev/null || true + +# Prevent systemd-networkd-wait-online timeout on boot +sudo systemctl disable systemd-networkd-wait-online.service 2>/dev/null || true +sudo systemctl mask systemd-networkd-wait-online.service 2>/dev/null || true + +echo "Network config: OK" diff --git a/install/config/hardware/powerprofiles.sh b/install/config/hardware/powerprofiles.sh new file mode 100644 index 00000000..30f5db37 --- /dev/null +++ b/install/config/hardware/powerprofiles.sh @@ -0,0 +1,26 @@ +# Auto-switch power profiles on AC/battery via udev rules +# Only applies if a battery is present and powerprofilesctl is available + +if command -v powerprofilesctl &>/dev/null && [ -d /sys/class/power_supply/BAT0 ]; then + mapfile -t profiles < <(kojarchy-powerprofiles-list) + + if [[ ${#profiles[@]} -gt 1 ]]; then + # Default AC profile: performance if 3 profiles, balanced if 2 + ac_profile="${profiles[2]:-${profiles[1]}}" + # Default Battery profile: balanced + battery_profile="${profiles[1]}" + + cat </dev/null + if command -v iw &>/dev/null; then + sudo iw reg set ${COUNTRY} + fi + echo "Wireless regulatory domain set to: $COUNTRY" + fi + fi +else + echo "Wireless regulatory domain already set: $WIRELESS_REGDOM" +fi diff --git a/install/config/hidden-apps.sh b/install/config/hidden-apps.sh new file mode 100644 index 00000000..c3064ee1 --- /dev/null +++ b/install/config/hidden-apps.sh @@ -0,0 +1,8 @@ +# Deploy hidden .desktop files to suppress unwanted app launcher entries +APPS_DIR="$HOME/.local/share/applications" +mkdir -p "$APPS_DIR" + +cp "$KOJARCHY_DIR/applications/hidden/"*.desktop "$APPS_DIR/" 2>/dev/null || true +update-desktop-database "$APPS_DIR" 2>/dev/null || true + +echo "Hidden desktop entries: OK" diff --git a/install/config/input-group.sh b/install/config/input-group.sh new file mode 100644 index 00000000..79af4ac0 --- /dev/null +++ b/install/config/input-group.sh @@ -0,0 +1,4 @@ +# Give user privileged input access for game controllers, dictation tools, etc. +sudo usermod -aG input ${USER} + +echo "Input group: OK" diff --git a/install/post-install/all.sh b/install/post-install/all.sh index 118259c2..4e9c9af5 100644 --- a/install/post-install/all.sh +++ b/install/post-install/all.sh @@ -1 +1,2 @@ +run_logged $KOJARCHY_INSTALL/post-install/reenable-mkinitcpio.sh run_logged $KOJARCHY_INSTALL/post-install/finished.sh diff --git a/install/post-install/reenable-mkinitcpio.sh b/install/post-install/reenable-mkinitcpio.sh new file mode 100644 index 00000000..0badf1d7 --- /dev/null +++ b/install/post-install/reenable-mkinitcpio.sh @@ -0,0 +1,15 @@ +# Re-enable mkinitcpio hooks and run once +echo "Re-enabling mkinitcpio hooks..." + +if [ -f /usr/share/libalpm/hooks/90-mkinitcpio-install.hook.disabled ]; then + sudo mv /usr/share/libalpm/hooks/90-mkinitcpio-install.hook.disabled /usr/share/libalpm/hooks/90-mkinitcpio-install.hook +fi + +if [ -f /usr/share/libalpm/hooks/60-mkinitcpio-remove.hook.disabled ]; then + sudo mv /usr/share/libalpm/hooks/60-mkinitcpio-remove.hook.disabled /usr/share/libalpm/hooks/60-mkinitcpio-remove.hook +fi + +# Run mkinitcpio once for all installed kernels +sudo mkinitcpio -P + +echo "mkinitcpio: OK" diff --git a/install/preflight/all.sh b/install/preflight/all.sh index 88393b84..91c76bd9 100644 --- a/install/preflight/all.sh +++ b/install/preflight/all.sh @@ -1,2 +1,3 @@ source $KOJARCHY_INSTALL/preflight/guard.sh source $KOJARCHY_INSTALL/preflight/begin.sh +run_logged $KOJARCHY_INSTALL/preflight/disable-mkinitcpio.sh diff --git a/install/preflight/disable-mkinitcpio.sh b/install/preflight/disable-mkinitcpio.sh new file mode 100644 index 00000000..0280575f --- /dev/null +++ b/install/preflight/disable-mkinitcpio.sh @@ -0,0 +1,14 @@ +# Temporarily disable mkinitcpio hooks to prevent multiple regenerations during package install +# This speeds up installation significantly — re-enabled in post-install + +echo "Temporarily disabling mkinitcpio hooks during installation..." + +if [ -f /usr/share/libalpm/hooks/90-mkinitcpio-install.hook ]; then + sudo mv /usr/share/libalpm/hooks/90-mkinitcpio-install.hook /usr/share/libalpm/hooks/90-mkinitcpio-install.hook.disabled +fi + +if [ -f /usr/share/libalpm/hooks/60-mkinitcpio-remove.hook ]; then + sudo mv /usr/share/libalpm/hooks/60-mkinitcpio-remove.hook /usr/share/libalpm/hooks/60-mkinitcpio-remove.hook.disabled +fi + +echo "mkinitcpio hooks disabled: OK" diff --git a/update.sh b/update.sh deleted file mode 100755 index 2c399320..00000000 --- a/update.sh +++ /dev/null @@ -1,84 +0,0 @@ -#!/bin/bash -set -euo pipefail - -KOJARCHY_DIR="$HOME/dotfiles" - -if [[ ! -d "$KOJARCHY_DIR/.git" ]]; then - echo "Error: $KOJARCHY_DIR is not a git repo. Run the installer first." - exit 1 -fi - -if ! command -v gum &>/dev/null; then - sudo pacman -S --needed --noconfirm gum -fi - -echo "Pulling latest changes..." -git -C "$KOJARCHY_DIR" pull - -ACTIONS=$(gum choose --no-limit --header "What do you want to update?" \ - "Packages (install new/missing packages from package lists)" \ - "Configs (re-deploy config/ to ~/.config/ — overwrites local changes)" \ - "Bin scripts (re-link bin/ to ~/.local/custom/bin/)" \ - "Shell (re-deploy ~/.zshrc from default/zshrc)" \ - "SDDM theme (re-copy sddm/macos/ to system theme dir)" \ - "Cargo packages (install missing cargo tools)" \ - "Neovim plugins (sync lazy.nvim)" \ - "Everything") - -if echo "$ACTIONS" | grep -q "Everything"; then - ACTIONS="Packages -Configs -Bin scripts -Shell -SDDM theme -Cargo packages -Neovim plugins" -fi - -while IFS= read -r action; do - case "$action" in - "Packages"*) - echo "Installing packages..." - mapfile -t packages < <(grep -v '^#' "$KOJARCHY_DIR/install/kojarchy-base.packages" | grep -v '^$') - yay -S --noconfirm --needed "${packages[@]}" - echo "Packages: OK" - ;; - "Configs"*) - echo "Deploying configs to ~/.config/..." - cp -R "$KOJARCHY_DIR/config/"* ~/.config/ - echo "Configs: OK" - ;; - "Bin scripts"*) - echo "Linking bin scripts..." - mkdir -p ~/.local/custom/bin - for script in "$KOJARCHY_DIR"/bin/*; do - ln -sf "$script" "$HOME/.local/custom/bin/$(basename "$script")" - done - echo "Bin scripts: OK" - ;; - "Shell"*) - echo "Deploying ~/.zshrc..." - cp "$KOJARCHY_DIR/default/zshrc" ~/.zshrc - echo "Shell: OK (restart your shell or run: source ~/.zshrc)" - ;; - "SDDM theme"*) - echo "Deploying SDDM theme..." - sudo cp -R "$KOJARCHY_DIR/sddm/macos/"* /usr/share/sddm/themes/macos/ - echo "SDDM: OK" - ;; - "Cargo packages"*) - echo "Installing cargo packages..." - source "$KOJARCHY_DIR/lib/packages.sh" - install_cargo_packages "$KOJARCHY_DIR/install/kojarchy-cargo.packages" - echo "Cargo: OK" - ;; - "Neovim plugins"*) - echo "Syncing neovim plugins..." - nvim --headless "+Lazy! sync" +qa 2>/dev/null || true - echo "Neovim: OK" - ;; - esac -done <<< "$ACTIONS" - -echo "" -echo "Update complete!" diff --git a/version b/version new file mode 100644 index 00000000..3eefcb9d --- /dev/null +++ b/version @@ -0,0 +1 @@ +1.0.0 From 7f66d4a45e7cf164f496bc39123cacebcee07ff3 Mon Sep 17 00:00:00 2001 From: princejoogie Date: Tue, 10 Feb 2026 17:44:09 +0800 Subject: [PATCH 18/44] feat: consolidate dmenu scripts into bin/ with kojarchy- prefix and add unified gum menu --- bin/kojarchy-calculator | 4 ++ .../scripts/camera => bin/kojarchy-camera | 6 +- .../kill-port => bin/kojarchy-kill-port | 4 +- .../kill-process => bin/kojarchy-kill-process | 4 +- bin/kojarchy-menu | 62 +++++++++++++++++++ .../open-file => bin/kojarchy-open-file | 4 +- bin/kojarchy-power-menu | 12 ++++ .../kojarchy-toggle-focusmode | 4 +- .../kojarchy-toggle-nightlight | 4 +- .../toggle-rgb => bin/kojarchy-toggle-rgb | 5 +- .../kojarchy-toggle-waybar | 4 +- config/wofi/dmenu/launcher.sh | 10 +-- config/wofi/dmenu/scripts/calculator | 3 - config/wofi/dmenu/scripts/close-all | 5 -- config/wofi/dmenu/scripts/reboot | 5 -- config/wofi/dmenu/scripts/shutdown | 5 -- default/hypr/bindings.conf | 9 ++- default/hypr/windows.conf | 9 +++ 18 files changed, 124 insertions(+), 35 deletions(-) create mode 100755 bin/kojarchy-calculator rename config/wofi/dmenu/scripts/camera => bin/kojarchy-camera (93%) rename config/wofi/dmenu/scripts/kill-port => bin/kojarchy-kill-port (95%) rename config/wofi/dmenu/scripts/kill-process => bin/kojarchy-kill-process (95%) create mode 100755 bin/kojarchy-menu rename config/wofi/dmenu/scripts/open-file => bin/kojarchy-open-file (93%) create mode 100755 bin/kojarchy-power-menu rename config/wofi/dmenu/scripts/toggle-black => bin/kojarchy-toggle-focusmode (94%) rename config/wofi/dmenu/scripts/toggle-hyprsunset => bin/kojarchy-toggle-nightlight (78%) rename config/wofi/dmenu/scripts/toggle-rgb => bin/kojarchy-toggle-rgb (83%) rename config/wofi/dmenu/scripts/toggle-waybar => bin/kojarchy-toggle-waybar (93%) delete mode 100755 config/wofi/dmenu/scripts/calculator delete mode 100755 config/wofi/dmenu/scripts/close-all delete mode 100755 config/wofi/dmenu/scripts/reboot delete mode 100755 config/wofi/dmenu/scripts/shutdown diff --git a/bin/kojarchy-calculator b/bin/kojarchy-calculator new file mode 100755 index 00000000..d83ff414 --- /dev/null +++ b/bin/kojarchy-calculator @@ -0,0 +1,4 @@ +#!/bin/bash + +# Launch wofi calculator +wofi-calc diff --git a/config/wofi/dmenu/scripts/camera b/bin/kojarchy-camera similarity index 93% rename from config/wofi/dmenu/scripts/camera rename to bin/kojarchy-camera index 04b29f6a..58f55054 100755 --- a/config/wofi/dmenu/scripts/camera +++ b/bin/kojarchy-camera @@ -1,4 +1,6 @@ -#!/usr/bin/env bash +#!/bin/bash + +# Open camera feed or show which app is using it device=$(v4l2-ctl --list-devices | grep -E '/dev/video[0-9]+' | head -n1 | xargs) @@ -22,7 +24,7 @@ if [ -n "$pids" ]; then fi fi done - + if [ -n "$apps" ]; then notify-send "Camera" "Camera is in use by:\n$apps" exit 1 diff --git a/config/wofi/dmenu/scripts/kill-port b/bin/kojarchy-kill-port similarity index 95% rename from config/wofi/dmenu/scripts/kill-port rename to bin/kojarchy-kill-port index 550f9bbc..10d392c1 100755 --- a/config/wofi/dmenu/scripts/kill-port +++ b/bin/kojarchy-kill-port @@ -1,4 +1,6 @@ -#!/usr/bin/env bash +#!/bin/bash + +# Kill a process listening on a port selected via wofi dmenu set -euo pipefail diff --git a/config/wofi/dmenu/scripts/kill-process b/bin/kojarchy-kill-process similarity index 95% rename from config/wofi/dmenu/scripts/kill-process rename to bin/kojarchy-kill-process index 0b214d28..6357e74e 100755 --- a/config/wofi/dmenu/scripts/kill-process +++ b/bin/kojarchy-kill-process @@ -1,4 +1,6 @@ -#!/usr/bin/env bash +#!/bin/bash + +# Kill a running process selected via wofi dmenu set -euo pipefail diff --git a/bin/kojarchy-menu b/bin/kojarchy-menu new file mode 100755 index 00000000..1ebf7eba --- /dev/null +++ b/bin/kojarchy-menu @@ -0,0 +1,62 @@ +#!/bin/bash + +# Kojarchy menu — unified launcher for all commands and scripts. +# Bound to ALT+SHIFT+SPACE. Runs in a floating terminal via gum. + +choice=$(gum choose \ + "Screenshot" \ + "Screenshot (clipboard)" \ + "Screen record" \ + "Color picker" \ + "Lock screen" \ + "Kill process" \ + "Kill port" \ + "Open file" \ + "Calculator" \ + "Camera" \ + "Toggle waybar" \ + "Toggle nightlight" \ + "Toggle focus mode" \ + "Toggle RGB" \ + "Audio switch" \ + "Keybindings" \ + "Font set" \ + "Package install" \ + "Package remove" \ + "Update system" \ + "Refresh hyprland" \ + "Refresh waybar" \ + "Debug info" \ + "Close all windows" \ + "Reboot" \ + "Shutdown" \ +) + +case "$choice" in + "Screenshot") kojarchy-cmd-screenshot region edit ;; + "Screenshot (clipboard)") kojarchy-cmd-screenshot region clipboard ;; + "Screen record") kojarchy-cmd-screenrecord ;; + "Color picker") hyprpicker | { read color; trimmed=$(printf "%s" "$color"); printf "%s" "$trimmed" | wl-copy; notify-send "Copied $color to clipboard"; } ;; + "Lock screen") kojarchy-lock-screen ;; + "Kill process") kojarchy-kill-process ;; + "Kill port") kojarchy-kill-port ;; + "Open file") kojarchy-open-file ;; + "Calculator") kojarchy-calculator ;; + "Camera") kojarchy-camera ;; + "Toggle waybar") kojarchy-toggle-waybar ;; + "Toggle nightlight") kojarchy-toggle-nightlight ;; + "Toggle focus mode") kojarchy-toggle-focusmode ;; + "Toggle RGB") kojarchy-toggle-rgb ;; + "Audio switch") kojarchy-cmd-audio-switch ;; + "Keybindings") kojarchy-menu-keybindings ;; + "Font set") font=$(kojarchy-font-list | gum filter --placeholder "Pick a font...") && kojarchy-font-set "$font" ;; + "Package install") kojarchy-pkg-install ;; + "Package remove") kojarchy-pkg-remove ;; + "Update system") kojarchy-update ;; + "Refresh hyprland") kojarchy-refresh-hyprland ;; + "Refresh waybar") kojarchy-refresh-waybar ;; + "Debug info") kojarchy-debug ;; + "Close all windows") kojarchy-hyprland-window-close-all ;; + "Reboot") kojarchy-cmd-reboot ;; + "Shutdown") kojarchy-cmd-shutdown ;; +esac diff --git a/config/wofi/dmenu/scripts/open-file b/bin/kojarchy-open-file similarity index 93% rename from config/wofi/dmenu/scripts/open-file rename to bin/kojarchy-open-file index 6b26cd6a..8299096c 100755 --- a/config/wofi/dmenu/scripts/open-file +++ b/bin/kojarchy-open-file @@ -1,4 +1,6 @@ -#!/usr/bin/env bash +#!/bin/bash + +# Browse and open a file via wofi dmenu root_path="$HOME" diff --git a/bin/kojarchy-power-menu b/bin/kojarchy-power-menu new file mode 100755 index 00000000..35b74524 --- /dev/null +++ b/bin/kojarchy-power-menu @@ -0,0 +1,12 @@ +#!/bin/bash + +# Power menu — lock, reboot, or shutdown via gum. +# Launched in a floating terminal from the keybinding. + +choice=$(gum choose "Lock" "Reboot" "Shutdown" "Cancel") + +case "$choice" in + "Lock") kojarchy-lock-screen ;; + "Reboot") kojarchy-cmd-reboot ;; + "Shutdown") kojarchy-cmd-shutdown ;; +esac diff --git a/config/wofi/dmenu/scripts/toggle-black b/bin/kojarchy-toggle-focusmode similarity index 94% rename from config/wofi/dmenu/scripts/toggle-black rename to bin/kojarchy-toggle-focusmode index 8d3e1ce3..c4491ee5 100755 --- a/config/wofi/dmenu/scripts/toggle-black +++ b/bin/kojarchy-toggle-focusmode @@ -1,4 +1,6 @@ -#!/usr/bin/env bash +#!/bin/bash + +# Toggle focus mode: black wallpaper, hide waybar, move to workspace 10, hide cursor set -euo pipefail diff --git a/config/wofi/dmenu/scripts/toggle-hyprsunset b/bin/kojarchy-toggle-nightlight similarity index 78% rename from config/wofi/dmenu/scripts/toggle-hyprsunset rename to bin/kojarchy-toggle-nightlight index 330d15f0..09ef7b0e 100755 --- a/config/wofi/dmenu/scripts/toggle-hyprsunset +++ b/bin/kojarchy-toggle-nightlight @@ -1,4 +1,6 @@ -#!/usr/bin/env bash +#!/bin/bash + +# Toggle hyprsunset nightlight filter if pgrep -x hyprsunset > /dev/null; then pkill -x hyprsunset diff --git a/config/wofi/dmenu/scripts/toggle-rgb b/bin/kojarchy-toggle-rgb similarity index 83% rename from config/wofi/dmenu/scripts/toggle-rgb rename to bin/kojarchy-toggle-rgb index 64fabd10..a7a591cb 100755 --- a/config/wofi/dmenu/scripts/toggle-rgb +++ b/bin/kojarchy-toggle-rgb @@ -1,4 +1,6 @@ -#!/usr/bin/env bash +#!/bin/bash + +# Toggle RGB lights between green and off via OpenRGB STATE_FILE="$HOME/.rgb_state" @@ -11,4 +13,3 @@ else echo "white" > "$STATE_FILE" notify-send "RGB lights set to white" fi - diff --git a/config/wofi/dmenu/scripts/toggle-waybar b/bin/kojarchy-toggle-waybar similarity index 93% rename from config/wofi/dmenu/scripts/toggle-waybar rename to bin/kojarchy-toggle-waybar index 16b0ce2f..abc3dbd1 100755 --- a/config/wofi/dmenu/scripts/toggle-waybar +++ b/bin/kojarchy-toggle-waybar @@ -1,4 +1,6 @@ -#!/usr/bin/env bash +#!/bin/bash + +# Toggle waybar visibility and adjust gaps/rounding accordingly WAYBAR_PID=$(pgrep -x waybar) GAPS_STATE_FILE="${XDG_CACHE_HOME:-$HOME/.cache}/waybar-gaps" diff --git a/config/wofi/dmenu/launcher.sh b/config/wofi/dmenu/launcher.sh index 9c10a3d3..8bf1da63 100755 --- a/config/wofi/dmenu/launcher.sh +++ b/config/wofi/dmenu/launcher.sh @@ -1,15 +1,17 @@ #!/bin/bash -SCRIPT_DIR="$HOME/.config/wofi/dmenu/scripts" -SCRIPTS=$(ls "$SCRIPT_DIR") +# Wofi dmenu launcher — lists all kojarchy commands, with web search fallback. +# Bound to ALT+CTRL+SPACE. -selected=$(printf "%s\n" "$SCRIPTS" | wofi --dmenu -p "Run script or Search web" --matching fuzzy) +SCRIPTS=$(compgen -c kojarchy- | sort -u) + +selected=$(printf "%s\n" "$SCRIPTS" | wofi --dmenu -p "Run command or search web" --matching fuzzy) # Exit if user presses Escape (no input at all) [ -z "$selected" ] && exit if printf "%s\n" "$SCRIPTS" | grep -Fxq "$selected"; then - exec "$SCRIPT_DIR/$selected" + exec "$selected" else printf "%s" "$selected" | jq -sRr @uri | xargs -r -I{} xdg-open "https://www.google.com/search?q={}" fi diff --git a/config/wofi/dmenu/scripts/calculator b/config/wofi/dmenu/scripts/calculator deleted file mode 100755 index 384a4e9d..00000000 --- a/config/wofi/dmenu/scripts/calculator +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash - -wofi-calc diff --git a/config/wofi/dmenu/scripts/close-all b/config/wofi/dmenu/scripts/close-all deleted file mode 100755 index 03d449db..00000000 --- a/config/wofi/dmenu/scripts/close-all +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -for pid in $(hyprctl --instance 0 clients -j | jq -r '.[] | .pid'); do - kill -9 "$pid" -done diff --git a/config/wofi/dmenu/scripts/reboot b/config/wofi/dmenu/scripts/reboot deleted file mode 100755 index d3fc2a7c..00000000 --- a/config/wofi/dmenu/scripts/reboot +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -systemctl reboot diff --git a/config/wofi/dmenu/scripts/shutdown b/config/wofi/dmenu/scripts/shutdown deleted file mode 100755 index ca2769d8..00000000 --- a/config/wofi/dmenu/scripts/shutdown +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -systemctl poweroff diff --git a/default/hypr/bindings.conf b/default/hypr/bindings.conf index 5cfdde08..f6e89ee9 100644 --- a/default/hypr/bindings.conf +++ b/default/hypr/bindings.conf @@ -6,7 +6,7 @@ bind = $mainMod, Q, killactive, bind = $mainMod, F, fullscreen, bind = $mainMod, M, exit, bind = $mainMod, E, exec, $fileManager -bind = $mainMod, W, exec, ~/.config/wofi/dmenu/scripts/toggle-waybar +bind = $mainMod, W, exec, kojarchy-toggle-waybar bind = $mainMod, V, togglefloating, bind = $mainMod, SPACE, exec, $menu bind = $mainMod CTRL, SPACE, exec, ~/.config/wofi/dmenu/launcher.sh @@ -91,8 +91,11 @@ bindl = , XF86AudioPrev, exec, playerctl previous # Lock screen bind = $mainMod CTRL, L, exec, kojarchy-lock-screen -# Power menu -bind = $mainMod, ESCAPE, exec, gum choose "Lock" "Reboot" "Shutdown" "Cancel" | xargs -I{} sh -c 'case "{}" in Lock) kojarchy-lock-screen;; Reboot) kojarchy-cmd-reboot;; Shutdown) kojarchy-cmd-shutdown;; esac' +# Power menu (floating terminal for gum) +bind = $mainMod, ESCAPE, exec, kitty --class kojarchy-power-menu -e kojarchy-power-menu + +# Kojarchy menu (unified launcher) +bind = $mainMod SHIFT, SPACE, exec, kitty --class kojarchy-menu -e kojarchy-menu # Keybindings viewer bind = $mainMod, SLASH, exec, kojarchy-menu-keybindings diff --git a/default/hypr/windows.conf b/default/hypr/windows.conf index d4e5b787..98f4c053 100644 --- a/default/hypr/windows.conf +++ b/default/hypr/windows.conf @@ -14,5 +14,14 @@ windowrule = match:workspace w[t1], border_size 0 windowrule = match:class ^(org\.freedesktop\.impl\.portal\.desktop\.kde)$, float on windowrule = match:class ^(org\.freedesktop\.impl\.portal\.desktop\.kde)$, size 900 600 +# Kojarchy floating menus +windowrule = float on, match:class ^(kojarchy-menu)$ +windowrule = size 400 600, match:class ^(kojarchy-menu)$ +windowrule = center on, match:class ^(kojarchy-menu)$ + +windowrule = float on, match:class ^(kojarchy-power-menu)$ +windowrule = size 300 250, match:class ^(kojarchy-power-menu)$ +windowrule = center on, match:class ^(kojarchy-power-menu)$ + # App-specific rules source = ~/dotfiles/default/hypr/apps.conf From 6ab484c1e6396d398e8d2adc6e601d0861af3f68 Mon Sep 17 00:00:00 2001 From: princejoogie Date: Tue, 10 Feb 2026 17:47:01 +0800 Subject: [PATCH 19/44] fix: replace blender-bin and telegram-desktop-bin with official repo packages --- install/kojarchy-optional.packages | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/kojarchy-optional.packages b/install/kojarchy-optional.packages index e0ff87cf..722310f2 100644 --- a/install/kojarchy-optional.packages +++ b/install/kojarchy-optional.packages @@ -14,14 +14,14 @@ discord vesktop legcord slack-desktop -telegram-desktop-bin +telegram-desktop # === Productivity === notion-calendar-electron obs-studio obs-backgroundremoval audacity -blender-bin +blender # === Video Calling === zoom From 98c4dc964f1c225d8065482e50199c9fb1ecdc5c Mon Sep 17 00:00:00 2001 From: princejoogie Date: Tue, 10 Feb 2026 17:48:52 +0800 Subject: [PATCH 20/44] fix: drop adwaita-qt5 and adwaita-qt6, kvantum handles Qt theming --- install/kojarchy-base.packages | 2 -- 1 file changed, 2 deletions(-) diff --git a/install/kojarchy-base.packages b/install/kojarchy-base.packages index 8706f40b..84ec6b42 100644 --- a/install/kojarchy-base.packages +++ b/install/kojarchy-base.packages @@ -117,8 +117,6 @@ qt6-wayland qt5-quickcontrols2 kvantum-qt5 kvantum -adwaita-qt5 -adwaita-qt6 nwg-look breeze sassc From e798587c11f0417ade8063bc72608ef3b7fc9f6d Mon Sep 17 00:00:00 2001 From: princejoogie Date: Tue, 10 Feb 2026 18:03:55 +0800 Subject: [PATCH 21/44] docs: add archinstall guide, update README with new menu and utility commands --- README.md | 45 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6ed15ead..0a100a16 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,29 @@ Personal Hyprland desktop environment for Arch Linux, automated from a fresh `ar ![demo_2](.github/assets/demo_2.png) ![demo_3](.github/assets/demo_3.png) +## Arch Linux Installation + +Boot from the Arch ISO and run `archinstall`. Configure these settings (leave anything not mentioned as-is): + +| Section | Option | +|:--------|:-------| +| Mirrors and repositories | Select regions > Your country | +| Disk configuration | Partitioning > Default partitioning layout > Select disk (with space + return) | +| Disk > File system | btrfs (default structure: yes + use compression) | +| Disk > Disk encryption | Encryption type: LUKS + Encryption password + Partitions (select the one) | +| Hostname | Give your computer a name | +| Bootloader | Limine | +| Authentication > Root password | Set yours | +| Authentication > User account | Add a user > Superuser: Yes > Confirm and exit | +| Applications > Audio | pipewire | +| Network configuration | Copy ISO network config | +| Timezone | Set yours | + +Once done, let `archinstall` finish and reboot into your new system. + ## Install -After a fresh Arch Linux install via `archinstall`, reboot and run: +After rebooting into your fresh Arch Linux install, run: ```bash curl -fsSL https://raw.githubusercontent.com/princejoogie/dotfiles/refs/heads/main/boot.sh | bash @@ -79,6 +99,8 @@ The installer handles everything: packages, configs, services, shell setup, and │ ├── gpg/ # GPG keyserver config (multiple fallbacks) │ └── systemd/ # Faster shutdown timeout ├── bin/ # CLI utilities -> ~/.local/custom/bin/ +│ ├── kojarchy-menu # Unified gum-based launcher (ALT+SHIFT+SPACE) +│ ├── kojarchy-power-menu # Power menu (lock/reboot/shutdown) │ ├── kojarchy-update # Update system (git pull + packages + migrations) │ ├── kojarchy-migrate # Run pending migrations │ ├── kojarchy-pkg-* # Package management helpers (add, drop, install TUI) @@ -86,7 +108,12 @@ The installer handles everything: packages, configs, services, shell setup, and │ ├── kojarchy-restart-* # Restart individual services (waybar, pipewire, bluetooth, etc.) │ ├── kojarchy-refresh-* # Reset individual configs to defaults │ ├── kojarchy-font-* # Font management (set, list, current) -│ ├── kojarchy-lock-screen # Lock screen via hyprlock +│ ├── kojarchy-toggle-* # Toggles (waybar, nightlight, focusmode, RGB) +│ ├── kojarchy-kill-* # Kill process or port (via wofi) +│ ├── kojarchy-open-file # Browse and open files (via wofi) +│ ├── kojarchy-calculator # Wofi calculator +│ ├── kojarchy-camera # Camera viewer +│ ├── kojarchy-lock-screen # Lock screen via hyprlock │ ├── kojarchy-debug # System debug info dump │ ├── kojarchy-version # Show version, branch, last package update │ ├── kojarchy-hook # Run user hooks @@ -206,7 +233,8 @@ All bindings use `ALT` as the main modifier. Press `ALT + /` to search all keybi |:--------|:-------| | `ALT + Return` | Open terminal | | `ALT + Space` | App launcher (wofi drun) | -| `ALT + CTRL + Space` | Dmenu scripts launcher | +| `ALT + SHIFT + Space` | Kojarchy menu (unified launcher) | +| `ALT + CTRL + Space` | Wofi command launcher | | `ALT + Q` | Kill active window | | `ALT + F` | Fullscreen | | `ALT + V` | Toggle floating | @@ -234,6 +262,8 @@ All bindings use `ALT` as the main modifier. Press `ALT + /` to search all keybi | Command | Description | |:--------|:------------| +| `kojarchy-menu` | Unified gum-based launcher for all commands | +| `kojarchy-power-menu` | Power menu (lock/reboot/shutdown) | | `kojarchy-update` | Full system update | | `kojarchy-version` | Show version | | `kojarchy-debug` | System debug info dump | @@ -246,6 +276,15 @@ All bindings use `ALT` as the main modifier. Press `ALT + /` to search all keybi | `kojarchy-font-set` | Change system monospace font | | `kojarchy-menu-keybindings` | Interactive keybinding search | | `kojarchy-pkg-install` | TUI package browser | +| `kojarchy-toggle-waybar` | Toggle waybar with gaps/rounding | +| `kojarchy-toggle-nightlight` | Toggle hyprsunset nightlight | +| `kojarchy-toggle-focusmode` | Focus mode (black wallpaper, hide UI) | +| `kojarchy-toggle-rgb` | Toggle RGB lights via OpenRGB | +| `kojarchy-kill-process` | Kill a process (via wofi) | +| `kojarchy-kill-port` | Kill a process by port (via wofi) | +| `kojarchy-open-file` | Browse and open files (via wofi) | +| `kojarchy-calculator` | Wofi calculator | +| `kojarchy-camera` | Camera viewer | ## Optional Packages From 7f31cc2f19eb115bc30d3c593db28aa7e963a450 Mon Sep 17 00:00:00 2001 From: princejoogie Date: Tue, 10 Feb 2026 18:28:29 +0800 Subject: [PATCH 22/44] fix: resolve logging/error handling drifts from omarchy audit - git.sh: source directly instead of run_logged (gum input was invisible) - systemd.sh: remove duplicate firewall and bluetooth enable - errors.sh: add GitHub issues support link on install failure - packages.sh: remove dead install_packages/install_aur_packages code - logging.sh: remove unnecessary packages.sh source from run_logged - cargo.sh: source packages.sh directly for install_cargo_packages - cmd-reboot/cmd-shutdown: add state clear + nohup pattern from omarchy - pkg-remove: use yay instead of pacman to include AUR packages - update-perform: add idle prevention during updates - update: add GitHub issues link to error trap - finished.sh: improve reboot prompt and add log line --- bin/kojarchy-cmd-reboot | 8 +++++++- bin/kojarchy-cmd-shutdown | 8 +++++++- bin/kojarchy-pkg-remove | 4 ++-- bin/kojarchy-update | 2 +- bin/kojarchy-update-perform | 6 ++++++ install/config/all.sh | 2 +- install/config/cargo.sh | 2 ++ install/config/git.sh | 4 ++-- install/post-install/finished.sh | 3 ++- install/services/systemd.sh | 8 ++------ lib/errors.sh | 10 +++++++++- lib/logging.sh | 3 --- lib/packages.sh | 16 ---------------- 13 files changed, 41 insertions(+), 35 deletions(-) diff --git a/bin/kojarchy-cmd-reboot b/bin/kojarchy-cmd-reboot index 16902416..910ecee3 100755 --- a/bin/kojarchy-cmd-reboot +++ b/bin/kojarchy-cmd-reboot @@ -3,5 +3,11 @@ # Gracefully close all Hyprland windows before rebooting. # Schedules reboot, then closes windows to give apps time to save state. -sudo shutdown -r +0 & +kojarchy-state clear re*-required + +# Schedule the reboot to happen after closing windows (detached from terminal) +nohup bash -c "sleep 2 && systemctl reboot --no-wall" >/dev/null 2>&1 & + +# Now close all windows kojarchy-hyprland-window-close-all +sleep 1 # Allow apps like Chrome to shutdown correctly diff --git a/bin/kojarchy-cmd-shutdown b/bin/kojarchy-cmd-shutdown index 38d7c842..169a4929 100755 --- a/bin/kojarchy-cmd-shutdown +++ b/bin/kojarchy-cmd-shutdown @@ -3,5 +3,11 @@ # Gracefully close all Hyprland windows before shutting down. # Schedules poweroff, then closes windows to give apps time to save state. -sudo shutdown -P +0 & +kojarchy-state clear re*-required + +# Schedule the shutdown to happen after closing windows (detached from terminal) +nohup bash -c "sleep 2 && systemctl poweroff --no-wall" >/dev/null 2>&1 & + +# Now close all windows kojarchy-hyprland-window-close-all +sleep 1 # Allow apps like Chrome to shutdown correctly diff --git a/bin/kojarchy-pkg-remove b/bin/kojarchy-pkg-remove index 8d6c02c3..43375903 100755 --- a/bin/kojarchy-pkg-remove +++ b/bin/kojarchy-pkg-remove @@ -4,7 +4,7 @@ fzf_args=( --multi - --preview 'pacman -Qi {1}' + --preview 'yay -Qi {1}' --preview-label='alt-p: toggle preview, alt-j/k: scroll, tab: multi-select' --preview-label-pos='bottom' --preview-window 'down:65%:wrap' @@ -14,7 +14,7 @@ fzf_args=( --color 'pointer:red,marker:red' ) -pkg_names=$(pacman -Qqe | fzf "${fzf_args[@]}") +pkg_names=$(yay -Qqe | fzf "${fzf_args[@]}") if [[ -n "$pkg_names" ]]; then echo "$pkg_names" | tr '\n' ' ' | xargs sudo pacman -Rns --noconfirm diff --git a/bin/kojarchy-update b/bin/kojarchy-update index e0176cd8..4ef9271d 100755 --- a/bin/kojarchy-update +++ b/bin/kojarchy-update @@ -4,7 +4,7 @@ set -e KOJARCHY_PATH="${KOJARCHY_PATH:-$HOME/dotfiles}" -trap 'echo ""; echo -e "\033[0;31mSomething went wrong during the update!\n\nPlease review the output above carefully, correct the error, and retry the update.\033[0m"' ERR +trap 'echo ""; echo -e "\033[0;31mSomething went wrong during the update!\n\nPlease review the output above carefully, correct the error, and retry the update.\n\nIf you need help, open an issue at:\nhttps://github.com/princejoogie/dotfiles/issues\033[0m"' ERR if [[ $1 == "-y" ]] || kojarchy-update-confirm; then kojarchy-update-git diff --git a/bin/kojarchy-update-perform b/bin/kojarchy-update-perform index 7a81a060..66555377 100755 --- a/bin/kojarchy-update-perform +++ b/bin/kojarchy-update-perform @@ -2,6 +2,9 @@ set -e +# Ensure screensaver/sleep doesn't set in during updates +hyprctl dispatch tagwindow +noidle &>/dev/null || true + # Capture update logs exec > >(tee "/tmp/kojarchy-update.log") 2>&1 @@ -13,3 +16,6 @@ kojarchy-update-aur-pkgs kojarchy-update-orphan-pkgs kojarchy-hook post-update kojarchy-update-restart + +# Re-enable screensaver/sleep after updates +hyprctl dispatch tagwindow -- -noidle &>/dev/null || true diff --git a/install/config/all.sh b/install/config/all.sh index abe57772..792be893 100644 --- a/install/config/all.sh +++ b/install/config/all.sh @@ -5,7 +5,7 @@ run_logged $KOJARCHY_INSTALL/config/tmux.sh run_logged $KOJARCHY_INSTALL/config/cargo.sh run_logged $KOJARCHY_INSTALL/config/neovim.sh run_logged $KOJARCHY_INSTALL/config/mise.sh -run_logged $KOJARCHY_INSTALL/config/git.sh +source $KOJARCHY_INSTALL/config/git.sh run_logged $KOJARCHY_INSTALL/config/docker.sh run_logged $KOJARCHY_INSTALL/config/gtk.sh run_logged $KOJARCHY_INSTALL/config/gpg.sh diff --git a/install/config/cargo.sh b/install/config/cargo.sh index 02b30f9a..1336d631 100644 --- a/install/config/cargo.sh +++ b/install/config/cargo.sh @@ -1,3 +1,5 @@ +source "$KOJARCHY_DIR/lib/packages.sh" + # Ensure rust toolchain is set up if ! command -v cargo &>/dev/null; then curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y diff --git a/install/config/git.sh b/install/config/git.sh index cefc6152..58b0f842 100644 --- a/install/config/git.sh +++ b/install/config/git.sh @@ -1,4 +1,4 @@ -# Prompt for git identity if not already set +# Prompt for git identity if not already set (runs via source, not run_logged) if [[ -z "$(git config --global user.name)" ]]; then name=$(gum input --placeholder "Your full name" --header "Git user.name:" >"$KOJARCHY_LOG" diff --git a/install/post-install/finished.sh b/install/post-install/finished.sh index 3062acbb..54484e6d 100644 --- a/install/post-install/finished.sh +++ b/install/post-install/finished.sh @@ -20,6 +20,7 @@ echo gum style --padding "0 0 0 $PADDING_LEFT" "Reboot to start using your new desktop." echo -if gum confirm "Reboot now?" >"$KOJARCHY_LOG" sudo reboot fi diff --git a/install/services/systemd.sh b/install/services/systemd.sh index 5919d02d..21d6d748 100644 --- a/install/services/systemd.sh +++ b/install/services/systemd.sh @@ -1,6 +1,5 @@ # Enable system services sudo systemctl enable --now NetworkManager.service -sudo systemctl enable --now bluetooth.service sudo systemctl enable --now docker.service sudo systemctl enable --now tailscaled.service @@ -9,10 +8,7 @@ systemctl --user enable --now pipewire.service systemctl --user enable --now pipewire-pulse.service systemctl --user enable --now wireplumber.service -# Firewall -sudo systemctl enable --now ufw.service -sudo ufw default deny incoming -sudo ufw default allow outgoing -sudo ufw enable +# Note: bluetooth is enabled by config/hardware/bluetooth.sh +# Note: firewall (ufw) is configured by config/firewall.sh echo "Systemd services: OK" diff --git a/lib/errors.sh b/lib/errors.sh index 4cc52c2d..effe48e4 100644 --- a/lib/errors.sh +++ b/lib/errors.sh @@ -71,8 +71,16 @@ catch_errors() { gum style "This command halted with exit code $exit_code:" show_failed_script_or_command + echo + gum style --foreground 245 "If you need help, open an issue at:" + gum style --foreground 4 "https://github.com/princejoogie/dotfiles/issues" + echo + while true; do - options=("Retry installation" "View full log" "Exit") + local options=() + options+=("Retry installation") + options+=("View full log") + options+=("Exit") choice=$(gum choose "${options[@]}" --header "What would you like to do?" --height 5 --padding "1 $PADDING_LEFT") diff --git a/lib/logging.sh b/lib/logging.sh index d7c85209..e0698368 100644 --- a/lib/logging.sh +++ b/lib/logging.sh @@ -88,13 +88,10 @@ run_logged() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] Starting: $script" >>"$KOJARCHY_LOG" - # Only source packages.sh for install helpers — NOT errors.sh/presentation.sh - # which would re-register traps and break fd redirects inside the subshell bash -c " export KOJARCHY_DIR='$KOJARCHY_DIR' export KOJARCHY_INSTALL='$KOJARCHY_INSTALL' export KOJARCHY_LOG='$KOJARCHY_LOG' - source '$KOJARCHY_DIR/lib/packages.sh' source '$script' " >"$KOJARCHY_LOG" 2>&1 diff --git a/lib/packages.sh b/lib/packages.sh index 54b0b101..10e9382e 100644 --- a/lib/packages.sh +++ b/lib/packages.sh @@ -2,22 +2,6 @@ # Kojarchy package install helpers -install_packages() { - local packages_file="$1" - mapfile -t packages < <(grep -v '^#' "$packages_file" | grep -v '^$') - if [ ${#packages[@]} -gt 0 ]; then - sudo pacman -S --noconfirm --needed "${packages[@]}" - fi -} - -install_aur_packages() { - local packages_file="$1" - mapfile -t packages < <(grep -v '^#' "$packages_file" | grep -v '^$') - if [ ${#packages[@]} -gt 0 ]; then - yay -S --noconfirm --needed "${packages[@]}" - fi -} - install_cargo_packages() { local packages_file="$1" From 567c02b50de3af7b8ab60b1e39ff838865d52230 Mon Sep 17 00:00:00 2001 From: princejoogie Date: Tue, 10 Feb 2026 21:04:02 +0800 Subject: [PATCH 23/44] fix: source finished.sh directly so reboot prompt is visible to user --- install/post-install/all.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/post-install/all.sh b/install/post-install/all.sh index 4e9c9af5..0694d091 100644 --- a/install/post-install/all.sh +++ b/install/post-install/all.sh @@ -1,2 +1,2 @@ run_logged $KOJARCHY_INSTALL/post-install/reenable-mkinitcpio.sh -run_logged $KOJARCHY_INSTALL/post-install/finished.sh +source $KOJARCHY_INSTALL/post-install/finished.sh From 3f240c54a253941ab08bdd27552ef974b968ea36 Mon Sep 17 00:00:00 2001 From: princejoogie Date: Tue, 10 Feb 2026 21:08:42 +0800 Subject: [PATCH 24/44] fix: add temporary NOPASSWD sudoers during install to prevent sudo timeout sudo cache expires after 5 minutes but package installation can take 30+ minutes. Inside run_logged subshells stdin is /dev/null so sudo can't re-prompt. This caused services like SDDM to silently fail to enable. Now grants NOPASSWD for the install duration and cleans up in finished.sh. --- install/post-install/finished.sh | 5 +++++ install/preflight/begin.sh | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/install/post-install/finished.sh b/install/post-install/finished.sh index 54484e6d..09f62584 100644 --- a/install/post-install/finished.sh +++ b/install/post-install/finished.sh @@ -1,6 +1,11 @@ # Installation complete! stop_install_log +# Remove temporary NOPASSWD sudoers (created in preflight/begin.sh) +if sudo test -f /etc/sudoers.d/99-kojarchy-installer; then + sudo rm -f /etc/sudoers.d/99-kojarchy-installer +fi + clear_logo # Calculate elapsed time diff --git a/install/preflight/begin.sh b/install/preflight/begin.sh index 013a70be..bdafe25f 100644 --- a/install/preflight/begin.sh +++ b/install/preflight/begin.sh @@ -5,4 +5,12 @@ echo # Ensure sudo is cached before starting the log (needs tty for password prompt) sudo -v /dev/null < Date: Tue, 10 Feb 2026 21:21:01 +0800 Subject: [PATCH 25/44] fix: add space in j logo --- logo.txt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/logo.txt b/logo.txt index defeba99..8cb0c044 100644 --- a/logo.txt +++ b/logo.txt @@ -1,9 +1,9 @@ - ▄█ ▄█▀ ▄██████▄ ▄█ ▄█████▄ ▄███████ ▄███████ ▄█ █▄ ▄█ █▄ - ██ ▄█▀ ███ ███ ██ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ - ███▀ ███ ███ ██ ███ ███ ███ ███ ███ █▀ ███ ███ ███ ███ - ██▀ ███ ███ ██ ▄███▄▄▄███ ▄███▄▄▄██▀ ███ ▄███▄▄▄███▄ ███▄▄▄███ - ██▄ ███ ███ ██ ▀███▀▀▀███ ▀███▀▀▀▀ ███ ▀▀███▀▀▀███ ▀▀▀▀▀▀███ - ██ ▀█▄ ███ █████ ██ ███ ███ ██████████ ███ █▄ ███ ███ ▄██ ███ - ██ ▀█▄ ███ ███ ██ ██ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ - ██ ▀█ ▀██████▀ ████ ███ █▀ ███ ███ ███████▀ ███ █▀ ▀█████▀ + ▄█ ▄█▀ ▄██████▄ ▄█▄ ▄█████▄ ▄███████ ▄███████ ▄█ █▄ ▄█ █▄ + ██ ▄█▀ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ + ███▀ ███ ███ ███ ███ ███ ███ ███ ███ █▀ ███ ███ ███ ███ + ██▀ ███ ███ ███ ▄███▄▄▄███ ▄███▄▄▄██▀ ███ ▄███▄▄▄███▄ ███▄▄▄███ + ██▄ ███ ███ ███ ▀███▀▀▀███ ▀███▀▀▀▀ ███ ▀▀███▀▀▀███ ▀▀▀▀▀▀███ + ██ ▀█▄ ███ ███ ██ ███ ███ ███ ██████████ ███ █▄ ███ ███ ▄██ ███ + ██ ▀█▄ ███ ███ ██ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ + ██ ▀█ ▀██████▀ █████▀ ███ █▀ ███ ███ ███████▀ ███ █▀ ▀█████▀ From 57fe89702696becbbc2291e56b691ea4a3288453 Mon Sep 17 00:00:00 2001 From: princejoogie Date: Tue, 10 Feb 2026 21:24:51 +0800 Subject: [PATCH 26/44] fix: pause log tail during interactive prompts to prevent screen corruption --- install/config/all.sh | 5 +++++ install/packaging/all.sh | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/install/config/all.sh b/install/config/all.sh index 792be893..4c99ad23 100644 --- a/install/config/all.sh +++ b/install/config/all.sh @@ -5,7 +5,12 @@ run_logged $KOJARCHY_INSTALL/config/tmux.sh run_logged $KOJARCHY_INSTALL/config/cargo.sh run_logged $KOJARCHY_INSTALL/config/neovim.sh run_logged $KOJARCHY_INSTALL/config/mise.sh +# Pause log tail for interactive git prompt +stop_log_output +clear_logo source $KOJARCHY_INSTALL/config/git.sh +clear_logo +start_log_output run_logged $KOJARCHY_INSTALL/config/docker.sh run_logged $KOJARCHY_INSTALL/config/gtk.sh run_logged $KOJARCHY_INSTALL/config/gpg.sh diff --git a/install/packaging/all.sh b/install/packaging/all.sh index 51dba05e..64dc7298 100644 --- a/install/packaging/all.sh +++ b/install/packaging/all.sh @@ -1,8 +1,12 @@ run_logged $KOJARCHY_INSTALL/packaging/aur-helper.sh run_logged $KOJARCHY_INSTALL/packaging/base.sh -# Interactive prompts must run in the main shell (needs tty for gum) +# Pause log tail for interactive prompts (it overwrites the screen) +stop_log_output +clear_logo source $KOJARCHY_INSTALL/packaging/nvidia.sh source $KOJARCHY_INSTALL/packaging/optional.sh +clear_logo +start_log_output run_logged $KOJARCHY_INSTALL/packaging/fonts.sh From 7af3845c0f91b91bd240b45875eac72fe631834c Mon Sep 17 00:00:00 2001 From: princejoogie Date: Tue, 10 Feb 2026 21:28:26 +0800 Subject: [PATCH 27/44] fix: logo --- logo.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logo.txt b/logo.txt index 8cb0c044..2406159e 100644 --- a/logo.txt +++ b/logo.txt @@ -1,5 +1,5 @@ - ▄█ ▄█▀ ▄██████▄ ▄█▄ ▄█████▄ ▄███████ ▄███████ ▄█ █▄ ▄█ █▄ + ▄█ ▄█▀ ▄██████▄ ▄█▄ ▄█████▄ ▄███████ ▄███████ ▄█ █▄ ▄█ █▄ ██ ▄█▀ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███▀ ███ ███ ███ ███ ███ ███ ███ ███ █▀ ███ ███ ███ ███ ██▀ ███ ███ ███ ▄███▄▄▄███ ▄███▄▄▄██▀ ███ ▄███▄▄▄███▄ ███▄▄▄███ From 73e063aaae42f49445ab5377ad84c0ad32a3dc75 Mon Sep 17 00:00:00 2001 From: princejoogie Date: Tue, 10 Feb 2026 21:43:25 +0800 Subject: [PATCH 28/44] fix: replace cargo builds with prebuilt packages to speed up install - bob-nvim -> bob (official repo) - tree-sitter-cli -> tree-sitter-cli (official repo) - cargo-update -> cargo-update (official repo) - tmux-sessionizer -> tmux-sessionizer-bin (AUR prebuilt) Rust/cargo toolchain still installed for dev workflow. --- install/config/cargo.sh | 5 ----- install/kojarchy-base.packages | 4 ++++ install/kojarchy-cargo.packages | 11 ++++++----- lib/packages.sh | 16 +--------------- 4 files changed, 11 insertions(+), 25 deletions(-) diff --git a/install/config/cargo.sh b/install/config/cargo.sh index 1336d631..c11952af 100644 --- a/install/config/cargo.sh +++ b/install/config/cargo.sh @@ -1,5 +1,3 @@ -source "$KOJARCHY_DIR/lib/packages.sh" - # Ensure rust toolchain is set up if ! command -v cargo &>/dev/null; then curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y @@ -8,7 +6,4 @@ fi rustup default stable -# Install cargo packages -install_cargo_packages "$KOJARCHY_INSTALL/kojarchy-cargo.packages" - echo "Cargo: OK" diff --git a/install/kojarchy-base.packages b/install/kojarchy-base.packages index 84ec6b42..77a7d716 100644 --- a/install/kojarchy-base.packages +++ b/install/kojarchy-base.packages @@ -73,6 +73,10 @@ docker-compose mise bun uv +bob +tree-sitter-cli +cargo-update +tmux-sessionizer-bin # === File Management === dolphin diff --git a/install/kojarchy-cargo.packages b/install/kojarchy-cargo.packages index 6fd1f587..b9d8834f 100644 --- a/install/kojarchy-cargo.packages +++ b/install/kojarchy-cargo.packages @@ -1,8 +1,9 @@ # Kojarchy cargo packages (format: crate=binary) # If binary name matches crate name, just use the crate name # Installed via install/config/cargo.sh - -bob-nvim=bob -tmux-sessionizer=tms -tree-sitter-cli=tree-sitter -cargo-update=cargo-install-update +# +# All packages moved to kojarchy-base.packages as prebuilt binaries: +# bob-nvim -> bob (official repo) +# tree-sitter-cli -> tree-sitter-cli (official repo) +# cargo-update -> cargo-update (official repo) +# tmux-sessionizer -> tmux-sessionizer-bin (AUR) diff --git a/lib/packages.sh b/lib/packages.sh index 10e9382e..8203fbb4 100644 --- a/lib/packages.sh +++ b/lib/packages.sh @@ -1,18 +1,4 @@ #!/bin/bash # Kojarchy package install helpers - -install_cargo_packages() { - local packages_file="$1" - - while IFS= read -r line; do - [[ -z "$line" || "$line" =~ ^# ]] && continue - - local crate="${line%%=*}" - local binary="${line##*=}" - - if ! command -v "$binary" &>/dev/null; then - cargo install "$crate" - fi - done <"$packages_file" -} +# (Currently empty — cargo packages moved to base packages as prebuilt binaries) From 6dadfb28c15c76c64b23ac02a74d5c217fcd714d Mon Sep 17 00:00:00 2001 From: princejoogie Date: Wed, 11 Feb 2026 03:12:01 +0800 Subject: [PATCH 29/44] add sudo for chsh --- install/config/shell.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/config/shell.sh b/install/config/shell.sh index 6fbdc00e..abbcaeb4 100644 --- a/install/config/shell.sh +++ b/install/config/shell.sh @@ -20,7 +20,7 @@ fi # Set zsh as default shell if [[ "$SHELL" != *"zsh"* ]]; then - chsh -s /usr/bin/zsh + sudo chsh -s /usr/bin/zsh "$USER" fi echo "Shell: OK" From e7597be97027785314da230dcfd9be7361bc4fee Mon Sep 17 00:00:00 2001 From: princejoogie Date: Wed, 11 Feb 2026 03:34:51 +0800 Subject: [PATCH 30/44] fix: standardize fonts on FiraCode, adopt omarchy base packages - Replace apple-fonts/geist/JetBrains with FiraCode Nerd Font Mono everywhere - Replace zathura/mupdf/ocrmypdf with evince, pavucontrol with wiremix - Add omarchy system infra: printing stack, gnome-keyring, gvfs, avahi, swayosd, uwsm - Add dev tools: ripgrep, lazygit, lazydocker, clang, llvm, rust, opencode - Add desktop utils: playerctl, brightnessctl, bluetui, mpv, satty, gnome-disk-utility - Move helium-browser-bin from optional to base - Fix chsh: use sudo to avoid silent failure in run_logged subshell --- config/fontconfig/fonts.conf | 2 +- config/hypr/hyprlock.conf | 2 +- install/kojarchy-base.packages | 61 +++++++++++++++++++++++++----- install/kojarchy-optional.packages | 1 - 4 files changed, 54 insertions(+), 12 deletions(-) diff --git a/config/fontconfig/fonts.conf b/config/fontconfig/fonts.conf index 5463ba30..e6869fe9 100644 --- a/config/fontconfig/fonts.conf +++ b/config/fontconfig/fonts.conf @@ -24,7 +24,7 @@ monospace - JetBrainsMono Nerd Font + FiraCode Nerd Font Mono diff --git a/config/hypr/hyprlock.conf b/config/hypr/hyprlock.conf index 5b3e0ca8..83890040 100644 --- a/config/hypr/hyprlock.conf +++ b/config/hypr/hyprlock.conf @@ -24,7 +24,7 @@ input-field { outer_color = rgb(7aa2f7) outline_thickness = 4 - font_family = JetBrainsMono Nerd Font + font_family = FiraCode Nerd Font Mono font_color = rgb(c0caf5) placeholder_text = Enter Password diff --git a/install/kojarchy-base.packages b/install/kojarchy-base.packages index 77a7d716..a6ae87f5 100644 --- a/install/kojarchy-base.packages +++ b/install/kojarchy-base.packages @@ -12,6 +12,8 @@ zip 7zip # === Networking === +avahi +nss-mdns bind net-tools networkmanager @@ -22,6 +24,7 @@ tailscale traceroute wget wireguard-tools +wireless-regdb # === Graphics (generic) === mesa-utils @@ -37,7 +40,9 @@ hyprshot hyprmon-bin hyprwhspr swaybg +swayosd waybar +wayfreeze dunst wofi wofi-calc @@ -45,11 +50,19 @@ xdg-desktop-portal-gtk xdg-desktop-portal-hyprland xdg-desktop-portal-kde xdg-utils +xdg-terminal-exec xorg-server xorg-xhost xorg-xinit xwaylandvideobridge sddm +uwsm +gnome-keyring +libsecret +bolt +playerctl +brightnessctl +bluetui # === Terminal & Shell === kitty @@ -70,6 +83,7 @@ git-delta github-cli docker docker-compose +docker-buildx mise bun uv @@ -77,6 +91,13 @@ bob tree-sitter-cli cargo-update tmux-sessionizer-bin +clang +llvm +rust +opencode +ripgrep +lazydocker +lazygit # === File Management === dolphin @@ -85,6 +106,10 @@ fd gdu ncdu tree +gvfs-mtp +gvfs-nfs +gvfs-smb +exfatprogs # === Media & Graphics === pipewire @@ -94,9 +119,12 @@ pipewire-pulse gst-plugin-pipewire libpulse wireplumber -pavucontrol +alsa-utils +wiremix imagemagick graphicsmagick +mpv +satty grim slurp wl-clipboard @@ -104,13 +132,14 @@ ffmpegthumbs yt-dlp # === Fonts === -otf-geist-mono-nerd ttf-firacode-nerd ttf-nerd-fonts-symbols +fontconfig +noto-fonts noto-fonts-cjk -noto-color-emoji-fontconfig +noto-fonts-emoji +noto-fonts-extra woff2-font-awesome -apple-fonts font-manager # === Qt/GTK Theming === @@ -127,6 +156,7 @@ sassc # === Firewall === ufw +ufw-docker # === Misc Tools === expac @@ -138,11 +168,24 @@ tesseract-data-eng hunspell-en_us bc lshw +inxi speedtest-cli +tzupdate + +# === Printing === +cups +cups-browsed +cups-filters +cups-pdf +system-config-printer # === Document & Image Viewing === -zathura -zathura-pdf-mupdf -mupdf -qview -ocrmypdf +evince +imv + +# === Browsers === +helium-browser-bin + +# === System Utilities === +gnome-calculator +gnome-disk-utility diff --git a/install/kojarchy-optional.packages b/install/kojarchy-optional.packages index 722310f2..1b922e61 100644 --- a/install/kojarchy-optional.packages +++ b/install/kojarchy-optional.packages @@ -29,7 +29,6 @@ uxplay # === Browsers === chromium -helium-browser-bin # === Remote === rustdesk-bin From e0ccb46a2e4030737f3ec05a97370c12ca41c6bc Mon Sep 17 00:00:00 2001 From: princejoogie Date: Wed, 11 Feb 2026 03:36:50 +0800 Subject: [PATCH 31/44] fix: remove printing packages from base --- install/kojarchy-base.packages | 7 ------- 1 file changed, 7 deletions(-) diff --git a/install/kojarchy-base.packages b/install/kojarchy-base.packages index a6ae87f5..ea262fb7 100644 --- a/install/kojarchy-base.packages +++ b/install/kojarchy-base.packages @@ -172,13 +172,6 @@ inxi speedtest-cli tzupdate -# === Printing === -cups -cups-browsed -cups-filters -cups-pdf -system-config-printer - # === Document & Image Viewing === evince imv From 487a29aedea18595390a0b08e15624a73d49573d Mon Sep 17 00:00:00 2001 From: princejoogie Date: Wed, 11 Feb 2026 03:53:14 +0800 Subject: [PATCH 32/44] fix: waybar style.css --- config/waybar/style.css | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/config/waybar/style.css b/config/waybar/style.css index 50eda037..40398c69 100644 --- a/config/waybar/style.css +++ b/config/waybar/style.css @@ -14,6 +14,7 @@ window#waybar { background: transparent; border-radius: 0px; + color: @text; } tooltip { @@ -28,6 +29,7 @@ tooltip { #battery, #network, #pulseaudio { + color: @text; margin: 6px 6px 2px 0px; padding: 2px 8px; } @@ -81,22 +83,26 @@ tooltip { } .custom-spotify { + color: @text; padding-left: 6px; padding-right: 6px; padding-top: 4px; } #custom-tailscale { + color: @text; padding-right: 6px; margin: 6px 6px 2px 0px; } #custom-tunnelbear { + color: @text; padding-right: 6px; margin: 6px 6px 2px 0px; } #custom-mouse-battery { + color: @text; margin: 6px 6px 2px 0px; padding: 2px 8px; } @@ -104,6 +110,7 @@ tooltip { #custom-hyprwhspr { background-color: @base; border: 1px solid @surface1; + color: @text; border-radius: 6px; margin: 6px 6px 2px 2px; padding: 2px 8px; From 5a09a25b62307f3a1a1147cfd80889510fdd9340 Mon Sep 17 00:00:00 2001 From: princejoogie Date: Wed, 11 Feb 2026 04:19:51 +0800 Subject: [PATCH 33/44] feat: unify Catppuccin Mocha theming across all apps - Fix hyprlock colors from Tokyo Night to Catppuccin Mocha (black bg) - Add btop Catppuccin Mocha theme file - Set up Kvantum with catppuccin-mocha-blue for Qt apps - Set GTK theme to catppuccin-mocha-blue via gsettings - Add Wayland env vars (GDK_BACKEND, QT_QPA_PLATFORM, SDL, Electron, Ozone) - Set QT_STYLE_OVERRIDE=kvantum, XDG session vars - Replace Dolphin with Nautilus, drop unnecessary Qt theming packages - Fix refresh-hyprland to cover all 4 config files + hyprctl reload - Add mocha.css to refresh-waybar --- bin/kojarchy-refresh-hyprland | 4 + bin/kojarchy-refresh-waybar | 1 + config/Kvantum/kvantum.kvconfig | 2 + config/btop/btop.conf | 2 +- config/btop/themes/catppuccin_mocha.theme | 92 +++++++++++++++++++++++ config/hypr/hyprlock.conf | 10 +-- default/hypr/envs.conf | 16 +++- install/config/gtk.sh | 5 +- install/kojarchy-base.packages | 12 ++- 9 files changed, 127 insertions(+), 17 deletions(-) create mode 100644 config/Kvantum/kvantum.kvconfig create mode 100644 config/btop/themes/catppuccin_mocha.theme diff --git a/bin/kojarchy-refresh-hyprland b/bin/kojarchy-refresh-hyprland index d7e624d5..4188532f 100755 --- a/bin/kojarchy-refresh-hyprland +++ b/bin/kojarchy-refresh-hyprland @@ -1,3 +1,7 @@ #!/bin/bash # Reset all Hyprland user configs to Kojarchy defaults. kojarchy-refresh-config hypr/hyprland.conf +kojarchy-refresh-config hypr/hyprlock.conf +kojarchy-refresh-config hypr/hypridle.conf +kojarchy-refresh-config hypr/hyprsunset.conf +hyprctl reload >/dev/null diff --git a/bin/kojarchy-refresh-waybar b/bin/kojarchy-refresh-waybar index 5c35e801..4530e0f5 100755 --- a/bin/kojarchy-refresh-waybar +++ b/bin/kojarchy-refresh-waybar @@ -2,4 +2,5 @@ # Reset Waybar config to Kojarchy defaults and restart. kojarchy-refresh-config waybar/config.jsonc kojarchy-refresh-config waybar/style.css +kojarchy-refresh-config waybar/mocha.css kojarchy-restart-waybar diff --git a/config/Kvantum/kvantum.kvconfig b/config/Kvantum/kvantum.kvconfig new file mode 100644 index 00000000..f1f65c2b --- /dev/null +++ b/config/Kvantum/kvantum.kvconfig @@ -0,0 +1,2 @@ +[General] +theme=catppuccin-mocha-blue diff --git a/config/btop/btop.conf b/config/btop/btop.conf index 14f19cc5..8e560fd4 100644 --- a/config/btop/btop.conf +++ b/config/btop/btop.conf @@ -2,7 +2,7 @@ #* Name of a btop++/bpytop/bashtop formatted ".theme" file, "Default" and "TTY" for builtin themes. #* Themes should be placed in "../share/btop/themes" relative to binary or "$HOME/.config/btop/themes" -color_theme = "Default" +color_theme = "catppuccin_mocha" #* If the theme set background should be shown, set to False if you want terminal background transparency. theme_background = true diff --git a/config/btop/themes/catppuccin_mocha.theme b/config/btop/themes/catppuccin_mocha.theme new file mode 100644 index 00000000..99afde07 --- /dev/null +++ b/config/btop/themes/catppuccin_mocha.theme @@ -0,0 +1,92 @@ +# Catppuccin Mocha theme for btop +# https://github.com/catppuccin/btop + +# Main background +theme[main_bg]="#000000" + +# Main text color +theme[main_fg]="#cdd6f4" + +# Title color for boxes +theme[title]="#cdd6f4" + +# Highlight color for keyboard shortcuts +theme[hi_fg]="#89b4fa" + +# Background color of selected item in processes box +theme[selected_bg]="#45475a" + +# Foreground color of selected item in processes box +theme[selected_fg]="#cdd6f4" + +# Color of inactive/disabled text +theme[inactive_fg]="#6c7086" + +# Color of text appearing on top of graphs +theme[graph_text]="#a6adc8" + +# Background color of the percentage meters +theme[meter_bg]="#45475a" + +# Misc colors for processes box including mini cpu graphs, ## ## details, binary, and details highlight color +theme[proc_misc]="#89b4fa" + +# CPU box outline color +theme[cpu_box]="#45475a" + +# Memory/disks box outline color +theme[mem_box]="#45475a" + +# Net box outline color +theme[net_box]="#45475a" + +# Processes box outline color +theme[proc_box]="#45475a" + +# Box divider line and target selector line color +theme[div_line]="#45475a" + +# Temperature graph colors +theme[temp_start]="#a6e3a1" +theme[temp_mid]="#f9e2af" +theme[temp_end]="#f38ba8" + +# CPU graph colors +theme[cpu_start]="#a6e3a1" +theme[cpu_mid]="#f9e2af" +theme[cpu_end]="#f38ba8" + +# Mem/Disk free meter +theme[free_start]="#a6e3a1" +theme[free_mid]="#a6e3a1" +theme[free_end]="#a6e3a1" + +# Mem/Disk cached meter +theme[cached_start]="#f9e2af" +theme[cached_mid]="#f9e2af" +theme[cached_end]="#f9e2af" + +# Mem/Disk available meter +theme[available_start]="#89b4fa" +theme[available_mid]="#89b4fa" +theme[available_end]="#89b4fa" + +# Mem/Disk used meter +theme[used_start]="#f38ba8" +theme[used_mid]="#fab387" +theme[used_end]="#f38ba8" + +# Download graph colors +theme[download_start]="#89b4fa" +theme[download_mid]="#74c7ec" +theme[download_end]="#94e2d5" + +# Upload graph colors +theme[upload_start]="#cba6f7" +theme[upload_mid]="#f5c2e7" +theme[upload_end]="#f5e0dc" + +# Process box color gradient for threads, mem and cpu usage +theme[process_start]="#89b4fa" +theme[process_mid]="#cba6f7" +theme[process_end]="#f38ba8" diff --git a/config/hypr/hyprlock.conf b/config/hypr/hyprlock.conf index 83890040..f3b7fa8e 100644 --- a/config/hypr/hyprlock.conf +++ b/config/hypr/hyprlock.conf @@ -4,7 +4,7 @@ general { background { monitor = - color = rgb(1a1b26) + color = rgb(000000) path = ~/dotfiles/wallpapers/pallete.png blur_passes = 3 } @@ -20,15 +20,15 @@ input-field { halign = center valign = center - inner_color = rgb(1a1b26) - outer_color = rgb(7aa2f7) + inner_color = rgb(000000) + outer_color = rgb(89b4fa) outline_thickness = 4 font_family = FiraCode Nerd Font Mono - font_color = rgb(c0caf5) + font_color = rgb(cdd6f4) placeholder_text = Enter Password - check_color = rgb(9ece6a) + check_color = rgb(a6e3a1) fail_text = $FAIL ($ATTEMPTS) rounding = 0 diff --git a/default/hypr/envs.conf b/default/hypr/envs.conf index 2cd293ab..0fd47ce7 100644 --- a/default/hypr/envs.conf +++ b/default/hypr/envs.conf @@ -1,7 +1,19 @@ env = XCURSOR_SIZE,24 env = HYPRCURSOR_SIZE,24 -env = QT_QPA_PLATFORMTHEME,qt6ct env = XDG_MENU_PREFIX,arch- -# Firefox/Zen native Wayland +# Wayland backends +env = GDK_BACKEND,wayland,x11,* +env = QT_QPA_PLATFORM,wayland;xcb +env = SDL_VIDEODRIVER,wayland,x11 env = MOZ_ENABLE_WAYLAND,1 +env = ELECTRON_OZONE_PLATFORM_HINT,wayland +env = OZONE_PLATFORM,wayland + +# Qt theming via Kvantum +env = QT_STYLE_OVERRIDE,kvantum + +# Session +env = XDG_SESSION_TYPE,wayland +env = XDG_CURRENT_DESKTOP,Hyprland +env = XDG_SESSION_DESKTOP,Hyprland diff --git a/install/config/gtk.sh b/install/config/gtk.sh index 288c9fbe..a50293bd 100644 --- a/install/config/gtk.sh +++ b/install/config/gtk.sh @@ -1,7 +1,8 @@ -# Set GTK/Qt dark theme via gsettings (like omarchy, no config files) +# Set GTK dark theme and icon theme via gsettings if command -v gsettings &>/dev/null; then - gsettings set org.gnome.desktop.interface gtk-theme "Adwaita-dark" 2>/dev/null || true + gsettings set org.gnome.desktop.interface gtk-theme "catppuccin-mocha-blue-standard+default" 2>/dev/null || true gsettings set org.gnome.desktop.interface color-scheme "prefer-dark" 2>/dev/null || true + gsettings set org.gnome.desktop.interface icon-theme "Adwaita" 2>/dev/null || true fi echo "GTK theme: OK" diff --git a/install/kojarchy-base.packages b/install/kojarchy-base.packages index ea262fb7..9f55d3a6 100644 --- a/install/kojarchy-base.packages +++ b/install/kojarchy-base.packages @@ -100,7 +100,7 @@ lazydocker lazygit # === File Management === -dolphin +nautilus yazi fd gdu @@ -143,16 +143,14 @@ woff2-font-awesome font-manager # === Qt/GTK Theming === -qt5ct -qt6ct qt5-wayland qt6-wayland -qt5-quickcontrols2 -kvantum-qt5 kvantum +kvantum-qt5 +kvantum-theme-catppuccin-git +catppuccin-gtk-theme-mocha nwg-look -breeze -sassc +gnome-themes-extra # === Firewall === ufw From e6e9929f14e02046da85f1e1db31ce7a72e79627 Mon Sep 17 00:00:00 2001 From: princejoogie Date: Wed, 11 Feb 2026 04:35:23 +0800 Subject: [PATCH 34/44] fix: add PATH to Hyprland envs, fix Kvantum theme name, remove old keybind - Add PATH entries to default/hypr/envs.conf so kojarchy-* scripts work from keybindings/menus - Fix Kvantum theme name capitalization (Catppuccin-Mocha-Blue) - Remove ALT+CTRL+SPACE binding (replaced by ALT+SHIFT+SPACE unified menu) --- config/Kvantum/kvantum.kvconfig | 2 +- default/hypr/bindings.conf | 1 - default/hypr/envs.conf | 7 +++++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/config/Kvantum/kvantum.kvconfig b/config/Kvantum/kvantum.kvconfig index f1f65c2b..1e4a4869 100644 --- a/config/Kvantum/kvantum.kvconfig +++ b/config/Kvantum/kvantum.kvconfig @@ -1,2 +1,2 @@ [General] -theme=catppuccin-mocha-blue +theme=Catppuccin-Mocha-Blue diff --git a/default/hypr/bindings.conf b/default/hypr/bindings.conf index f6e89ee9..79a040ab 100644 --- a/default/hypr/bindings.conf +++ b/default/hypr/bindings.conf @@ -9,7 +9,6 @@ bind = $mainMod, E, exec, $fileManager bind = $mainMod, W, exec, kojarchy-toggle-waybar bind = $mainMod, V, togglefloating, bind = $mainMod, SPACE, exec, $menu -bind = $mainMod CTRL, SPACE, exec, ~/.config/wofi/dmenu/launcher.sh bind = $mainMod, P, pseudo, bind = $mainMod SHIFT, J, togglesplit, bind = $mainMod SHIFT, C, exec, hyprpicker | { read color; trimmed=$(printf "%s" "$color"); printf "%s" "$trimmed" | wl-copy; notify-send "Copied $color to clipboard"; } diff --git a/default/hypr/envs.conf b/default/hypr/envs.conf index 0fd47ce7..b83966fc 100644 --- a/default/hypr/envs.conf +++ b/default/hypr/envs.conf @@ -13,6 +13,13 @@ env = OZONE_PLATFORM,wayland # Qt theming via Kvantum env = QT_STYLE_OVERRIDE,kvantum +# PATH — Hyprland is started by SDDM, not from a shell, +# so child processes need PATH set here for keybindings and menus. +env = PATH,$HOME/.local/custom/bin:$HOME/.cargo/bin:$HOME/.local/bin:$HOME/.local/share/bob/nvim-bin:$HOME/.duckdb/cli/latest:$HOME/.opencode/bin:$HOME/.lmstudio/bin:$HOME/.bun/bin:$HOME/go/bin:$PATH + +# Editor +env = EDITOR,nvim + # Session env = XDG_SESSION_TYPE,wayland env = XDG_CURRENT_DESKTOP,Hyprland From b3e2dd0aed404cb6a0ac40232beaeb45f564bb4e Mon Sep 17 00:00:00 2001 From: princejoogie Date: Wed, 11 Feb 2026 04:39:25 +0800 Subject: [PATCH 35/44] fix: add delay before screenshot/screenrecord so menu closes first --- bin/kojarchy-menu | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bin/kojarchy-menu b/bin/kojarchy-menu index 1ebf7eba..5fdb8637 100755 --- a/bin/kojarchy-menu +++ b/bin/kojarchy-menu @@ -33,10 +33,10 @@ choice=$(gum choose \ ) case "$choice" in - "Screenshot") kojarchy-cmd-screenshot region edit ;; - "Screenshot (clipboard)") kojarchy-cmd-screenshot region clipboard ;; - "Screen record") kojarchy-cmd-screenrecord ;; - "Color picker") hyprpicker | { read color; trimmed=$(printf "%s" "$color"); printf "%s" "$trimmed" | wl-copy; notify-send "Copied $color to clipboard"; } ;; + "Screenshot") sleep 0.3 && kojarchy-cmd-screenshot region edit ;; + "Screenshot (clipboard)") sleep 0.3 && kojarchy-cmd-screenshot region clipboard ;; + "Screen record") sleep 0.3 && kojarchy-cmd-screenrecord ;; + "Color picker") sleep 0.3 && hyprpicker | { read color; trimmed=$(printf "%s" "$color"); printf "%s" "$trimmed" | wl-copy; notify-send "Copied $color to clipboard"; } ;; "Lock screen") kojarchy-lock-screen ;; "Kill process") kojarchy-kill-process ;; "Kill port") kojarchy-kill-port ;; From 2dfdfcd6cd27c810e54c107e89bac8481875f0ee Mon Sep 17 00:00:00 2001 From: princejoogie Date: Wed, 11 Feb 2026 04:44:39 +0800 Subject: [PATCH 36/44] feat: replace gum menu with walker dmenu, add wayfreeze to screenshots - Rewrite kojarchy-menu to use walker --dmenu instead of kitty+gum - Add walker-bin package, walker config, and Catppuccin Mocha theme - Remove kitty window rules for old menu (walker is its own overlay) - Add wayfreeze to screenshot script so screen freezes before capture - Simplify keybinding: no longer needs kitty wrapper --- bin/kojarchy-cmd-screenshot | 6 ++ bin/kojarchy-menu | 70 ++++++------- config/walker/config.toml | 24 +++++ config/walker/themes/kojarchy/layout.xml | 119 +++++++++++++++++++++++ config/walker/themes/kojarchy/style.css | 81 +++++++++++++++ default/hypr/bindings.conf | 2 +- default/hypr/windows.conf | 4 - install/kojarchy-base.packages | 1 + 8 files changed, 268 insertions(+), 39 deletions(-) create mode 100644 config/walker/config.toml create mode 100644 config/walker/themes/kojarchy/layout.xml create mode 100644 config/walker/themes/kojarchy/style.css diff --git a/bin/kojarchy-cmd-screenshot b/bin/kojarchy-cmd-screenshot index 4c47c209..feaa3ae6 100755 --- a/bin/kojarchy-cmd-screenshot +++ b/bin/kojarchy-cmd-screenshot @@ -26,10 +26,16 @@ get_rectangles() { case "$MODE" in region) + wayfreeze & PID=$! + sleep 0.1 SELECTION=$(slurp 2>/dev/null) + kill $PID 2>/dev/null ;; window) + wayfreeze & PID=$! + sleep 0.1 SELECTION=$(get_rectangles | slurp -r 2>/dev/null) + kill $PID 2>/dev/null ;; fullscreen) SELECTION=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true) | "\(.x),\(.y) \((.width / .scale) | floor)x\((.height / .scale) | floor)"') diff --git a/bin/kojarchy-menu b/bin/kojarchy-menu index 5fdb8637..e45e91b9 100755 --- a/bin/kojarchy-menu +++ b/bin/kojarchy-menu @@ -1,42 +1,44 @@ #!/bin/bash # Kojarchy menu — unified launcher for all commands and scripts. -# Bound to ALT+SHIFT+SPACE. Runs in a floating terminal via gum. +# Bound to ALT+SHIFT+SPACE. Uses walker in dmenu mode. -choice=$(gum choose \ - "Screenshot" \ - "Screenshot (clipboard)" \ - "Screen record" \ - "Color picker" \ - "Lock screen" \ - "Kill process" \ - "Kill port" \ - "Open file" \ - "Calculator" \ - "Camera" \ - "Toggle waybar" \ - "Toggle nightlight" \ - "Toggle focus mode" \ - "Toggle RGB" \ - "Audio switch" \ - "Keybindings" \ - "Font set" \ - "Package install" \ - "Package remove" \ - "Update system" \ - "Refresh hyprland" \ - "Refresh waybar" \ - "Debug info" \ - "Close all windows" \ - "Reboot" \ - "Shutdown" \ -) +OPTIONS="Screenshot +Screenshot (clipboard) +Screen record +Color picker +Lock screen +Kill process +Kill port +Open file +Calculator +Camera +Toggle waybar +Toggle nightlight +Toggle focus mode +Toggle RGB +Audio switch +Keybindings +Font set +Package install +Package remove +Update system +Refresh hyprland +Refresh waybar +Debug info +Close all windows +Reboot +Shutdown" + +choice=$(echo "$OPTIONS" | walker --dmenu --width 295 --minheight 1 --maxheight 630 -p "Kojarchy…" 2>/dev/null) + +[ -z "$choice" ] && exit 0 case "$choice" in - "Screenshot") sleep 0.3 && kojarchy-cmd-screenshot region edit ;; - "Screenshot (clipboard)") sleep 0.3 && kojarchy-cmd-screenshot region clipboard ;; - "Screen record") sleep 0.3 && kojarchy-cmd-screenrecord ;; - "Color picker") sleep 0.3 && hyprpicker | { read color; trimmed=$(printf "%s" "$color"); printf "%s" "$trimmed" | wl-copy; notify-send "Copied $color to clipboard"; } ;; + "Screenshot") kojarchy-cmd-screenshot region edit ;; + "Screenshot (clipboard)") kojarchy-cmd-screenshot region clipboard ;; + "Screen record") kojarchy-cmd-screenrecord ;; + "Color picker") hyprpicker | { read color; trimmed=$(printf "%s" "$color"); printf "%s" "$trimmed" | wl-copy; notify-send "Copied $color to clipboard"; } ;; "Lock screen") kojarchy-lock-screen ;; "Kill process") kojarchy-kill-process ;; "Kill port") kojarchy-kill-port ;; @@ -49,7 +51,7 @@ case "$choice" in "Toggle RGB") kojarchy-toggle-rgb ;; "Audio switch") kojarchy-cmd-audio-switch ;; "Keybindings") kojarchy-menu-keybindings ;; - "Font set") font=$(kojarchy-font-list | gum filter --placeholder "Pick a font...") && kojarchy-font-set "$font" ;; + "Font set") font=$(kojarchy-font-list | walker --dmenu -p "Pick a font…" 2>/dev/null) && kojarchy-font-set "$font" ;; "Package install") kojarchy-pkg-install ;; "Package remove") kojarchy-pkg-remove ;; "Update system") kojarchy-update ;; diff --git a/config/walker/config.toml b/config/walker/config.toml new file mode 100644 index 00000000..084b6e81 --- /dev/null +++ b/config/walker/config.toml @@ -0,0 +1,24 @@ +force_keyboard_focus = true +selection_wrap = true +theme = "kojarchy" +hide_action_hints = true + +[placeholders] +"default" = { input = " Search...", list = "No Results" } + +[keybinds] +quick_activate = [] + +[providers] +max_results = 256 +default = [ + "desktopapplications", +] + +[[providers.prefixes]] +prefix = "=" +provider = "calc" + +[[providers.prefixes]] +prefix = "$" +provider = "clipboard" diff --git a/config/walker/themes/kojarchy/layout.xml b/config/walker/themes/kojarchy/layout.xml new file mode 100644 index 00000000..5316081b --- /dev/null +++ b/config/walker/themes/kojarchy/layout.xml @@ -0,0 +1,119 @@ + + + + + + true + Walker + + + + 500 + hidden + horizontal + center + center + + + + vertical + true + true + 8 + + + + hidden + horizontal + fill + true + true + + + + fill + true + true + + + + + + + + horizontal + 8 + true + true + + + + No Results + 0.0 + true + + + + + + true + false + true + 480 + 400 + 0 + true + true + automatic + automatic + + + + 1 + false + + + + + + + + + + + + + + + 0 + false + + + + + + + + diff --git a/config/walker/themes/kojarchy/style.css b/config/walker/themes/kojarchy/style.css new file mode 100644 index 00000000..6bef150b --- /dev/null +++ b/config/walker/themes/kojarchy/style.css @@ -0,0 +1,81 @@ +@define-color selected-text #89b4fa; +@define-color text #cdd6f4; +@define-color base #000000; +@define-color border #45475a; +@define-color foreground #cdd6f4; +@define-color background #000000; + +* { + all: unset; +} + +* { + font-family: "FiraCode Nerd Font"; + font-size: 16px; + color: @text; +} + +scrollbar { + opacity: 0; +} + +.normal-icons { + -gtk-icon-size: 16px; +} + +.large-icons { + -gtk-icon-size: 32px; +} + +.box-wrapper { + background: alpha(@base, 0.95); + padding: 16px; + border: 1px solid @border; + border-radius: 8px; +} + +.search-container { + background: @base; + padding: 8px; +} + +.input placeholder { + opacity: 0.5; +} + +.input:focus, +.input:active { + box-shadow: none; + outline: none; +} + +child:selected .item-box * { + color: @selected-text; +} + +.item-box { + padding-left: 12px; +} + +.item-text-box { + all: unset; + padding: 10px 0; +} + +.item-subtext { + font-size: 0px; + min-height: 0px; + margin: 0px; + padding: 0px; +} + +.item-image { + margin-right: 12px; + -gtk-icon-transform: scale(0.9); +} + +.keybind-hints { + background: @background; + padding: 8px; + margin-top: 8px; +} diff --git a/default/hypr/bindings.conf b/default/hypr/bindings.conf index 79a040ab..591d4f92 100644 --- a/default/hypr/bindings.conf +++ b/default/hypr/bindings.conf @@ -94,7 +94,7 @@ bind = $mainMod CTRL, L, exec, kojarchy-lock-screen bind = $mainMod, ESCAPE, exec, kitty --class kojarchy-power-menu -e kojarchy-power-menu # Kojarchy menu (unified launcher) -bind = $mainMod SHIFT, SPACE, exec, kitty --class kojarchy-menu -e kojarchy-menu +bind = $mainMod SHIFT, SPACE, exec, kojarchy-menu # Keybindings viewer bind = $mainMod, SLASH, exec, kojarchy-menu-keybindings diff --git a/default/hypr/windows.conf b/default/hypr/windows.conf index 98f4c053..4c24e136 100644 --- a/default/hypr/windows.conf +++ b/default/hypr/windows.conf @@ -15,10 +15,6 @@ windowrule = match:class ^(org\.freedesktop\.impl\.portal\.desktop\.kde)$, float windowrule = match:class ^(org\.freedesktop\.impl\.portal\.desktop\.kde)$, size 900 600 # Kojarchy floating menus -windowrule = float on, match:class ^(kojarchy-menu)$ -windowrule = size 400 600, match:class ^(kojarchy-menu)$ -windowrule = center on, match:class ^(kojarchy-menu)$ - windowrule = float on, match:class ^(kojarchy-power-menu)$ windowrule = size 300 250, match:class ^(kojarchy-power-menu)$ windowrule = center on, match:class ^(kojarchy-power-menu)$ diff --git a/install/kojarchy-base.packages b/install/kojarchy-base.packages index 9f55d3a6..fb212720 100644 --- a/install/kojarchy-base.packages +++ b/install/kojarchy-base.packages @@ -149,6 +149,7 @@ kvantum kvantum-qt5 kvantum-theme-catppuccin-git catppuccin-gtk-theme-mocha +walker-bin nwg-look gnome-themes-extra From d00a7d6e0ad2053dd4e4108b2b18d3f350ed40fd Mon Sep 17 00:00:00 2001 From: princejoogie Date: Wed, 11 Feb 2026 04:45:51 +0800 Subject: [PATCH 37/44] fix: update fileManager to nautilus in hyprland.conf --- config/hypr/hyprland.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/hypr/hyprland.conf b/config/hypr/hyprland.conf index 5ed79c61..93a32730 100644 --- a/config/hypr/hyprland.conf +++ b/config/hypr/hyprland.conf @@ -1,7 +1,7 @@ monitor=,2560x1440@240,auto,1 $terminal = kitty -$fileManager = dolphin +$fileManager = nautilus $menu = wofi --show drun --matching startswith # Source defaults (updated via git pull, don't edit these) From 4628d2e860c5546c7ae48f23d74a3b6dc26df906 Mon Sep 17 00:00:00 2001 From: princejoogie Date: Wed, 11 Feb 2026 05:05:50 +0800 Subject: [PATCH 38/44] fix: symlink GTK4 theme for libadwaita apps (Nautilus, etc.) --- install/config/gtk.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/install/config/gtk.sh b/install/config/gtk.sh index a50293bd..47a225e4 100644 --- a/install/config/gtk.sh +++ b/install/config/gtk.sh @@ -5,4 +5,13 @@ if command -v gsettings &>/dev/null; then gsettings set org.gnome.desktop.interface icon-theme "Adwaita" 2>/dev/null || true fi +# Link GTK4/libadwaita theme (Nautilus, GNOME apps ignore gtk-theme gsetting) +THEME_DIR="/usr/share/themes/catppuccin-mocha-blue-standard+default/gtk-4.0" +if [[ -d "$THEME_DIR" ]]; then + mkdir -p ~/.config/gtk-4.0 + ln -snf "$THEME_DIR/assets" ~/.config/gtk-4.0/assets + ln -snf "$THEME_DIR/gtk.css" ~/.config/gtk-4.0/gtk.css + ln -snf "$THEME_DIR/gtk-dark.css" ~/.config/gtk-4.0/gtk-dark.css +fi + echo "GTK theme: OK" From 7e1154bc1d80fc346b67b9a8c7f35ff17af4bba0 Mon Sep 17 00:00:00 2001 From: princejoogie Date: Wed, 11 Feb 2026 05:10:09 +0800 Subject: [PATCH 39/44] feat: migrate power-menu/keybindings to walker, improve nightlight toggle and audio switch - Power menu: replace kitty+gum with walker --dmenu, remove window rules - Keybindings viewer: replace wofi with walker --dmenu - Toggle nightlight: use hyprctl temperature toggle instead of kill/restart - Audio switch: add swayosd volume/mute icon feedback with notify-send fallback - Add swayosd-server to hyprland autostart --- bin/kojarchy-cmd-audio-switch | 35 +++++++++++++++++++++++++++++++--- bin/kojarchy-menu-keybindings | 4 ++-- bin/kojarchy-power-menu | 16 +++++++++++----- bin/kojarchy-toggle-nightlight | 25 ++++++++++++++++++------ default/hypr/autostart.conf | 1 + default/hypr/bindings.conf | 4 ++-- default/hypr/windows.conf | 5 +---- 7 files changed, 68 insertions(+), 22 deletions(-) diff --git a/bin/kojarchy-cmd-audio-switch b/bin/kojarchy-cmd-audio-switch index 25746afa..5fbe0283 100755 --- a/bin/kojarchy-cmd-audio-switch +++ b/bin/kojarchy-cmd-audio-switch @@ -1,7 +1,7 @@ #!/bin/bash # Switch between audio outputs while preserving the mute status. -# By default mapped to Super + Mute. +# Shows volume/mute icon feedback via swayosd. focused_monitor="$(hyprctl monitors -j | jq -r '.[] | select(.focused == true).name')" @@ -9,7 +9,13 @@ sinks=$(pactl -f json list sinks | jq '[.[] | select((.ports | length == 0) or ( sinks_count=$(echo "$sinks" | jq '. | length') if [ "$sinks_count" -eq 0 ]; then - notify-send "No audio devices found" -u critical -t 3000 + if command -v swayosd-client &>/dev/null; then + swayosd-client \ + --monitor "$focused_monitor" \ + --custom-message "No audio devices found" + else + notify-send "No audio devices found" -u critical -t 3000 + fi exit 1 fi @@ -31,8 +37,31 @@ if [ "$next_sink_description" = "(null)" ] || [ "$next_sink_description" = "null next_sink_description=$(wpctl status | grep -E "\s+\*?\s+${sink_id}\." | sed -E 's/^.*[0-9]+\.\s+//' | sed -E 's/\s+\[.*$//') fi +next_sink_volume=$(echo "$next_sink" | jq -r \ + '.volume | to_entries[0].value.value_percent | sub("%"; "")') +next_sink_is_muted=$(echo "$next_sink" | jq -r '.mute') + +if [ "$next_sink_is_muted" = "true" ] || [ "$next_sink_volume" -eq 0 ]; then + icon_state="muted" +elif [ "$next_sink_volume" -le 33 ]; then + icon_state="low" +elif [ "$next_sink_volume" -le 66 ]; then + icon_state="medium" +else + icon_state="high" +fi + +next_sink_volume_icon="sink-volume-${icon_state}-symbolic" + if [ "$next_sink_name" != "$current_sink_name" ]; then pactl set-default-sink "$next_sink_name" fi -notify-send "Audio Output" "$next_sink_description" -t 2000 +if command -v swayosd-client &>/dev/null; then + swayosd-client \ + --monitor "$focused_monitor" \ + --custom-message "$next_sink_description" \ + --custom-icon "$next_sink_volume_icon" +else + notify-send "Audio Output" "$next_sink_description" -t 2000 +fi diff --git a/bin/kojarchy-menu-keybindings b/bin/kojarchy-menu-keybindings index 6ef8b2c5..0308be7f 100755 --- a/bin/kojarchy-menu-keybindings +++ b/bin/kojarchy-menu-keybindings @@ -1,6 +1,6 @@ #!/bin/bash -# Display Hyprland keybindings in an interactive search using wofi. +# Display Hyprland keybindings in an interactive search using walker. output_keybindings() { hyprctl -j binds | @@ -47,5 +47,5 @@ output_keybindings() { if [[ "$1" == "--print" || "$1" == "-p" ]]; then output_keybindings else - output_keybindings | wofi --show dmenu -p 'Keybindings' --width 800 --height 600 + output_keybindings | walker --dmenu --width 600 --maxheight 630 -p "Keybindings…" 2>/dev/null fi diff --git a/bin/kojarchy-power-menu b/bin/kojarchy-power-menu index 35b74524..9c2f8fde 100755 --- a/bin/kojarchy-power-menu +++ b/bin/kojarchy-power-menu @@ -1,12 +1,18 @@ #!/bin/bash -# Power menu — lock, reboot, or shutdown via gum. -# Launched in a floating terminal from the keybinding. +# Power menu — lock, reboot, or shutdown via walker dmenu. +# Bound to ALT+ESCAPE. -choice=$(gum choose "Lock" "Reboot" "Shutdown" "Cancel") +OPTIONS="Lock +Reboot +Shutdown" + +choice=$(echo "$OPTIONS" | walker --dmenu --width 200 --minheight 1 --maxheight 150 -p "Power…" 2>/dev/null) + +[ -z "$choice" ] && exit 0 case "$choice" in - "Lock") kojarchy-lock-screen ;; - "Reboot") kojarchy-cmd-reboot ;; + "Lock") kojarchy-lock-screen ;; + "Reboot") kojarchy-cmd-reboot ;; "Shutdown") kojarchy-cmd-shutdown ;; esac diff --git a/bin/kojarchy-toggle-nightlight b/bin/kojarchy-toggle-nightlight index 09ef7b0e..4981838c 100755 --- a/bin/kojarchy-toggle-nightlight +++ b/bin/kojarchy-toggle-nightlight @@ -1,11 +1,24 @@ #!/bin/bash -# Toggle hyprsunset nightlight filter +# Toggle hyprsunset nightlight filter between warm (4000K) and neutral (6000K). +# Uses hyprctl to set temperature instead of killing the process. -if pgrep -x hyprsunset > /dev/null; then - pkill -x hyprsunset - notify-send "'hyprsunset' stopped" +ON_TEMP=4000 +OFF_TEMP=6000 + +# Ensure hyprsunset is running +if ! pgrep -x hyprsunset > /dev/null; then + setsid hyprsunset & + sleep 1 +fi + +# Query current temperature +CURRENT_TEMP=$(hyprctl hyprsunset temperature 2>/dev/null | grep -oE '[0-9]+') + +if [[ "$CURRENT_TEMP" == "$OFF_TEMP" ]]; then + hyprctl hyprsunset temperature $ON_TEMP + notify-send "Nightlight on" "Temperature set to ${ON_TEMP}K" else - hyprsunset --temperature 4000 & - notify-send "'hyprsunset' started" + hyprctl hyprsunset temperature $OFF_TEMP + notify-send "Nightlight off" "Temperature set to ${OFF_TEMP}K" fi diff --git a/default/hypr/autostart.conf b/default/hypr/autostart.conf index ad8f15c7..68f35194 100644 --- a/default/hypr/autostart.conf +++ b/default/hypr/autostart.conf @@ -1,5 +1,6 @@ exec-once = systemctl --user start hyprpolkitagent exec-once = waybar & dunst +exec-once = swayosd-server exec-once = swaybg -i ~/dotfiles/wallpapers/pallete.png -m fill exec-once = [workspace 1 silent] kitty exec-once = [workspace 2 silent] flatpak run app.zen_browser.zen diff --git a/default/hypr/bindings.conf b/default/hypr/bindings.conf index 591d4f92..67f8de3a 100644 --- a/default/hypr/bindings.conf +++ b/default/hypr/bindings.conf @@ -90,8 +90,8 @@ bindl = , XF86AudioPrev, exec, playerctl previous # Lock screen bind = $mainMod CTRL, L, exec, kojarchy-lock-screen -# Power menu (floating terminal for gum) -bind = $mainMod, ESCAPE, exec, kitty --class kojarchy-power-menu -e kojarchy-power-menu +# Power menu +bind = $mainMod, ESCAPE, exec, kojarchy-power-menu # Kojarchy menu (unified launcher) bind = $mainMod SHIFT, SPACE, exec, kojarchy-menu diff --git a/default/hypr/windows.conf b/default/hypr/windows.conf index 4c24e136..54bdffa9 100644 --- a/default/hypr/windows.conf +++ b/default/hypr/windows.conf @@ -14,10 +14,7 @@ windowrule = match:workspace w[t1], border_size 0 windowrule = match:class ^(org\.freedesktop\.impl\.portal\.desktop\.kde)$, float on windowrule = match:class ^(org\.freedesktop\.impl\.portal\.desktop\.kde)$, size 900 600 -# Kojarchy floating menus -windowrule = float on, match:class ^(kojarchy-power-menu)$ -windowrule = size 300 250, match:class ^(kojarchy-power-menu)$ -windowrule = center on, match:class ^(kojarchy-power-menu)$ + # App-specific rules source = ~/dotfiles/default/hypr/apps.conf From e0d08f384099f5ecdaabb860a161e6897d77ed8d Mon Sep 17 00:00:00 2001 From: princejoogie Date: Sun, 12 Apr 2026 13:37:04 +0800 Subject: [PATCH 40/44] fix: port main config and tooling updates Carry over the remaining main-branch workflow and config changes into the rewritten installer layout so shell, tmux, Hyprland, Neovim, and worktree behavior stay aligned. --- bin/_wt | 2 +- default/gitconfig | 61 ++++++++++++++++++++++++++++++++++++++ default/hypr/bindings.conf | 1 + default/hypr/input.conf | 2 +- default/zsh/aliases | 1 + install/config/git.sh | 7 +++++ 6 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 default/gitconfig diff --git a/bin/_wt b/bin/_wt index fb1088f6..3f1eae01 100755 --- a/bin/_wt +++ b/bin/_wt @@ -9,7 +9,7 @@ wt_root() { # Replace $HOME with ~ in a path wt_short_path() { -case "$1" in + case "$1" in "$HOME"*) printf '%s' "~${1#"$HOME"}" ;; *) printf '%s' "$1" ;; esac diff --git a/default/gitconfig b/default/gitconfig new file mode 100644 index 00000000..2c65e1bc --- /dev/null +++ b/default/gitconfig @@ -0,0 +1,61 @@ +[credential] + helper = store +[alias] + co = "!f() { git branch -a | awk '{gsub(\"remotes/origin/\", \"\", $1); print $1}' | sort -u | fzf-tmux -p --reverse | xargs git checkout; }; f" + col = "!f() { git branch | awk '{gsub(\"remotes/origin/\", \"\", $1); print $1}' | sort -u | fzf-tmux -p --reverse | xargs git checkout; }; f" + squash = "!f(){ git reset --soft HEAD~${1} && git commit --edit -m\"$(git log --format=%B --reverse HEAD..HEAD@{1})\"; }; f" + gone = "!f() { git fetch --all --prune; git branch -vv | awk '/: gone]/{print $1}' | xargs git branch -D; }; f" + ll = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(auto)%d%C(reset)' + root = rev-parse --show-toplevel +[core] + pager = delta +[interactive] + diffFilter = delta --color-only +[add.interactive] + useBuiltin = false +[delta] + navigate = true + light = false + side-by-side = false + + blame-palette = "#1e1e2e #181825 #11111b #313244 #45475a" + commit-decoration-style = "#6c7086" bold box ul + dark = true + file-decoration-style = "#6c7086" + file-style = "#cdd6f4" + hunk-header-decoration-style = "#6c7086" box ul + hunk-header-file-style = bold + hunk-header-line-number-style = bold "#a6adc8" + hunk-header-style = file line-number syntax + line-numbers-left-style = "#6c7086" + line-numbers-minus-style = bold "#f38ba8" + line-numbers-plus-style = bold "#a6e3a1" + line-numbers-right-style = "#6c7086" + line-numbers-zero-style = "#6c7086" + minus-emph-style = bold syntax "#53394c" + minus-style = syntax "#34293a" + plus-emph-style = bold syntax "#404f4a" + plus-style = syntax "#2c3239" + map-styles = \ + bold purple => syntax "#494060", \ + bold blue => syntax "#384361", \ + bold cyan => syntax "#384d5d", \ + bold yellow => syntax "#544f4e" +[merge] + conflictstyle = diff3 +[diff] + colorMoved = default +[init] + defaultBranch = main +[push] + autoSetupRemote = true +[rerere] + enabled = true +[credential "https://github.com"] + helper = + helper = !gh auth git-credential +[credential "https://gist.github.com"] + helper = + helper = !gh auth git-credential +[pull] + rebase = true diff --git a/default/hypr/bindings.conf b/default/hypr/bindings.conf index 67f8de3a..1807ddca 100644 --- a/default/hypr/bindings.conf +++ b/default/hypr/bindings.conf @@ -69,6 +69,7 @@ bindm = $mainMod, mouse:272, movewindow bindm = $mainMod, mouse:273, resizewindow # Screenshots & screen recording +bind = $mainMod SHIFT, P, exec, kojarchy-cmd-screenshot region edit bind = , PRINT, exec, kojarchy-cmd-screenshot region edit bind = SHIFT, PRINT, exec, kojarchy-cmd-screenshot region clipboard bind = $mainMod, PRINT, exec, kojarchy-cmd-screenrecord diff --git a/default/hypr/input.conf b/default/hypr/input.conf index 57f9e675..7751e46d 100644 --- a/default/hypr/input.conf +++ b/default/hypr/input.conf @@ -2,7 +2,7 @@ input { kb_layout = us kb_variant = kb_model = - kb_options = + kb_options = ctrl:nocaps kb_rules = repeat_delay = 300 diff --git a/default/zsh/aliases b/default/zsh/aliases index 51a70287..ba0741d4 100644 --- a/default/zsh/aliases +++ b/default/zsh/aliases @@ -9,3 +9,4 @@ alias pip=pip3 alias wt=". _wt" alias ai="noglob opencode run --model \"opencode/gemini-3-flash\"" alias open=xdg-open +alias claude="claude --dangerously-skip-permissions" diff --git a/install/config/git.sh b/install/config/git.sh index 58b0f842..47476328 100644 --- a/install/config/git.sh +++ b/install/config/git.sh @@ -1,3 +1,10 @@ +# Keep shared git defaults in-repo so they update with git pull. +include_path="$KOJARCHY_DIR/default/gitconfig" + +if [[ -f "$include_path" ]] && ! git config --global --get-all include.path 2>/dev/null | grep -Fxq "$include_path"; then + git config --global --add include.path "$include_path" +fi + # Prompt for git identity if not already set (runs via source, not run_logged) if [[ -z "$(git config --global user.name)" ]]; then name=$(gum input --placeholder "Your full name" --header "Git user.name:" Date: Sun, 12 Apr 2026 13:44:08 +0800 Subject: [PATCH 41/44] fix: move worktrees skill into config/opencode Keep opencode skills under the rewritten config layout so the rebased branch no longer carries a duplicate top-level opencode tree. --- .../.config => config}/opencode/skills/worktrees/SKILL.md | 6 +++--- .../skills/worktrees/references/cursor-worktrees-json.md | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) rename {opencode/.config => config}/opencode/skills/worktrees/SKILL.md (93%) rename {opencode/.config => config}/opencode/skills/worktrees/references/cursor-worktrees-json.md (85%) diff --git a/opencode/.config/opencode/skills/worktrees/SKILL.md b/config/opencode/skills/worktrees/SKILL.md similarity index 93% rename from opencode/.config/opencode/skills/worktrees/SKILL.md rename to config/opencode/skills/worktrees/SKILL.md index a6ab6dba..2e2c15c4 100644 --- a/opencode/.config/opencode/skills/worktrees/SKILL.md +++ b/config/opencode/skills/worktrees/SKILL.md @@ -9,7 +9,7 @@ description: > # Git Worktrees -All worktrees go in `~/.worktrees///` — outside the project, no `.gitignore` needed. +All worktrees go in `~/.worktrees///` -- outside the project, no `.gitignore` needed. ## Workflow @@ -29,7 +29,7 @@ Derive `` from the branch name (e.g. `fix/IH-694-missing-icon` -> `ih-694` ### 2. Run setup -Check for `.cursor/worktrees.json` first. If it exists, execute its hooks and skip steps 3–4. +Check for `.cursor/worktrees.json` first. If it exists, execute its hooks and skip steps 3-4. See [references/cursor-worktrees-json.md](references/cursor-worktrees-json.md) for full schema. @@ -63,7 +63,7 @@ find . -name '.env*' -type f -not -name '*.sample' -not -path '*/node_modules/*' done ``` -Never use `ln -s` — glob-based tooling (bundlers, config loaders) silently ignores symlinks. +Never use `ln -s` -- glob-based tooling (bundlers, config loaders) silently ignores symlinks. ### 4. Install dependencies diff --git a/opencode/.config/opencode/skills/worktrees/references/cursor-worktrees-json.md b/config/opencode/skills/worktrees/references/cursor-worktrees-json.md similarity index 85% rename from opencode/.config/opencode/skills/worktrees/references/cursor-worktrees-json.md rename to config/opencode/skills/worktrees/references/cursor-worktrees-json.md index d2152dd7..cefd57e1 100644 --- a/opencode/.config/opencode/skills/worktrees/references/cursor-worktrees-json.md +++ b/config/opencode/skills/worktrees/references/cursor-worktrees-json.md @@ -31,7 +31,7 @@ Set this before executing any commands from the config. ## Examples -**Command array** — each string runs sequentially: +**Command array** -- each string runs sequentially: ```json { @@ -43,7 +43,7 @@ Set this before executing any commands from the config. } ``` -**Script reference** — single string, resolved relative to the worktree root: +**Script reference** -- single string, resolved relative to the worktree root: ```json { @@ -52,7 +52,7 @@ Set this before executing any commands from the config. } ``` -**Script with args** — `$ROOT_WORKTREE_PATH` is available: +**Script with args** -- `$ROOT_WORKTREE_PATH` is available: ```json { @@ -67,4 +67,4 @@ Set this before executing any commands from the config. 1. Run commands **sequentially** from the worktree directory. 2. Export `ROOT_WORKTREE_PATH` pointing to the main repo before running. 3. If the value is a single string (not array), treat it as a script path relative to the worktree root. -4. **Stop on failure** — if a command exits non-zero, halt and report the error. +4. **Stop on failure** -- if a command exits non-zero, halt and report the error. From a39f977c4f471bdaae6d823e62adbd9f0a864c5b Mon Sep 17 00:00:00 2001 From: princejoogie Date: Sun, 12 Apr 2026 14:23:41 +0800 Subject: [PATCH 42/44] feat: sync selected omarchy upstream improvements Port the approved upstream shell, Hyprland, update, installer, and tooling changes into the rewritten Kojarchy layout so the branch stays aligned without pulling in the larger platform-specific churn. --- bin/kojarchy-npx-install | 21 +++++ bin/kojarchy-update | 6 ++ bin/kojarchy-update-perform | 3 - bin/kojarchy-update-system-pkgs | 3 + check-upstream.sh | 2 +- config/opencode/opencode.json | 1 + default/hypr/bindings.conf | 3 +- default/hypr/looknfeel.conf | 6 ++ .../nautilus-python/extensions/localsend.py | 83 +++++++++++++++++++ default/zsh/init | 4 +- default/zsh/rc | 2 +- install/config/all.sh | 2 + install/config/gtk.sh | 5 ++ install/config/hardware/vulkan.sh | 20 +++++ install/config/nautilus-python.sh | 6 ++ install/kojarchy-base.packages | 2 +- install/kojarchy-nvidia.packages | 1 + install/packaging/all.sh | 1 + install/packaging/npx.sh | 6 ++ 19 files changed, 168 insertions(+), 9 deletions(-) create mode 100755 bin/kojarchy-npx-install create mode 100644 default/nautilus-python/extensions/localsend.py create mode 100644 install/config/hardware/vulkan.sh create mode 100644 install/config/nautilus-python.sh create mode 100644 install/packaging/npx.sh diff --git a/bin/kojarchy-npx-install b/bin/kojarchy-npx-install new file mode 100755 index 00000000..d7e43afc --- /dev/null +++ b/bin/kojarchy-npx-install @@ -0,0 +1,21 @@ +#!/bin/bash + +# Install an npx-backed wrapper command into ~/.local/bin. +# Usage: kojarchy-npx-install [command-name] + +if [[ -z ${1:-} ]]; then + echo "Usage: kojarchy-npx-install [command-name]" + exit 1 +fi + +package=$1 +command=${2:-$1} + +mkdir -p "$HOME/.local/bin" + +cat > "$HOME/.local/bin/$command" </dev/null || true -# Capture update logs -exec > >(tee "/tmp/kojarchy-update.log") 2>&1 - # Perform all update steps kojarchy-update-time kojarchy-update-system-pkgs diff --git a/bin/kojarchy-update-system-pkgs b/bin/kojarchy-update-system-pkgs index 36a78418..3a7b7e43 100755 --- a/bin/kojarchy-update-system-pkgs +++ b/bin/kojarchy-update-system-pkgs @@ -2,5 +2,8 @@ set -e +echo -e "\e[32m\nUpdate Arch signing keys\e[0m" +sudo pacman -Sy --noconfirm archlinux-keyring >/dev/null + echo -e "\e[32m\nUpdate system packages\e[0m" sudo pacman -Syyu --noconfirm diff --git a/check-upstream.sh b/check-upstream.sh index 7a412b70..fb2b6b21 100755 --- a/check-upstream.sh +++ b/check-upstream.sh @@ -11,7 +11,7 @@ OMARCHY_LOCAL="/tmp/kojarchy-omarchy-upstream" DIFF_FILE="/tmp/kojarchy-omarchy-diff.patch" # Last omarchy commit hash we synced against -OMARCHY_BASELINE="ffafe1727e32c38ba5a291bf3a12d5995a01fda0" +OMARCHY_BASELINE="1732551873aae48a8418595ef9bc3b2cbb756b0c" echo "=== Kojarchy Upstream Sync Check ===" echo "Baseline: $OMARCHY_BASELINE" diff --git a/config/opencode/opencode.json b/config/opencode/opencode.json index d6ab867e..886572f6 100644 --- a/config/opencode/opencode.json +++ b/config/opencode/opencode.json @@ -1,5 +1,6 @@ { "$schema": "https://opencode.ai/config.json", + "autoupdate": false, "plugin": ["opencode-anthropic-auth"], "mcp": { "playwriter": { diff --git a/default/hypr/bindings.conf b/default/hypr/bindings.conf index 1807ddca..c24b66bf 100644 --- a/default/hypr/bindings.conf +++ b/default/hypr/bindings.conf @@ -70,7 +70,7 @@ bindm = $mainMod, mouse:273, resizewindow # Screenshots & screen recording bind = $mainMod SHIFT, P, exec, kojarchy-cmd-screenshot region edit -bind = , PRINT, exec, kojarchy-cmd-screenshot region edit +bind = , PRINT, exec, kojarchy-cmd-screenshot bind = SHIFT, PRINT, exec, kojarchy-cmd-screenshot region clipboard bind = $mainMod, PRINT, exec, kojarchy-cmd-screenrecord @@ -96,6 +96,7 @@ bind = $mainMod, ESCAPE, exec, kojarchy-power-menu # Kojarchy menu (unified launcher) bind = $mainMod SHIFT, SPACE, exec, kojarchy-menu +bind = $mainMod CTRL, O, exec, kojarchy-menu # Keybindings viewer bind = $mainMod, SLASH, exec, kojarchy-menu-keybindings diff --git a/default/hypr/looknfeel.conf b/default/hypr/looknfeel.conf index c60d7b72..4793e472 100644 --- a/default/hypr/looknfeel.conf +++ b/default/hypr/looknfeel.conf @@ -54,6 +54,7 @@ animations { animation = workspaces, 1, 1.5, almostLinear, fade animation = workspacesIn, 1, 3, easeOutQuint, slide animation = workspacesOut, 1, 3, easeOutQuint, slide + animation = specialWorkspace, 1, 4, easeOutQuint, slidevert } dwindle { @@ -69,4 +70,9 @@ misc { focus_on_activate = true force_default_wallpaper = -1 disable_hyprland_logo = false + disable_scale_notification = true +} + +cursor { + warp_on_change_workspace = 1 } diff --git a/default/nautilus-python/extensions/localsend.py b/default/nautilus-python/extensions/localsend.py new file mode 100644 index 00000000..114c5b02 --- /dev/null +++ b/default/nautilus-python/extensions/localsend.py @@ -0,0 +1,83 @@ +import shutil + +from gi import require_version + +require_version("Nautilus", "4.1") + +from gi.repository import GObject, Gio, Nautilus + + +class SendViaLocalSendAction(GObject.GObject, Nautilus.MenuProvider): + def _launch_localsend(self, paths): + command = self._resolve_command() + if not command: + return + + if command[-1] == "@@": + command = command + paths + ["@@"] + else: + command = command + paths + + Gio.Subprocess.new(command, Gio.SubprocessFlags.NONE) + + def _resolve_command(self): + localsend = shutil.which("localsend") + if localsend: + return [localsend, "--headless", "send"] + + flatpak = shutil.which("flatpak") + if flatpak and self._has_flatpak_app(flatpak, "org.localsend.localsend_app"): + return [ + flatpak, + "run", + "--file-forwarding", + "org.localsend.localsend_app", + "@@", + ] + + return None + + def _has_flatpak_app(self, flatpak, app_id): + process = Gio.Subprocess.new( + [flatpak, "info", app_id], + Gio.SubprocessFlags.STDOUT_SILENCE | Gio.SubprocessFlags.STDERR_SILENCE, + ) + return process.wait_check() + + def _selected_paths(self, files): + paths = [] + + for file in files: + location = file.get_location() + if not location: + continue + + path = location.get_path() + if path and path not in paths: + paths.append(path) + + return paths + + def _make_item(self, paths): + label = ( + "Send via LocalSend" if len(paths) == 1 else "Send selected via LocalSend" + ) + item = Nautilus.MenuItem( + name="LocalSendNautilus::send_via_localsend", + label=label, + icon="localsend", + ) + item.connect("activate", self._on_activate, paths) + return item + + def _on_activate(self, _menu, paths): + self._launch_localsend(paths) + + def get_file_items(self, *args): + files = args[0] if len(args) == 1 else args[1] + paths = self._selected_paths(files) + + if not paths or not self._resolve_command(): + return [] + + return [self._make_item(paths)] diff --git a/default/zsh/init b/default/zsh/init index 8ebf16f0..87801c5e 100644 --- a/default/zsh/init +++ b/default/zsh/init @@ -1,11 +1,11 @@ # starship -if [[ -x "$(command -v starship)" ]]; then +if [[ $- == *i* ]] && [[ ${TERM:-} != "dumb" ]] && [[ -x "$(command -v starship)" ]]; then eval "$(starship init zsh)" fi # mise (replaces fnm) if command -v mise &>/dev/null; then - eval "$(mise activate zsh)" + eval "$(mise activate zsh --shims)" fi # uv diff --git a/default/zsh/rc b/default/zsh/rc index 65ac45a2..3617ef1e 100644 --- a/default/zsh/rc +++ b/default/zsh/rc @@ -1,5 +1,5 @@ +source ~/dotfiles/default/zsh/envs source ~/dotfiles/default/zsh/shell source ~/dotfiles/default/zsh/aliases source ~/dotfiles/default/zsh/functions source ~/dotfiles/default/zsh/init -source ~/dotfiles/default/zsh/envs diff --git a/install/config/all.sh b/install/config/all.sh index 4c99ad23..c3b55d29 100644 --- a/install/config/all.sh +++ b/install/config/all.sh @@ -13,6 +13,7 @@ clear_logo start_log_output run_logged $KOJARCHY_INSTALL/config/docker.sh run_logged $KOJARCHY_INSTALL/config/gtk.sh +run_logged $KOJARCHY_INSTALL/config/nautilus-python.sh run_logged $KOJARCHY_INSTALL/config/gpg.sh run_logged $KOJARCHY_INSTALL/config/mimetypes.sh run_logged $KOJARCHY_INSTALL/config/ssh-flakiness.sh @@ -28,6 +29,7 @@ run_logged $KOJARCHY_INSTALL/config/detect-keyboard-layout.sh run_logged $KOJARCHY_INSTALL/config/hardware/network.sh run_logged $KOJARCHY_INSTALL/config/hardware/bluetooth.sh run_logged $KOJARCHY_INSTALL/config/hardware/intel.sh +run_logged $KOJARCHY_INSTALL/config/hardware/vulkan.sh run_logged $KOJARCHY_INSTALL/config/hardware/set-wireless-regdom.sh run_logged $KOJARCHY_INSTALL/config/hardware/fix-fkeys.sh run_logged $KOJARCHY_INSTALL/config/hardware/fix-synaptic-touchpad.sh diff --git a/install/config/gtk.sh b/install/config/gtk.sh index 47a225e4..59b98b97 100644 --- a/install/config/gtk.sh +++ b/install/config/gtk.sh @@ -14,4 +14,9 @@ if [[ -d "$THEME_DIR" ]]; then ln -snf "$THEME_DIR/gtk-dark.css" ~/.config/gtk-4.0/gtk-dark.css fi +# Default Chromium to follow the system appearance for newly created profiles. +if [[ -d /usr/lib/chromium ]]; then + printf '%s\n' '{"browser":{"theme":{"color_scheme":0}}}' | sudo tee /usr/lib/chromium/initial_preferences >/dev/null +fi + echo "GTK theme: OK" diff --git a/install/config/hardware/vulkan.sh b/install/config/hardware/vulkan.sh new file mode 100644 index 00000000..5c3832fd --- /dev/null +++ b/install/config/hardware/vulkan.sh @@ -0,0 +1,20 @@ +# Install Vulkan drivers matching detected GPU hardware. +# NVIDIA Vulkan is covered by the NVIDIA driver package set. + +declare -A VULKAN_DRIVERS=( + [Intel]=vulkan-intel + [AMD]=vulkan-radeon + [Apple]=vulkan-asahi +) + +PACKAGES=() + +for vendor in "${!VULKAN_DRIVERS[@]}"; do + if lspci | grep -iE "(VGA|Display).*$vendor" >/dev/null; then + PACKAGES+=("${VULKAN_DRIVERS[$vendor]}") + fi +done + +if (( ${#PACKAGES[@]} > 0 )); then + yay -S --noconfirm --needed "${PACKAGES[@]}" +fi diff --git a/install/config/nautilus-python.sh b/install/config/nautilus-python.sh new file mode 100644 index 00000000..49f8879d --- /dev/null +++ b/install/config/nautilus-python.sh @@ -0,0 +1,6 @@ +EXTENSIONS_DIR="$HOME/.local/share/nautilus-python/extensions" + +mkdir -p "$EXTENSIONS_DIR" +cp "$KOJARCHY_DIR/default/nautilus-python/extensions/localsend.py" "$EXTENSIONS_DIR/" + +echo "Nautilus extensions: OK" diff --git a/install/kojarchy-base.packages b/install/kojarchy-base.packages index fb212720..1aac94fe 100644 --- a/install/kojarchy-base.packages +++ b/install/kojarchy-base.packages @@ -94,13 +94,13 @@ tmux-sessionizer-bin clang llvm rust -opencode ripgrep lazydocker lazygit # === File Management === nautilus +nautilus-python yazi fd gdu diff --git a/install/kojarchy-nvidia.packages b/install/kojarchy-nvidia.packages index f90f0438..10c1d1a5 100644 --- a/install/kojarchy-nvidia.packages +++ b/install/kojarchy-nvidia.packages @@ -2,5 +2,6 @@ # Only install these on systems with NVIDIA GPUs nvidia-open-dkms +nvidia-utils lib32-nvidia-utils libva-nvidia-driver diff --git a/install/packaging/all.sh b/install/packaging/all.sh index 64dc7298..5c1f968d 100644 --- a/install/packaging/all.sh +++ b/install/packaging/all.sh @@ -1,5 +1,6 @@ run_logged $KOJARCHY_INSTALL/packaging/aur-helper.sh run_logged $KOJARCHY_INSTALL/packaging/base.sh +run_logged $KOJARCHY_INSTALL/packaging/npx.sh # Pause log tail for interactive prompts (it overwrites the screen) stop_log_output diff --git a/install/packaging/npx.sh b/install/packaging/npx.sh new file mode 100644 index 00000000..6f0615bd --- /dev/null +++ b/install/packaging/npx.sh @@ -0,0 +1,6 @@ +$KOJARCHY_DIR/bin/kojarchy-npx-install @openai/codex codex +$KOJARCHY_DIR/bin/kojarchy-npx-install @google/gemini-cli gemini +$KOJARCHY_DIR/bin/kojarchy-npx-install @github/copilot copilot +$KOJARCHY_DIR/bin/kojarchy-npx-install playwright playwright-cli +$KOJARCHY_DIR/bin/kojarchy-npx-install @mariozechner/pi-coding-agent pi +$KOJARCHY_DIR/bin/kojarchy-npx-install opencode-ai opencode From 7b1e70396b7793673459bd063bf4497b58c73644 Mon Sep 17 00:00:00 2001 From: princejoogie Date: Sun, 12 Apr 2026 15:10:07 +0800 Subject: [PATCH 43/44] feat: symlink managed config files Deploy repo-managed config files into ~/.config as symlinks and refresh them during git-based updates so edits under ~/.config map directly back to the dotfiles repo. --- bin/kojarchy-sync-config | 10 ++++++++++ bin/kojarchy-update-git | 4 ++++ install/config/config.sh | 23 ++++++++++++++++++++--- 3 files changed, 34 insertions(+), 3 deletions(-) create mode 100755 bin/kojarchy-sync-config diff --git a/bin/kojarchy-sync-config b/bin/kojarchy-sync-config new file mode 100755 index 00000000..15581c39 --- /dev/null +++ b/bin/kojarchy-sync-config @@ -0,0 +1,10 @@ +#!/bin/bash + +set -e + +KOJARCHY_PATH="${KOJARCHY_PATH:-$HOME/dotfiles}" +KOJARCHY_DIR="$KOJARCHY_PATH" + +source "$KOJARCHY_PATH/install/config/config.sh" +source "$KOJARCHY_PATH/install/config/bin.sh" +source "$KOJARCHY_PATH/install/config/detect-keyboard-layout.sh" diff --git a/bin/kojarchy-update-git b/bin/kojarchy-update-git index f44b8e38..4181040e 100755 --- a/bin/kojarchy-update-git +++ b/bin/kojarchy-update-git @@ -7,3 +7,7 @@ KOJARCHY_PATH="${KOJARCHY_PATH:-$HOME/dotfiles}" echo -e "\e[32mUpdate Kojarchy\e[0m" git -C "$KOJARCHY_PATH" pull --autostash git -C "$KOJARCHY_PATH" --no-pager diff --check || git -C "$KOJARCHY_PATH" reset --merge + +if [[ -x "$KOJARCHY_PATH/bin/kojarchy-sync-config" ]]; then + KOJARCHY_PATH="$KOJARCHY_PATH" "$KOJARCHY_PATH/bin/kojarchy-sync-config" +fi diff --git a/install/config/config.sh b/install/config/config.sh index 495c854b..5fa73946 100644 --- a/install/config/config.sh +++ b/install/config/config.sh @@ -1,8 +1,25 @@ -# Copy over Kojarchy configs to ~/.config/ +# Symlink Kojarchy-managed configs into ~/.config/ so updates apply immediately. mkdir -p ~/.config -cp -R "$KOJARCHY_DIR/config/"* ~/.config/ + +while IFS= read -r -d '' source_path; do + rel_path="${source_path#$KOJARCHY_DIR/config/}" + target_path="$HOME/.config/$rel_path" + + mkdir -p "$(dirname "$target_path")" + + if [[ -L "$target_path" ]]; then + if [[ "$(readlink "$target_path")" == "$source_path" ]]; then + continue + fi + rm -f "$target_path" + elif [[ -e "$target_path" ]]; then + mv "$target_path" "${target_path}.bak.$(date +%Y%m%d%H%M%S)" + fi + + ln -s "$source_path" "$target_path" +done < <(find "$KOJARCHY_DIR/config" \( -type f -o -type l \) -print0) # Use default zshrc from Kojarchy cp "$KOJARCHY_DIR/default/zshrc" ~/.zshrc -echo "Configs deployed to ~/.config/" +echo "Configs symlinked into ~/.config/" From a66d25e89090ab0a446d823391302f93092665a3 Mon Sep 17 00:00:00 2001 From: princejoogie Date: Sat, 18 Apr 2026 11:40:13 +0800 Subject: [PATCH 44/44] feat: persist waybar and hyprland toggle state --- bin/kojarchy-hyprland-toggle | 41 +++++++++++++++++++++++++++ bin/kojarchy-hyprland-toggle-disabled | 5 ++++ bin/kojarchy-hyprland-toggle-enabled | 5 ++++ bin/kojarchy-toggle | 35 +++++++++++++++++++++++ bin/kojarchy-toggle-disabled | 5 ++++ bin/kojarchy-toggle-enabled | 5 ++++ bin/kojarchy-toggle-waybar | 28 +++++++++++++++--- check-upstream.sh | 10 +++++-- config/hypr/hyprland.conf | 3 ++ default/hypr/autostart.conf | 3 +- default/hypr/toggles/flags.conf | 2 ++ install/config/all.sh | 1 + install/config/kojarchy-toggles.sh | 5 ++++ 13 files changed, 140 insertions(+), 8 deletions(-) create mode 100755 bin/kojarchy-hyprland-toggle create mode 100755 bin/kojarchy-hyprland-toggle-disabled create mode 100755 bin/kojarchy-hyprland-toggle-enabled create mode 100755 bin/kojarchy-toggle create mode 100755 bin/kojarchy-toggle-disabled create mode 100755 bin/kojarchy-toggle-enabled create mode 100644 default/hypr/toggles/flags.conf create mode 100644 install/config/kojarchy-toggles.sh diff --git a/bin/kojarchy-hyprland-toggle b/bin/kojarchy-hyprland-toggle new file mode 100755 index 00000000..ca414909 --- /dev/null +++ b/bin/kojarchy-hyprland-toggle @@ -0,0 +1,41 @@ +#!/bin/bash + +# Toggle persistent Hyprland config fragments and reload Hyprland. + +set -euo pipefail + +ENABLED_NOTIFICATION="" +DISABLED_NOTIFICATION="" + +while [[ $# -gt 1 ]]; do + case "$1" in + --enabled-notification) ENABLED_NOTIFICATION="$2"; shift 2 ;; + --disabled-notification) DISABLED_NOTIFICATION="$2"; shift 2 ;; + *) break ;; + esac +done + +FLAG_NAME="${1:-}" +FLAG_DIR="$HOME/.local/state/kojarchy/toggles/hypr" +FLAG="$FLAG_DIR/$FLAG_NAME.conf" +FLAG_SOURCE="$HOME/dotfiles/default/hypr/toggles/$FLAG_NAME.conf" + +if [[ -z "$FLAG_NAME" ]]; then + echo "Usage: kojarchy-hyprland-toggle [--enabled-notification msg] [--disabled-notification msg] " >&2 + exit 1 +fi + +mkdir -p "$FLAG_DIR" + +if [[ -f "$FLAG" ]]; then + rm -f "$FLAG" + [[ -n "$DISABLED_NOTIFICATION" ]] && notify-send -u low "$DISABLED_NOTIFICATION" +elif [[ -f "$FLAG_SOURCE" ]]; then + cp "$FLAG_SOURCE" "$FLAG" + [[ -n "$ENABLED_NOTIFICATION" ]] && notify-send -u low "$ENABLED_NOTIFICATION" +else + echo "Unknown Hyprland toggle: $FLAG_NAME" >&2 + exit 1 +fi + +hyprctl reload >/dev/null diff --git a/bin/kojarchy-hyprland-toggle-disabled b/bin/kojarchy-hyprland-toggle-disabled new file mode 100755 index 00000000..2ef0ec8f --- /dev/null +++ b/bin/kojarchy-hyprland-toggle-disabled @@ -0,0 +1,5 @@ +#!/bin/bash + +# Check if a Hyprland toggle is currently disabled. + +[[ ! -f "$HOME/.local/state/kojarchy/toggles/hypr/$1.conf" ]] diff --git a/bin/kojarchy-hyprland-toggle-enabled b/bin/kojarchy-hyprland-toggle-enabled new file mode 100755 index 00000000..293c328d --- /dev/null +++ b/bin/kojarchy-hyprland-toggle-enabled @@ -0,0 +1,5 @@ +#!/bin/bash + +# Check if a Hyprland toggle is currently enabled. + +[[ -f "$HOME/.local/state/kojarchy/toggles/hypr/$1.conf" ]] diff --git a/bin/kojarchy-toggle b/bin/kojarchy-toggle new file mode 100755 index 00000000..a8a2612a --- /dev/null +++ b/bin/kojarchy-toggle @@ -0,0 +1,35 @@ +#!/bin/bash + +# Toggle persistent Kojarchy feature flags on or off. + +set -euo pipefail + +ENABLED_NOTIFICATION="" +DISABLED_NOTIFICATION="" + +while [[ $# -gt 1 ]]; do + case "$1" in + --enabled-notification) ENABLED_NOTIFICATION="$2"; shift 2 ;; + --disabled-notification) DISABLED_NOTIFICATION="$2"; shift 2 ;; + *) break ;; + esac +done + +FLAG_NAME="${1:-}" +FLAG_DIR="$HOME/.local/state/kojarchy/toggles" +FLAG="$FLAG_DIR/$FLAG_NAME" + +if [[ -z "$FLAG_NAME" ]]; then + echo "Usage: kojarchy-toggle [--enabled-notification msg] [--disabled-notification msg] " >&2 + exit 1 +fi + +mkdir -p "$FLAG_DIR" + +if [[ -f "$FLAG" ]]; then + rm -f "$FLAG" + [[ -n "$DISABLED_NOTIFICATION" ]] && notify-send -u low "$DISABLED_NOTIFICATION" +else + touch "$FLAG" + [[ -n "$ENABLED_NOTIFICATION" ]] && notify-send -u low "$ENABLED_NOTIFICATION" +fi diff --git a/bin/kojarchy-toggle-disabled b/bin/kojarchy-toggle-disabled new file mode 100755 index 00000000..22047742 --- /dev/null +++ b/bin/kojarchy-toggle-disabled @@ -0,0 +1,5 @@ +#!/bin/bash + +# Check if a Kojarchy toggle is currently disabled. + +[[ ! -f "$HOME/.local/state/kojarchy/toggles/$1" ]] diff --git a/bin/kojarchy-toggle-enabled b/bin/kojarchy-toggle-enabled new file mode 100755 index 00000000..69a451ae --- /dev/null +++ b/bin/kojarchy-toggle-enabled @@ -0,0 +1,5 @@ +#!/bin/bash + +# Check if a Kojarchy toggle is currently enabled. + +[[ -f "$HOME/.local/state/kojarchy/toggles/$1" ]] diff --git a/bin/kojarchy-toggle-waybar b/bin/kojarchy-toggle-waybar index abc3dbd1..eceb920d 100755 --- a/bin/kojarchy-toggle-waybar +++ b/bin/kojarchy-toggle-waybar @@ -2,8 +2,15 @@ # Toggle waybar visibility and adjust gaps/rounding accordingly -WAYBAR_PID=$(pgrep -x waybar) +set -euo pipefail + GAPS_STATE_FILE="${XDG_CACHE_HOME:-$HOME/.cache}/waybar-gaps" +WAYBAR_FLAG="waybar-off" + +WAYBAR_RUNNING=0 +if pgrep -x waybar >/dev/null; then + WAYBAR_RUNNING=1 +fi get_gap_value() { local option="$1" @@ -11,7 +18,7 @@ get_gap_value() { } # Check if Waybar is running -if [ -n "$WAYBAR_PID" ]; then +if [ "$WAYBAR_RUNNING" -eq 1 ]; then # Store current gaps/rounding and set to 0 gaps_in=$(get_gap_value "general:gaps_in") gaps_out=$(get_gap_value "general:gaps_out") @@ -21,8 +28,14 @@ if [ -n "$WAYBAR_PID" ]; then hyprctl keyword general:gaps_out 0 hyprctl keyword decoration:rounding 0 - # Kill Waybar using its PID - kill "$WAYBAR_PID" + if kojarchy-toggle-disabled "$WAYBAR_FLAG"; then + kojarchy-toggle \ + --enabled-notification " Bar hidden" \ + --disabled-notification " Bar visible" \ + "$WAYBAR_FLAG" + fi + + pkill -x waybar || true else # Restore gaps/rounding if saved if [ -f "$GAPS_STATE_FILE" ]; then @@ -33,6 +46,13 @@ else rm -f "$GAPS_STATE_FILE" fi + if kojarchy-toggle-enabled "$WAYBAR_FLAG"; then + kojarchy-toggle \ + --enabled-notification " Bar hidden" \ + --disabled-notification " Bar visible" \ + "$WAYBAR_FLAG" + fi + # Start Waybar waybar & fi diff --git a/check-upstream.sh b/check-upstream.sh index fb2b6b21..ee1fe1fd 100755 --- a/check-upstream.sh +++ b/check-upstream.sh @@ -11,7 +11,7 @@ OMARCHY_LOCAL="/tmp/kojarchy-omarchy-upstream" DIFF_FILE="/tmp/kojarchy-omarchy-diff.patch" # Last omarchy commit hash we synced against -OMARCHY_BASELINE="1732551873aae48a8418595ef9bc3b2cbb756b0c" +OMARCHY_BASELINE="e852895e5c2810350dff48ced51df6eca3fdec1c" echo "=== Kojarchy Upstream Sync Check ===" echo "Baseline: $OMARCHY_BASELINE" @@ -55,7 +55,7 @@ echo "Handing off to opencode..." echo "" # Single interactive opencode session that analyzes, asks, and applies -opencode run "You are reviewing upstream changes from omarchy to sync into our kojarchy dotfiles repo. +echo "You are reviewing upstream changes from omarchy to sync into our kojarchy dotfiles repo. ## Context - Our kojarchy repo: $KOJARCHY_DIR @@ -89,4 +89,8 @@ $DIFF_STAT 6. Adapt all changes to kojarchy naming/structure — do not copy omarchy references verbatim 7. Do NOT commit — just make the file changes 8. After applying, print a summary of what was changed and remind me to review with git diff and commit when ready -9. Then update the OMARCHY_BASELINE variable in $KOJARCHY_DIR/check-upstream.sh from \"$OMARCHY_BASELINE\" to \"$OMARCHY_LATEST\" by editing the file directly" +9. Then update the OMARCHY_BASELINE variable in $KOJARCHY_DIR/check-upstream.sh from \"$OMARCHY_BASELINE\" to \"$OMARCHY_LATEST\" by editing the file directly" | opencode run + +echo "continuing session..." + +opencode -c diff --git a/config/hypr/hyprland.conf b/config/hypr/hyprland.conf index 93a32730..68ed3ccb 100644 --- a/config/hypr/hyprland.conf +++ b/config/hypr/hyprland.conf @@ -12,6 +12,9 @@ source = ~/dotfiles/default/hypr/input.conf source = ~/dotfiles/default/hypr/bindings.conf source = ~/dotfiles/default/hypr/windows.conf +# Persistent Hyprland toggle fragments live here. +source = ~/.local/state/kojarchy/toggles/hypr/*.conf + # User overrides (edit these files in ~/.config/hypr/) # source = ~/.config/hypr/monitors.conf # source = ~/.config/hypr/overrides.conf diff --git a/default/hypr/autostart.conf b/default/hypr/autostart.conf index 68f35194..f6731788 100644 --- a/default/hypr/autostart.conf +++ b/default/hypr/autostart.conf @@ -1,5 +1,6 @@ exec-once = systemctl --user start hyprpolkitagent -exec-once = waybar & dunst +exec-once = sh -lc 'if ! kojarchy-toggle-enabled waybar-off; then waybar; fi' +exec-once = dunst exec-once = swayosd-server exec-once = swaybg -i ~/dotfiles/wallpapers/pallete.png -m fill exec-once = [workspace 1 silent] kitty diff --git a/default/hypr/toggles/flags.conf b/default/hypr/toggles/flags.conf new file mode 100644 index 00000000..bf08ae0c --- /dev/null +++ b/default/hypr/toggles/flags.conf @@ -0,0 +1,2 @@ +# This directory holds persistent Hyprland toggle fragments. +# Do not remove this file; the sourced glob should always match at least one file. diff --git a/install/config/all.sh b/install/config/all.sh index c3b55d29..16700bf6 100644 --- a/install/config/all.sh +++ b/install/config/all.sh @@ -25,6 +25,7 @@ run_logged $KOJARCHY_INSTALL/config/default-keyring.sh run_logged $KOJARCHY_INSTALL/config/firewall.sh run_logged $KOJARCHY_INSTALL/config/dns-resolver.sh run_logged $KOJARCHY_INSTALL/config/input-group.sh +run_logged $KOJARCHY_INSTALL/config/kojarchy-toggles.sh run_logged $KOJARCHY_INSTALL/config/detect-keyboard-layout.sh run_logged $KOJARCHY_INSTALL/config/hardware/network.sh run_logged $KOJARCHY_INSTALL/config/hardware/bluetooth.sh diff --git a/install/config/kojarchy-toggles.sh b/install/config/kojarchy-toggles.sh new file mode 100644 index 00000000..2f07c41f --- /dev/null +++ b/install/config/kojarchy-toggles.sh @@ -0,0 +1,5 @@ +# Initialize persistent toggle directories used by Kojarchy. + +TOGGLE_DIR="$HOME/.local/state/kojarchy/toggles/hypr" +mkdir -p "$TOGGLE_DIR" +cp "$KOJARCHY_DIR/default/hypr/toggles/flags.conf" "$TOGGLE_DIR/flags.conf"