diff --git a/.chezmoi.toml.tmpl b/.chezmoi.toml.tmpl
new file mode 100644
index 0000000..144621b
--- /dev/null
+++ b/.chezmoi.toml.tmpl
@@ -0,0 +1,7 @@
+{{- $hosttype := "desktop" -}}
+{{- if eq .chezmoi.hostname "framework13pro" -}}
+{{- $hosttype = "laptop" -}}
+{{- end -}}
+
+[data]
+ hosttype = "{{ $hosttype }}"
diff --git a/.chezmoiignore.tmpl b/.chezmoiignore.tmpl
new file mode 100644
index 0000000..65e45a5
--- /dev/null
+++ b/.chezmoiignore.tmpl
@@ -0,0 +1,7 @@
+**/*.bak
+{{ if ne .chezmoi.hostname "flow" -}}
+.config/pulsemeeter
+{{- end }}
+{{ if eq .chezmoi.hostname "framework13pro" -}}
+.config/teams-for-linux
+{{- end }}
diff --git a/.chezmoitemplates/bar-primary b/.chezmoitemplates/bar-primary
new file mode 100644
index 0000000..ebfc4d4
--- /dev/null
+++ b/.chezmoitemplates/bar-primary
@@ -0,0 +1,11 @@
+{
+ "output": "{{ .out }}",
+ "layer": "top",
+ "position": "left",
+ "width": 44,
+ "modules-left": ["clock", "pulseaudio"],
+ "modules-center": ["sway/workspaces"],
+ "modules-right": ["tray", "battery", "custom/power"],
+{{ template "workspaces" (dict "out" .out "ws" .ws) }}
+{{ template "waybar-modules" . }}
+}
diff --git a/.chezmoitemplates/bar-secondary b/.chezmoitemplates/bar-secondary
new file mode 100644
index 0000000..0bd8359
--- /dev/null
+++ b/.chezmoitemplates/bar-secondary
@@ -0,0 +1,14 @@
+{
+ "output": "DP-2",
+ "layer": "top",
+ "position": "top",
+ "height": 44,
+ "modules-right": ["clock"],
+ "modules-center": ["sway/workspaces"],
+{{ template "workspaces" (dict "out" "DP-2" "ws" (list "5" "6" "7" "8")) }}
+ "clock": {
+ "timezone": "America/Montreal",
+ "tooltip-format": "{:%Y %B}\n{calendar}",
+ "format": "š {:%H:%M š
%d/%m/%y}"
+ }
+}
diff --git a/.chezmoitemplates/waybar-modules b/.chezmoitemplates/waybar-modules
new file mode 100644
index 0000000..a0f45d5
--- /dev/null
+++ b/.chezmoitemplates/waybar-modules
@@ -0,0 +1,44 @@
+ "tray": {
+ "icon-size": 21,
+ "spacing": 10
+ },
+ "clock": {
+ "timezone": "America/Montreal",
+ "tooltip-format": "{:%Y %B}\n{calendar}",
+ "format": "š\n{:%H\n%M\n\nš
\n%d\n%m\n%y} "
+ },
+ "backlight": {
+ "device": "intel_backlight",
+ "format": "{icon}",
+ "format-icons": ["ī", "ī", "ī", "ī", "ī", "ī", "ī", "ī", "ī"]
+ },
+ "battery": {
+ "states": {
+ "warning": 30,
+ "critical": 15
+ },
+ "format": "š\n{capacity}",
+ "format-charging": "ā”\n{capacity}",
+ "format-plugged": "š\n{capacity}",
+ "format-alt": "{icon}",
+ "format-icons": ["ļ", "ļ¹", "ļŗ", "ļ»", "ļ¼", "ļ½", "ļ½", "ļ¾", "ļæ", "ļ", "ļ", "ļø"]
+ },
+ "custom/power": {
+ "format" : "ā»",
+ "tooltip": false,
+ "menu": "on-click",
+ "menu-file": "~/.config/waybar/power_menu.xml",
+ "menu-actions": {
+ "logout": "loginctl terminate-user \"\"",
+ "shutdown": "systemctl poweroff",
+ "reboot": "systemctl reboot"
+ }
+ },
+ "pulseaudio": {
+ "format": "{icon}\n{volume}",
+ "format-muted": "ļ¦",
+ "format-icons": {
+ "default": ["ļ¦", "ļ§", "ļØ "]
+ },
+ "on-click": "pwvucontrol"
+ },
diff --git a/.chezmoitemplates/workspaces b/.chezmoitemplates/workspaces
new file mode 100644
index 0000000..d7dfd13
--- /dev/null
+++ b/.chezmoitemplates/workspaces
@@ -0,0 +1,14 @@
+ "sway/workspaces": {
+ "persistent-workspaces": {
+{{- range $ws := .ws }}
+ "{{ $ws }}": ["{{ $.out }}"],
+{{- end }}
+ },
+ "disable-scroll": true,
+ "sort-by-name": true,
+ "format": "{icon}",
+ "format-icons": {
+ "default": "ā",
+ "focused": "ā",
+ },
+ },
diff --git a/.config/dotfiles/aur-packages.txt b/.config/dotfiles/aur-packages.txt
deleted file mode 100644
index d4214d6..0000000
--- a/.config/dotfiles/aur-packages.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-1password
-losslesscut-bin
-rustdesk-bin
-v4l2loopback-dkms-git
diff --git a/.config/dotfiles/packages.txt b/.config/dotfiles/packages.txt
deleted file mode 100644
index 3012dec..0000000
--- a/.config/dotfiles/packages.txt
+++ /dev/null
@@ -1,229 +0,0 @@
-accountsservice
-adobe-source-han-sans-cn-fonts
-adobe-source-han-sans-jp-fonts
-adobe-source-han-sans-kr-fonts
-alsa-firmware
-alsa-plugins
-alsa-utils
-appmenu-gtk-module
-awesome-terminal-fonts
-base
-base-devel
-bash-completion
-bind
-bluez
-bluez-hid2hci
-bluez-libs
-bluez-utils
-btop
-btrfs-progs
-cachyos-fish-config
-cachyos-gaming-meta
-cachyos-hello
-cachyos-hooks
-cachyos-kernel-manager
-cachyos-keyring
-cachyos-micro-settings
-cachyos-mirrorlist
-cachyos-packageinstaller
-cachyos-plymouth-bootanimation
-cachyos-rate-mirrors
-cachyos-settings
-cachyos-v3-mirrorlist
-cachyos-v4-mirrorlist
-cachyos-wallpapers
-cachyos-zsh-config
-chromium
-chwd
-cpupower
-cryptsetup
-cups
-cups-filters
-cups-pdf
-device-mapper
-dhclient
-diffutils
-discord
-dmidecode
-dmraid
-dnsmasq
-dolphin
-dosfstools
-duf
-e2fsprogs
-efibootmgr
-efitools
-egl-wayland
-ethtool
-exfatprogs
-f2fs-tools
-fastfetch
-ffmpegthumbnailer
-foomatic-db
-foomatic-db-engine
-foomatic-db-gutenprint-ppds
-foomatic-db-nonfree
-foomatic-db-nonfree-ppds
-foomatic-db-ppds
-fsarchiver
-gamemode
-gamescope
-ghostscript
-git
-glances
-gnome-keyring
-gpu-screen-recorder-ui
-gsfonts
-gst-libav
-gst-plugin-pipewire
-gst-plugin-va
-gst-plugins-bad
-gst-plugins-ugly
-gutenprint
-haveged
-hdparm
-hwdetect
-hwinfo
-inetutils
-iptables-nft
-iwd
-jfsutils
-kcalc
-kitty
-lazygit
-less
-lib32-gamemode
-lib32-mesa
-lib32-opencl-mesa
-libdbusmenu-glib
-libdvdcss
-libgsf
-libopenraw
-libwnck3
-limine
-limine-mkinitcpio-hook
-linux-cachyos
-linux-cachyos-headers
-linux-cachyos-lts
-linux-cachyos-lts-headers
-linux-firmware
-logrotate
-lsb-release
-lsscsi
-lvm2
-ly
-man-db
-man-pages
-mangohud
-mdadm
-mediainfo
-meld
-mesa
-mesa-utils
-micro
-mkinitcpio
-modemmanager
-mpv
-mtools
-nano-syntax-highlighting
-neovim
-netctl
-networkmanager
-networkmanager-openvpn
-nfs-utils
-nilfs-utils
-noise-suppression-for-voice
-noto-color-emoji-fontconfig
-noto-fonts
-noto-fonts-cjk
-noto-fonts-emoji
-nss-mdns
-ntp
-obs-studio
-obs-vkcapture
-octopi
-opencl-mesa
-opendesktop-fonts
-openssh
-os-prober
-otf-font-awesome
-pacman-contrib
-paru
-perl
-pipewire-alsa
-pipewire-pulse
-pkgfile
-plocate
-plymouth
-poppler-glib
-power-profiles-daemon
-proton-mail-bin
-pv
-pwvucontrol
-python
-python-defusedxml
-python-packaging
-rebuild-detector
-reflector
-ripgrep
-rofi
-rsync
-rtkit
-s-nail
-sg3_utils
-signal-desktop
-smartmontools
-sof-firmware
-splix
-starship
-steam
-sudo
-sway
-swaylock
-sysfsutils
-system-config-printer
-tailscale
-texinfo
-tmux
-ttf-bitstream-vera
-ttf-dejavu
-ttf-jetbrains-mono-nerd
-ttf-liberation
-ttf-meslo-nerd
-ttf-opensans
-ufw
-unrar
-unzip
-upower
-usb_modeswitch
-usbmuxd
-usbutils
-uwsm
-v4l2loopback-dkms
-vim
-vlc-plugins-all
-waybar
-wayland-protocols
-wget
-which
-wireless-regdb
-wireplumber
-wl-clipboard
-wmenu
-wofi
-wpa_supplicant
-xdg-desktop-portal
-xdg-desktop-portal-wlr
-xdg-user-dirs
-xdg-utils
-xf86-input-libinput
-xfsprogs
-xl2tpd
-xorg-server
-xorg-xdpyinfo
-xorg-xinit
-xorg-xinput
-xorg-xkill
-xorg-xrandr
-xorg-xwayland
-yazi
diff --git a/.config/kitty/kitty.conf.bak b/.config/kitty/kitty.conf.bak
deleted file mode 100644
index 7871ede..0000000
--- a/.config/kitty/kitty.conf.bak
+++ /dev/null
@@ -1,11 +0,0 @@
-# Font Configuration
-font_family JetBrainsMono Nerd Font
-bold_font auto
-italic_font auto
-bold_italic_font auto
-
-# Shell Integration - Start tmux by default
-shell /usr/bin/tmux new-session -A -D -s main
-
-# Terminal Type
-term xterm-256color
diff --git a/.config/opencode/AGENTS.md b/.config/opencode/AGENTS.md
deleted file mode 100644
index bdda14f..0000000
--- a/.config/opencode/AGENTS.md
+++ /dev/null
@@ -1,3 +0,0 @@
-- Prefer concise, readable code over clever one-liners
-- No unnecessary comments ā code should be self-documenting
-- Docker-friendly: no hardcoded paths, use env vars for config
diff --git a/.config/opencode/opencode.json b/.config/opencode/opencode.json
deleted file mode 100644
index 50fbc37..0000000
--- a/.config/opencode/opencode.json
+++ /dev/null
@@ -1,30 +0,0 @@
-{
- "$schema": "https://opencode.ai/config.json",
- "agent": {
- "build": {
- "model": "opencode-go/deepseek-v4-flash",
- "temperature": 1.0,
- "top_p": 0.95,
- "permission":{
- "skill": {
- "git-*": "allow"
- }
- }
- },
- "plan": {
- "model": "kimi-for-coding/k3",
- }
- },
- "mcp": {
- "gitea-mcp": {
- "enabled": true,
- "type": "local",
- "command": [
- "gitea-mcp",
- "-t", "stdio",
- "-H", "https://gitea.itspm.cc",
- "-T", "82e8aeb9bcf9b26d1bad9167549f6532f968bcb0"
- ]
- }
- }
-}
diff --git a/.config/waybar/config.jsonc b/.config/waybar/config.jsonc
deleted file mode 100644
index 144924b..0000000
--- a/.config/waybar/config.jsonc
+++ /dev/null
@@ -1,98 +0,0 @@
-[{
- "output": "DP-1",
- "layer": "top", // Waybar at top layer
- "position": "left", // Waybar position (top|bottom|left|right)
- "width": 44, // Waybar width
- // Choose the order of the modules
- "modules-left": ["clock", "pulseaudio"],
- "modules-center": ["sway/workspaces"],
- "modules-right": ["tray", "battery", "custom/power"],
- "sway/workspaces": {
- "persistent-workspaces": {
- "1": ["DP-1"],
- "2": ["DP-1"],
- "3": ["DP-1"],
- "4": ["DP-1"],
- },
- "disable-scroll": true,
- "sort-by-name": true,
- "format": "{icon}",
- "format-icons": {
- "default": "ā",
- "focused": "ā",
- },
- },
- "tray": {
- "icon-size": 21,
- "spacing": 10
- },
- "clock": {
- "timezone": "America/Montreal",
- "tooltip-format": "{:%Y %B}\n{calendar}",
- "format": "š\n{:%H\n%M\n\nš
\n%d\n%m\n%y} "
- },
- "backlight": {
- "device": "intel_backlight",
- "format": "{icon}",
- "format-icons": ["ī", "ī", "ī", "ī", "ī", "ī", "ī", "ī", "ī"]
- },
- "battery": {
- "states": {
- "warning": 30,
- "critical": 15
- },
- "format": "š\n{capacity}",
- "format-charging": "ā”\n{capacity}",
- "format-plugged": "š\n{capacity}",
- "format-alt": "{icon}",
- "format-icons": ["ļ", "ļ¹", "ļŗ", "ļ»", "ļ¼", "ļ½", "ļ½", "ļ¾", "ļæ", "ļ", "ļ", "ļø"]
- },
- "custom/power": {
- "format" : "ā»",
- "tooltip": false,
- "menu": "on-click",
- "menu-file": "~/.config/waybar/power_menu.xml",
- "menu-actions": {
- "logout": "loginctl terminate-user \"\"",
- "shutdown": "systemctl poweroff",
- "reboot": "systemctl reboot"
- }
- },
- "pulseaudio": {
- // "scroll-step": 1, // %, can be a float
- "format": "{icon}\n{volume}",
- "format-muted": "ļ¦",
- "format-icons": {
- "default": ["ļ¦", "ļ§", "ļØ "]
- },
- "on-click": "pwvucontrol"
- },
-},
-{
- "output": "DP-2",
- "layer": "top",
- "position": "top",
- "height": 44,
- "modules-right": ["clock"],
- "modules-center": ["sway/workspaces"],
- "sway/workspaces": {
- "persistent-workspaces": {
- "5": ["DP-2"],
- "6": ["DP-2"],
- "7": ["DP-2"],
- "8": ["DP-2"],
- },
- "disable-scroll": true,
- "sort-by-name": true,
- "format": "{icon}",
- "format-icons": {
- "default": "ā",
- "focused": "ā",
- },
- },
- "clock": {
- "timezone": "America/Montreal",
- "tooltip-format": "{:%Y %B}\n{calendar}",
- "format": "š {:%H:%M š
%d/%m/%y}"
- }
-}]
diff --git a/.config/yazi/package.toml b/.config/yazi/package.toml
deleted file mode 100644
index 376b367..0000000
--- a/.config/yazi/package.toml
+++ /dev/null
@@ -1,12 +0,0 @@
-[[plugin.deps]]
-use = "AnirudhG07/rich-preview"
-rev = "573b275"
-hash = "c3e2871c9ef244fd181f203791f9b0d2"
-
-[[plugin.deps]]
-use = "yazi-rs/plugins:git"
-rev = "6c71385"
-hash = "36a484acf6a0a0219c543ccb4cee218f"
-
-[flavor]
-deps = []
diff --git a/dot_config/dotfiles/aur-packages.txt.tmpl b/dot_config/dotfiles/aur-packages.txt.tmpl
new file mode 100644
index 0000000..ae55543
--- /dev/null
+++ b/dot_config/dotfiles/aur-packages.txt.tmpl
@@ -0,0 +1,4 @@
+opencode-bin
+{{ if eq .chezmoi.hostname "flow" -}}
+pulsemeeter-git
+{{- end }}
diff --git a/.config/dotfiles/install.sh b/dot_config/dotfiles/install.sh
similarity index 100%
rename from .config/dotfiles/install.sh
rename to dot_config/dotfiles/install.sh
diff --git a/dot_config/dotfiles/packages.txt.tmpl b/dot_config/dotfiles/packages.txt.tmpl
new file mode 100644
index 0000000..ba064e6
--- /dev/null
+++ b/dot_config/dotfiles/packages.txt.tmpl
@@ -0,0 +1,30 @@
+# Software with configs in this repo + runtime deps referenced by those configs
+{{ if eq .hosttype "desktop" -}}
+teams-for-linux
+{{- end }}
+brightnessctl
+cachyos-fish-config
+chezmoi
+dunst
+fish
+git
+gnome-keyring
+kitty
+lazygit
+neovim
+paru
+pipewire-pulse
+polkit-gnome
+pwvucontrol
+rofi
+starship
+sway
+swayidle
+swaylock
+tmux
+ttf-jetbrains-mono-nerd
+uwsm
+waybar
+wl-clipboard
+yazi
+zsh
diff --git a/.config/dunst/dunstrc b/dot_config/dunst/dunstrc
similarity index 100%
rename from .config/dunst/dunstrc
rename to dot_config/dunst/dunstrc
diff --git a/.config/environment.d/electron.conf b/dot_config/environment.d/electron.conf
similarity index 100%
rename from .config/environment.d/electron.conf
rename to dot_config/environment.d/electron.conf
diff --git a/.config/environment.d/neovim.conf b/dot_config/environment.d/neovim.conf
similarity index 100%
rename from .config/environment.d/neovim.conf
rename to dot_config/environment.d/neovim.conf
diff --git a/.config/environment.d/proton.conf b/dot_config/environment.d/proton.conf
similarity index 100%
rename from .config/environment.d/proton.conf
rename to dot_config/environment.d/proton.conf
diff --git a/.config/environment.d/ssh-agent.conf b/dot_config/environment.d/ssh-agent.conf
similarity index 100%
rename from .config/environment.d/ssh-agent.conf
rename to dot_config/environment.d/ssh-agent.conf
diff --git a/.config/environment.d/theme.conf b/dot_config/environment.d/theme.conf
similarity index 100%
rename from .config/environment.d/theme.conf
rename to dot_config/environment.d/theme.conf
diff --git a/.config/fish/config.fish b/dot_config/fish/config.fish
similarity index 60%
rename from .config/fish/config.fish
rename to dot_config/fish/config.fish
index 49ed97f..54a7dfc 100644
--- a/.config/fish/config.fish
+++ b/dot_config/fish/config.fish
@@ -1,6 +1,6 @@
source /usr/share/cachyos-fish-config/cachyos-config.fish
-alias dotfiles='/usr/bin/git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME'
+alias dotfiles='chezmoi'
fish_add_path ~/.local/bin
diff --git a/.config/kitty/current-theme.conf b/dot_config/kitty/current-theme.conf
similarity index 100%
rename from .config/kitty/current-theme.conf
rename to dot_config/kitty/current-theme.conf
diff --git a/.config/kitty/kitty.conf b/dot_config/kitty/kitty.conf
similarity index 100%
rename from .config/kitty/kitty.conf
rename to dot_config/kitty/kitty.conf
diff --git a/.config/lazygit/config.yml b/dot_config/lazygit/config.yml
similarity index 100%
rename from .config/lazygit/config.yml
rename to dot_config/lazygit/config.yml
diff --git a/.config/nvim/init.lua b/dot_config/nvim/init.lua
similarity index 100%
rename from .config/nvim/init.lua
rename to dot_config/nvim/init.lua
diff --git a/.config/nvim/lsp/lua_ls.lua b/dot_config/nvim/lsp/lua_ls.lua
similarity index 100%
rename from .config/nvim/lsp/lua_ls.lua
rename to dot_config/nvim/lsp/lua_ls.lua
diff --git a/.config/nvim/lua/config/autocmds.lua b/dot_config/nvim/lua/config/autocmds.lua
similarity index 100%
rename from .config/nvim/lua/config/autocmds.lua
rename to dot_config/nvim/lua/config/autocmds.lua
diff --git a/.config/nvim/lua/config/diagnostics.lua b/dot_config/nvim/lua/config/diagnostics.lua
similarity index 100%
rename from .config/nvim/lua/config/diagnostics.lua
rename to dot_config/nvim/lua/config/diagnostics.lua
diff --git a/.config/nvim/lua/config/init.lua b/dot_config/nvim/lua/config/init.lua
similarity index 100%
rename from .config/nvim/lua/config/init.lua
rename to dot_config/nvim/lua/config/init.lua
diff --git a/.config/nvim/lua/config/keymaps.lua b/dot_config/nvim/lua/config/keymaps.lua
similarity index 100%
rename from .config/nvim/lua/config/keymaps.lua
rename to dot_config/nvim/lua/config/keymaps.lua
diff --git a/.config/nvim/lua/config/lsp.lua b/dot_config/nvim/lua/config/lsp.lua
similarity index 100%
rename from .config/nvim/lua/config/lsp.lua
rename to dot_config/nvim/lua/config/lsp.lua
diff --git a/.config/nvim/lua/config/options.lua b/dot_config/nvim/lua/config/options.lua
similarity index 100%
rename from .config/nvim/lua/config/options.lua
rename to dot_config/nvim/lua/config/options.lua
diff --git a/.config/nvim/lua/plugins/blink.lua b/dot_config/nvim/lua/plugins/blink.lua
similarity index 100%
rename from .config/nvim/lua/plugins/blink.lua
rename to dot_config/nvim/lua/plugins/blink.lua
diff --git a/.config/nvim/lua/plugins/conform.lua b/dot_config/nvim/lua/plugins/conform.lua
similarity index 100%
rename from .config/nvim/lua/plugins/conform.lua
rename to dot_config/nvim/lua/plugins/conform.lua
diff --git a/.config/nvim/lua/plugins/git.lua b/dot_config/nvim/lua/plugins/git.lua
similarity index 100%
rename from .config/nvim/lua/plugins/git.lua
rename to dot_config/nvim/lua/plugins/git.lua
diff --git a/.config/nvim/lua/plugins/log-highlight.lua b/dot_config/nvim/lua/plugins/log-highlight.lua
similarity index 100%
rename from .config/nvim/lua/plugins/log-highlight.lua
rename to dot_config/nvim/lua/plugins/log-highlight.lua
diff --git a/.config/nvim/lua/plugins/lualine.lua b/dot_config/nvim/lua/plugins/lualine.lua
similarity index 100%
rename from .config/nvim/lua/plugins/lualine.lua
rename to dot_config/nvim/lua/plugins/lualine.lua
diff --git a/.config/nvim/lua/plugins/markdown.lua b/dot_config/nvim/lua/plugins/markdown.lua
similarity index 100%
rename from .config/nvim/lua/plugins/markdown.lua
rename to dot_config/nvim/lua/plugins/markdown.lua
diff --git a/.config/nvim/lua/plugins/neotree.lua b/dot_config/nvim/lua/plugins/neotree.lua
similarity index 100%
rename from .config/nvim/lua/plugins/neotree.lua
rename to dot_config/nvim/lua/plugins/neotree.lua
diff --git a/.config/nvim/lua/plugins/telescope.lua b/dot_config/nvim/lua/plugins/telescope.lua
similarity index 100%
rename from .config/nvim/lua/plugins/telescope.lua
rename to dot_config/nvim/lua/plugins/telescope.lua
diff --git a/.config/nvim/lua/plugins/theme.lua b/dot_config/nvim/lua/plugins/theme.lua
similarity index 100%
rename from .config/nvim/lua/plugins/theme.lua
rename to dot_config/nvim/lua/plugins/theme.lua
diff --git a/.config/nvim/lua/plugins/treesitter.lua b/dot_config/nvim/lua/plugins/treesitter.lua
similarity index 100%
rename from .config/nvim/lua/plugins/treesitter.lua
rename to dot_config/nvim/lua/plugins/treesitter.lua
diff --git a/.config/nvim/lua/plugins/whichkey.lua b/dot_config/nvim/lua/plugins/whichkey.lua
similarity index 100%
rename from .config/nvim/lua/plugins/whichkey.lua
rename to dot_config/nvim/lua/plugins/whichkey.lua
diff --git a/dot_config/opencode/AGENTS.md b/dot_config/opencode/AGENTS.md
new file mode 100644
index 0000000..d83d6ae
--- /dev/null
+++ b/dot_config/opencode/AGENTS.md
@@ -0,0 +1,27 @@
+- Prefer concise, readable code over clever one-liners
+- No unnecessary comments ā code should be self-documenting
+- Docker-friendly: no hardcoded paths, use env vars for config
+
+
+# Codebase Knowledge Graph (codebase-memory-mcp)
+
+This project uses codebase-memory-mcp to maintain a knowledge graph of the codebase.
+ALWAYS prefer MCP graph tools over grep/glob/file-search for code discovery.
+
+## Priority Order
+1. `search_graph` ā find functions, classes, routes, variables by pattern
+2. `trace_path` ā trace who calls a function or what it calls
+3. `get_code_snippet` ā read specific function/class source code
+4. `query_graph` ā run Cypher queries for complex patterns
+5. `get_architecture` ā high-level project summary
+
+## When to fall back to grep/glob
+- Searching for string literals, error messages, config values
+- Searching non-code files (Dockerfiles, shell scripts, configs)
+- When MCP tools return insufficient results
+
+## Examples
+- Find a handler: `search_graph(name_pattern=".*OrderHandler.*")`
+- Who calls it: `trace_path(function_name="OrderHandler", direction="inbound")`
+- Read source: `get_code_snippet(qualified_name="pkg/orders.OrderHandler")`
+
diff --git a/dot_config/opencode/opencode.json b/dot_config/opencode/opencode.json
new file mode 100644
index 0000000..f9ec669
--- /dev/null
+++ b/dot_config/opencode/opencode.json
@@ -0,0 +1,40 @@
+{
+ "$schema": "https://opencode.ai/config.json",
+ "agent": {
+ "build": {
+ "model": "opencode-go/deepseek-v4-flash",
+ "temperature": 1.0,
+ "top_p": 0.95,
+ "permission": {
+ "skill": {
+ "git-*": "allow"
+ }
+ }
+ },
+ "plan": {
+ "model": "kimi-for-coding/k3"
+ }
+ },
+ "mcp": {
+ "gitea-mcp": {
+ "enabled": true,
+ "type": "local",
+ "command": [
+ "gitea-mcp",
+ "-t",
+ "stdio",
+ "-H",
+ "https://gitea.itspm.cc",
+ "-T",
+ "82e8aeb9bcf9b26d1bad9167549f6532f968bcb0"
+ ]
+ },
+ "codebase-memory-mcp": {
+ "enabled": true,
+ "type": "local",
+ "command": [
+ "/home/pmcc/.local/bin/codebase-memory-mcp"
+ ]
+ }
+ }
+}
diff --git a/.config/opencode/skills/git-commit/SKILL.md b/dot_config/opencode/skills/git-commit/SKILL.md
similarity index 100%
rename from .config/opencode/skills/git-commit/SKILL.md
rename to dot_config/opencode/skills/git-commit/SKILL.md
diff --git a/.config/pulsemeeter/config.json b/dot_config/pulsemeeter/config.json
similarity index 100%
rename from .config/pulsemeeter/config.json
rename to dot_config/pulsemeeter/config.json
diff --git a/.config/rofi/catppuccin-default.rasi b/dot_config/rofi/catppuccin-default.rasi
similarity index 100%
rename from .config/rofi/catppuccin-default.rasi
rename to dot_config/rofi/catppuccin-default.rasi
diff --git a/.config/rofi/catppuccin-mocha.rasi b/dot_config/rofi/catppuccin-mocha.rasi
similarity index 100%
rename from .config/rofi/catppuccin-mocha.rasi
rename to dot_config/rofi/catppuccin-mocha.rasi
diff --git a/.config/rofi/config.rasi b/dot_config/rofi/config.rasi
similarity index 100%
rename from .config/rofi/config.rasi
rename to dot_config/rofi/config.rasi
diff --git a/.config/starship.toml b/dot_config/starship.toml
similarity index 100%
rename from .config/starship.toml
rename to dot_config/starship.toml
diff --git a/.config/sway/config b/dot_config/sway/config
similarity index 100%
rename from .config/sway/config
rename to dot_config/sway/config
diff --git a/dot_config/sway/config.d/binds.conf.tmpl b/dot_config/sway/config.d/binds.conf.tmpl
new file mode 100644
index 0000000..d0f597b
--- /dev/null
+++ b/dot_config/sway/config.d/binds.conf.tmpl
@@ -0,0 +1,6 @@
+{{ if eq .hosttype "laptop" -}}
+bindsym XF86MonBrightnessDown exec brightnessctl -d intel_backlight s 5%-
+bindsym XF86MonBrightnessUp exec brightnessctl -d intel_backlight s +5%
+
+bindsym --no-repeat $mod+Shift+r exec ~/.config/sway/scripts/toggle-refresh-rate.sh
+{{- end }}
diff --git a/dot_config/sway/config.d/inputs.conf.tmpl b/dot_config/sway/config.d/inputs.conf.tmpl
new file mode 100644
index 0000000..7a14641
--- /dev/null
+++ b/dot_config/sway/config.d/inputs.conf.tmpl
@@ -0,0 +1,10 @@
+{{ if eq .hosttype "laptop" -}}
+input "type:pointer" {
+ accel_profile flat
+ pointer_accel 0
+}
+
+input "2362:4931:PIXA3854:00_093A:1343_Touchpad" {
+ tap enabled
+}
+{{- end }}
diff --git a/dot_config/sway/config.d/outputs.conf.tmpl b/dot_config/sway/config.d/outputs.conf.tmpl
new file mode 100644
index 0000000..1e79ae0
--- /dev/null
+++ b/dot_config/sway/config.d/outputs.conf.tmpl
@@ -0,0 +1,11 @@
+{{ if eq .chezmoi.hostname "framework13pro" -}}
+output eDP-1 mode 2880x1920@120Hz
+{{- else if eq .chezmoi.hostname "flow" -}}
+# TODO: fill in flow's outputs (run: swaymsg -t get_outputs)
+# output DP-1 mode 2560x1440@144Hz position 0 0
+# output DP-2 mode 2560x1440@144Hz position 2560 0
+{{- else if eq .chezmoi.hostname "gata" -}}
+# TODO: fill in gata's outputs (run: swaymsg -t get_outputs)
+# output DP-1 mode 2560x1440@144Hz position 0 0
+# output DP-2 mode 1920x1080@60Hz position 2560 0
+{{- end }}
diff --git a/dot_config/sway/scripts/executable_toggle-refresh-rate.sh b/dot_config/sway/scripts/executable_toggle-refresh-rate.sh
new file mode 100644
index 0000000..d5d967b
--- /dev/null
+++ b/dot_config/sway/scripts/executable_toggle-refresh-rate.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+OUTPUT="eDP-1"
+CURRENT=$(swaymsg -rt get_outputs | jq -r ".[] | select(.name==\"$OUTPUT\") | .current_mode.refresh" | cut -d. -f1)
+
+if [ "$CURRENT" -eq 120000 ]; then
+ swaymsg output "$OUTPUT" mode 2880x1920@60Hz
+ notify-send "Refresh Rate" "Switched to 60Hz" -t 2000
+else
+ swaymsg output "$OUTPUT" mode 2880x1920@120Hz
+ notify-send "Refresh Rate" "Switched to 120Hz" -t 2000
+fi
+
+pkill -RTMIN+8 waybar
diff --git a/.config/swaylock/config b/dot_config/swaylock/config
similarity index 100%
rename from .config/swaylock/config
rename to dot_config/swaylock/config
diff --git a/.config/teams-for-linux/config.json b/dot_config/teams-for-linux/config.json
similarity index 100%
rename from .config/teams-for-linux/config.json
rename to dot_config/teams-for-linux/config.json
diff --git a/dot_config/waybar/config.jsonc.tmpl b/dot_config/waybar/config.jsonc.tmpl
new file mode 100644
index 0000000..565ff46
--- /dev/null
+++ b/dot_config/waybar/config.jsonc.tmpl
@@ -0,0 +1,11 @@
+{{- if eq .chezmoi.hostname "framework13pro" -}}
+[{{ template "bar-primary" (dict "out" "eDP-1" "ws" (list "1" "2" "3" "4")) }},
+{{ template "bar-secondary" . }}]
+{{- else if eq .chezmoi.hostname "flow" -}}
+[{{ template "bar-primary" (dict "out" "DP-1" "ws" (list "1" "2" "3" "4")) }},
+{{ template "bar-secondary" . }}]
+{{- else if eq .chezmoi.hostname "gata" -}}
+// TODO: fill in gata's outputs (run: swaymsg -t get_outputs)
+[{{ template "bar-primary" (dict "out" "DP-1" "ws" (list "1" "2" "3" "4")) }},
+{{ template "bar-secondary" . }}]
+{{- end }}
diff --git a/.config/waybar/mocha.css b/dot_config/waybar/mocha.css
similarity index 100%
rename from .config/waybar/mocha.css
rename to dot_config/waybar/mocha.css
diff --git a/.config/waybar/power_menu.xml b/dot_config/waybar/power_menu.xml
similarity index 100%
rename from .config/waybar/power_menu.xml
rename to dot_config/waybar/power_menu.xml
diff --git a/.config/waybar/style.css b/dot_config/waybar/style.css
similarity index 100%
rename from .config/waybar/style.css
rename to dot_config/waybar/style.css
diff --git a/.config/waybar/waybar-roon.json b/dot_config/waybar/waybar-roon.json
similarity index 100%
rename from .config/waybar/waybar-roon.json
rename to dot_config/waybar/waybar-roon.json
diff --git a/.config/yazi/init.lua b/dot_config/yazi/init.lua
similarity index 100%
rename from .config/yazi/init.lua
rename to dot_config/yazi/init.lua
diff --git a/dot_config/yazi/package.toml b/dot_config/yazi/package.toml
new file mode 100644
index 0000000..b7a7902
--- /dev/null
+++ b/dot_config/yazi/package.toml
@@ -0,0 +1,12 @@
+[[plugin.deps]]
+use = "AnirudhG07/rich-preview"
+rev = "7d616ad"
+hash = "d64feec9761392cbc250d199ab4b8a3a"
+
+[[plugin.deps]]
+use = "yazi-rs/plugins:git"
+rev = "9014ed2"
+hash = "88e56a64b7ce7c4314427452343fef17"
+
+[flavor]
+deps = []
diff --git a/.config/yazi/theme.toml b/dot_config/yazi/theme.toml
similarity index 100%
rename from .config/yazi/theme.toml
rename to dot_config/yazi/theme.toml
diff --git a/.config/yazi/yazi.toml b/dot_config/yazi/yazi.toml
similarity index 100%
rename from .config/yazi/yazi.toml
rename to dot_config/yazi/yazi.toml
diff --git a/.tmux.conf b/dot_tmux.conf
similarity index 100%
rename from .tmux.conf
rename to dot_tmux.conf
diff --git a/.zshrc b/dot_zshrc
similarity index 87%
rename from .zshrc
rename to dot_zshrc
index c7867c5..b007f73 100644
--- a/.zshrc
+++ b/dot_zshrc
@@ -13,7 +13,7 @@ bindkey "^[[3~" delete-char
alias ls='ls --color=auto'
alias grep='grep --color=auto'
-alias dotfiles='/usr/bin/git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME'
+alias dotfiles='chezmoi'
eval "$(starship init zsh)"