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:
@@ -0,0 +1,96 @@
|
||||
onboarding = false
|
||||
# Mirrors the Omarchy tmux config in config/tmux/tmux.conf
|
||||
# tmux session -> herdr workspace, tmux window -> herdr tab, tmux pane -> herdr pane
|
||||
|
||||
[theme]
|
||||
# tmux ran on the terminal's own palette (bg=default, fg=default, ANSI blue accents)
|
||||
name = "terminal"
|
||||
|
||||
[theme.custom]
|
||||
# The active tab is drawn as panel_bg text on an accent background, so panel_bg
|
||||
# has to be dark for it to read - same colors as status-left's "#[fg=black,bg=blue]"
|
||||
panel_bg = "black"
|
||||
|
||||
[terminal]
|
||||
# Matches -c "#{pane_current_path}" on every split, window, and session
|
||||
new_cwd = "follow"
|
||||
|
||||
[keys]
|
||||
prefix = "ctrl+space"
|
||||
|
||||
# Config and help
|
||||
reload_config = "prefix+q"
|
||||
help = "prefix+?"
|
||||
detach = "prefix+d"
|
||||
|
||||
# Copy mode
|
||||
copy_mode = "prefix+["
|
||||
|
||||
# Panes
|
||||
split_horizontal = ["prefix+h", "alt+enter"]
|
||||
split_vertical = ["prefix+v", "alt+shift+enter"]
|
||||
close_pane = ["prefix+x", "alt+esc"]
|
||||
zoom = "prefix+z"
|
||||
last_pane = "prefix+;"
|
||||
|
||||
focus_pane_left = "ctrl+alt+left"
|
||||
focus_pane_down = "ctrl+alt+down"
|
||||
focus_pane_up = "ctrl+alt+up"
|
||||
focus_pane_right = "ctrl+alt+right"
|
||||
|
||||
resize_mode = ["prefix+ctrl+left", "prefix+ctrl+down", "prefix+ctrl+up", "prefix+ctrl+right"]
|
||||
|
||||
# Like resize-pane on C-M-S-arrows
|
||||
resize_pane_left = "ctrl+alt+shift+left"
|
||||
resize_pane_down = "ctrl+alt+shift+down"
|
||||
resize_pane_up = "ctrl+alt+shift+up"
|
||||
resize_pane_right = "ctrl+alt+shift+right"
|
||||
|
||||
# No tmux equivalent; herdr's default prefix+shift+p is taken by previous session
|
||||
rename_pane = "prefix+shift+o"
|
||||
|
||||
# Windows -> tabs
|
||||
new_tab = "prefix+c"
|
||||
rename_tab = "prefix+r"
|
||||
close_tab = "prefix+k"
|
||||
switch_tab = ["prefix+1..9", "alt+1..9"]
|
||||
previous_tab = ["prefix+p", "alt+left"]
|
||||
next_tab = ["prefix+n", "alt+right"]
|
||||
|
||||
# Like swap-window -t -1/+1 on M-S-Left/Right
|
||||
move_tab_previous = "alt+shift+left"
|
||||
move_tab_next = "alt+shift+right"
|
||||
|
||||
# Sessions -> workspaces
|
||||
new_workspace = "prefix+shift+c"
|
||||
rename_workspace = "prefix+shift+r"
|
||||
close_workspace = "prefix+shift+k"
|
||||
previous_workspace = ["prefix+shift+p", "alt+up"]
|
||||
next_workspace = ["prefix+shift+n", "alt+down"]
|
||||
|
||||
[ui]
|
||||
accent = "blue"
|
||||
|
||||
# tmux drew single-line dividers between adjacent panes and no outer frame
|
||||
pane_gaps = false
|
||||
pane_outer_borders = false
|
||||
|
||||
# tmux had no scrollbar column beside its panes
|
||||
pane_scrollbars = false
|
||||
|
||||
# kill-window and kill-session never asked
|
||||
confirm_close = false
|
||||
|
||||
# automatic-rename gave windows a name without prompting
|
||||
prompt_new_tab_name = false
|
||||
|
||||
# set -g mouse on
|
||||
mouse_capture = true
|
||||
|
||||
# status-right had the zoom flag followed by #h
|
||||
tab_bar_right = [{ type = "zoom" }, { type = "hostname" }]
|
||||
|
||||
# set -g set-titles on / set -g set-titles-string '#h:#W', where tmux's #W was
|
||||
# the basename of the pane cwd. This is what Hyprland shows in the group bar,
|
||||
# and it resolves on the server so remote sessions name the remote host.
|
||||
window_title = "{hostname}: {workspace}"
|
||||
@@ -0,0 +1,83 @@
|
||||
-- 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 traditional (non-inverse) scrolling.
|
||||
-- natural_scroll = false,
|
||||
--
|
||||
-- -- Re-enable tap-to-click (one-finger tap = left, two-finger = right).
|
||||
-- tap_to_click = 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 (handoff) virtual pointer: DO NOT add sensitivity/accel_profile rules here.
|
||||
--
|
||||
-- Tried and measured as INERT on 2026-10-10. `hl.device({name="unknown-device", ...})` does
|
||||
-- match the device (proven by toggling scroll_factor and watching hyprctl report it), 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
|
||||
-- travel with `lan-mouse test-emulation` + hyprctl cursorpos was 398x198px at sensitivity 0
|
||||
-- AND at -0.9 -- identical, and exactly 1:1 with the raw deltas. Both machines measure the
|
||||
-- same 398x198, so neither end scales.
|
||||
--
|
||||
-- Corollary: global `accel_profile = "flat"` would also be a no-op for the virtual pointer
|
||||
-- while permanently changing how the real trackpad feels. Pure loss -- do not do it.
|
||||
-- The magnitude of forwarded motion originates on the SENDING machine's trackpad.
|
||||
--
|
||||
-- ROOT CAUSE FOUND 2026-10-10: lan-mouse 0.11.0 forwards UNACCELERATED deltas.
|
||||
-- input-capture/src/layer_shell.rs:887 destructures the relative-pointer event as
|
||||
-- `dx_unaccel: dx, dy_unaccel: dy, ..` -- the `..` throws away the accelerated dx/dy that the
|
||||
-- same event carries. So the accel curve is stripped at the SENDER and nothing replaces it at
|
||||
-- the receiver. Consequence: sensitivity/accel_profile are inert for forwarded motion on BOTH
|
||||
-- ends, so "sync the sensitivity between the laptops" is impossible by configuration.
|
||||
-- The only fix is a source patch to use the accelerated dx/dy.
|
||||
-- See memory: lan-mouse-forwards-unaccelerated-deltas.md
|
||||
@@ -0,0 +1,22 @@
|
||||
-- See https://wiki.hypr.land/Configuring/Basics/Monitors/
|
||||
-- List current monitors and supported resolutions with: hyprctl monitors all
|
||||
|
||||
-- Monitor scale is Hyprland's scale for the output. It sizes everything
|
||||
-- Wayland-native, accepts fractions (1.6, 1.75), and applies immediately.
|
||||
-- "auto" lets Hyprland pick per display.
|
||||
local omarchy_monitor_scale = 1.33333
|
||||
hl.monitor({ output = "", mode = "preferred", position = "auto", scale = omarchy_monitor_scale })
|
||||
|
||||
-- Configure a specific monitor.
|
||||
-- hl.monitor({ output = "DP-2", mode = "2560x1440@144", position = "0x0", scale = 1 })
|
||||
|
||||
-- Portrait/rotated secondary monitor (transform: 1 = 90°, 3 = 270°).
|
||||
-- hl.monitor({ output = "DP-2", mode = "preferred", position = "auto", scale = 1, transform = 1 })
|
||||
|
||||
-- GDK scale is GDK_SCALE, the factor GTK draws its own UI at. It's what
|
||||
-- sizes X11/XWayland windows, which Omarchy leaves unscaled so they stay
|
||||
-- crisp instead of being stretched by the compositor. GTK only honors whole
|
||||
-- numbers, so use the nearest integer to the monitor scale, and restart an
|
||||
-- app for a change to reach it.
|
||||
local omarchy_gdk_scale = 1
|
||||
hl.env("GDK_SCALE", tostring(omarchy_gdk_scale))
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"$schema": "https://opencode.ai/config.json",
|
||||
"theme": "system",
|
||||
"autoupdate": false
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
# Voxtype Configuration
|
||||
#
|
||||
# Location: ~/.config/voxtype/config.toml
|
||||
# All settings can be overridden via CLI flags
|
||||
#
|
||||
# State file for external integrations (Waybar, polybar, etc.)
|
||||
# Use "auto" for default location ($XDG_RUNTIME_DIR/voxtype/state),
|
||||
# a custom path, or "disabled" to turn off. The daemon writes state
|
||||
# ("idle", "recording", "transcribing") to this file whenever it changes.
|
||||
# Required for `voxtype record toggle` and `voxtype status` commands.
|
||||
state_file = "auto"
|
||||
|
||||
[hotkey]
|
||||
# Hotkey is configured in Hyprland. Default is Super + Ctrl + X
|
||||
enabled = false
|
||||
|
||||
[audio]
|
||||
# Audio input device ("default" uses system default)
|
||||
# List devices with: pactl list sources short
|
||||
device = "default"
|
||||
|
||||
# Sample rate in Hz (whisper expects 16000)
|
||||
sample_rate = 16000
|
||||
|
||||
# Maximum recording duration in seconds (safety limit)
|
||||
max_duration_secs = 60
|
||||
|
||||
# Pause MPRIS media players during recording
|
||||
pause_media = true
|
||||
|
||||
# [audio.feedback]
|
||||
# Enable audio feedback sounds (beeps when recording starts/stops)
|
||||
# enabled = true
|
||||
#
|
||||
# Sound theme: "default", "subtle", "mechanical", or path to custom theme directory
|
||||
# theme = "default"
|
||||
#
|
||||
# Volume level (0.0 to 1.0)
|
||||
# volume = 0.7
|
||||
|
||||
[whisper]
|
||||
# Model to use for transcription
|
||||
# Options: tiny, tiny.en, base, base.en, small, small.en, medium, medium.en, large-v3, large-v3-turbo
|
||||
# .en models are English-only but faster and more accurate for English
|
||||
# large-v3-turbo is faster than large-v3 with minimal accuracy loss (recommended for GPU)
|
||||
# Or provide absolute path to a custom .bin model file
|
||||
model = "base.en"
|
||||
|
||||
# Language for transcription
|
||||
# Use "en" for English, "auto" for auto-detection
|
||||
# See: https://github.com/openai/whisper#available-models-and-languages
|
||||
language = "en"
|
||||
|
||||
# Translate non-English speech to English
|
||||
translate = false
|
||||
|
||||
# Number of CPU threads for inference (omit for auto-detection)
|
||||
# threads = 4
|
||||
|
||||
[output]
|
||||
# Primary output mode: "type" or "clipboard"
|
||||
# - type: Simulates keyboard input at cursor position (requires ydotool)
|
||||
# - clipboard: Copies text to clipboard (requires wl-copy)
|
||||
mode = "type"
|
||||
|
||||
# Fall back to clipboard if typing fails
|
||||
fallback_to_clipboard = true
|
||||
|
||||
# Delay between typed characters in milliseconds
|
||||
# 0 = fastest possible, increase if characters are dropped
|
||||
type_delay_ms = 1
|
||||
|
||||
# Post-processing command (optional)
|
||||
# Pipe transcribed text through an external command for cleanup before output.
|
||||
# The command receives text on stdin and outputs processed text on stdout.
|
||||
# Useful for LLM-based text cleanup, grammar correction, filler word removal.
|
||||
# On any failure (timeout, error), falls back to original transcription.
|
||||
#
|
||||
# [output.post_process]
|
||||
# command = "ollama run llama3.2:1b 'Clean up this dictation. Fix grammar, remove filler words. Output only the cleaned text:'"
|
||||
# timeout_ms = 30000 # 30 second timeout (generous for LLM)
|
||||
|
||||
[output.notification]
|
||||
# Show notification when recording starts (hotkey pressed)
|
||||
on_recording_start = false
|
||||
|
||||
# Show notification when recording stops (transcription beginning)
|
||||
on_recording_stop = false
|
||||
|
||||
# Show notification with transcribed text after transcription completes
|
||||
on_transcription = false
|
||||
|
||||
# [text]
|
||||
# Text processing options (word replacements, spoken punctuation)
|
||||
#
|
||||
# Enable spoken punctuation conversion (e.g., say "period" to get ".")
|
||||
# spoken_punctuation = false
|
||||
#
|
||||
# Custom word replacements (case-insensitive)
|
||||
# replacements = { "hyperwhisper" = "hyprwhspr" }
|
||||
Reference in New Issue
Block a user