install,provision: modules and roles, monitor-manager extracted, container CI - #19
Merged
Merged
Conversation
.gitmodules has listed tpm, nord-tmux, and tmux-sensible since #1, but the tree only ever carried a gitlink for dotbot, so `git submodule update --init --recursive` created nothing under tmux/plugins/ and tmux.conf's `run '~/.tmux/plugins/tpm/tpm'` failed on every fresh clone. Add the three gitlinks at their current upstream heads. Claude-Session: https://claude.ai/code/session_01R1D4FTi7umCLFpkuR355od
The repo modelled one axis of variation - desktop or not - as a flag, but the machines it serves vary along more: the new headless VPS is neither half, and --no-desktop still gave it kitty, fonts, xclip, a rust toolchain, and a source-built tree-sitter. Per-machine values (DPI, redshift's location, polybar's hardware ids) were either symlinked to every machine or seeded once and never updated, and the desktop half had no overlay seam at all, which is why the work-laptop profiles #11 moved out came back in #15. Layout: modules/<name>/ holds one tool's config (install.conf.yaml, sources module-relative) and the provisioning that makes it work (provision.sh, standalone-runnable). roles/{server,workstation,desktop} list modules, nesting via @ROLE; modules may declare `requires`, and a selection that leaves one out is refused up front. ./install and ./provision.sh take --roles/--modules, save the selection to ~/.config/dotfiles/roles, and re-apply it on a bare run; --no-desktop remains as an alias for --roles workstation. lib/roles.sh resolves, lib/common.sh logs, lib/provision-lib.sh keeps every pin and sha256 helper and gains a package layer: pkg_ensure installs only what is missing and refreshes the index once per run on first need, so a converged machine touches neither apt nor sudo; pkg_candidate_version and version_ge let the x11 module take the distro polybar (>= 3.7.0) and picom (>= 13) where they are new enough instead of always source-building 22.04's replacements; require_supported_platform states the Debian-family / x86_64 limit up front. cli-tools goes first in every role because it installs curl. Per-machine values are data: hosts/defaults.env < hosts/<hostname>.env < untracked ~/.config/dotfiles/local.env, merged by ./install into ~/.config/dotfiles/host.env. A dotbot `render:` directive (lib/dotbot-plugins/render.py) substitutes ${NAME} into the two files that carry such values - Xresources and redshift.conf are now templates copied into place, refreshed on every install - and bspwmrc exports the same file into the session so polybar's backlight/battery ids and network-env.sh's fallback interface come from it too. apps/monitor-manager/ is the Python monitor-profile system, extracted from ~/.config/bspwm where its tests and lockfile were being symlinked: the package is renamed lib -> monitor_manager, monitor-manager.py becomes monitor_manager/cli.py behind a `monitor-manager` console script, and the x11 module installs it as an editable uv tool constrained to uv.lock. bspwmrc, apply-auto.sh, and monitor-switch.sh call the tool instead of three different python/uv invocations. ProfileService reads a search path - ~/.config/bspwm/profiles (the tracked profiles, linked individually so ~/.config/bspwm is a real directory) then ~/.config/bspwm/profiles.d - which is the desktop half's overlay seam. The reconciler's polybar env vars are named in one place (bar_env, POLYBAR_ENV_VARS) and tests/test_polybar_contract.py holds the polybar config to that list. Overlay seams now win: bashrc sources ~/.config/dotfiles/env.sh before the interactive gate (for ssh commands, cron, units), ~/.bash_aliases after every tool block instead of before them, prepends rather than assigns PROMPT_COMMAND, and guards the lsd aliases; gitconfig's include moves to the bottom so ~/.gitconfig.local can override any key; tmux.conf gains `source -q ~/.tmux.conf.local` and kitty.conf `globinclude ~/.config/kitty.local.conf`. clipimg, the remote-side half of the clipboard kitten, moves to cli-tools so servers get it; AGENTS.md is also linked to ~/.codex/AGENTS.md; wacominit is its own per-host module. launch.sh reads font_size from kitty.conf instead of duplicating it and honours the cwd it computes. Dead config goes: polybar's never-included user_modules.ini and the unused wired/wireless-network modules, starship's [custom.foxdev] that the explicit format never rendered, the stray top-level kitty theme (now themes/aquarium_dark.conf). rofi's themes referenced an undefined @ac; colors.rasi now defines it as bspwm's accent. dunstrc resolves rofi and xdg-open on PATH rather than /usr/bin. The networkmanager_dmenu click action pointed at a binary nothing provisions; nm-connection-editor ships with network-manager-gnome. The one test that shells out to xrandr skips without a DISPLAY instead of failing. CI installs the server role from scratch in ubuntu:22.04 and ubuntu:24.04 containers as a non-root user, checks the shell and tools, and re-runs both scripts asserting only [skip]/[note] output; tests verify_sha256's refusal and install_release_binary's refusal to install on a mismatch; tests role resolution; runs the monitor-manager suite and its uv tool install; shellchecks every tracked script. Claude-Session: https://claude.ai/code/session_01R1D4FTi7umCLFpkuR355od
For the saved (or given) selection: every link in each module's install.conf.yaml resolves into this checkout, every render: destination exists as a real file, and every tool a module's provision.sh pins (found by grepping for `pin_satisfied <cmd> "$VAR"`) is installed at or above the pin. Then which overlay seams are present, whether git has an identity, and that the hooks and submodules are wired. Nonzero exit on any problem; changes nothing. Claude-Session: https://claude.ai/code/session_01R1D4FTi7umCLFpkuR355od
tpm stays only to load nord-tmux, the status-bar theme. tmux-sensible's contribution was a few options (history-limit, display-time, status-interval, focus-events, aggressive-resize, default-terminal); they are now set directly in settings.conf, with tmux-256color and a Tc override for kitty so truecolor works without the plugin. Claude-Session: https://claude.ai/code/session_01R1D4FTi7umCLFpkuR355od
pkg_ensure installs only missing packages, so on a machine that already had a distro git the git-core PPA was added and then never used - the 22.04 container run kept git 2.34.1, which cannot read the feature.manyFiles index gitconfig turns on. Check the installed version against the floor and apt-get install (an upgrade) when it is below. Claude-Session: https://claude.ai/code/session_01R1D4FTi7umCLFpkuR355od
The container user has no git identity, which doctor rightly reports; give it one the way a real machine would - ~/.gitconfig.local - and assert git reads it, which also proves the include at the bottom of gitconfig works. Then run doctor against the fresh install. Claude-Session: https://claude.ai/code/session_01R1D4FTi7umCLFpkuR355od
dotbot runs on python3 and a minimal ubuntu:24.04 has none. It only ever worked because the git module's PPA step pulled it in through software-properties-common; now that a new-enough distro git skips that step, the dependency has to be stated. Claude-Session: https://claude.ai/code/session_01R1D4FTi7umCLFpkuR355od
`git config --global KEY` does not follow [include] directives (a plain lookup does), so doctor reported a missing identity on every machine that sets it the documented way, in ~/.gitconfig.local. Ask for includes explicitly; CI's seam check does the same. Claude-Session: https://claude.ai/code/session_01R1D4FTi7umCLFpkuR355od
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Replaces the shell/desktop halves with
modules/<name>/(one tool's config + its provisioning) selected byroles/{server,workstation,desktop}; per-host values viahosts/*.envmerged into~/.config/dotfiles/host.envand a dotbotrender:plugin for the two files that carry them; overlay seams that actually win (env.sh pre-gate, aliases last, gitconfig include at the bottom, tmux/kitty local includes,profiles.dfor monitor profiles);apps/monitor-manager/as a real package (monitor_manager, console script) installed withuv tooland constrained touv.lock;./doctor; tmux plugin submodules fixed and trimmed to tpm + nord-tmux.CI now installs the
serverrole from scratch on ubuntu:22.04 and 24.04 as a non-root user, checks the shell and tools, seeds an identity through~/.gitconfig.local, runsdoctor, and asserts a secondprovision.sh+installis a no-op; plus sha256-refusal and role-resolution tests, the monitor-manager suite (211 tests) and its uv tool install, and shellcheck over every tracked script.Verified locally in docker on both images end to end. Three bugs the containers caught are fixed in-branch: git not upgrading from the PPA on 22.04 (
pkg_ensureonly installs missing packages),python3undeclared for dotbot on a minimal 24.04, andgit config --globalnot following includes indoctor.Not yet verified: the
desktoprole on a real X11 machine (bspwmrc→monitor-manageron PATH, renderedXresources/redshift.conf,~/.config/bspwmas a real directory)../doctorthere is the quick check. Deferred: theme-as-data (P6 of the review), unusedrichdependency, CLI/lid-state test gaps.Review page: https://claude.ai/code/artifact/406327af-2e10-42f9-a611-feb4586321da
🤖 Generated with Claude Code
https://claude.ai/code/session_01R1D4FTi7umCLFpkuR355od