Profiles: machines, roles and shared layers

The repo was one machine's capture. It is now a set of profiles built from
layers under profiles/:

  machines/  hp-laptop, macbook-air-m2, coder-desktop
  roles/     developer, devops, ai-agents
  features/  handoff (lan-mouse)
  shared     base, personal, personal-desktop

A profile resolves to its includes (depth first), any --roles, then itself;
for a path several layers provide, the last wins. install.sh --show prints
the layers and which one owns each file.

Hyprland settings no longer share a file: base's hyprland.lua loads
~/.config/hypr/layers/*.lua with Omarchy's own require_all, and bindings.lua
stays stock so nothing binds twice. Verified with Hyprland 0.56.2
--verify-config for all three profiles, plus a broken probe layer to prove
the directory is loaded.

packages.txt gains per-line arch (Arch Linux ARM lacks opencode, codex, mise,
shellcheck) and cmd= (skip when dotfiles' ~/.local/bin already provides the
command), and an [ignore] section that replaces capture.sh's hard-coded list.
Tab-separated records would have collapsed empty fields under read, so
package records use the unit separator.

hp-laptop: re-captured. monitors.lua catch-all scale is now 1, shell.json
has four new plugins, fix-stuck-displays has its connector-name fix,
navbar-cat is gone, plugin-manager and omarchy-phone are pinned, the
herdr-hud working tree is re-diffed and bin/herdr-web rides along. Its
handoff peer is now the Air (192.168.1.49); the old default list was the
HP's own addresses, written from the Air's side.

macbook-air-m2: captured read-only over SSH as it is (no themes, plugins
or bar changes). Its LAN_MOUSE_POINTER_SCALE=0.7 moves from the shared unit
into a lan-mouse.service.d drop-in in its own layer.

coder-desktop: the Omarchy settings covert-cloud's image used to patch in
by hand (Virtual-1 at 1920x1080, no animations, stay-awake, Retro 82 once),
for the image to apply at a pinned commit. Roles reach it per workspace via
install.sh --roles ... --no-clobber.

capture.sh writes each file back into the layer that owns it, and refuses
to run before the first layered install unless --force, since the old file
shapes would land in shared layers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0153egowV1Xw2RNjZnSyZicc
This commit is contained in:
2026-10-16 16:01:54 -04:00
co-authored by Claude Opus 5.5
parent b3f3f46b98
commit 87a31858fd
98 changed files with 2010 additions and 532 deletions
@@ -0,0 +1,10 @@
-- Extra autostart processes.
-- o.launch_on_start("my-service")
-- Keyboard/mouse sharing with the other Omarchy laptop (lan-mouse).
-- Runs as a daemon; input only crosses the screen edge once the peer is
-- activated, so starting it here is inert until Handoff is toggled on.
-- Superseded by the lan-mouse.service systemd user unit (journald logging,
-- ordering after the portal, Restart=on-failure). launch_on_start sent both
-- output streams to /dev/null, which hid every pairing failure.
-- o.launch_on_start("lan-mouse daemon")
@@ -0,0 +1,72 @@
-- Keep only your personal input overrides here. Uncommented settings below
-- replace Omarchy's defaults.
-- Keyboard layout and options.
-- See https://wiki.hypr.land/Configuring/Basics/Variables/#input
-- hl.config({
-- input = {
-- -- Use multiple keyboard layouts and switch between them with Left Alt + Right Alt.
-- kb_layout = "us,dk,eu",
-- kb_options = "compose:caps,shift:both_capslock_cancel,grp:alts_toggle",
--
-- -- Use a specific keyboard variant if needed (e.g. intl for international keyboards).
-- kb_variant = "intl",
--
-- -- Change speed of keyboard repeat.
-- repeat_rate = 40,
-- repeat_delay = 250,
--
-- -- Start with numlock on by default.
-- numlock_by_default = true,
--
-- -- Increase sensitivity for mouse/trackpad (default: 0).
-- sensitivity = 0.35,
--
-- -- Turn off mouse acceleration (default: adaptive).
-- accel_profile = "flat",
--
-- touchpad = {
-- -- Use natural (inverse) scrolling.
-- natural_scroll = true,
--
-- -- Use two-finger clicks for right-click instead of lower-right corner.
-- clickfinger_behavior = true,
--
-- -- Control the speed of your scrolling.
-- scroll_factor = 0.4,
--
-- -- Enable the touchpad while typing.
-- disable_while_typing = false,
--
-- -- Left-click-and-drag with three fingers.
-- drag_3fg = 1,
-- },
-- },
-- })
-- App-specific touchpad scroll speeds.
-- o.window("(Alacritty|kitty|foot)", { scroll_touchpad = 1.5 })
-- o.window("com.mitchellh.ghostty", { scroll_touchpad = 0.2 })
-- Enable touchpad gestures for changing workspaces.
-- See https://wiki.hypr.land/Configuring/Advanced-and-Cool/Gestures/
hl.gesture({ fingers = 3, direction = "horizontal", action = "workspace" })
-- Enable touchpad gestures for moving focus (helpful on scrolling layout).
-- hl.gesture({ fingers = 3, direction = "left", action = function() hl.dispatch(hl.dsp.focus({ direction = "l" })) end })
-- hl.gesture({ fingers = 3, direction = "right", action = function() hl.dispatch(hl.dsp.focus({ direction = "r" })) end })
-- lan-mouse (omarchy-handoff) virtual pointer: kill the SECOND acceleration pass.
-- lan-mouse forwards RELATIVE deltas that the SENDING compositor has already
-- accelerated. Omarchy leaves accel_profile unset (adaptive), so the receiver
-- amplifies them again and the pointer arrives hypersensitive while the local
-- trackpad feels normal. "flat" applies no curve, so a forwarded delta moves
-- exactly as far as the sender intended.
-- The name is "unknown-device" because wlr-virtual-pointer gives Hyprland no
-- name (virtual KEYBOARDS get named, pointers don't). Verified on this machine
-- with `lan-mouse test-emulation` + `hyprctl devices`: no real device here is
-- named unknown-device* (real pointers are elan0138:*, mouse-passthrough*,
-- dp-3-1), so this rule cannot touch the trackpad. Two entries because the
-- daemon may hold more than one virtual pointer at a time.
hl.device({ name = "unknown-device", sensitivity = 0, accel_profile = "flat" })
hl.device({ name = "unknown-device-1", sensitivity = 0, accel_profile = "flat" })
@@ -0,0 +1,48 @@
-- BEGIN hyprmoncfg wake settings
-- Shared with Omarchy while hyprmoncfg manages displays.
hl.monitor({ output = "eDP-1", mode = "preferred", position = "0x0", scale = 1.25 })
-- END hyprmoncfg wake settings
-- See https://wiki.hypr.land/Configuring/Basics/Monitors/
-- List current monitors and supported resolutions with: hyprctl monitors all
--
-- SINGLE SOURCE OF TRUTH for display config.
-- Do not add monitor rules anywhere else (hyprland.lua, a hyprmoncfg-generated
-- file, etc.) -- overlapping rules from several files were what made external
-- displays unrecoverable before.
local omarchy_gdk_scale = 1
local omarchy_monitor_scale = 1
hl.env("GDK_SCALE", tostring(omarchy_gdk_scale))
-- Catch-all: anything not named below gets its EDID-preferred mode.
hl.monitor({ output = "", mode = "preferred", position = "auto", scale = omarchy_monitor_scale })
-- Built-in laptop panel.
hl.monitor({
output = "desc:Chimei Innolux Corporation 0x1642",
mode = "1920x1200@60",
position = "auto",
scale = 1.25,
})
-- LG IPS236 on the laptop's own HDMI port.
hl.monitor({
output = "desc:LG Electronics IPS236 105NDLS5A720",
mode = "1920x1080@60",
position = "auto",
scale = 1,
})
-- LG TV via the Anker USB-C dock.
-- Deliberately NOT forced to 3840x2160@60: the dock negotiates DP alt-mode
-- with only 2 lanes (pin assignment D), which leaves no bandwidth headroom at
-- 4K60. Forcing it produced a "monitor has no mode" loop. "preferred" is
-- 3840x2160@30 here, which links reliably. Use 1920x1080@120 instead if you
-- want high refresh over this dock.
hl.monitor({
output = "desc:LG Electronics LG TV SSCR2 0x01010101",
mode = "preferred",
position = "auto",
scale = 1.25,
})