Personal fresh-machine bootstrap for exactly two targets:
- Ubuntu 24.04 with Cinnamon
- Kubuntu 26.04 installed from its ISO with KDE Plasma
The steps below rebuild either machine; commands are run from the repository root unless stated otherwise.
sudo apt-get install -y git
git clone https://github.com/kuator/dotfiles.git "$HOME/dotfiles"
cd "$HOME/dotfiles"
./scripts/setup.shThis is the only automatic entry point. It rejects other Ubuntu release/desktop combinations before making changes, asks for sudo normally, installs the base APT packages and Zinit, links the tracked configuration, installs Mise-managed tools including Kanata and Bob's Neovim nightly, and applies the tracked desktop keyboard settings. It is safe to rerun: an existing destination is moved to <name>-old, and setup stops rather than overwriting an existing backup.
Run every remaining command only after scripts/setup.sh succeeds.
Disable Snap before installing Firefox, then apply the remaining system and shell changes:
./scripts/optional/system/disable-snap.sh
./scripts/optional/shell/configure-bash-xdg.sh
./scripts/optional/shell/set-default-zsh.sh
./scripts/optional/system/configure-kanata.sh
./scripts/optional/system/configure-ssh-xdg.sh
./scripts/optional/system/disable-sudo-admin-flag.shThe final script applies the legacy home-marker fix on Ubuntu 24.04 and exits without changing anything under Kubuntu 26.04's sudo-rs.
Close every Codex process, then install Codex with its home under $XDG_DATA_HOME. The script also migrates an existing ~/.codex:
./scripts/optional/shell/install-codex.shInstall the Appgate Debian package before installing the XDG wrapper. For example, from the directory containing the package:
sudo dpkg -i AppGate-SDP-client.deb
cd "$HOME/dotfiles"
./scripts/optional/system/configure-appgate-xdg.shThe Appgate wrapper uses a private fake home under $XDG_DATA_HOME; the system service and running VPN client remain vendor software.
Reboot before continuing. This activates the new login shell, Kanata group membership, system keyboard configuration, and any display-manager changes.
After logging in, configs/system/keyboard is the source of truth for layouts and switching. Cinnamon applies it through X11 and KDE derives its keyboard configuration from the same file.
Install the shared terminal font:
./scripts/optional/desktop/install-ubuntu-mono-nerd-font.shImport the GNOME Terminal profile, then apply the LightDM home-cleanup changes used by this machine:
./scripts/optional/desktop/import-gnome-terminal-profile.sh
./scripts/optional/desktop/lightdm/configure-xauthority.sh
./scripts/optional/desktop/lightdm/patch-binary.shUse Kubuntu's installed KDE terminal and display manager. Do not run the GNOME Terminal or LightDM scripts; the bootstrap has already written KDE's keyboard and repeat settings.
Install Firefox after Snap has been disabled:
./scripts/optional/firefox/install.shLaunch Firefox once so it creates a default profile, then close Firefox and run:
./scripts/optional/firefox/configure-profile.sh
./scripts/optional/firefox/patch-keybindings.sh
./scripts/optional/firefox/configure-new-tab.shInstall New Tab Override and Vimium through Firefox Add-ons. In New Tab Override, select Custom URL, enter http://127.0.0.1:8766/blank.html, and enable focusing the website instead of the address bar. In Vimium, set New tab URL to Browser's default new tab page. Firefox requires these extension changes to be made manually.
The new-tab service binds only to 127.0.0.1. Firefox updates replace omni.ja, so rerun firefox/patch-keybindings.sh after an update if the custom browser shortcuts stop working.
Install Valve's Steam package and the fixsteam fake-home launcher:
./scripts/optional/desktop/install-steam.shThe script preserves the existing library in $XDG_DATA_HOME/Steam and installs fixsteam under $XDG_DATA_HOME/fixsteam. Run steam once afterwards so fixsteam can create its fake home and desktop launcher. Steam remains outside the automatic bootstrap.
Install Anki, link mpv configuration, install mpvacious, and check the Anki add-on manifest:
./scripts/optional/japanese/setup.shPaste any printed codes into Anki → Tools → Add-ons → Get Add-ons, then restart Anki. After add-on 1045800357 exists, restore its optional 2.5 GiB local-audio collection:
./scripts/optional/japanese/download-yomitan-audio.shThe torrent and archive stay in ${XDG_CACHE_HOME:-$HOME/.cache}/dotfiles/yomitan-audio; the main bootstrap never starts this download.
The eight selected Yomitan dictionary ZIPs are carried directly in japanese/yomitan/dictionaries/. If an archive is missing, restore it from the manifest:
./scripts/optional/japanese/download-yomitan-dictionaries.shIn Yomitan, import the numbered archives from japanese/yomitan/dictionaries/, then import japanese/yomitan/settings.json from Settings → Backup → Import Settings. Follow japanese/yomitan/README.md to apply the tracked order to the currently selected profile.
Finally, start Anki with AnkiConnect enabled and update or create the official Japanese Sentences note type with the local compatibility changes:
./scripts/optional/japanese/update-japanese-sentences.shRestart Anki afterward so AJT Japanese refreshes its injected CSS and JavaScript.
./tests/bootstrap.sh
nvim --version
mise doctor
test ! -e "$HOME/.appgate" && echo 'Appgate home is clean'On Ubuntu 24.04 Cinnamon/X11, also run setxkbmap -query. On Kubuntu 26.04, run kreadconfig6 --file kxkbrc --group Layout --key LayoutList. The first command above is the repository regression suite; the others are quick checks of installed tools and machine-level changes.
configs/home/profiledefines the login environment, XDG locations, and user-tool paths and is linked to~/.profile.configs/xdg/contains application configuration linked into$XDG_CONFIG_HOME, grouped by application. Notable exceptions handled specially by the linker are Codium's files and the globalty.toml.configs/system/keyboardis the single tracked source for the system, Cinnamon, KDE, IBus, and live X11 keyboard layout;configs/gnome-terminal/profile.dconfis imported rather than linked.docs/ergonomic-keyboard.mdrecords the ergonomic-keyboard requirements, shortlist, and current recommendation.docs/todo.mdtracks setup that still requires an external account or private recovery material.japanese/anki/addons.txtis the named AnkiWeb add-on manifest.japanese/yomitan/dictionaries.txt,japanese/yomitan/settings.json, andjapanese/yomitan/sort-dictionaries.jsdefine the selected dictionaries, exported settings, and active-profile order.japanese/anime/contains older subtitle timing tools and source-specific data; it is not part of bootstrap.
scripts/setup.shis the only entry point.scripts/bootstrap/install-packages.shinstalls Ubuntu packages.scripts/bootstrap/link-configs.shbacks up and links tracked configuration.scripts/bootstrap/install-mise.shinstalls Mise-managed CLI tools and Bob's Neovim nightly.scripts/bootstrap/configure-desktop.shderives desktop keyboard settings fromconfigs/system/keyboard.
Nothing under scripts/optional/ runs automatically. Several scripts use sudo, alter installed software, or require an application to be open or closed.
| Script | Purpose |
|---|---|
desktop/import-gnome-terminal-profile.sh |
Imports the tracked GNOME Terminal profile. |
desktop/install-steam.sh |
Installs Valve's Steam package and fixsteam fake-home launcher. |
desktop/install-ubuntu-mono-nerd-font.sh |
Downloads and installs UbuntuMono Nerd Font. |
desktop/lightdm/configure-xauthority.sh |
Stores LightDM Xauthority data outside the home root. |
desktop/lightdm/patch-binary.sh |
Patches LightDM to move .xsession-errors; use only with LightDM. |
firefox/configure-new-tab.sh |
Enables the localhost-only tracked new-tab page service. |
firefox/configure-profile.sh |
Links Firefox preferences and content CSS into its default profile. |
firefox/install.sh |
Installs Firefox from the Mozilla Team PPA. |
firefox/patch-keybindings.sh |
Rebuilds Firefox's omni.ja with the custom shortcuts. |
japanese/download-yomitan-audio.sh |
Downloads, caches, and installs the optional local-audio collection. |
japanese/download-yomitan-dictionaries.sh |
Restores missing dictionary archives from the tracked manifest. |
japanese/setup.sh |
Installs Anki and mpvacious and reports missing Anki add-ons. |
japanese/update-japanese-sentences.sh |
Fetches upstream Japanese Sentences, applies compatibility patches, and updates it through AnkiConnect. |
shell/configure-bash-xdg.sh |
Makes system Bash startup and history use XDG locations. |
shell/install-codex.sh |
Installs Codex through Mise-managed npm with an XDG data home and migrates an existing ~/.codex; Codex must be closed. |
shell/set-default-zsh.sh |
Interactively changes the login shell to Zsh. |
system/configure-appgate-xdg.sh |
Installs the Appgate fake-home wrapper with dpkg-divert. |
system/configure-kanata.sh |
Configures Linux groups, udev, and uinput, then enables the tracked Kanata user service. |
system/configure-ssh-xdg.sh |
Makes all OpenSSH clients use the tracked XDG config and migrates host keys. |
system/disable-snap.sh |
Removes Snap while preserving user data and prevents its reinstallation. |
system/disable-sudo-admin-flag.sh |
Prevents classic sudo from creating its home marker; safely does nothing under sudo-rs. |
bin/appgategives the vendor Appgate client a private fake home.bin/codiumlaunches VSCodium with its XDG data directory.bin/fdexposes Ubuntu'sfdfindexecutable under its upstreamfdname.bin/rgmakes ripgrep share the ignore file used by fd.bin/steamlaunches the optional fixsteam installation from its XDG data path.
tests/bootstrap.shchecks links, environment settings, desktop configuration, wrappers, migrations, and documented scripts.tests/python-environment.shchecks thevenv-based uv and ty project environment.tests/update-japanese-sentences.shexercises note-type download, patching, and AnkiConnect behavior with local fakes.tests/yomitan-sort-dictionaries.jschecks dictionary ordering without Yomitan.
japanese/anki/addons21/contains downloaded Anki add-ons and is intentionally ignored;japanese/anki/addons.txtis the reproducible source list.japanese/yomitan/dictionaries/contains the eight Git-tracked importable archives. Their internals are third-party data and are not documented here.configs/xdg/mpv/scripts/mpvacious/is the installed upstream mpvacious checkout.japanese/setup.shinstalls the pinned release and reapplies the intentional menu-line-length mutation.
Put general declarative configuration under configs/ and Japanese study resources under japanese/. Put automatic fresh-machine work under scripts/bootstrap/ and call it from scripts/setup.sh; put destructive, optional, application-dependent, or machine-level work under the matching scripts/optional/ responsibility folder. Add a regression check when behavior—not just data—changes.