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:
@@ -1,67 +1,185 @@
|
||||
# omarchy-setup
|
||||
|
||||
Every customization this laptop has on top of a stock Omarchy install, in one
|
||||
place, so a second machine can be brought to the same state.
|
||||
Omarchy customizations on top of a stock install, as **profiles**: one per
|
||||
machine, each built from shared **layers** and generic **roles**.
|
||||
|
||||
Captured from Omarchy **4.0.4-1** on **2026-10-10**.
|
||||
| Profile | Machine |
|
||||
|---|---|
|
||||
| `hp-laptop` | The HP (`omarchy-laptop`): Intel, Anker dock, LG displays. Where this repo started. |
|
||||
| `macbook-air-m2` | The Air (`omarchy-air`): Asahi Linux on Arch Linux ARM, aarch64. |
|
||||
| `coder-desktop` | The streamed Coder desktops, built by covert-cloud's image pipeline. |
|
||||
|
||||
| Role | Adds |
|
||||
|---|---|
|
||||
| `developer` | gh, delta, uv, just, direnv, shfmt/shellcheck, httpie, mise, VS Code |
|
||||
| `devops` | kubectl, helm, k9s, kubectx, stern, kustomize, talosctl, cilium, tofu, terragrunt, packer, ansible, go-task, yq, sops/age, dig/mtr/nmap/tcpdump |
|
||||
| `ai-agents` | Claude Code, OpenCode, Codex, Gemini CLI, Copilot CLI |
|
||||
|
||||
```bash
|
||||
git clone <this repo> ~/omarchy-setup
|
||||
git clone https://git.nic-oconnor.com/public/omarchy-setup.git ~/omarchy-setup
|
||||
cd ~/omarchy-setup
|
||||
./install.sh --dry-run # see what it would change
|
||||
./install.sh # do it
|
||||
./install.sh --profiles # what exists
|
||||
./install.sh --profile hp-laptop --show # its layers, and which layer owns each file
|
||||
./install.sh --dry-run # see what it would change (profile picked by hostname)
|
||||
./install.sh # do it
|
||||
./install.sh --roles devops,ai-agents # add roles on top of the profile
|
||||
```
|
||||
|
||||
`install.sh` is idempotent and backs up anything it overwrites as
|
||||
`<file>.bak.<epoch>`. `capture.sh` runs the other way, pulling live changes back
|
||||
into the repo so this stays the source of truth.
|
||||
`<file>.bak.<epoch>`. It records the profile and roles it applied in
|
||||
`~/.config/omarchy-setup/profile`, so later runs (and `capture.sh`) need no
|
||||
flags. `capture.sh` runs the other way, pulling live changes back into the
|
||||
layer that owns each file, so the repo stays the source of truth.
|
||||
|
||||
## What is in here
|
||||
## How profiles are built
|
||||
|
||||
| Path | What |
|
||||
Everything lives under `profiles/`. A layer is a directory with a `profile`
|
||||
file (bash: `description`, `include=(...)`, and for machines `hostnames`,
|
||||
`arch`, `handoff_peer_ips`) and any of the same pieces this repo always had:
|
||||
|
||||
| Path in a layer | Installed to |
|
||||
|---|---|
|
||||
| `config/` | Mirrors `~/.config`. Only files that differ from Omarchy's shipped defaults. |
|
||||
| `themes/` | The three hand-built themes, wallpapers included. |
|
||||
| `plugins.txt` | The 10 Omarchy shell plugins, each pinned to a commit. |
|
||||
| `plugin-patches/` | Local plugin work that exists on no remote (see below). |
|
||||
| `bin/` | `omarchy-handoff` and `fix-stuck-displays`. |
|
||||
| `handoff/` | The lan-mouse source patch that fixes pointer feel, plus example `config.toml`s. Not a `~/.config` mirror. |
|
||||
| `systemd/user/` | `lan-mouse.service`, `voxtype.service`. |
|
||||
| `system/` | `/etc` drop-ins: the ARP sysctl and `hid_apple` fnmode. |
|
||||
| `packages.txt` | Packages beyond the Omarchy baseline, each with a reason. |
|
||||
| `config/` | `~/.config`, mirrored |
|
||||
| `themes/` | `~/.config/omarchy/themes` |
|
||||
| `plugins.txt`, `plugin-patches/` | `~/.config/omarchy/plugins`, pinned; local work replayed |
|
||||
| `bin/` | `~/.local/bin` |
|
||||
| `systemd/user/` | user units, plus `<unit>.service.d/*.conf` drop-ins |
|
||||
| `system/` | `/etc`, mirrored (sudo) |
|
||||
| `handoff/` | the lan-mouse patch and example configs (`install.sh handoff`) |
|
||||
| `packages.txt` | `omarchy pkg add` / `omarchy pkg aur add` |
|
||||
| `setup.sh` | run last, for state outside `~/.config` (markers, gsettings, a first-run theme) |
|
||||
|
||||
## The customizations, and why
|
||||
A profile resolves to an ordered list of layers: its `include`s first (depth
|
||||
first, each once), then any `--roles`, then the profile itself. **For a path
|
||||
several layers provide, the last one wins**, so a machine overrides the roles
|
||||
and shared layers beneath it. `./install.sh --show` prints the result.
|
||||
|
||||
**Displays** (`config/hypr/monitors.lua`) are the fiddliest part. The file is the
|
||||
single source of truth for monitor rules on purpose — overlapping rules spread
|
||||
across several files is what previously made external displays unrecoverable.
|
||||
Three outputs are named by EDID description rather than connector, so they match
|
||||
whichever port they land on: the built-in Chimei panel at 1.25x, the LG IPS236 on
|
||||
HDMI at 1x, and the LG TV through the Anker dock. The TV is deliberately left on
|
||||
`preferred` (3840x2160@30) — the dock negotiates DP alt-mode with only two lanes,
|
||||
so forcing 4K60 produced a "monitor has no mode" loop. `GDK_SCALE=1` with a 1.25
|
||||
monitor scale; the stock pairing is 2 and `auto`.
|
||||
| Layer | Used by | What |
|
||||
|---|---|---|
|
||||
| `base` | all | `hyprland.lua` with the `hypr/layers/` loader; `bindings.lua` kept at stock |
|
||||
| `personal` | both laptops | branding, default agent (`claude`), herdr, opencode, voxtype |
|
||||
| `personal-desktop` | HP | the three hand-built themes, the shell plugins, bar layout, Claude/Herdr bindings |
|
||||
| `features/handoff` | both laptops | `omarchy-handoff` + patched lan-mouse, its unit and binding |
|
||||
| `roles/*` | per profile, or `--roles` | packages, and any bindings the role needs |
|
||||
| `machines/*` | — | displays, input, hardware packages, `/etc` drop-ins, per-machine overrides |
|
||||
|
||||
`hyprland.lua` sources `hyprmoncfg-monitors.lua` last so the `hyprmoncfg` daemon's
|
||||
generated layout wins over anything above it.
|
||||
**Hyprland settings never share a file.** `base`'s `hyprland.lua` loads every
|
||||
`~/.config/hypr/layers/*.lua` in name order (Omarchy's own `require_all`, with
|
||||
reload), after `monitors`/`input`/`bindings`/`looknfeel`/`autostart`. Each
|
||||
layer ships its own `NN-<layer>.lua` there — roles 20s, `personal-desktop` 40,
|
||||
features 50, machines 80 — and `bindings.lua` stays stock so nothing is bound
|
||||
twice. `install.sh` warns about a file in `hypr/layers/` that no layer of the
|
||||
current profile provides (a role you dropped).
|
||||
|
||||
`bin/fix-stuck-displays` recovers the related kernel-side failure: after
|
||||
suspend/resume i915 can leave an unplugged connector "disconnected" but still
|
||||
"enabled" on a pipe Hyprland has forgotten, which blocks every other output from
|
||||
modesetting. It forces the connector on, disables it through Hyprland to release
|
||||
the pipe, then returns it to auto-detect. It needs passwordless sudo for
|
||||
`tee /sys/class/drm/*/status`.
|
||||
**Packages** lines are `name [arch...] [cmd=a,b] # why`, in `[repo]`, `[aur]`,
|
||||
`[optional]` or `[ignore]` sections. An arch limits a line to `x86_64` or
|
||||
`aarch64` (Arch Linux ARM lacks `opencode`, `openai-codex`, `mise` and
|
||||
`shellcheck`). `cmd=` skips the package when one of those commands is already
|
||||
on PATH — on the laptops, `dotfiles`' `bin/` puts most devops and agent CLIs in
|
||||
`~/.local/bin`, and the Arch package would only duplicate them; on a Coder
|
||||
desktop, which has no `dotfiles`, the package is the tool. `[ignore]` is for
|
||||
packages a machine has on purpose but this repo does not manage, so
|
||||
`capture.sh packages` stays quiet about them.
|
||||
|
||||
**Keyboard/mouse sharing** (`bin/omarchy-handoff`, `systemd/user/lan-mouse.service`)
|
||||
drives `lan-mouse` to share input with the other Omarchy laptop, bound to
|
||||
`SUPER+SHIFT+K` (`SUPER+K` is already Keybindings). The script's header comment
|
||||
is the real documentation — it records the non-obvious facts that cost hours:
|
||||
`capture_backend` must be `layer-shell` (the portal backend is a silent no-op on
|
||||
Hyprland 0.56.2), `[authorized_fingerprints]` is keyed by fingerprint and the
|
||||
reversed form fails silently, and the log variable is `LAN_MOUSE_LOG_LEVEL`, not
|
||||
`RUST_LOG`. It runs as a user unit rather than from `autostart.lua` because
|
||||
`o.launch_on_start` sends both streams to `/dev/null`, hiding every pairing
|
||||
failure.
|
||||
Roles name the `dotfiles` modules they pair with (`dotfiles=(...)`), and
|
||||
`install.sh` prints them when `~/.dotfiles` is absent. It never runs
|
||||
`dotfiles` itself: that needs a 1Password token, which a Coder desktop does
|
||||
not have.
|
||||
|
||||
## Coder desktops
|
||||
|
||||
The image is built by `covert-cloud`
|
||||
(`platform/workspaces/omarchy-desktop/image/`). Its `provision/user.sh` clones
|
||||
this repo at a **pinned commit** into `~/.local/share/omarchy-setup` and runs
|
||||
`install.sh --profile coder-desktop`, which bakes in `base`, `developer` and
|
||||
the `coder-desktop` layer:
|
||||
|
||||
- one fixed `Virtual-1` monitor at 1920x1080, GDK scale 1 — **must match**
|
||||
`selkies.service`'s `--manual-width/--manual-height`; the build fails if the
|
||||
line is missing;
|
||||
- no window animations, and GTK reduced motion: the VM has no GPU, so every
|
||||
frame is drawn on the CPU;
|
||||
- Omarchy's stay-awake mode: the desktop user has no password, so a lock
|
||||
screen could never be unlocked; the build checks for the marker;
|
||||
- Retro 82 as the default theme, set once only, so a theme the developer picks
|
||||
survives restarts. (The image itself installs the Covert Cloud themes.)
|
||||
|
||||
The plumbing stays in `covert-cloud`: Selkies, the Coder agent, the Super key
|
||||
stand-in, the start page, autologin, and the lockdown (no SSH, no file
|
||||
transfer, locked password). Nothing from `personal*` or `handoff` goes on a
|
||||
desktop that other people use.
|
||||
|
||||
**Roles per workspace.** The Coder template has a **Roles** parameter
|
||||
(multi-select: `devops`, `ai-agents`). At every workspace start it runs
|
||||
`install.sh --profile coder-desktop --roles <chosen> --no-clobber`:
|
||||
idempotent, so an unchanged choice costs a few seconds, and `--no-clobber`
|
||||
keeps any file the developer has edited. Deselecting a role stops managing
|
||||
it but does not uninstall its packages; its `hypr/layers/` file is left in place
|
||||
and reported.
|
||||
|
||||
**Changing what the desktops get** is a commit here plus a pin bump there:
|
||||
`OMARCHY_SETUP_REF` in `covert-cloud`'s `provision/user.sh` (rebuild the image)
|
||||
and in the template's `main.tf` (template push; reaches running desktops at
|
||||
their next start).
|
||||
|
||||
## The MacBook Air M2
|
||||
|
||||
Captured as it was on 2026-10-16 (Omarchy 4.0.3rc4), read-only over SSH: no
|
||||
hand-built themes, no shell plugins, stock bar and terminal fonts, so it
|
||||
includes `personal` but not `personal-desktop`. Add that to its `include=` to
|
||||
give it the HP's desktop. What is its own:
|
||||
|
||||
- `monitors.lua`: monitor scale 1.33333, GDK scale 1, no named outputs.
|
||||
- `input.lua`: stock gestures (no three-finger workspace swipe), and the
|
||||
measured note on why `sensitivity`/`accel_profile` rules are inert for the
|
||||
lan-mouse virtual pointer.
|
||||
- `/etc/modprobe.d`: `hid_apple fnmode=1` (the built-in keyboard; the HP uses 2
|
||||
for an external Apple keyboard) and `appledrm show_notch=1`.
|
||||
- `lan-mouse.service.d/pointer-scale.conf`: `LAN_MOUSE_POINTER_SCALE=0.7`, for
|
||||
the Air's 140 logical ppi against the LG's ~96.
|
||||
- Its own `herdr/config.toml` (no agent-row customization yet), `opencode.json`
|
||||
(`"theme": "system"`) and `voxtype/config.toml`.
|
||||
- The Asahi platform packages, listed so `capture.sh` notices drift.
|
||||
|
||||
Left out: `~/.config/opencode/opencode.gateway.json` (holds the LiteLLM key;
|
||||
`dotfiles`' `mcp-config` writes it), `~/.config/lan-mouse/`, and the
|
||||
post-update hooks and `omarchy-asahi-mic.service`, which Omarchy installs
|
||||
itself.
|
||||
|
||||
## The HP laptop: its customizations, and why
|
||||
|
||||
**Displays** (`profiles/machines/hp-laptop/config/hypr/monitors.lua`) are the
|
||||
fiddliest part. The file is the single source of truth for monitor rules on
|
||||
purpose — overlapping rules spread across several files is what previously made
|
||||
external displays unrecoverable. Three outputs are named by EDID description
|
||||
rather than connector, so they match whichever port they land on: the built-in
|
||||
Chimei panel at 1.25x, the LG IPS236 on HDMI at 1x, and the LG TV through the
|
||||
Anker dock. The TV is deliberately left on `preferred` (3840x2160@30) — the dock
|
||||
negotiates DP alt-mode with only two lanes, so forcing 4K60 produced a "monitor
|
||||
has no mode" loop. `GDK_SCALE=1` with a catch-all monitor scale of 1 (the
|
||||
built-in panel and the TV set 1.25 in their own rules); the stock pairing is 2
|
||||
and `auto`.
|
||||
|
||||
`hyprland.lua` sources `hyprmoncfg-monitors.lua` last so the `hyprmoncfg`
|
||||
daemon's generated layout wins over anything above it.
|
||||
|
||||
`profiles/machines/hp-laptop/bin/fix-stuck-displays` recovers the related
|
||||
kernel-side failure: after suspend/resume i915 can leave an unplugged connector
|
||||
"disconnected" but still "enabled" on a pipe Hyprland has forgotten, which
|
||||
blocks every other output from modesetting. It forces the connector on, disables
|
||||
it through Hyprland to release the pipe, then returns it to auto-detect. It
|
||||
needs passwordless sudo for `tee /sys/class/drm/*/status`.
|
||||
|
||||
**Keyboard/mouse sharing** (`profiles/features/handoff/`: `bin/omarchy-handoff`,
|
||||
`systemd/user/lan-mouse.service`) drives `lan-mouse` to share input with the
|
||||
other Omarchy laptop (the Air), bound to `SUPER+SHIFT+K` (`SUPER+K` is already
|
||||
Keybindings). The script's header comment is the real documentation — it records
|
||||
the non-obvious facts that cost hours: `capture_backend` must be `layer-shell`
|
||||
(the portal backend is a silent no-op on Hyprland 0.56.2),
|
||||
`[authorized_fingerprints]` is keyed by fingerprint and the reversed form fails
|
||||
silently, and the log variable is `LAN_MOUSE_LOG_LEVEL`, not `RUST_LOG`. It runs
|
||||
as a user unit rather than from `autostart.lua` because `o.launch_on_start`
|
||||
sends both streams to `/dev/null`, hiding every pairing failure.
|
||||
|
||||
Three further facts were only established after the above was first written, and
|
||||
they are what actually made it work:
|
||||
@@ -72,7 +190,8 @@ they are what actually made it work:
|
||||
digest is the *correct* digest, valid TOML, non-empty, passes every guard, and
|
||||
never matches: the DTLS handshake dies `bad_certificate`, indistinguishable
|
||||
from a wrong key or a dropped packet. This was the root cause of a full day of
|
||||
dead crossings. `omarchy-handoff fixcase` repairs it; `doctor` now fails on it.
|
||||
dead crossings. `omarchy-handoff fixcase` repairs it; `doctor` now fails on
|
||||
it.
|
||||
- **Authorization is receiver-side only, not mutual.** `connect.rs` sets
|
||||
`insecure_skip_verify`, so the *connecting* side never checks the peer's
|
||||
certificate — only the listener consults `authorized_fingerprints`. Each
|
||||
@@ -80,65 +199,73 @@ they are what actually made it work:
|
||||
needs both lists, and a sender cannot tell whether it is talking to the real
|
||||
peer. Input goes to whatever answers on that IP:port.
|
||||
- **`ufw` is default-deny inbound**, and a dropped inbound 4242 presents
|
||||
*identically* to a bad certificate. `install.sh --handoff` opens it for the
|
||||
peer's addresses. Check it first: `journalctl -k -g 'UFW BLOCK'`.
|
||||
*identically* to a bad certificate. `install.sh handoff` opens it for the
|
||||
addresses in the profile's `handoff_peer_ips`. Check it first: `journalctl -k
|
||||
-g 'UFW BLOCK'`.
|
||||
|
||||
`handoff/patch/` carries a two-line source patch so the daemon forwards the
|
||||
accelerated deltas, which is the only way to make the sender's `sensitivity` and
|
||||
`accel_profile` affect remote pointer feel at all; it also adds
|
||||
`LAN_MOUSE_POINTER_SCALE` for the residual difference in logical pixel density
|
||||
between the two screens. `install.sh` builds it per-machine — the two laptops are
|
||||
different architectures — and `systemd/user/lan-mouse.service` runs the result.
|
||||
`profiles/features/handoff/handoff/patch/` carries a two-line source patch so
|
||||
the daemon forwards the accelerated deltas, which is the only way to make the
|
||||
sender's `sensitivity` and `accel_profile` affect remote pointer feel at all; it
|
||||
also adds `LAN_MOUSE_POINTER_SCALE` for the residual difference in logical pixel
|
||||
density between the two screens. `install.sh` builds it per-machine — the two
|
||||
laptops are different architectures — and `lan-mouse.service` runs the result.
|
||||
The Air's `LAN_MOUSE_POINTER_SCALE=0.7` is a systemd drop-in in its own layer
|
||||
(`lan-mouse.service.d/pointer-scale.conf`), so the shared unit stays at 1.0.
|
||||
|
||||
`system/sysctl.d/99-omarchy-handoff-arp.conf` goes with it: Wi-Fi and the dock's
|
||||
ethernet both sit on `192.168.1.0/24`, and with the default ARP settings the
|
||||
subnet's mapping collapses onto whichever NIC replied last.
|
||||
`profiles/machines/hp-laptop/system/sysctl.d/99-omarchy-handoff-arp.conf` goes
|
||||
with it: Wi-Fi and the dock's ethernet both sit on `192.168.1.0/24`, and with
|
||||
the default ARP settings the subnet's mapping collapses onto whichever NIC
|
||||
replied last.
|
||||
|
||||
**Bar and shell** (`config/omarchy/shell.json`) adds `omarchy.active-window` to
|
||||
the left, five plugin widgets, and `indie.herdr-hud` as a non-bar plugin. Idle is
|
||||
stretched a long way past stock — screensaver at 20 minutes, lock at 30, against
|
||||
2.5 and 5.
|
||||
**Bar and shell** (`profiles/personal-desktop/config/omarchy/shell.json`) adds
|
||||
`omarchy.active-window` to the left, five plugin widgets, and `indie.herdr-hud`
|
||||
as a non-bar plugin. Idle is stretched a long way past stock — screensaver at 20
|
||||
minutes, lock at 30, against 2.5 and 5.
|
||||
|
||||
**Keybindings** (`config/hypr/bindings.lua`) rebinds `SUPER+SHIFT+A` from the
|
||||
stock ChatGPT webapp to Claude, and adds four Herdr HUD bindings plus Handoff.
|
||||
**Keybindings** live in two layer files.
|
||||
`profiles/personal-desktop/config/hypr/layers/40-personal-desktop.lua` rebinds
|
||||
`SUPER+SHIFT+A` from the stock ChatGPT webapp to Claude and adds four Herdr HUD
|
||||
bindings; the handoff feature's `50-handoff.lua` adds Handoff.
|
||||
|
||||
**Input** (`config/hypr/input.lua`) enables the three-finger horizontal
|
||||
workspace gesture that ships commented out, and flattens pointer acceleration for
|
||||
`unknown-device*`.
|
||||
**Input** (`profiles/machines/hp-laptop/config/hypr/input.lua`) enables the
|
||||
three-finger horizontal workspace gesture that ships commented out, and flattens
|
||||
pointer acceleration for `unknown-device*`.
|
||||
|
||||
That second rule is **a no-op, and the reasoning originally given for it was
|
||||
wrong.** It was added believing lan-mouse forwards deltas the sending compositor
|
||||
had already accelerated, which the receiver then amplified a second time. Upstream
|
||||
does the opposite: it forwards the *unaccelerated* deltas and discards the
|
||||
accelerated pair in the same event (`handoff/patch/REBUILD.md`). And the rule
|
||||
cannot act either way — `hl.device({name="unknown-device"})` does match the
|
||||
virtual pointer (provable by toggling `scroll_factor`), but `sensitivity` and
|
||||
`accel_profile` are libinput pointer-acceleration settings and a
|
||||
`wlr-virtual-pointer` is not a libinput device, so they have nothing to act on.
|
||||
Measured 2026-10-10 on both machines with `lan-mouse test-emulation` + `hyprctl
|
||||
cursorpos`: travel was 398x198px at `sensitivity = 0` and identical at `-0.9`,
|
||||
exactly 1:1 with the raw deltas. The lines are kept because they are harmless and
|
||||
the `unknown-device` naming note is worth preserving; the real fix is
|
||||
`handoff/patch/`. Do not add sensitivity or accel_profile rules here expecting
|
||||
them to change remote pointer feel.
|
||||
had already accelerated, which the receiver then amplified a second time.
|
||||
Upstream does the opposite: it forwards the *unaccelerated* deltas and discards
|
||||
the accelerated pair in the same event
|
||||
(`profiles/features/handoff/handoff/patch/REBUILD.md`). And the rule cannot act
|
||||
either way — `hl.device({name="unknown-device"})` does match the virtual pointer
|
||||
(provable by toggling `scroll_factor`), but `sensitivity` and `accel_profile`
|
||||
are libinput pointer-acceleration settings and a `wlr-virtual-pointer` is not a
|
||||
libinput device, so they have nothing to act on. Measured 2026-10-10 on both
|
||||
machines with `lan-mouse test-emulation` + `hyprctl cursorpos`: travel was
|
||||
398x198px at `sensitivity = 0` and identical at `-0.9`, exactly 1:1 with the raw
|
||||
deltas. The lines are kept because they are harmless and the `unknown-device`
|
||||
naming note is worth preserving; the real fix is `handoff/patch/`. Do not add
|
||||
sensitivity or accel_profile rules here expecting them to change remote pointer
|
||||
feel.
|
||||
|
||||
**Terminals** are all dropped to a smaller font (9 -> 8) except ghostty, which
|
||||
went the other way to 12. `shell.toml` sets the bar font base size to 10.
|
||||
|
||||
**Branding** (`config/omarchy/branding/`) replaces the about and screensaver
|
||||
ASCII art.
|
||||
**Branding** (`profiles/personal/config/omarchy/branding/`, shared with the Air)
|
||||
replaces the about and screensaver ASCII art.
|
||||
|
||||
**`hid_apple` fnmode=2** makes the F-keys act as F-keys on an Apple keyboard.
|
||||
It only takes effect after `sudo mkinitcpio -P` or a module reload.
|
||||
|
||||
## Local plugin work
|
||||
|
||||
`indie.herdr-hud` is the one piece that exists on no remote. Ten commits live on
|
||||
its `local` branch — touchpad scroll feel, agent ordering, context-size display —
|
||||
and they stay off the upstream PR deliberately. `plugin-patches/` carries them as
|
||||
a git bundle plus a patch for the uncommitted working tree, and `install.sh`
|
||||
replays both after cloning. `io.github.tallsam.navbar-cat` has a one-file working
|
||||
tree change captured the same way.
|
||||
`indie.herdr-hud` is the one piece that exists on no remote. Its `local` branch
|
||||
carries commits — touchpad scroll feel, agent ordering, context-size display —
|
||||
and they stay off the upstream PR deliberately.
|
||||
`profiles/personal-desktop/plugin-patches/` carries them as a git bundle plus a
|
||||
patch for the uncommitted working tree, and `install.sh` replays both after
|
||||
cloning. Two untracked scripts in the same plugin, `bin/herdr-agents` and
|
||||
`bin/herdr-web`, ride along as `indie.herdr-hud--bin--<name>`.
|
||||
|
||||
`capture.sh plugins` re-bundles and re-diffs these, so local work keeps flowing
|
||||
back into the repo.
|
||||
@@ -148,42 +275,62 @@ back into the repo.
|
||||
- **Secrets.** `~/.config/lan-mouse/` holds a private key and per-machine
|
||||
fingerprints; `~/.config/novnc/auth.env`, SSH keys and the git credential
|
||||
helpers are likewise machine-local. Start from
|
||||
`handoff/config/config.toml.example-{air,laptop}` (which carry the
|
||||
`capture_backend`, edge and lowercase-fingerprint rules), then pair with
|
||||
`omarchy-handoff pair <peer> <lowercase-sha256>` and `omarchy-handoff doctor`.
|
||||
A fresh install regenerates the certificate, so this machine's fingerprint
|
||||
changes and the *peer* has to re-pair. Back up `lan-mouse.pem` beforehand if
|
||||
you would rather keep it stable — somewhere private, not here.
|
||||
`profiles/features/handoff/handoff/config/config.toml.example-{air,laptop}`
|
||||
(which carry the `capture_backend`, edge and lowercase-fingerprint rules),
|
||||
then pair with `omarchy-handoff pair <peer> <lowercase-sha256>` and
|
||||
`omarchy-handoff doctor`. A fresh install regenerates the certificate, so this
|
||||
machine's fingerprint changes and the *peer* has to re-pair. Back up
|
||||
`lan-mouse.pem` beforehand if you would rather keep it stable — somewhere
|
||||
private, not here.
|
||||
- **Shell, git and dev tooling.** That is already its own repo, `dotfiles`
|
||||
(`git.nic-oconnor.com/public/dotfiles`), which handles zsh, mise, 1Password and
|
||||
the `~/.local/bin` tool shims. The only overlap avoided here is
|
||||
(`git.nic-oconnor.com/public/dotfiles`), which handles zsh, mise, 1Password
|
||||
and the `~/.local/bin` tool shims. The only overlap avoided here is
|
||||
`~/.config/git/config`, whose customizations are identity and credential
|
||||
helpers — `dotfiles` territory.
|
||||
- **The remote-access stack.** `wayvnc`, `novnc`, `sunshine`, `freerdp`, `remmina`
|
||||
and `omarchy-remote-desktop` are installed on this laptop but scoped out.
|
||||
`kokd.remote-desktop` is still in `plugins.txt` since it is a bar plugin, but
|
||||
it is not placed in `shell.json`.
|
||||
- **Work tooling.** The keycloak helpers (`kcadm`, `kclogin`, `wren-keycloak`) and
|
||||
`paperclipai.service`.
|
||||
- **The remote-access stack.** `wayvnc`, `novnc`, `sunshine`, `freerdp`,
|
||||
`remmina` and `omarchy-remote-desktop` are installed on this laptop but scoped
|
||||
out. `kokd.remote-desktop` is still in `plugins.txt` since it is a bar plugin,
|
||||
but it is not placed in `shell.json`.
|
||||
- **Two plugins with no remote yet.** `niccoconnor.mantel` and
|
||||
`niccoconnor.keyhints` are installed on the HP and placed in `shell.json`, but
|
||||
neither has an `origin`, so `plugins.txt` cannot pin them (`capture.sh` says
|
||||
so). Until they are pushed, another machine gets a bar with those two slots
|
||||
empty.
|
||||
- **Work tooling.** The keycloak helpers (`kcadm`, `kclogin`, `wren-keycloak`)
|
||||
and `paperclipai.service`.
|
||||
- **aether-managed themes.** `pink-gt3rs`, `porsche-cayman` and `porsche-rain`
|
||||
carry a `.aether-managed` marker and are reinstallable with `aether`, so their
|
||||
~18MB of wallpapers and previews stay out.
|
||||
- **`btop.conf`.** Its only diff against stock is v1.4.7 default drift, not a
|
||||
real customization.
|
||||
- **Backup files.** Fifteen `.bak.*` and `.prefix.*` files are sitting in
|
||||
`~/.config/hypr` and `~/.config/omarchy` from earlier editing sessions. They are
|
||||
not tracked and are safe to delete.
|
||||
`~/.config/hypr` and `~/.config/omarchy` from earlier editing sessions. They
|
||||
are not tracked and are safe to delete.
|
||||
|
||||
## Adding a file
|
||||
## Adding things
|
||||
|
||||
`capture.sh` only refreshes what the repo already tracks, so start it by hand:
|
||||
**A file.** `capture.sh` only refreshes what the repo already tracks, so start
|
||||
it by hand, in the layer it belongs to:
|
||||
|
||||
```bash
|
||||
cp ~/.config/foo/bar.conf config/foo/bar.conf # path mirrors ~/.config
|
||||
git add config/foo/bar.conf
|
||||
cp ~/.config/foo/bar.conf profiles/machines/hp-laptop/config/foo/bar.conf
|
||||
git add profiles/machines/hp-laptop/config/foo/bar.conf
|
||||
```
|
||||
|
||||
`install.sh config` and `capture.sh config` both walk `config/` recursively, so
|
||||
nothing else needs changing. Check first that the file actually differs from
|
||||
stock — `diff /usr/share/omarchy/config/foo/bar.conf ~/.config/foo/bar.conf` —
|
||||
or you will be tracking a file Omarchy already ships.
|
||||
Check first that it actually differs from stock —
|
||||
`diff /usr/share/omarchy/config/foo/bar.conf ~/.config/foo/bar.conf` — or you
|
||||
will be tracking a file Omarchy already ships. A Hyprland setting goes in that
|
||||
layer's `config/hypr/layers/NN-<layer>.lua`, not in `bindings.lua` or
|
||||
`looknfeel.lua`.
|
||||
|
||||
**A role.** `mkdir profiles/roles/<name>`, give it a `profile` (`description=`,
|
||||
optionally `dotfiles=(...)`) and a `packages.txt`, plus
|
||||
`config/hypr/layers/2N-<name>.lua` if it needs bindings. Use `cmd=` for any
|
||||
package `dotfiles` might already provide, and an arch for anything Arch Linux
|
||||
ARM lacks. To offer it on Coder desktops, add it to the template's Roles
|
||||
parameter in `covert-cloud`.
|
||||
|
||||
**A machine.** `mkdir profiles/machines/<name>` with a `profile` naming
|
||||
`hostnames=`, `arch=` and `include=(base ...)`, then its `monitors.lua`,
|
||||
`input.lua`, `packages.txt` and `/etc` drop-ins. Run `./install.sh --profile
|
||||
<name> --dry-run` on it, then `./capture.sh` after any hand-tuning.
|
||||
|
||||
Reference in New Issue
Block a user