This is the abridged developer documentation for Dotfiles # Dotfiles > An agent-driven Omarchy setup for development, desktop, and automation. These are my public [Omarchy](https://omarchy.org) dotfiles (Omarchy is an Arch Linux based distro), managed with [GNU Stow](https://www.gnu.org/software/stow/) and a single compiled `dot` binary. They cover shell, editor, and desktop config, plus the tooling that keeps multiple machines in sync. These are my personal dotfiles They are tightly tuned for my [Omarchy](https://omarchy.org) setup and my specific machines, and are **not** meant to be installed as-is by anyone else. They are unlikely to work on plain Arch (or any other distro) without replicating my setup, and they lean on a deeply integrated private overlay (`dotfiles-private`) that is not public, so the public repo on its own is an incomplete picture. Use them as a reference to borrow from, or pull individual pieces into your own dotfiles, rather than as a turnkey setup. The shared [OpenCode](https://opencode.ai) config (agents, commands, skills, and plugins) is the exception: it is published separately as [`opencode-config`](https://github.com/timmo001/opencode-config) and deliberately written to be portable and reusable on its own. ## At a glance [Section titled “At a glance”](#at-a-glance) Stow-based dotfiles Public config for shell, editor, and tooling, rooted at `~/.config/dotfiles` and laid down with GNU Stow. The dot binary A single compiled binary ([Bun](https://bun.sh) + [Effect](https://effect.website) v4 + [OpenTUI](https://github.com/anomalyco/opentui)) with a TUI dashboard and a full CLI for setup, updates, and git tooling. Git & GitHub tooling Diff, log, status, workflow runs, and a notification inbox across every managed repo, with status-bar modules. Omarchy & Hyprland Managed Omarchy repos and per-host Hyprland overrides, with a desktop controls menu. OpenCode & agents Shared agents, commands, skills, and plugins, published to [opencode-config](https://github.com/timmo001/opencode-config). Private overlay A deeply integrated private overlay (`~/.config/dotfiles-private`) layers machine-specific config on top of the public repo. ## Get started [Section titled “Get started”](#get-started) [Install](/getting-started/install/)Prerequisites, bootstrap build, and the ongoing workflow. [New Machine Checklist](/getting-started/new-machine/)Step-by-step setup for a new Omarchy machine. ## Explore [Section titled “Explore”](#explore) [The dot Command](/dot/)The TUI dashboard and CLI, with the stow, notes, and utilities workflows. [Configuration](/configuration/)Environment options, private git config, and private packages. [Git & GitHub](/git/)Diff, log, status, workflow runs, and notifications. [Omarchy & Hyprland](/omarchy/)Managed Omarchy repos and per-host Hyprland overrides. [Knowledge Base](/knowledge-base/)Practical runbooks for system customisations and one-off fixes. [OpenCode & Agents](/opencode/)Agents, commands, skills, and plugins, with the generated reference. ## Reference [Section titled “Reference”](#reference) [Bar Integrations](/bar-integrations/)The shared --bar-json status-bar contract. [Cleanup](/cleanup/)Remove stowed links and reverse setup side effects. [Agents / LLMs](/agents-llms/)llms.txt bundles for loading the docs into AI-assisted sessions. # Agents / LLMs > Context bundles for working with this documentation in AI-assisted sessions. This site publishes [llms.txt](https://llmstxt.org) bundles so the docs can be loaded as plain text during AI-assisted work. The files are generated at build time from the same source as the site, which keeps them aligned with the published pages without maintaining a second copy. Use them when you want the dotfiles docs available outside the browser: setup steps, command behaviour, configuration notes, and the generated reference pages can all be pulled from the same published source. ## Pick A File [Section titled “Pick A File”](#pick-a-file) | File | Contents | | ---------------------------------- | ---------------------------------------------------------------------------- | | [/llms.txt](/llms.txt) | Start here when you want an index of the available bundles. | | [/llms-full.txt](/llms-full.txt) | Use this when the task needs the whole docs site in one file. | | [/llms-small.txt](/llms-small.txt) | Use this for quick lookups when the full site is more context than you need. | The full bundle is the safest default for broad questions because it includes the generated command and OpenCode reference pages alongside the hand-written docs. The compact bundle is better for focused lookups where a smaller prompt matters more than complete coverage. ## Copy-Ready URLs [Section titled “Copy-Ready URLs”](#copy-ready-urls) Complete docs bundle: ```text https://dotfiles.timmo.dev/llms-full.txt ``` Compact docs bundle: ```text https://dotfiles.timmo.dev/llms-small.txt ``` Bundle index: ```text https://dotfiles.timmo.dev/llms.txt ``` ## Notes [Section titled “Notes”](#notes) * The bundles are generated from the docs source during the site build. If a page is stale, fix the source page rather than editing the generated text output. * The URLs are stable, but the contents change whenever the docs are rebuilt from new commits. * For repository-specific work, pair these docs with current branch context from [`context git`](https://context.timmo.dev/context/git/) and tech-stack context from [`context stack`](https://context.timmo.dev/context/stack/). The docs explain the workflow; the commands explain the live checkout. # Bar Integrations > The --bar-json status-bar contract shared by dot commands and external tools. `--bar-json` is a shared status-bar contract rather than a single command. Tools emit one-line `--bar-json` output (with `text`, `tooltip`, and `class` fields) meant to be polled by a status bar module through its own short-lived cache. Left click opens the relevant TUI; right click refreshes the cache. `dot git-diff` status scans disable Git’s optional index locks. Background bar and TUI polling can read working-tree state during a rebase, merge, or another index-writing operation without refreshing the index or competing for `.git/index.lock`. The JSON format is bar-agnostic: it works with [Waybar](https://github.com/Alexays/Waybar), [Quickshell](https://quickshell.outfoxxed.me), or any bar that can run a command and parse JSON. My own setup uses Waybar, so the bundled modules and `dot doctor` checks target Waybar, but the commands themselves do not depend on it. ## dot commands with bar output [Section titled “dot commands with bar output”](#dot-commands-with-bar-output) [Diff & Repo Watcher](/git/diff/)dot git-diff --bar-json flags managed repos that have uncommitted or unpushed changes. [Workflow Runs](/git/workflows/)dot git-workflows --bar-json --since surfaces recent GitHub Actions activity for each repo's checked-out commit. [Notifications](/git/notifications/)dot git-notifications --bar-json shows the GitHub notification inbox; left click opens the filtered TUI. The [command reference](/dot/commands/) lists the full `--bar-json` flag set on each command. ## External applications [Section titled “External applications”](#external-applications) `--bar-json` is not limited to `dot`. Other tools in this setup emit the same bar-friendly JSON, so one bar can poll them the same way. [go-automate](https://go-automate.timmo.dev) is one example: its [`--bar-json` reference](https://go-automate.timmo.dev/reference/bar-json/) documents the Home Assistant watcher output it exposes to a status bar. go-automate’s entity watcher is a long-running stream, but a polled bar module or a dashboard source card wants one line per refresh. The bundled `ha-entity-bar-json-once` script bridges the two: it runs `go-automate ha bridge watch entity --bar-json`, reads the first line, stops the watcher, and prints that single line (or a hidden placeholder if nothing arrives). It takes the same flags as the watcher, for example: ```bash ha-entity-bar-json-once --icon '' input_text.current_next_event_in_an_hour ``` ## Configuration [Section titled “Configuration”](#configuration) Which repos and which activity reach the bar is controlled by the private `dot-git.yml` config; the `notifications.bar.ignore_bot_activity` key tames bot noise. See [Private Git Config](/configuration/private-git/). ## Health checks [Section titled “Health checks”](#health-checks) `dot doctor` verifies the active status-bar module wiring for `git-workflows` and `git-notifications`, alongside `dot-git.yml` and the absence of legacy `git-workflow-watch` leftovers. # Cleanup > Remove stowed links and manually reverse first-use setup changes. Use this page when you want to remove the changes `dot` made to a machine. The safe first step is always `dot clean`; everything after that is optional and more destructive. Caution Review each command before running it. Some steps remove system config, package repositories, cloned repos, or user services. Do not run the whole page as a script. ## Remove stowed links [Section titled “Remove stowed links”](#remove-stowed-links) `dot clean` only removes symlinks managed by GNU Stow. It unstows the private overlay first when it is available, then the public packages. ```bash dot clean ``` This does not remove packages, cloned repositories, pacman config, firewall rules, systemd user units, shell changes, generated agent instruction copies, logs, or backup files. ## Restore backed-up files [Section titled “Restore backed-up files”](#restore-backed-up-files) `dot install`, `dot init`, and `dot stow` move conflicting live files into backup paths instead of deleting them. Check the public/private repo backup directories and any Omarchy init backups before removing the repos. ```bash ls ~/.config/dotfiles/backup ls ~/.config/dotfiles-private/backup ls ~/.config/*.dot-init-backup-* ``` Move back only the files you still want to keep. ## Disable user services [Section titled “Disable user services”](#disable-user-services) Disable user timers/services that were enabled from these dotfiles. ```bash systemctl --user disable --now dot-doctor-startup.timer systemctl --user disable --now daily-volume-zero.timer systemctl --user disable --now git-workflow-watch.timer git-workflow-watch.service systemctl --user reset-failed git-workflow-watch.timer git-workflow-watch.service systemctl --user daemon-reload ``` `daily-volume-zero.timer` only exists on laptop stow packages, and `git-workflow-watch.*` are obsolete legacy units, so these commands may report that some units are missing. ## Remove synced agent instruction copies [Section titled “Remove synced agent instruction copies”](#remove-synced-agent-instruction-copies) `dot init` runs `dot agents-sync`, which mirrors the global OpenCode agent instructions into other harnesses. Remove these only if you want those harnesses unmanaged too. Check for the `dot agents-sync` header before deleting anything you may have edited by hand. ```bash grep -H "dot agents-sync" ~/.cursor/rules/global-agents.mdc ~/.claude/CLAUDE.md rm -f ~/.cursor/rules/global-agents.mdc ~/.claude/CLAUDE.md ``` ## Remove managed firewall rules [Section titled “Remove managed firewall rules”](#remove-managed-firewall-rules) `dot init` adds managed `ufw` allow rules when `ufw` is installed. Delete only the rules you no longer want. ```bash sudo ufw status numbered sudo ufw delete sudo ufw reload ``` The managed rules are labelled in `ufw status` with their purpose, for example KDE Connect, Home Assistant, OpenCode server, LocalSend, and libvirt. ## Remove private pacman repo config [Section titled “Remove private pacman repo config”](#remove-private-pacman-repo-config) If `dot setup-private-repo` or `dot init` registered the private package repo, remove the include line and snippet manually. ```bash sudoedit /etc/pacman.conf sudo rm -f /etc/pacman.d/timmo-private.conf sudo pacman -Sy ``` Remove this line from `/etc/pacman.conf` if present: ```ini Include = /etc/pacman.d/timmo-private.conf ``` If your private config overrides `DOT_PRIVATE_PACMAN_REPO_CONFIG` or `DOT_PRIVATE_PACMAN_MAIN_CONFIG`, use those paths instead. `dot setup-private-repo` also syncs a local `file://` mirror from the private package repo config. If you want to remove that mirror and source clone too, check `path=` and `mirror_path=` in `~/.config/dotfiles-private/.dot-private-package-repo` and remove only those directories. ## Remove pacman hooks [Section titled “Remove pacman hooks”](#remove-pacman-hooks) Public/private pacman hooks are installed into `/etc/pacman.d/hooks` from stowed hook sources. Remove only hooks that came from these dotfiles. ```bash ls ~/.config/pacman-hooks ls /etc/pacman.d/hooks sudo rm /etc/pacman.d/hooks/.hook ``` ## Restore the login shell [Section titled “Restore the login shell”](#restore-the-login-shell) `dot init` sets the login shell to zsh when needed. Change it back if you no longer want zsh as the login shell. ```bash chsh -s /bin/bash "$USER" ``` If init added `/usr/bin/zsh` to `/etc/shells`, leave it unless you know nothing else on the machine needs it. ## Remove Git config include [Section titled “Remove Git config include”](#remove-git-config-include) `dot init` adds the managed Git include to your global Git config. Remove it if you no longer want Git to load the stowed dotfiles settings. ```bash git config --global --fixed-value --unset-all include.path "~/.config/git/config.dotfiles" ``` ## Revert generated locales [Section titled “Revert generated locales”](#revert-generated-locales) `dot init` ensures `en_GB.UTF-8` is enabled in `/etc/locale.gen` and runs `locale-gen`. Leave the locale in place unless you specifically want to remove it. ```bash sudoedit /etc/locale.gen sudo locale-gen ``` ## Remove cloned repos and state [Section titled “Remove cloned repos and state”](#remove-cloned-repos-and-state) After the stowed links and system config are removed, delete cloned repos and generated state only if you no longer need them. ```bash rm -rf ~/.config/dotfiles-private rm -rf ~/.config/bootstrap ~/.config/waybar ~/.config/uwsm rm -rf ~/.local/state/dot ~/.cache/dot ``` Private package repos and other private Git clones are configured by the private overlay. Review `~/.config/dotfiles-private/.dot-private-package-repo` and `~/.config/dotfiles-private/dot-git.yml`, then remove only clones and mirrors you no longer need. If you removed Omarchy config directories that `dot init` replaces with managed repos, or stowed config directories that Omarchy should own again, refresh the stock Omarchy defaults afterwards. ```bash omarchy refresh waybar omarchy refresh shell omarchy refresh hyprland omarchy refresh config ghostty/config omarchy refresh config uwsm/env ``` Run `omarchy refresh --help` on the target machine for the exact refresh commands supported by that Omarchy version. Do not remove `~/.config/dotfiles` until you no longer need the `dot` binary, docs, or backup directory. ## Remove installed packages [Section titled “Remove installed packages”](#remove-installed-packages) `dot init` installs the public/private package lists but does not track ownership of packages afterwards. Removing packages is intentionally manual. This command only covers the default public package list; if you override `DOT_PUBLIC_PACKAGES_FILE`, use that file instead. ```bash comm -12 <(sort ~/.config/dotfiles/.dot-public-packages) <(pacman -Qq | sort) ``` Review that output, then remove only packages you no longer use. ```bash sudo pacman -Rns ``` For private packages, review the private package list before removing anything. `dot install` and `dot init` may also install setup prerequisites such as `stow`, `gum`, or `mise` when they are missing. Remove those manually only if nothing else uses them. ## Remove mise-managed tools [Section titled “Remove mise-managed tools”](#remove-mise-managed-tools) `dot init` runs `mise install`, which can install language and CLI tool versions from the stowed mise config. Remove only versions you no longer use. ```bash mise ls --installed mise uninstall ``` ## Remove GitHub CLI extensions [Section titled “Remove GitHub CLI extensions”](#remove-github-cli-extensions) `dot init` installs the GitHub CLI extensions listed in `.dot-gh-extensions` when `gh` is available. Remove only extensions you no longer want. ```bash gh extension list gh extension remove ``` ## Final check [Section titled “Final check”](#final-check) Run doctor after cleanup to see what managed state remains. It will report missing dotfiles pieces if the repo is partly removed, which is expected during a full uninstall. ```bash dot doctor ``` # Configuration > Environment options and private git configuration. Most behaviour is controlled by explicit CLI flags. Runtime configuration uses environment variables for process context, tracked application config files, and private YAML files for git/GitHub repo tracking and optional dashboard source cards. [Environment Variables](/configuration/environment/)All DOT\_\*, DOTFILES\_\*, and OMARCHY\_\* options. [Private Git Config](/configuration/private-git/)The dot-git.yml schema for repo activity, workflows, and notifications. [Private Dashboard Config](/configuration/private-dashboard/)The dot-dashboard.yml schema for optional dashboard source cards. [Yazi](/configuration/yazi/)Restore the shared Yazi plugin set across devices. [Plannotator](/configuration/plannotator/)Restore shared Plannotator review settings across devices. [Private Packages](/configuration/private-packages/)Build and publish Arch packages to the private pacman repo. # Environment Variables > All DOT_*, DOTFILES_*, and OMARCHY_* options that influence dot. These variables tune paths and behaviour for `dot`. Most have sensible defaults; set them only when you need to override the default. ## Paths and overlay [Section titled “Paths and overlay”](#paths-and-overlay) | Variable | Description | | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | | `DOTFILES_PUBLIC_DIR` | Public dotfiles path (default `~/.config/dotfiles`). | | `DOTFILES_PRIVATE_DIR` | Private dotfiles path (default `~/.config/dotfiles-private`). | | `DOT_ALLOW_PRIVATE` | Private overlay policy: optional `auto`, required `always`, or skipped `never` (default `auto`). A failed attempted clone is fatal in `auto` mode. | ## Git and GitHub [Section titled “Git and GitHub”](#git-and-github) | Variable | Description | | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `DOT_GIT_CONFIG_FILE` | Private git repo config for `git-diff`, `git-log`, `git-workflows`, `git-notifications --bar-json`, `update`, and `doctor` (default `$DOTFILES_PRIVATE_DIR/dot-git.yml`). | | `DOT_GITHUB_RETRIES` | Extra `gh` retry attempts after the first try (default `2`). | | `DOT_GITHUB_RATE_LIMIT_TTL_SECONDS` | Seconds to cache `gh api rate_limit` results (default `60`). | | `DOT_GITHUB_RATE_LIMIT_MIN_REMAINING` | Minimum REST quota remaining before `gh` calls wait (default `0`). | | `DOT_GITHUB_RATE_LIMIT_MAX_WAIT_SECONDS` | Upper bound on rate-limit backoff waits (default `60`). | | `DOT_INCLUDE_OMARCHY_DIFF_REPOS` | Include Omarchy repos in `dot git-diff` (`1\|0`, default `1`). | | `DOT_FETCH_TTL_SECONDS` | Seconds to reuse the last upstream fetch (default `300`). | | `DOT_GH_EXTENSIONS_FILE` | Public `gh` extension list installed by `dot init` (default `$DOTFILES_PUBLIC_DIR/.dot-gh-extensions`). | | `DOT_GH_MCP_BEARER` | Bearer token for the read-only GitHub MCP server. The shell wrappers and `opencode-server` set it only for agent harness processes; it is not exported globally. | ## Private packages [Section titled “Private packages”](#private-packages) | Variable | Description | | --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | | `DOT_PUBLIC_PACKAGES_FILE` | Public Arch/AUR package list for `dot init`, full `dot update`, and package checks (default `$DOTFILES_PUBLIC_DIR/.dot-public-packages`). | | `DOT_PRIVATE_PACKAGE_REPO_FILE` | Private pacman repo config (default `$DOTFILES_PRIVATE_DIR/.dot-private-package-repo`). | | `DOT_PRIVATE_PACKAGES_FILE` | Private package list (default `$DOTFILES_PRIVATE_DIR/.dot-private-packages`). | | `DOT_PRIVATE_PACKAGE_MAP_FILE` | Private package name-to-source map for `dot private-pkg-publish` (default `$DOTFILES_PRIVATE_DIR/.dot-private-package-map`). | | `DOT_PRIVATE_PACMAN_REPO_CONFIG` | Pacman repo snippet path written by `dot` (default `/etc/pacman.d/timmo-private.conf`). | | `DOT_PRIVATE_PACMAN_MAIN_CONFIG` | Main pacman config file scanned for the private repo `Include` (default `/etc/pacman.conf`). | | `DOT_PRIVATE_BROWSER_CHECKS_FILE` | Private browser-extension doctor checks (default `$DOTFILES_PRIVATE_DIR/.dot-browser-checks`). | ## Omarchy and Hyprland [Section titled “Omarchy and Hyprland”](#omarchy-and-hyprland) | Variable | Description | | ----------------------- | ------------------------------------------------------------------------------------------------------ | | `OMARCHY_REPO_BASE_DIR` | Omarchy repo base path (default `~/.config`). | | `OMARCHY_HOST` | Hypr host override name; `dot init` defaults to `desktop` when unset unless `--host ` is passed. | | `DOT_OMARCHY_BRANCH` | Branch override for non-bootstrap Omarchy repos during sync. | | `DOT_BOOTSTRAP_BRANCH` | Branch for `bootstrap` sync (default `distro/omarchy`). | ## Init and logging [Section titled “Init and logging”](#init-and-logging) | Variable | Description | | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | | `DOT_INIT_NONINTERACTIVE` | Force non-interactive init mode (`1\|0`, default `0`). | | `DOT_INIT_LOG_FILE` | Default `dot init` log path when `--log` is not passed (default `~/.local/state/dot/init.log`). | | `DOT_LOG_FILE` | Active log file for the current `dot` run. Set automatically during `dot init`; child commands inherit it when `DOT_TEE_INHERIT_LOG=1`. | | `DOT_LOG_MIRROR_FILE` | Secondary log destination mirrored after each write. Set automatically when `dot init --log` targets a GVFS path that cannot be written directly. | | `DOT_TEE_INHERIT_LOG` | When `1`, child processes launched by `dot` append stdout/stderr to `DOT_LOG_FILE` (set automatically during `dot init`). | | `DOT_UFW_RULES_FILE` | ufw rules file scanned by the firewall setup and doctor check (default `/etc/ufw/user.rules`). | ## Agents sync [Section titled “Agents sync”](#agents-sync) `dot agents-sync` mirrors `~/.config/opencode/AGENTS.md` to agent harness instruction files. It runs automatically at the end of full `dot update` and `dot init`; phase-scoped updates skip it. There is no environment toggle to disable it. Each target receives a transformed copy with harness-appropriate formatting where needed. All targets include a `dot agents-sync` HTML comment with source path and timestamp. OpenCode remains the single source of truth; other agent harnesses get plain file copies, not symlinks. | Variable | Description | | --------------------------- | --------------------------------------------------------------------------------------------- | | `DOT_AGENTS_SYNC_SOURCE` | AGENTS file to mirror (default `~/.config/opencode/AGENTS.md`). | | `DOT_AGENTS_SYNC_RULE_FILE` | Override path for a primary agents-sync target (default `~/.cursor/rules/global-agents.mdc`). | ## MCP sync [Section titled “MCP sync”](#mcp-sync) | Variable | Description | | --------------------- | --------------------------------------------------------------------------------------- | | `DOT_MCP_CONFIG_FILE` | Private MCP sync spec read by `dot mcp-sync` (default `$DOTFILES_PRIVATE_DIR/mcp.yml`). | ## Debugging and output [Section titled “Debugging and output”](#debugging-and-output) | Variable | Description | | ------------------------- | --------------------------------------------------------------------------------------------- | | `DOT_DEBUG` | Enable stderr debug logging from `dot` subsystems (`1` or any non-empty value). | | `DOT_USAGE_DIR` | Usage event root (default `$XDG_STATE_HOME/tool-usage`). | | `DOT_USAGE_DISABLE` | Disable automatic live `dot` usage recording when set to `1`; explicit backfill still writes. | | `DOT_CONTEXT_CAPTURE` | Capture assembled OpenCode starter context when set to `1`. | | `DOT_CONTEXT_CAPTURE_DIR` | Parent for private `context-baseline-*` capture directories (default `/tmp/opencode`). | | `NO_COLOR` | Disable ANSI colour in TTY-aware output such as `context git` (any non-empty value). | Context capture writes numbered system-prompt segments, `system-index.json`, per-tool schemas, and `tools.jsonl` into a unique private child directory. It measures assembled context without changing prompts or tool definitions. ## Agent detection [Section titled “Agent detection”](#agent-detection) | Variable | Description | | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | | `DOT_AGENT` | Override AI agent detection used by `dot is-agent` and the interactive-TUI guard: `1` forces agent mode, `0` forces it off, unset auto-detects. | ## Notes [Section titled “Notes”](#notes) | Variable | Description | | --------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | `NOTES` | Notes vault git repo used by the standalone `notes` CLI/MCP server and OpenCode note commands (preferred; default `~/Documents/notes`). | | `DOT_NOTES_DIR` | Compatibility notes vault override used when `NOTES` is unset. | # Plannotator > Restore shared Plannotator review settings across devices. Plannotator provides a local browser interface for reviewing plans, code changes, files, folders, and web pages. The CLI is installed from the pinned `backnotprop/plannotator` GitHub release through mise because it is not available from Arch, AUR, or the Aqua registry. See the [Plannotator documentation](https://plannotator.ai/docs/) for installation, commands, OpenCode integration, configuration, remote use, and sharing. ## Dotfiles integration [Section titled “Dotfiles integration”](#dotfiles-integration) This setup adds: * The `plannotator` CLI through mise’s GitHub backend. * The `@plannotator/opencode` plugin in the private OpenCode configuration. * `/plannotator-review`, `/plannotator-annotate`, and `/plannotator-last` command registrations. * A public stow package for portable settings. The plugin uses the `plan-agent` workflow and explicitly targets OpenCode’s built-in `plan` agent. The `/plan` command starts that agent directly, while execution agents such as `ask`, `build-ask`, and `refactorer` can hand broad work to it through `plan_enter`. They do not need to be listed as Plannotator planning agents because `submit_plan` runs after the handoff, inside the built-in `plan` agent. This keeps `submit_plan` out of build and specialist agents. The plugin’s `planningAgents` option only needs another name if a separate custom planning agent is added later. The command files contain frontmatter only because the plugin handles their names through OpenCode’s command hook. Restart OpenCode after changing its plugin configuration. For usage, see the upstream [OpenCode integration guide](https://plannotator.ai/docs/guides/opencode/) and its linked command guides. Code review feedback authorises the agent to apply the requested corrections immediately. The correction run stays within the human feedback, performs relevant validation, and asks before proceeding when a request is unclear, conflicts with the codebase, or cannot be applied safely. ## Local data [Section titled “Local data”](#local-data) Only `config.json` belongs in dotfiles. The rest of `~/.plannotator/` contains runtime or machine-local data and is deliberately not tracked: This includes drafts, sessions, semantic-diff data, history, and saved plans. Keeping these directories local avoids publishing reviewed project content, transient state, or machine-specific session details. # Private Dashboard Config > The dot-dashboard.yml schema for optional dashboard source cards. `dot dashboard` reads an optional private YAML file that wires bounded external commands into dashboard cards. It lives in the private overlay at `$DOTFILES_PRIVATE_DIR/dot-dashboard.yml` by default. Without this file, the dashboard still shows git diff, notifications, workflow, and update cards from in-process services. The optional `sources` block adds Twitch, environment, calendar, and todo cards when commands are configured. ## Schema [Section titled “Schema”](#schema) The file has a top-level `sources` map. Each key is a source ID; each value is a bounded shell command plus optional display metadata: | Key | Type | Required | Purpose | | -------------- | ------ | -------- | ----------------------------------------------------------------------------------------------------- | | `command` | string | yes | One-shot shell command run on each refresh. Must exit quickly and print a single JSON line on stdout. | | `unit` | string | no | Unit suffix appended to numeric readings (for example `°C` or `ppm`). | | `open_command` | string | no | Shell command run when Enter opens the card (for example a Home Assistant more-info launcher). | Supported source IDs: | Source ID | Dashboard card | | --------------- | ----------------------------------------------------------- | | `twitch` | Live Channels | | `calendar` | Events in the next hour (hidden when the source is missing) | | `todo_my_tasks` | My Tasks | | `todo_work` | Work Tasks | | `temperature` | Temperature | | `co2` | CO2 | | `voc` | VOC | Example: ```yaml sources: twitch: command: twitch-menu channels --bar-json calendar: command: ha-entity-bar-json-once input_text.current_next_event_in_an_hour temperature: command: ha-entity-bar-json-once sensor.living_room_temperature unit: "°C" open_command: home-assistant-tui more-info sensor.living_room_temperature todo_my_tasks: command: home-assistant-tui todo todo.my_tasks --bar-json open_command: home-assistant-tui todo todo.my_tasks ``` ## Command contract [Section titled “Command contract”](#command-contract) Each `command` must behave like a status-bar poll, not a long-running watcher: * Print one JSON object on the first line of stdout. * Use the same `--bar-json` shape as Waybar modules: `text`, `tooltip`, and `class` fields. See [Bar Integrations](/bar-integrations/). * Finish within eight seconds. `dot dashboard` kills overdue commands with `SIGTERM`. * Avoid unbounded stream helpers. Commands containing `ha-watch-singleton`, `singleton-stream`, or `doorbell` are rejected as unsafe. On refresh failure the card shows a diagnostic message; a `{"error":"..."}` JSON line is treated as an error state. An empty first line hides the card. ## Refresh behaviour [Section titled “Refresh behaviour”](#refresh-behaviour) After the initial load, dashboard sources refresh automatically every 60 seconds and on manual refresh (`r` in the TUI). Git, notification, and workflow cards use the same live services as their dedicated TUI views. # Private Git Config > The dot-git.yml schema for repo activity, workflows, and notifications. The git and GitHub tooling reads a private YAML config that lists the repositories to track and how. It lives in the private overlay at `$DOTFILES_PRIVATE_DIR/dot-git.yml` by default (override with `DOT_GIT_CONFIG_FILE`). It is consumed by `dot git-diff`, `dot git-log`, `dot git-workflows`, `dot git-notifications --bar-json`, `dot update`, and `dot doctor`. ## Per-repo keys [Section titled “Per-repo keys”](#per-repo-keys) Each repo entry has three required sections, each with an explicit `enabled` flag and a 5-field cron `schedule`: * `activity` — include the repo in `dot git-diff` / `dot git-log` and pull it during `dot update`. * `workflows` — show the repo’s GitHub Actions runs in `dot git-workflows`. * `notifications` — include the repo in the notification inbox surfaces. The `notifications.bar.ignore_bot_activity` key controls status-bar bot noise. A repo’s `remote.upstream.url` lets upstream notifications match a managed fork. ## Requirements [Section titled “Requirements”](#requirements) * `dot git-notifications` requires `gh` authenticated with a classic token carrying the `notifications` or `repo` scope. * `dot doctor` verifies `dot-git.yml`, the active status-bar module wiring, and the absence of legacy `git-workflow-watch` leftovers. # Private Packages > Build and publish Arch packages to the private pacman repo. `dot` can build and publish mapped private packages into a private pacman repository, and register the repo include in `pacman.conf`. ## Public packages [Section titled “Public packages”](#public-packages) `dot init` and a full unscoped `dot update` install the Arch and AUR packages listed in `.dot-public-packages` at the repo root. The file is one package name per line; blank lines and `#` comments are ignored. The list covers shared tooling rather than desktop apps you might install separately, including build helpers, diagnostics, shell and terminal tools, and desktop integrations. Override the path with `DOT_PUBLIC_PACKAGES_FILE`. Missing public packages are installed with `omarchy-pkg-aur-add`; already-installed packages are left in place. `dot doctor` checks the public and private package lists after setup. Some AUR packages conflict with an official-repo package that must be removed first. `dot` handles the known case (`mise-bin` replacing `mise`) before installing. Private packages from `.dot-private-packages` in the private overlay are installed after the public list during init when the overlay is available. ## Register the private repo [Section titled “Register the private repo”](#register-the-private-repo) ```bash dot setup-private-repo ``` Syncs the private Arch package repo mirror, writes the private pacman repo snippet, and adds the `Include` line to `/etc/pacman.conf` when it is missing. If the local source clone is missing, setup skips cloning only when the configured mirror already contains `.db`, `.db.tar.gz`, or `.db.tar.zst` and pacman registration is current. This supports an already usable local mirror, but publishing still requires the configured source clone to exist. The command repairs Omarchy `pacman.conf` refreshes that remove local repository includes. Privileged writes prefer `pkexec` and fall back to `sudo`. ## Publish a package [Section titled “Publish a package”](#publish-a-package) ```bash dot private-pkg-publish dot private-pkg-publish --install dot private-pkg-publish --skip-build --no-git ``` Builds and publishes a mapped private package into the private pacman repo, syncs the mirror, refreshes pacman metadata, optionally installs it, and commits/pushes by default. | Flag | Effect | | -------------- | ------------------------------------------------------- | | `--no-git` | Skip the package repo commit and push. | | `--skip-build` | Publish an existing dist package artifact. | | `--install` | Install the published package after syncing the mirror. | ## Configuration [Section titled “Configuration”](#configuration) Package lists, the repo map, and pacman paths are overridable with environment variables: * `DOT_PUBLIC_PACKAGES_FILE` — public Arch/AUR package list (default `$DOTFILES_PUBLIC_DIR/.dot-public-packages`). * `DOT_PRIVATE_PACKAGE_REPO_FILE` — private pacman repo config (default `$DOTFILES_PRIVATE_DIR/.dot-private-package-repo`). * `DOT_PRIVATE_PACKAGES_FILE` — private package list (default `$DOTFILES_PRIVATE_DIR/.dot-private-packages`). * `DOT_PRIVATE_PACKAGE_MAP_FILE` — package name-to-source map for `dot private-pkg-publish` (default `$DOTFILES_PRIVATE_DIR/.dot-private-package-map`). * `DOT_PRIVATE_PACMAN_REPO_CONFIG` — pacman repo snippet path written by `dot` (default `/etc/pacman.d/timmo-private.conf`). * `DOT_PRIVATE_PACMAN_MAIN_CONFIG` — main pacman config scanned for the private repo `Include` (default `/etc/pacman.conf`). See [Environment Variables](/configuration/environment/) for the full list. # Yazi > Restore the shared Yazi plugin set across devices. Yazi is installed from the public package list. Its configuration and `package.toml` lockfile are stowed from `yazi/.config/yazi/`, while downloaded plugin code remains local to each device. In the file manager, `Enter` only enters directories. Press `o` to explicitly open the selected file, or `O` to choose how to open it. Both `q` and the Vim-style `:q` followed by `Enter` quit Yazi. After `dot init` or `dot update` has stowed the configuration, restore the locked plugins: ```bash ya pkg install ``` Add, remove, or upgrade plugins with `ya pkg`. These commands update the tracked lockfile through its stowed path: ```bash ya pkg add yazi-rs/plugins:git ya pkg delete yazi-rs/plugins:git ya pkg upgrade ``` # The dot Command > The TUI dashboard and CLI that drives the dotfiles system. `dot` is the single binary that manages these dotfiles. It is compiled from `dot/` in the repo ([Bun](https://bun.sh) + [Effect](https://effect.website) v4 + [OpenTUI](https://github.com/anomalyco/opentui)) to a single executable, stowed to `~/.local/bin/dot`. It has two faces: * **A TUI dashboard**: run `dot` with no arguments to open the interactive menu, with git diff/log views, GitHub workflow runs, the notification inbox, and Omarchy menus. * **A native CLI**: core maintenance actions are also subcommands (`dot update`, `dot git-diff --raw`, `dot doctor`, …), suitable for scripts and status bars. [Command Reference](/dot/commands/)Every command, alias, flag, and example, generated from the CLI registry. [Stow Workflow](/dot/stow/)How packages are stowed into your home directory. [Shell Setup](/dot/shell/)Zsh completions, editing keys, aliases, and small shell helpers. [System Utilities](/dot/utilities/)Health checks, benchmarks, and optional timers. [Notes & Handoffs](/dot/notes/)Standalone notes CLI, MCP server, and handoff workflow. [Cleanup](/cleanup/)Remove stowed links and reverse setup side effects. ## Common commands [Section titled “Common commands”](#common-commands) | Command | What it does | | ---------------- | -------------------------------------------------------------------------------------------------------- | | `dot dashboard` | Open the dot dashboard. | | `dot init` | One-time first-use setup for a fresh machine. | | `dot update` | Self-update and relaunch, pull, reconcile packages/config, stow, and rebuild. | | `dot stow` | Stow refresh only (no git pull). | | `dot doctor` | Run dotfiles system health checks. | | `dot firewall` | Reconcile managed ufw firewall rules. | | `dot git-diff` | Diff / repo watcher view across managed repos. | | `context git` | Branch context for the current repo (agent context), provided by [`context`](https://context.timmo.dev). | | `context stack` | Tech-stack context for a directory (agent context), provided by [`context`](https://context.timmo.dev). | | `dot git-commit` | Guarded commit gateway for scoped, styled commits. | | `dot omarchy` | Open the Omarchy desktop controls menu. | See the full [Command Reference](/dot/commands/) for every subcommand and flag. ## Progress and timeouts [Section titled “Progress and timeouts”](#progress-and-timeouts) Long-running Effect-managed CLI workflows use the same progress wrapper: an interactive spinner, elapsed duration logging, and a timeout that interrupts the running child process group. This covers the main first-use setup phases (`dot init`), updates, doctor checks, skill update checks/applies/diffs, stow/install/clean, private package publishing, and other bounded maintenance commands. `dot update` keeps each phase bounded so a slow remote, stuck hook, or helper process cannot leave the update sitting silently. Individual repository pulls are retried once and skipped after repeated failure or timeout. A repository scan, pull phase, stow phase, or rebuild timeout stops the update with failure instead of continuing with a partial result. `dot init` uses the spinner and timeout wrapper for each required setup phase. Its private-overlay pull or clone is a synchronous preflight before that bounded workflow and before the already-initialised check. If a required init phase times out, init stops instead of writing the complete marker. `dot doctor` keeps its live “running checks” spinner and also times out individual checks, reporting timed-out checks as warnings. Post-hooks and the final resume refresh are bounded but non-fatal. If either helper does not return, the step is stopped and the completed update is not turned into a failure. ## Dashboard [Section titled “Dashboard”](#dashboard) `dot dashboard` opens a full-screen dashboard. It combines tracked repo state, GitHub notifications, workflow runs, and optional bounded source commands for Twitch, environment, todo, and calendar cards. Cards are intentionally readable and always present; Enter opens an existing deeper TUI view, or suspends `dot` while another TUI runs, when a card has one. ### Layout [Section titled “Layout”](#layout) Cards are grouped into four sections: | Section | Cards | Source | | ----------- | ----------------------------------------------------------------- | ------------------------------------------------------------------- | | Overview | Events in the next hour (when configured), Updates, Live Channels | Private `calendar`/`twitch` sources; in-process repo diff state | | Git | Git Diff, Git Notifications | In-process `DotDiff`, notification inbox, and workflow-run services | | Todos | My Tasks, Work Tasks | Private `todo_*` sources | | Environment | Temperature, CO2, VOC | Private `temperature`/`co2`/`voc` sources | The summary header at the top highlights attention signals (dirty worktrees, behind core repos, important notifications, workflow failures, environment warnings). ### Keyboard [Section titled “Keyboard”](#keyboard) | Key | Action | | ---------------- | ------------------------------------------- | | Arrow keys / Tab | Move between cards | | Enter | Open the linked view or run the card action | | `r` | Refresh all dashboard sources | | Esc / Backspace | Return to the main menu | ### Enter actions [Section titled “Enter actions”](#enter-actions) | Card | Enter behaviour | | ----------------- | ------------------------------------------------------------------------ | | Updates | Runs `dot update` when core repos are behind (exits the dashboard) | | Git Diff | Opens the `dot git-diff` TUI | | Git Notifications | Opens the `dot git-notifications` TUI (includes workflow failure counts) | | Live Channels | Runs `twitch-menu channels` (suspends the dashboard) | | Todo cards | Runs the configured Home Assistant todo TUI (suspends) | | Environment cards | Runs `open_command` from `dot-dashboard.yml` when set (silent) | Optional source cards read from `dot-dashboard.yml` in the private overlay. Each source runs a one-shot `--bar-json` command on refresh (eight-second timeout, 60-second auto-refresh). Without that file, git and update cards still work from in-process services. See [Private Dashboard Config](/configuration/private-dashboard/) for the schema and supported source IDs. ## Source of truth [Section titled “Source of truth”](#source-of-truth) Command and flag metadata lives in `dot/src/cli/spec.ts`. Help rendering, shell completions, and the generated [Command Reference](/dot/commands/) all read from that one registry. When a command changes, regenerate the reference page and shell completions from `spec.ts`. # Command Reference > Every dot command, alias, flag and example, generated from the CLI registry. This page lists every `dot` command, generated from the same registry that powers `dot help` and shell completions. Run any command with `--help` to see the same details at the terminal. ## `dot dashboard` [Section titled “dot dashboard”](#dot-dashboard) Open the dot dashboard ```text dot dashboard [options] ``` Open the full-screen dot dashboard. It combines tracked repo state, GitHub notifications, workflow runs, and optional bounded source commands for Twitch, environment, and calendar cards. **Modes** ```text (default) Interactive dashboard ``` **Examples** ```bash dot dashboard ``` ## `dot init` [Section titled “dot init”](#dot-init) Run one-time first-use machine setup ```text dot init [options] ``` Run the one-time first-use setup workflow for a fresh machine. Init prepares repos, stow links, mise tools, packages, and machine hooks. After init completes, reboot so the Omarchy session picks up host env, then run dot doctor. Before the bounded workflow starts, init updates or clones the optional private overlay according to DOT\_ALLOW\_PRIVATE. Use dot update for ongoing maintenance. **Options** | Option | Description | | ----------------------------- | ----------------------------------------------------------------- | | `--confirm` | Compatibility flag; accepted but does not suppress prompts | | `--noninteractive` | Skip the Hypr host questionnaire for this run | | `--interactive` | Enable the Hypr host questionnaire when no host is selected | | `--force` | Re-run init even if the machine looks initialised | | `--host` `` | Hypr host to link before stow (default: OMARCHY\_HOST or desktop) | | `--log` `` | Init log path (default: \~/.local/state/dot/init.log) | | `--branch` `` | Branch override for non-bootstrap Omarchy repos | | `--bootstrap-branch` `` | Branch override for bootstrap | **Examples** ```bash dot init --noninteractive dot init --host laptop --noninteractive dot init --force --noninteractive dot init --branch main --bootstrap-branch distro/omarchy ``` ## `dot install` [Section titled “dot install”](#dot-install) Ensure prerequisites, then backup/adopt dotfiles ```text dot install ``` ## `dot update` [Section titled “dot update”](#dot-update) Aliases: `dot up` Self-update, pull repos, stow dotfiles, rebuild ```text dot update ``` A full update pulls the public dotfiles, installs Bun dependencies, rebuilds and relaunches dot, then scans and pulls tracked repositories. It trusts tracked mise configs, regenerates completions, installs missing public Arch/AUR packages, runs the required MCP sync, stows, rebuilds again, runs agents sync, backfills the init marker, and starts the resume refresh. Phase flags are inclusive: passing any of —pull, —stow, or —app runs only the selected phases. Scoped runs skip full-update package reconciliation, agents sync, and init-marker backfill. Every mode that reaches the end starts the bounded resume refresh. **Options** | Option | Description | | ------------- | -------------------------------------------------------------------- | | `--pull` | Run the repository pull phase only | | `--stow` | Generate completions, sync MCP configs, and stow only | | `--app` | Install Bun dependencies and rebuild the dot binary only | | `--check` | Report core/system repos behind upstream (no update); exit 10 if any | | `--check-all` | Report all tracked repos behind upstream (no update); exit 10 if any | **Exit codes** ```text 0 Update completed, or an update check found nothing behind 1 Fatal workflow failure 2 Update check could not scan repositories 10 Update check found repositories behind upstream 11 Legacy Hypr migration is required before update can continue ``` ## `dot stow` [Section titled “dot stow”](#dot-stow) Re-stow public/private dotfiles ```text dot stow ``` **Options** | Option | Description | | ----------- | -------------------------- | | `--public` | Stow public dotfiles only | | `--private` | Stow private dotfiles only | ## `dot firewall` [Section titled “dot firewall”](#dot-firewall) Reconcile managed ufw firewall rules ```text dot firewall ``` Ensure the managed ufw allow rules are present with their exact source, destination, interface/direction, and purpose comment. Missing rules are added, stale-comment rules are deleted and re-added, then ufw is reloaded once. A source-restricted rule does not satisfy a managed any-source rule. **Examples** ```bash dot firewall ``` ## `dot doctor` [Section titled “dot doctor”](#dot-doctor) Run dotfiles system health checks ```text dot doctor [options] ``` Run health checks on the dotfiles system. Verifies dependencies, repos, stow integrity, systemd timers, packages, browser config, and more. All checks run in parallel and each section streams to the terminal as it finishes, so sections appear in completion order. A grouped summary of any errors and warnings, ordered by section, follows at the end. A log file is always written to \~/.local/state/dot/logs/. **Options** | Option | Description | | ----------------- | -------------------------------------------------- | | `--open-opencode` | Save the report and attempt to open it in OpenCode | **Checks performed** ```text Dependencies Required/optional CLI tools (git, stow, gh, gum, ...) gh extensions Configured gh CLI extensions are installed Repositories Public/private dotfiles + private git repos exist and have upstreams Origin HEAD Local origin/HEAD tracks the remote default branch (not stale) Stow integrity Dry-run restow to detect drift OpenCode location Canonical paths, legacy remnants Git config Managed include is active Workflow runs Repo list, status bar config, legacy watcher cleanup Git notifications API scope and status bar notification module wiring Doctor startup Startup notification timer Daily volume reset Laptop-only optional timer Omarchy repos Diff repos + worktree branch correctness Legacy Hypr repo Flags a retired omarchy-hypr clone at ~/.config/hypr Neovim theme link Repairs a mislocated omarchy-nvim theme.lua symlink Browser flags Symlinks from private stow package Hardware video VAAPI render nodes, drivers, packages Browser extensions Private extension check list Public packages AUR packages installed + version check Private packages Private repo + packages installed Pacman hooks Hook files installed and up to date Firewall rules Managed ufw rules (KDE Connect, Home Assistant, OpenCode, LocalSend, libvirt); repair with dot firewall ``` **Exit codes** ```text 0 No critical errors (warnings may still be present) 1 One or more critical errors found ``` **Examples** ```bash dot doctor dot doctor --open-opencode ``` ## `dot clean` [Section titled “dot clean”](#dot-clean) Unstow managed dotfiles ```text dot clean ``` ## `dot git-diff` [Section titled “dot git-diff”](#dot-git-diff) Aliases: `dot diff` Open the git diff/repo watcher view ```text dot git-diff [options] ``` Open the diff/repo watcher view. Without flags, opens the interactive TUI. **Modes** ```text (default) Interactive TUI diff view --raw Text summary of repos with changes --bar-json JSON output for status bars and shell modules --list-changed Changed repos as name|path rows --list-all All tracked repos as name|path rows ``` **Options** | Option | Description | | ---------------- | ----------------------------------------------------------------------------------------- | | `--no-fetch` | Skip fetching from remotes (use local refs only) | | `--tab` `` | Initial pane to focus in TUI (default: changed) (one of: `changed`, `other`, `unchanged`) | | `--raw` | Text summary output | | `--bar-json` | JSON output for status bars and shell modules | | `--list-changed` | Changed repos as rows | | `--list-all` | All tracked repos as rows | **Examples** ```bash dot git-diff dot git-diff --raw dot git-diff --bar-json dot git-diff --tab other ``` ## `dot git-commit` [Section titled “dot git-commit”](#dot-git-commit) Commit staged changes through the guarded gateway ```text dot git-commit --message [options] | --amend [options] ``` Create a commit through dot’s guarded gateway instead of raw git commit. The subject is validated as a single line with no trailing full stop and a length limit, then the staged set (or an explicit —path scope) is committed. It never runs git add -A. Pass —amend to rewrite the previous commit instead of creating a new one; it keeps the existing message unless you pass —message. With —push, an amend force-pushes with —force-with-lease (never a plain force). Agents are routed here by the git-commit skill and blocked from raw git commit in the OpenCode permission config, so commits stay in the maintainer’s concise one-line style. **Modes** ```text (default) Commit the staged set --path Commit only the named files --amend Rewrite the previous commit --dry-run Preview the plan, change nothing ``` **Options** | Option | Description | | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------- | | `--message` `-m` `` | Single-line commit subject (required unless —amend) | | `--path` `` | Commit only this file; repeatable | | `--amend` | Amend the previous commit; keeps its message unless —message is given | | `--push` | Push the current branch after committing (pulls —rebase first, or force-with-lease when amending, never a plain force) | | `--dry-run` | Preview the commit and push plan without changing anything | **Message guards** ```text Single line Rejects multi-line messages No em/en-dash Rejects '—' and '–'; use a hyphen No full stop Rejects a trailing '.' Warn over 60 Warns on stderr, still commits Reject over 120 Fails; shorten the subject ``` **Base branch guard** ```text Refuses commits to the base branch of a repo you do not own, including a fork kept for upstream PRs. Owners you control are listed in `git config dot.owner`. Work on a feature branch. ``` **Examples** ```bash dot git-commit -m "Add commit gateway" dot git-commit -m "Scope to one file" --path src/git/commands/Status.ts dot git-commit -m "Commit and push" --push dot git-commit --amend dot git-commit --amend -m "Reword the previous commit" dot git-commit -m "Preview only" --dry-run ``` ## `dot git-log` [Section titled “dot git-log”](#dot-git-log) Open recent commits across tracked repos ```text dot git-log [options] ``` Open the recent commit history view. The left pane lists tracked repositories from dot git-diff, sorted by latest commit activity. The right pane lists recent commits for the selected repository. **Modes** ```text (default) Interactive git log TUI --raw Text summary of recent commits ``` **Options** | Option | Description | | ------- | ------------------------------ | | `--raw` | Text summary of recent commits | **Examples** ```bash dot git-log dot git-log --raw ``` ## `dot git-workflows` [Section titled “dot git-workflows”](#dot-git-workflows) Open watched GitHub workflow runs ```text dot git-workflows [options] ``` Open the watched GitHub workflow runs view. The left pane lists watched repositories from the private repo list. The right pane lists runs for the selected repo’s locally checked-out HEAD commit. **Modes** ```text (default) Interactive workflow runs TUI --raw Text summary of watched workflow runs --bar-json JSON output for status bars and shell modules --list-repos Watched repo summaries as rows --list-runs Workflow runs as rows ``` **Options** | Option | Description | | ------------------ | -------------------------------------------------------------------------------- | | `--since` `` | Only include runs active at or after this date (ISO/RFC/epoch/relative duration) | | `--raw` | Text summary of watched workflow runs | | `--bar-json` | JSON output for status bars and shell modules | | `--list-repos` | Watched repo summaries as rows | | `--list-runs` | Workflow runs as rows | **Examples** ```bash dot git-workflows dot git-workflows --raw dot git-workflows --bar-json dot git-workflows --since "$(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%SZ)" dot git-workflows --list-runs ``` ## `dot git-notifications` [Section titled “dot git-notifications”](#dot-git-notifications) Open GitHub notification inbox ```text dot git-notifications [options] ``` Open the authenticated user’s GitHub notification inbox. Without machine or action flags, opens the interactive TUI. **Modes** ```text (default) Interactive notifications TUI --raw Text summary of notification threads --bar-json JSON output for status bars and shell modules --list-threads Notification threads as rows --bar-filter Apply watched-repo filtering in raw/list output ``` **Options** | Option | Description | | -------------------- | --------------------------------------------------------- | | `--raw` | Text summary of notification threads | | `--bar-json` | JSON output for status bars and shell modules | | `--list-threads` | Notification threads as rows | | `--bar-filter` | Apply watched-repo filtering in raw/list output | | `--all` | Include read notifications | | `--participating` | Only include participating or mentioned threads | | `--since` `` | Only include notifications updated after this date | | `--mark-read` `` | Mark a notification thread as read | | `--mark-bot-read` | Mark unread Renovate/Dependabot/bot notifications as read | | `--dry-run` | Preview —mark-bot-read without mutating GitHub state | | `--mark-done` `` | Mark a notification thread as done | | `--ignore` `` | Ignore new notifications for a thread | | `--unignore` `` | Stop ignoring notifications for a thread | **Examples** ```bash dot git-notifications dot git-notifications --bar-json dot git-notifications --participating dot git-notifications --mark-bot-read --dry-run dot git-notifications --mark-read 12345 ``` ## `dot agents-sync` [Section titled “dot agents-sync”](#dot-agents-sync) Mirror AGENTS.md to agent harness instruction files ```text dot agents-sync ``` ## `dot mcp-sync` [Section titled “dot mcp-sync”](#dot-mcp-sync) Regenerate MCP configs for all harnesses from the spec ```text dot mcp-sync ``` Regenerate each active harness’s native MCP config from the single private spec (mcp.yml), keeping agent harness MCP configs aligned. Writes into the stowed private source tree; run dot stow after. Some agent harnesses are documented stubs and are not written. OpenCode gated servers also receive a default-off tools gate so their tool schemas stay out of the baseline context until an agent re-enables them. **Examples** ```bash dot mcp-sync ``` ## `dot is-agent` [Section titled “dot is-agent”](#dot-is-agent) Detect whether an AI coding agent is running dot ```text dot is-agent [options] ``` Detect whether dot is running under an agent harness from agent environment variables, falling back to a Linux /proc process-ancestry check. Exits 0 when an agent is detected and 1 otherwise, so scripts can branch with `if dot is-agent`. Set DOT\_AGENT=1 to force detection on or DOT\_AGENT=0 to force it off. **Modes** ```text (default) Print the detected agent, or a no-agent message --quiet Print only the provider id (nothing when no agent) --json Print the detection result as JSON ``` **Options** | Option | Description | | -------------- | ---------------------------------- | | `--quiet` `-q` | Print only the provider id | | `--json` | Print the detection result as JSON | **Examples** ```bash dot is-agent dot is-agent --quiet dot is-agent --json dot is-agent && echo running under an agent ``` ## `dot setup-private-repo` [Section titled “dot setup-private-repo”](#dot-setup-private-repo) Sync and register the private pacman repository ```text dot setup-private-repo ``` Sync the private Arch package repo mirror, write the private pacman repo snippet, and add the Include line to /etc/pacman.conf when it is missing. This repairs Omarchy pacman.conf refreshes that remove local repository includes. Privileged writes prefer pkexec and fall back to sudo. **Examples** ```bash dot setup-private-repo ``` ## `dot private-pkg-publish` [Section titled “dot private-pkg-publish”](#dot-private-pkg-publish) Build and publish a private package ```text dot private-pkg-publish [options] ``` Build and publish a mapped private package into the private pacman repo. **Options** | Option | Description | | -------------- | ------------------------------------------------------ | | `--no-git` | Skip package repo commit and push | | `--skip-build` | Publish an existing dist package artifact | | `--install` | Install the published package after syncing the mirror | **Arguments** | Argument | Description | | ---------------- | ----------- | | `` | | **Examples** ```bash dot private-pkg-publish twitch-notifications --install dot private-pkg-publish --skip-build --no-git twitch-notifications ``` ## `dot skill-updates` [Section titled “dot skill-updates”](#dot-skill-updates) Check/apply imported skill updates ```text dot skill-updates ``` **Options** | Option | Description | | --------------- | --------------------------- | | `--check` | Check only without applying | | `--update` | Auto-apply clean updates | | `--skip-review` | Skip local-edit review | ## `dot skill-check` [Section titled “dot skill-check”](#dot-skill-check) Validate skill maintenance wiring ```text dot skill-check ``` **Options** | Option | Description | | ----------------- | -------------------------------------------------------------------------------------------------------- | | `--open-opencode` | Run checks and attempt OpenCode analysis | | `--diff-origin` | Diff imported skills against their upstream origins; with —open-opencode, include the diff in the prompt | ## `dot completions` [Section titled “dot completions”](#dot-completions) Generate shell completions ```text dot completions [bash|fish|zsh] [--stdout] ``` Generate shell completions for dot. By default this writes the managed completion file for the selected shell in the public dotfiles repo so the next dot stow installs it. **Options** | Option | Description | | ---------- | ------------------------------------------------- | | `--stdout` | Print the completion script instead of writing it | **Arguments** | Argument | Description | | --------- | ------------------------------ | | `` | One of: `bash`, `fish`, `zsh`. | **Examples** ```bash dot completions zsh dot completions bash --stdout dot completions fish --stdout ``` ## `dot omarchy` [Section titled “dot omarchy”](#dot-omarchy) Open an Omarchy submenu by path ```text dot omarchy [submenu...] ``` Open the Omarchy desktop controls menu. Pass a submenu path to jump straight to it: dot omarchy theme Theme submenu dot omarchy theme set Execute theme set directly **Arguments** | Argument | Description | | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `` | Repeatable. One of: `theme`, `font`, `toggle`, `capture`, `system`, `launch`, `refresh`, `restart`, `install`, `remove`, `packages`, `share`, `reminder`, `setup`, `snapshot`, `brightness`, `power`. | **Available submenus** ```text theme Theme management font Font management toggle Toggle system features capture Screenshots and recordings system Lock, logout, reboot, shutdown launch Launch applications refresh Refresh system components restart Restart system services install Install software and tools remove Remove software and features packages Package management share Share clipboard, files, folders reminder Reminders setup DNS, security setup snapshot System snapshots brightness Display and keyboard brightness power Power profiles ``` ## `dot usage` [Section titled “dot usage”](#dot-usage) Local-first analytics for dot usage ```text dot usage [summary|stale|path|backfill] [options] ``` Report local-first usage analytics for dot. Dispatched dot commands append NDJSON events under $XDG\_STATE\_HOME/tool-usage with timestamps, machine, canonical command, recognised flag names, exit status, duration, source, and invoker. Live dot events never store positional values. Optional shell-history backfill observes selected standalone tools without requiring integration. It uses whitespace tokenisation, so review the source history before applying when arguments may contain sensitive text. Set DOT\_USAGE\_DISABLE=1 to stop automatic live recording, or DOT\_USAGE\_DIR to relocate the event root. Explicit backfill —apply still writes events. **Modes** ```text summary Per-feature usage table (default) stale Features not used within the window path Print the event storage root backfill Import whitelisted invocations from shell history ``` **Options** | Option | Description | | ------------------ | -------------------------------------------------------- | | `--days` `` | Window for summary/stale (default: 90) | | `--format` `` | summary format (one of: `text`, `json`, `agent-context`) | | `--root` `` | Extra event root to combine (repeatable) | | `--history` | Backfill from shell history (accepted for clarity) | | `--apply` | Write events during backfill (default: dry run) | **Examples** ```bash dot usage summary --days 30 dot usage summary --format agent-context dot usage stale --days 90 dot usage backfill --history dot usage backfill --history --apply ``` ## `dot help` [Section titled “dot help”](#dot-help) Show this help menu ```text dot help ``` # Notes & Handoffs > Repository notes and the handoff workflow. Repository notes live in the standalone [`notes`](https://notes.timmo.dev) CLI and MCP server. Dotfiles keeps the OpenCode plugins, slash commands, and handoff skill that consume it. Notes live in a notes vault git repo (`~/Documents/notes` by default, overridable with `NOTES`). Inside the vault, files are scoped per repository under `repo-notes/{owner}/{repo}/`, keyed off the current git remote. ## Browse notes [Section titled “Browse notes”](#browse-notes) ```bash notes list notes list --all notes list --format json notes root --repo-notes ``` ## Handoffs [Section titled “Handoffs”](#handoffs) Handoffs are notes tagged `handoff`, used to pass context between agents or sessions. ```bash notes handoffs notes handoffs --all notes handoffs --format json ``` `notes handoff` is an alias for `notes handoffs`. Handoffs carry a `priority` of `low`, `medium`, `high`, or `critical`. Any handoff without an explicit `priority` is treated as `medium`. ## Read / write note files [Section titled “Read / write note files”](#read--write-note-files) ```bash notes read --path notes write --path --stdin notes delete --path ``` Writes and deletes are committed to the notes vault and pushed when it has a remote. The push is best-effort: a failed or skipped push never fails the note operation. ## OpenCode integration [Section titled “OpenCode integration”](#opencode-integration) Agents do not touch the vault with built-in file tools. The same files are created and loaded inside an OpenCode session through slash commands backed by two plugins. ### Slash commands [Section titled “Slash commands”](#slash-commands) | Command | What it does | | ----------------- | ----------------------------------------------------------------------------------------- | | `/note-create` | Summarise the current conversation into a new note for this repo. | | `/note-append` | Add new content to an existing note (pick from a ranked list). | | `/note-reference` | Load one or more notes, any skills they reference, and suggested next steps into context. | | `/notes-list` | List this repo’s notes, optionally filtered by tag. | | `/notes-search` | Rank this repo’s notes against a topic, keyword, or tag. | | `/handoff` | Write a handoff document for the next agent session. | | `/handoffs-list` | List handoff notes for this repo (equivalent to `/notes-list handoff`). | See the [commands reference](/reference/commands/) for the full list. ### How it works [Section titled “How it works”](#how-it-works) Two OpenCode [plugins](/reference/plugins/) wire the commands to the vault: * **`repo-notes`** injects a `` block at the top of each note command. It runs `notes context --command --json`, which resolves the owner and repo from git and reports the target notes path. For listing and search commands it includes existing note metadata; `/note-reference` reads only the selected note bodies through `notes_note_read`. * **`notes-guard`** blocks built-in file and shell tools from touching the vault, so the note MCP tools are the only way in. Agent harnesses prefix MCP server names onto tool calls, so note commands and plugins refer to `notes_note_read`, `notes_note_write`, `notes_note_delete`, and `notes_note_list`. The underlying standalone MCP server registers them as `note_read`, `note_write`, `note_delete`, and `note_list`; see the [Notes MCP docs](https://notes.timmo.dev/mcp/). So a typical create flow is: run `/note-create` -> `repo-notes` injects the repo context -> the command summarises the conversation and calls the pre-approved `notes_note_write` tool -> `notes mcp` writes the file, commits it, best-effort pushes the vault, then emits a desktop notification with the push result. Read-only agents still deny note writes. ### Handoffs [Section titled “Handoffs”](#handoffs-1) `/handoff` defers to the [`handoff` skill](/reference/skills/), which compacts the conversation into a `handoff-{slug}.md` note tagged `handoff`. For work spanning multiple phases, branches, or PRs, the skill offers to split the handoff rather than writing one combined note, using a shared `handoff-{feature}-{phase}` naming convention so related handoffs group together under `notes handoffs`. ## Configuration [Section titled “Configuration”](#configuration) * `NOTES` - notes vault git repo (preferred; default `~/Documents/notes`). * `DOT_NOTES_DIR` - compatibility override used when `NOTES` is unset. # Shell Setup > Shell completions, editing keys, aliases, and small shell helpers. ## Shell completions [Section titled “Shell completions”](#shell-completions) The `zsh/` package adds `${XDG_DATA_HOME:-~/.local/share}/zsh/site-functions` to `fpath` before `zsh-autocomplete` runs `compinit`. Generated completions are stowed for the two local CLIs: * `dot completions bash|fish|zsh` writes the stowed `dot` completions in this repo. * `context completions bash|fish|zsh` writes the stowed `context` completions in this repo. * `_omarchy` is a stowed zsh completion wrapper for dynamic Omarchy subcommands. Installed package completions are also wired into common aliases where needed. `handoffs` completes through `_notes` and runs `notes handoffs`. Zsh also has a live generated completion: * `mise completion zsh` is generated at shell startup into the live, non-stowed `_mise` path and refreshed when the `mise` binary is newer than the cached completion. The live `_mise` file is intentionally not version-controlled; it tracks the installed `mise` binary on each machine. ## Editing keys [Section titled “Editing keys”](#editing-keys) The zsh config restores the standard editing bindings used by this setup after plugins load, including Delete as forward-delete. `dot doctor` checks the Delete binding and reports drift when a plugin or local override changes it. ## Small helpers [Section titled “Small helpers”](#small-helpers) The shell keeps a few typo and navigation helpers close to the aliases. For example, `cwd` prints a short reminder that the real command is `pwd`, then runs `pwd` so the mistake still returns useful output. Run `update` to select maintenance steps with Gum. All steps start selected, get their own section heading, and run in order: `dot update`, `topgrade`, then `omarchy update -y`. Use `update -y` or `update --yes`, or run it in a non-interactive shell, to run all three without command prompts. Agent-driven runs route internal `sudo` calls through a temporary `pkexec` helper so authentication can use the desktop PolicyKit prompt without a controlling terminal. The sequence stops if a selected step fails. # Stow Workflow > How dotfiles packages are applied into your home directory with GNU Stow. The repository is a [GNU Stow](https://www.gnu.org/software/stow/) package root targeting `~/`. Each top-level directory (`zsh`, `neovim`, `starship`, `hypr`, `ghostty`, `scripts`, …) is a stow package whose contents are symlinked into your home directory. ## Always use `dot stow` [Section titled “Always use dot stow”](#always-use-dot-stow) Apply packages with `dot stow` (or `dot update`, which refreshes stow). Do **not** run GNU `stow` directly from the repo root: `dot` applies the correct backup, no-folding, and public-then-private flow. The first-use `dot install` and `dot init` commands add the adopt step; `dot stow` is the steady-state relink. Apply stow packages ```bash dot stow # stow public + private dot stow --public # public only dot stow --private # private only ``` ## What `dot stow` does [Section titled “What dot stow does”](#what-dot-stow-does) * Lays down public packages first, then the private overlay from `~/.config/dotfiles-private`. * Stows any package that targets runtime-owned directories with `--no-folding`, including `hypr/`, `ghostty/`, `herdr/`, shell completions, `.local/bin`, and systemd user units. This keeps `~/.config/herdr/` local while stowing only `config.toml`, so logs, sockets, and session state never enter the repository. For Hypr it also creates/repairs the `~/.config/hypr/host` symlink for the active host. * Before stow, moves unmanaged real files or directories that block active package targets into the repo’s `backup/` directory and logs each source-to-backup path. This includes host-specific packages such as `chromium--laptop`. It does not follow an unmanaged parent symlink into an external tree; those conflicts are left for manual resolution. * Before public stow, backs up the retired `timmo001/omarchy-ghostty` clone at `~/.config/ghostty` when present, so the `ghostty/` package can own that path. * During `dot install` and `dot init`, public packages use `--adopt`, but a committed-wins pre-pass first backs up differing live files so stock config cannot silently overwrite committed public files. Any remaining adopted changes are reported for review. Private packages use normal stow without `--adopt`. ## Hypr package handling [Section titled “Hypr package handling”](#hypr-package-handling) The Hypr package is treated differently from every other stow package. Hyprland enables config autoreload by default. If `~/.config/hypr/hyprland.conf` goes missing even briefly, Hyprland writes a default stub as a real file. That stub then blocks the next stow because stow cannot replace a regular file with a symlink. To avoid that gap, the steady-state `dot stow` flow and the install flow used by `dot install` and `dot init` never unstow the `hypr` package. Before stowing Hypr, they atomically repair `~/.config/hypr/hyprland.conf` when the link is missing or points at the wrong target: the link is created through a temporary path and renamed into place, so Hyprland never sees a missing file. The idempotent stow step then fills in any other missing Hypr files without an unstow/restow cycle. After the Hypr package is laid down, `dot stow` also creates or repairs the `~/.config/hypr/host` symlink for the active `OMARCHY_HOST`. See [Host Overrides](/omarchy/host-overrides/) for how host overrides are selected. ## Unstowing packages [Section titled “Unstowing packages”](#unstowing-packages) Use `dot clean` when you need to remove the symlinks that `dot stow` manages, for example before inspecting a conflict or proving whether a file is coming from the dotfiles repo. Temporarily remove managed links ```bash dot clean # unstow private packages first, then public packages dot stow # reapply the managed symlinks afterwards ``` `dot clean` discovers stow packages the same way `dot stow` does: top-level package directories only, excluding repo internals such as `dot/`, `docs/`, and `backup/`. Host-specific packages (`name--host`) are included only when their suffix matches the resolved Omarchy host, from `OMARCHY_HOST` or the current `~/.config/hypr/host` link. If the private overlay is available, it is unstowed before the public repo so overlay links are removed before the base packages. The command removes managed Stow links; it is not a general home-directory cleanup tool. Re-run `dot stow` or `dot update` after a clean to restore the expected links and host repairs. ## Ignore rules [Section titled “Ignore rules”](#ignore-rules) `.stowrc` sets the stow target and ignore rules. Files that should never be symlinked into `~/` are ignored there, including top-level docs, the `dot/` source, the `docs/` site, and repo metadata. Keep `.stowrc` ignore rules in sync when adding root-only files. Caution The repo root stows to `~/`. Anything not ignored in `.stowrc` becomes a symlink under your home directory. When adding new root-level files or directories that should not be stowed (such as `docs/`), add a matching `--ignore` rule. ## Health check [Section titled “Health check”](#health-check) `dot doctor` runs a dry-run restow to detect drift, alongside its other checks. Run it after changing stow packages to confirm nothing is broken. # Usage Analytics > Local-first usage tracking for dot with optional shell-history observations. `dot usage` records local-first analytics for the `dot` CLI so you can see which features are actually used, split human from agent from automated calls, and decide whether a feature earns its keep. Its optional history backfill can also observe selected standalone CLI invocations without requiring those projects to integrate with dotfiles. Recording stays local: each dispatched `dot` command appends one NDJSON event under `$XDG_STATE_HOME/tool-usage`. Live events store the timestamp, machine, canonical subcommand path, recognised flag names, exit status, duration, source, and invoker. They do not store positional values such as paths, ids, or note text. Help and unresolved invocations exit before the recording hook. ## How it works [Section titled “How it works”](#how-it-works) `dot` installs a best-effort exit hook that appends one event when the process exits, capturing the real exit code and duration: ```json {"ts":"2026-07-08T20:45:30Z","machine":"desktop","tool":"dot","invokedAs":"dot","command":["git-diff"],"flags":["--raw"],"exitCode":0,"durationMs":63,"source":"live","invoker":"human"} ``` Events are written per machine and per day: ```text $XDG_STATE_HOME/tool-usage/events//YYYY-MM-DD.ndjson ``` `invoker` is one of `human`, `agent` (an AI coding agent was detected), or `automation` (a status-bar poll, detected from `--bar-json`), so Waybar polling does not drown out genuine feature usage. ## Reporting [Section titled “Reporting”](#reporting) ```bash dot usage summary # per-feature table (last 90 days) dot usage summary --days 30 # narrow the window dot usage summary --format json # machine-readable dot usage summary --format agent-context # compact, for feeding an agent dot usage stale --days 90 # features not used recently + dot commands never seen dot usage path # print the event root ``` The summary groups by tool and command, showing total, human, agent, automation, failure count, median duration, and last-seen date. ## Backfill from shell history [Section titled “Backfill from shell history”](#backfill-from-shell-history) Prefill from existing shell history. Only whitelisted binaries (`dot`, `context`, `notes`, `note`, `handoff`, `handoffs`) are observed, and only from shells that timestamp history (fish and zsh extended history); bash is skipped because its history is undated. This is a dot-owned observation layer: the standalone projects remain independent and do not write dot usage events. The backfill parser splits history on whitespace and does not interpret shell quoting. `dot` history entries keep only flags declared by the matched command, but standalone tools have no command-specific flag allowlist. Review the dry run and source history before applying if standalone arguments may include sensitive text beginning with `-`. ```bash dot usage backfill --history # dry run: counts by tool, writes nothing dot usage backfill --history --apply # write the imported events ``` Backfilled events are attributed to `human`, marked `source: "history"`, and have a null exit code and duration. Re-running is safe: exact history duplicates are removed, and matching history events at or after the first live event for the same machine, tool, command, and flags are suppressed. ## Two machines [Section titled “Two machines”](#two-machines) Each machine writes its own per-machine files, so nothing conflicts when the directory is synced (Syncthing, a shared folder, or a private repo). Combine roots at read time for `summary` and `stale`: ```bash dot usage summary --root ~/synced/other-machine/tool-usage ``` `--root` does not change where `backfill --apply` writes; imports always use the local `DOT_USAGE_DIR` root. ## Configuration [Section titled “Configuration”](#configuration) * `DOT_USAGE_DIR` - relocate the event root (default `$XDG_STATE_HOME/tool-usage`). * `DOT_USAGE_DISABLE=1` - stop automatic live dot recording. Explicit `backfill --apply` still writes. * `OMARCHY_HOST` - overrides the machine identifier used to partition event files (falls back to the system hostname). # System Utilities > Health checks, system updates, benchmarks, and optional timers. ## System health check [Section titled “System health check”](#system-health-check) `system-health-check` is a friendly multi-snapshot system health report covering CPU, memory, network, pressure, and known logs. ```bash system-health-check # write a health report system-health-check --open-opencode # run opencode run against the report, then open an interactive session ``` Add `--open-opencode` to run `opencode run` against the saved report and then open a full interactive OpenCode session with `opencode --continue`. ## Times [Section titled “Times”](#times) `times` prints current local, Pacific, Mountain, Central, and Eastern times. `SUPER+CTRL+ALT+T` shows an aligned compact version in a desktop notification. ```bash times ``` ## System updates [Section titled “System updates”](#system-updates) [topgrade](https://github.com/topgrade-rs/topgrade) runs the machine’s update steps (AUR via `yay`, Flatpak, firmware checks, `mise` tools, `rustup`, `cargo`, and more) in one pass. The repo stows a tuned config to `~/.config/topgrade.toml` and a logging wrapper at `scripts/.local/bin/topgrade` that shadows the system binary via `~/.local/bin` on `PATH`. ```bash topgrade # full run (all enabled steps) topgrade mise cargo # run only named steps ``` * The wrapper logs the full session to `$XDG_STATE_HOME/topgrade.log` (default `~/.local/state/topgrade.log`) with `script`, mirroring the `omarchy-update` pattern, so you can review a run afterwards. * It adds `--sudoloop` automatically when a run includes steps that need root (a full run, or the `system`, `firmware`, or `containers` steps) so credentials stay cached during long runs, and skips it for user-only steps. * Firmware is check-only, `mise` bumps tool versions, and `yay` runs with `--noconfirm --cleanafter`. * Steps managed elsewhere or unused are disabled (for example `bun`, `deno`, `go`, and `pnpm` come from `mise`; `hyprpm` is skipped because it drops the shared sudo credential). A desktop notification fires only on failure. ## Benchmarks and diagnostics [Section titled “Benchmarks and diagnostics”](#benchmarks-and-diagnostics) The stowed utility scripts include a quick system benchmark and an ambient resource-growth diagnostic: * `system-quick-benchmark` - short CPU/memory/network benchmark snapshot. * `system-resource-leak-check` - samples whole-system memory, swap, pressure, and sockets over time. It is a diagnostic, not a deterministic test. ```bash # Quick benchmark (minimal defaults) system-quick-benchmark # Include LAN throughput (requires an iperf3 target) system-quick-benchmark --iperf-host 192.168.1.50 # Resource growth diagnostic system-resource-leak-check ``` * Reports are written beneath `$XDG_STATE_HOME` (default `~/.local/state`) in directories matching each command name. Use `--output` to select another path. * LAN network throughput is opt-in and requires `--iperf-host`. * Scripts use ANSI colour output by default; set `NO_COLOR=1` to disable. * All scripts include an uptime/load snapshot near the top of output. Repository regression tests live under `tests/`, use temporary directories, and run through mise tasks and the `lint.yml` workflow: * `tests/github/opencode-publish.test.sh` checks publication of shared `lib/` modules and rejects missing relative plugin imports before cleaning the publish checkout. * `tests/scripts/workspace-restore.test.sh` checks that captured browser URLs remain one shell argument and cannot execute command substitutions during restore. * `tests/dot/cli-smoke.test.sh` builds `dot` and checks side-effect-free CLI entry points. `.github/scripts/validate-skills.sh` validates public `SKILL.md` files with [`skills-ref`](https://github.com/agentskills/agentskills/tree/main/skills-ref). Run locally with `mise run skills:validate`; CI runs it as the dedicated `validate-skills` job in `lint.yml`. Run `mise run tests:integration` for deterministic repository tests and `mise run tests:smoke` for the build plus CLI smoke checks. TypeScript unit tests mirror `dot/src/` under `dot/tests/` and run through `mise run dot:test`. ## Firewall rules [Section titled “Firewall rules”](#firewall-rules) `dot firewall` configures a managed set of [ufw](https://wiki.archlinux.org/title/Uncomplicated_Firewall) rules, `dot init` runs it during first-use setup, and `dot doctor` verifies the rules are still present. The setup reads the world-readable ufw rules file first, so a fully configured machine adds nothing and never prompts for a password. When changes are needed, missing or stale-comment rules are applied in one elevated batch, followed by a single `ufw reload`, so the firewall step should only ask for authentication once. Each rule is tagged with its purpose as a ufw comment, so it appears in `ufw status`. Most rules are inbound port allows on any interface. The libvirt rules are scoped to the `virbr0` bridge: two inbound allows for guest DHCP and DNS, plus a forwarding (route) allow so the default NAT network can route guest traffic off the bridge. Without them, ufw’s default `deny (incoming)` and `deny (routed)` policy leaves guests without an address or internet access. Rule identity includes the complete ufw tuple: source, destination, protocol/port, and interface/direction. A source-restricted existing rule does not satisfy a managed any-source rule, so `dot firewall` adds the broader managed rule rather than treating the restricted rule as equivalent. | Port(s) | Protocol | Scope | Purpose | | ----------- | --------- | -------- | -------------------------------------------------- | | `1714:1764` | UDP + TCP | any | KDE Connect device discovery and transfer. | | `8123` | TCP | any | Home Assistant frontend. | | `8124` | TCP | any | Home Assistant companion port. | | `4096` | TCP | any | OpenCode local server. | | `53317` | UDP + TCP | any | LocalSend device discovery and transfer. | | `67` | UDP | `virbr0` | libvirt guest DHCP. | | `53` | TCP + UDP | `virbr0` | libvirt guest DNS. | | forward | any | `virbr0` | libvirt NAT: forward guest traffic off the bridge. | If `ufw` is not installed, firewall setup and doctor skip the firewall step with a warning. The doctor check reports any missing rule with the `sudo ufw allow ...` command to add it, or a rule present without its managed comment, and you can run `dot firewall` to reconcile. Override the scanned rules file with `DOT_UFW_RULES_FILE`. After elevation, `dot firewall` re-reads the rules file and fails when any managed rule is still missing or carries a stale comment. That catches silent ufw write failures instead of leaving init marked complete with half-applied rules. ## Daily volume reset (laptop only) [Section titled “Daily volume reset (laptop only)”](#daily-volume-reset-laptop-only) Public dotfiles provide `daily-volume-zero.timer` in laptop-only stow packages (`scripts--laptop` and `systemd--laptop`), a user systemd timer that runs at 5am local time. * The timer runs `daily-volume-zero`, which sends a 10-second desktop notification, clears default sink mute, then sets the default PipeWire/WirePlumber sink volume to `0%`. * It is optional and not enabled by `dot`. Enable it on machines that should use it: ```bash systemctl --user enable --now daily-volume-zero.timer ``` # Getting Started > Bootstrap a fresh Omarchy machine and run the ongoing dotfiles workflow. The dotfiles are designed to bootstrap a fresh [Omarchy](https://omarchy.org) machine and then keep it in sync with a single command. Start with the install guide, then use the checklist for a clean walkthrough. Personal dotfiles These are my own dotfiles, tuned for [Omarchy](https://omarchy.org) and my machines, and they lean on a deeply integrated private overlay that is not public. Don’t install them wholesale on a machine you care about, and don’t expect them to work on plain Arch without replicating my setup. Read them, take the bits you want, and fold them into your own dotfiles instead. The steps below are how *I* set up a new machine, documented for reference. [Install](/getting-started/install/)Prerequisites, bootstrap build, and the ongoing workflow. [New Machine Checklist](/getting-started/new-machine/)A numbered, end-to-end setup for a new machine. ## How it fits together [Section titled “How it fits together”](#how-it-fits-together) * Public dotfiles live at `~/.config/dotfiles` and are applied with GNU Stow. * Optional private dotfiles at `~/.config/dotfiles-private` overlay machine-specific config. * The [`dot`](/dot/) binary owns setup (`dot init`), ongoing sync (`dot update`), and day-to-day tooling. # Install > Prerequisites, bootstrap build, and the ongoing dotfiles workflow. ## Prerequisites [Section titled “Prerequisites”](#prerequisites) On a fresh [Omarchy](https://omarchy.org) machine, install the bootstrap build prerequisites ([git](https://git-scm.com) and [mise](https://mise.jdx.dev)): ```bash yay -S --needed git mise-bin ``` If you want the private dotfiles overlay, authenticate [`gh`](https://cli.github.com) (the GitHub CLI) before `dot init` so it can clone `dotfiles-private` automatically: ```bash gh auth status || gh auth login ``` ## Clone and build [Section titled “Clone and build”](#clone-and-build) Clone the public dotfiles first, then build the `dot` binary before it is on your `PATH`. Trust and install the pinned toolchain with mise, then run the build task (it installs dependencies first, and `mise run` provides Bun without needing shell activation yet): ```bash git clone git@github.com:timmo001/dotfiles.git ~/.config/dotfiles cd ~/.config/dotfiles mise trust mise install mise run dot:build ``` ## First-use setup [Section titled “First-use setup”](#first-use-setup) `dot init` runs the one-time first-use setup: it bootstraps private dotfiles when allowed, syncs Omarchy repos, selects the Hypr host, installs and adopts config, installs stowed mise tools, sets up packages and machine hooks, and syncs agents. It logs to `~/.local/state/dot/init.log` by default. The private-overlay pull or clone runs first as an unbounded preflight; the setup phases that follow use the same spinner and timeout handling as `dot update`. ```bash ~/.config/dotfiles/scripts/.local/bin/dot init --noninteractive ``` For a laptop, select the laptop host: ```bash dot init --host laptop --noninteractive ``` Or run `dot init` in an interactive shell to be prompted. `--noninteractive` skips only the Hypr host questionnaire; elevation and package tools may still prompt. `--confirm` remains accepted for compatibility but does not suppress prompts. Private overlay preflight is controlled by `DOT_ALLOW_PRIVATE`: `auto` skips without GitHub authentication and tolerates an existing-overlay pull failure, but a failed attempted clone is fatal; `always` requires the overlay to update or clone successfully; `never` skips it. ## Ongoing workflow [Section titled “Ongoing workflow”](#ongoing-workflow) After init completes, restart your shell so `dot` is on `PATH`, then reboot so the Omarchy session picks up `OMARCHY_HOST`. Run doctor after the reboot to verify the setup, and use update for ongoing maintenance: ```bash dot doctor # health checks dot update # self-update and relaunch, then pull, reconcile, stow, and rebuild dot git-diff # review changes across managed repos context git # branch context for the current repo (from the context-git package) ``` `context git` and `context stack` come from the `context-git` AUR package installed during init. They are used by OpenCode plugins and agent harnesses for repository context; see [Context Integration](/git/context/). `dot update` is the everyday command. It pulls the public dotfiles, installs Bun dependencies, rebuilds and relaunches on the new binary, then scans and pulls tracked repositories. The remaining full-update phases trust mise configs, regenerate completions, install missing public packages, sync MCP configs, stow, rebuild, sync agents, backfill the init marker, and refresh resume-managed services. See the [Command Reference](/dot/commands/) for scoped phase flags and exit codes. # New Machine Checklist > Step-by-step setup for a new Omarchy machine. A clean, end-to-end walkthrough for setting up a new machine. 1. Clone `dotfiles` to `~/.config/dotfiles`. 2. If you want private dotfiles, confirm `gh auth status` works before `dot init`; init clones `dotfiles-private` to `~/.config/dotfiles-private` automatically when auth is available. 3. Install bootstrap build prerequisites: Install bootstrap prerequisites ```bash yay -S --needed git mise-bin ``` 4. Build the `dot` binary (mise trusts and installs the pinned toolchain, then the build task installs dependencies and compiles it): Build dot ```bash cd ~/.config/dotfiles mise trust mise install mise run dot:build ``` 5. Run first-use setup using the mode that matches this machine. 6. If stock Omarchy config directories already exist at `~/.config/bootstrap`, `~/.config/waybar`, or `~/.config/uwsm`, `dot init` backs them up with a `.dot-init-backup-*` suffix before cloning the managed repos. Hyprland and Ghostty config are stowed from the `hypr/` and `ghostty/` packages instead. 7. `dot init` opens the managed [firewall rules](/dot/utilities/#firewall-rules) (KDE Connect, Home Assistant, the OpenCode server, LocalSend, and the libvirt NAT network) when `ufw` is installed. 8. Restart your shell and confirm `dot help` is on `PATH`. 9. Run `dot git-diff` and verify the expected repo state. 10. Reboot so the Omarchy session picks up `OMARCHY_HOST`, then run `dot doctor` to verify the setup. Use `dot update` for ongoing sync, stow refreshes, and rebuilds. * Desktop / VM First-use setup ```bash ~/.config/dotfiles/scripts/.local/bin/dot init --noninteractive ``` * Laptop First-use setup ```bash dot init --host laptop --noninteractive ``` * Interactive First-use setup ```bash dot init ``` `--noninteractive` skips the Hypr host questionnaire; elevation and package tools may still prompt. The accepted `--confirm` compatibility flag does not suppress those prompts. # Git & GitHub > Diff, log, status, workflow runs, and a notification inbox across managed repos. `dot` includes git and GitHub tools that work across every managed repo (public and private dotfiles, configured private git repos, and Omarchy repos), and integrates the standalone `context` CLI for branch and stack context. Most watcher commands have an interactive TUI plus `--raw` and `--bar-json` output for scripts and status bars. Local commit automation goes through the guarded `dot git-commit` gateway. [Diff & Repo Watcher](/git/diff/)The git-diff TUI and CLI for dirty worktrees and ahead/behind state. [Context Integration](/git/context/)How OpenCode plugins consume the standalone context CLI. [Commit Gateway](/git/commit/)Guarded commits with scoped paths, message checks, and safe push mode. [Workflow Runs](/git/workflows/)Watched GitHub Actions runs for each repo's checked-out HEAD. [Notifications](/git/notifications/)The GitHub notification inbox with read/done/ignore actions. ## Status bar integration [Section titled “Status bar integration”](#status-bar-integration) Several of these commands emit `--bar-json` output for a status bar module. See [Bar Integrations](/bar-integrations/) for the JSON format, click actions, and which commands support it. ## Private repo configuration [Section titled “Private repo configuration”](#private-repo-configuration) Repo activity, workflow, and notification settings live in the private `dot-git.yml` config. See [Private Git Config](/configuration/private-git/) for the schema. # Commit Gateway > Guarded commits through dot git-commit instead of raw git commit. ## `dot git-commit` [Section titled “dot git-commit”](#dot-git-commit) `dot git-commit` is the guarded commit path for agents and local workflow commands. It creates normal git commits, but wraps the dangerous parts so commits stay scoped, styled, and harder to run on the wrong branch. ```bash dot git-commit -m "Add commit gateway" # commit the staged set dot git-commit -m "Scope to one file" --path src/git/Status.ts # commit only named files dot git-commit -m "Commit and push" --push # commit, rebase-pull, then push dot git-commit --amend # fold staged changes into HEAD, keep its message dot git-commit --amend -m "Reword last commit" # rewrite HEAD's subject dot git-commit -m "Preview only" --dry-run # show the plan, change nothing ``` Agents use this command through the `git-commit` skill. Raw `git commit` is blocked in the OpenCode permission config, so `/commit` and `/commit-push` both route through the gateway. A commit or push request authorises only that specific action; a later change still needs a fresh explicit request. ## Agent workflow [Section titled “Agent workflow”](#agent-workflow) Before staging or writing a subject, read working tree state through the Context MCP server’s `git_context` tool rather than raw `git status` or `git diff`. Set `diff: true` when the message depends on the change content. The tool exposes the same structured branch context the `branch-context` plugin renders for slash commands; see [Context Integration](/git/context/) for the XML sections and when to refresh. Staging and commit still go through `dot git-commit` only after the user explicitly requests a commit or push. ## Scope [Section titled “Scope”](#scope) Without `--path`, the command commits the current staged set. It never runs `git add -A`. Use repeated `--path ` flags when one working tree contains several unrelated changes. That commits only those files and leaves other staged or unstaged files alone. `--dry-run` validates the message, resolves the target branch, prints the commit or push plan, and exits before staging, committing, or pushing. ## Amend Mode [Section titled “Amend Mode”](#amend-mode) `--amend` rewrites the previous commit instead of creating a new one. It folds the staged set (or a `--path` scope) into HEAD and, without `--message`, keeps HEAD’s existing message. Pass `--message` to reword the subject; it runs through the same message guards. An amend with nothing staged is allowed, so `--amend -m "..."` is the way to reword the last commit. ## Message Guards [Section titled “Message Guards”](#message-guards) The gateway validates the subject before committing: | Guard | Behaviour | | --------------------- | --------------------------------------------------------------------------------------------------- | | Single line | Rejects multi-line messages and bodies. | | Non-empty | Rejects blank subjects after trimming. | | No em/en-dash | Rejects typographic dash punctuation; use a hyphen. | | No trailing full stop | Rejects subjects ending in `.`. | | Length limits | Warns over 60 characters, rejects over 120. | | Plain text | Rejects tabs and control characters; warns on curly quotes, non-breaking spaces, and double spaces. | The preferred style is a concise, imperative, single-line subject, for example `Add git commit gateway`. ## Branch Guard [Section titled “Branch Guard”](#branch-guard) The command refuses commits to the base branch of a repository you do not own. Ownership is configured with one or more `git config dot.owner ` values. The guard catches both a direct clone of someone else’s repository and a fork with a foreign `upstream` remote. It resolves the base branch from the repository’s default branch metadata rather than assuming `main` or `master`. Work on a feature branch for upstream PRs. Personal repos, takeover forks with no foreign remote, and non-base branches are allowed. ## Push Mode [Section titled “Push Mode”](#push-mode) `--push` commits first, then pulls with `--rebase` before pushing. It sets an upstream for the current branch when one is missing and never runs a plain force-push. Agents must only use it for the specific commit/push request the user just made. When combined with `--amend`, the push instead uses `--force-with-lease`: the rewritten commit only overwrites the remote branch when it still matches the ref we last saw, so a teammate’s or bot’s newer commit blocks the push rather than being clobbered. The pull-rebase step is skipped in this case. If the rebase conflicts, the command aborts the push path and leaves the commit in place for manual integration. # Context Integration > How dotfiles OpenCode plugins consume the standalone context tool. Generic branch and stack context lives in the standalone [`context`](https://context.timmo.dev) CLI and MCP server. The dotfiles repo no longer embeds that logic in `dot`; it installs the tool, stows shell completions, and keeps the OpenCode plugins that turn the JSON payloads into prompt XML. ## Install [Section titled “Install”](#install) `dot init` installs the `context-git` AUR package from [`.dot-public-packages`](/configuration/private-packages/#public-packages). That package provides the `context` binary on `PATH`. After init, verify in any git checkout: ```bash context git --json | head context stack --json | head ``` Shell completions for `context` are stowed from this repo. Regenerate them after upgrading the binary with `context completions bash|fish|zsh`, then `dot stow`. See [Shell Setup](/dot/shell/#shell-completions). ## CLI usage [Section titled “CLI usage”](#cli-usage) Use the commands directly when scripting or debugging agent context: ```bash context git # human-readable branch context context git --json # structured payload for tools and plugins context stack # human-readable tech-stack summary context stack --json # structured stack payload context help git # command help (also exposed as an MCP resource) ``` `NO_COLOR` disables ANSI colour in TTY-aware output. See [Environment Variables](/configuration/environment/#debugging-and-output). ## MCP server [Section titled “MCP server”](#mcp-server) Repository context tools are provided by the standalone `context` MCP server: ```bash context mcp ``` Typical tools (names from `tools/list`): | Tool | Purpose | | --------------- | ----------------------------------------- | | `git_context` | Branch context for the current repository | | `stack_context` | Tech-stack summary for a directory | | `command_help` | Help text for a `context` subcommand | Read-only resources include `context://git`, `context://stack`, and `context://command/{name}`. Wire the server in an agent harness with `["context", "mcp"]` as the command. Full schemas and examples are on . Use [`notes mcp`](https://notes.timmo.dev/mcp/) for the notes vault. Agent harnesses that need repository context and notes load both standalone stdio servers side by side. ## OpenCode plugins in dotfiles [Section titled “OpenCode plugins in dotfiles”](#opencode-plugins-in-dotfiles) The dotfiles repo keeps the OpenCode plugins that consume `context` JSON and render prompt blocks: * `branch-context` runs `context git --json` and injects `` XML for scoped slash commands (PR-inclusive branch context, or work-scope-only variants without the pull request). PR descriptions are capped at 4,000 characters; up to 20 comments and 20 reviews are included, with each body capped at 2,000 characters. * `stack-context` runs `context stack --json` and injects `` XML automatically on the first message of a session inside a git repository, and on demand for `/inject-stack` or `/inject-context`. Plugin-specific command allowlists and injection rules stay in `agents/.config/opencode/plugins/`. For CLI flags, JSON payload fields, and MCP tool parameters, see . ## Injected XML blocks [Section titled “Injected XML blocks”](#injected-xml-blocks) The plugins render the structured JSON into tagged XML sections. Treat injected blocks as the primary source for branch and stack analysis; avoid re-running `git`/`gh` or re-scanning the tree unless the user asks for a fresh snapshot or the block reports collection failure. ### Branch context (``) [Section titled “Branch context (\)”](#branch-context-branch-context) | Section | Purpose | | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `context-metadata` | How the snapshot was produced (`context git --json`) and when it was generated. | | `branch-metadata` | Repository identity, current branch, HEAD, default remote/branch, base ref, upstream, ahead/behind, and whether HEAD is on the default branch. Unresolved default-branch metadata is labelled `(unresolved)` rather than guessed. | | `status` | Compact `git status -sb` summary. | | `work-scope` | Current work scope in priority order: unstaged, staged, then branch-only changes. On the default branch, branch scope is skipped and recent commits are shown instead. | | `pull-request` | PR metadata, description, comments, reviews, and checks (branch-focused commands only). | | `truncations` | Applied output limits. Treat affected sections as partial. | | `warnings` | Non-fatal collection issues, fallbacks, or missing data. | `work-scope` reflects the producer’s `workScope.state`: | State | Meaning | | ---------------- | ------------------------------------------------------------------------------------ | | `collected` | Branch-only commits, files, and diff stat are present. | | `not-applicable` | HEAD is on the default branch; branch scope is skipped and recent commits are shown. | | `unresolved` | Default branch could not be resolved; recent commits are shown with a reason. | Work-scope-only commands (for example scoped refactor helpers) call `context git --json --no-pr` and omit the `pull-request` section. ### Stack context (``) [Section titled “Stack context (\)”](#stack-context-stack-context) | Section | Purpose | | ------------------ | -------------------------------------------------------------------------------------------------------------- | | `context-metadata` | How the snapshot was produced (`context stack --json`), repository root, and files scanned. | | `languages` | Detected languages with file counts and general locations. | | `ecosystems` | Package ecosystems from manifest files. | | `tooling` | Package managers, linters, formatters, task runners, build tools, and test runners from lockfiles and configs. | | `frameworks` | Frameworks and libraries from declared dependencies. | | `truncations` | Scan or output limits that make a section partial. | | `warnings` | Non-fatal collection issues. | Automatic session injection runs at most once per session and only inside a git worktree with a non-empty detection result. ## MCP refresh outside plugin-backed commands [Section titled “MCP refresh outside plugin-backed commands”](#mcp-refresh-outside-plugin-backed-commands) Plugin injection covers registered slash commands. For ad-hoc work (for example `/commit` scope checks or manual branch inspection), use the Context MCP server’s `git_context` tool with only the fields the task needs (`diff`, `branchDiff`, PR details, and so on). See [Commit Gateway](/git/commit/#agent-workflow) for the commit path. # Diff & Repo Watcher > The dot git-diff TUI and CLI for tracking dirty worktrees and ahead/behind state across managed repos. ## `dot git-diff` [Section titled “dot git-diff”](#dot-git-diff) A two-pane repo watcher across every managed repository: public and private dotfiles, the notes vault, Omarchy repos (when enabled), and schedule-gated activity repos from `dot-git.yml`. The **Changed** pane lists repos with uncommitted changes or non-zero ahead/behind counts against their upstream; **Other** lists the rest. ```bash dot git-diff # interactive TUI (alias: dot diff) dot git-diff --raw # text summary of repos with changes dot git-diff --bar-json # JSON for status bars and shell modules dot git-diff --list-changed # changed repos as name|path rows dot git-diff --list-all # all tracked repos as name|path rows dot git-diff --no-fetch # skip upstream fetches; use local refs only dot git-diff --tab other # open with the Other pane focused ``` The TUI polls every ten seconds and loads Waybar cache on startup for a fast first paint. `dot git-log` reuses the same tracked repo list. ## TUI layout [Section titled “TUI layout”](#tui-layout) | Pane | Contents | | ------- | ------------------------------------------------------------- | | Changed | Repos with dirty worktrees or ahead/behind upstream | | Other | Tracked repos with a clean worktree and no ahead/behind drift | The status bar shows when the last poll ran, how many repos changed, and how many have a stale `.git/index.lock` file. Repos with a lock file show a lock icon in the list. ## Keyboard [Section titled “Keyboard”](#keyboard) | Key | Action | | --------------- | ------------------------------------------------------- | | ↑ / ↓ | Navigate the active pane | | Tab | Switch between Changed and Other | | Enter | Open lazygit in the selected repo (suspends the TUI) | | `e` | Open the repo in your default editor | | `E` | Open the repo in your visual editor | | `o` | Open an interactive OpenCode session | | `O` | Open an OpenCode plan session | | `t` | Open a terminal in the repo directory | | `w` | Open the repo on GitHub in the browser | | `x` | Remove a stale `.git/index.lock` from the selected repo | | `r` | Refresh immediately | | Esc / Backspace | Return to the main menu | Repo pulls and fetches are not available from this view; use `dot update` or work inside the repo directly. ## Index locks [Section titled “Index locks”](#index-locks) Status scans run `git --no-optional-locks status` so background polling does not refresh the index or compete with an in-flight rebase, merge, or other index-writing operation. That keeps bar modules and the TUI from creating or waiting on `.git/index.lock` during normal reads. When a crashed git process leaves a stale lock behind, the repo appears with a lock indicator. Press `x` on the selected repo to remove the lock file and trigger a refresh. Only remove a lock when no git command is actively running in that repository. ## Upstream fetches [Section titled “Upstream fetches”](#upstream-fetches) When a repo has an upstream configured, `dot git-diff` fetches the tracking branch before computing ahead/behind counts. Fetches are TTL-cached (default five minutes, controlled by `DOT_FETCH_TTL_SECONDS`). Pass `--no-fetch` to skip network fetches and rely on local tracking refs. ## Status bar module [Section titled “Status bar module”](#status-bar-module) A status bar module polls `dot git-diff --bar-json` through its own short-lived cache; left click opens the TUI and right click refreshes the cache. See [Bar Integrations](/bar-integrations/) for the shared JSON contract. ## Configuration [Section titled “Configuration”](#configuration) Which repos appear and whether Omarchy repos are included is controlled by the private `dot-git.yml` config and `DOT_INCLUDE_OMARCHY_DIFF_REPOS`. See [Private Git Config](/configuration/private-git/) and [Environment Variables](/configuration/environment/#git-and-github). # Notifications > The GitHub notification inbox with read, done, ignore, and bot-read actions. ## `dot git-notifications` [Section titled “dot git-notifications”](#dot-git-notifications) The authenticated user’s GitHub notification inbox. Without machine or action flags it opens the interactive TUI with open, mark-read, done, ignore, unignore, and bot-read actions. ```bash dot git-notifications # interactive TUI dot git-notifications --raw # text summary of notification threads dot git-notifications --bar-json # JSON for status bars and shell modules dot git-notifications --list-threads # notification threads as rows dot git-notifications --participating # only participating or mentioned threads dot git-notifications --all # include read notifications ``` ### Actions [Section titled “Actions”](#actions) ```bash dot git-notifications --mark-read # mark a thread read dot git-notifications --mark-done # mark a thread done dot git-notifications --ignore # ignore new notifications for a thread dot git-notifications --unignore # stop ignoring a thread ``` ### Bot notifications [Section titled “Bot notifications”](#bot-notifications) ```bash dot git-notifications --mark-bot-read --dry-run # preview matched bot threads dot git-notifications --mark-bot-read # mark Renovate/Dependabot/bot threads read ``` Use `--dry-run` first to preview the threads that would be marked. ## Requirements [Section titled “Requirements”](#requirements) The notification API requires `gh` authenticated with a classic token carrying the `notifications` or `repo` scope. ## Status bar module [Section titled “Status bar module”](#status-bar-module) A status bar module refreshes `dot git-notifications --bar-json` through its own short-lived cache. Notification surfaces hide repos that are not enabled in `dot-git.yml`, while upstream notifications can match a managed fork’s `remote.upstream.url`. Left click opens `dot git-notifications --bar-filter`; right click refreshes the cache. `dot doctor` verifies GitHub notification API access plus the active notification module wiring. # Workflow Runs > Watched GitHub Actions runs for each repo's locally checked-out HEAD commit. ## `dot git-workflows` [Section titled “dot git-workflows”](#dot-git-workflows) A two-pane view of watched GitHub workflow runs. The left pane lists watched repositories from the private repo list; the right pane lists runs for the selected repo’s locally checked-out HEAD commit. Disabled workflows are hidden. ```bash dot git-workflows # interactive TUI dot git-workflows --raw # text summary of watched workflow runs dot git-workflows --bar-json # JSON for status bars and shell modules dot git-workflows --list-repos # watched repo summaries as rows dot git-workflows --list-runs # workflow runs as rows dot git-workflows --since # only runs active at or after this date ``` The `--since` filter accepts ISO/RFC/epoch dates and relative values such as `1h` or `1 hour ago`. For status bars, combine `--bar-json` with `--since`: ```bash dot git-workflows --bar-json --since "$(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%SZ)" ``` ## Status bar module [Section titled “Status bar module”](#status-bar-module) A status bar module refreshes `dot git-workflows --bar-json --since ` through its own short-lived cache; left click opens the filtered TUI and right click refreshes the cache. `dot doctor` verifies `dot-git.yml`, the active workflow-runs module wiring, and the absence of legacy `git-workflow-watch` leftovers. # Knowledge Base > Practical setup notes for system customisations and one-off fixes. This section collects practical runbooks that sit below the main dotfiles reference. They are for system state that is useful to repeat, but too specific for the core command docs. [FIDO2 Security Key Auth](/knowledge-base/fido2-security-key-auth/)Set up Omarchy FIDO2 auth for sudo, polkit, and Hyprlock with touch-first daily prompts. [Workspace Setup](/knowledge-base/workspace-setup/)Rebuild the desktop host's work and non-work workspace layout. [Workspace Relayout](/knowledge-base/workspace-relayout/)Apply and capture ratio-based Hyprland layouts for the active workspace. [Workspace Session Recovery](/knowledge-base/workspace-session-recovery/)Capture and restore Hyprland window sessions after restarts, crashes, or layout experiments. [Work Browser Launchers](/knowledge-base/work-browser-launchers/)Launch work Chrome, Slack, and Discord into predictable Hyprland workspaces. [URL Routing and Webapps](/knowledge-base/url-routing-webapps/)Route matching URLs to Omarchy webapps while keeping the normal browser fallback. [Hyprsunset Dimming](/knowledge-base/hyprsunset-dimming/)Use gamma-only dimming on the laptop without changing colour temperature. [Doorbell Popup](/knowledge-base/doorbell-popup/)Open a Home Assistant camera popup from a doorbell or motion entity. [Twitch Desktop Tools](/knowledge-base/twitch-desktop-tools/)Use the Twitch menu, channel picker, and notification recovery scripts. [Resume Recovery](/knowledge-base/resume-recovery/)Refresh Waybar, git caches, Twitch notifications, and update prompts after suspend. [System Health Triage](/knowledge-base/system-health-triage/)Collect a short health report for freezes, slowdowns, thermal issues, and noisy logs. [Desktop Command Wrappers](/knowledge-base/desktop-command-wrappers/)Small helper scripts for terminal launches, notifications, loading overlays, and workspace placement. [GitHub Dotenv Secrets](/knowledge-base/github-dotenv-secrets/)Import simple .env keys into GitHub Actions repository secrets with gh. # Desktop Command Wrappers > Small helper scripts for terminal launches, notifications, loading overlays, and workspace placement. These wrappers make other scripts and Hypr bindings friendlier on the desktop. They are intentionally small, but they are useful when composing menu actions or one-shot helpers. ## Run a command in a terminal [Section titled “Run a command in a terminal”](#run-a-command-in-a-terminal) `run-in-terminal` opens a command in a new terminal window: ```bash run-in-terminal 'dot doctor' ``` Modes: | Mode | Behaviour | | --------- | ------------------------------------------------------------------------------------ | | `--shell` | Default. Run the command, then stay in an interactive shell. | | `--wait` | Run the command, then print a prompt saying Ctrl-D closes or the shell can continue. | | `--exit` | Run the command and close the terminal when it exits. | Examples: ```bash run-in-terminal --wait 'workspace-restore --dry-run' run-in-terminal --exit 'dot doctor' ``` For `--shell` and `--wait`, the wrapper creates a temporary `ZDOTDIR` so the command runs after shell initialisation, then removes that temp directory from the generated shell startup file. ## Notify around a command [Section titled “Notify around a command”](#notify-around-a-command) `run-with-notify` runs a command and sends a desktop notification with the result: ```bash run-with-notify 'Capture' workspace-capture run-with-notify -a 'Workspace' 'Restore' workspace-restore ``` On success, the notification body is command output or `Done`. On failure, it sends a critical notification with the captured stderr/stdout or `Unknown error`. Both use Omarchy’s glyph and spacing format. ## Loading overlay [Section titled “Loading overlay”](#loading-overlay) `popup-loading` shows a singleton GTK layer-shell loading overlay on the focused Hyprland monitor: ```bash popup-loading show 'Updating...' popup-loading hide ``` Calling it with only a message also shows the overlay: ```bash popup-loading 'Loading dashboard...' ``` The overlay keeps a runtime socket and lock under `${XDG_RUNTIME_DIR:-/tmp}`: ```text popup-loading.sock popup-loading.lock ``` It reads theme colours from: ```text ~/.config/omarchy/current/theme/colors.toml ``` If theme colours are unavailable, it falls back to a dark default. ## Wrap a command with the loading overlay [Section titled “Wrap a command with the loading overlay”](#wrap-a-command-with-the-loading-overlay) `with-popup-loading` shows the overlay, runs the command, then hides the overlay on exit: ```bash with-popup-loading 'Updating dotfiles...' dot update ``` If no command is passed, it only shows the overlay and lets the shell trap hide it when the wrapper exits. ## Launch on a workspace [Section titled “Launch on a workspace”](#launch-on-a-workspace) `launch-on-workspace` starts a command, waits for a new Hyprland client matching a class regex, then moves that new window to the target workspace: ```bash launch-on-workspace 3 '^(work-browser|google-chrome)$' 'uwsm app -- google-chrome-stable --new-window' ``` It compares matching client addresses before and after launch. Only a newly detected address is moved. This helper is used by the work browser launchers documented in [Work Browser Launchers](/knowledge-base/work-browser-launchers/). ## Troubleshooting [Section titled “Troubleshooting”](#troubleshooting) If `run-in-terminal --exit` closes too quickly, use `--wait` while debugging. If `popup-loading` fails to show, check that the session supports GTK4 layer shell and that `hyprctl -j monitors` works. If `launch-on-workspace` launches the app but does not move it, the class regex probably does not match the final Hyprland class. Inspect clients with: ```bash hyprctl -j clients ``` # Doorbell Popup > Open a Home Assistant camera popup from a doorbell or motion entity. `doorbell-popup` opens a Home Assistant more-info camera popup as an Omarchy webapp and positions it as a floating Hyprland window. It can run once, or watch a Home Assistant entity and open the popup when that entity turns on. ## Host bindings [Section titled “Host bindings”](#host-bindings) Both public host overrides expose a permanent open-only popup on: ```text SUPER+ALT+C ``` The desktop host opens on monitor `DP-1` with the default camera and a larger popup. The laptop host opens on monitor `eDP-1`, sets `camera.front_door_snapshot`, and uses a smaller popup size. ## Defaults [Section titled “Defaults”](#defaults) The script defaults to: | Setting | Default | | ------------------ | --------------------------------- | | Motion entity | `input_boolean.doorbell` | | Camera entity | `camera.front_door_snapshot` | | Home Assistant URL | `http://homeassistant.local:8123` | | Target workspace | `1` | | Size | `640x640` | | Duration | `20` seconds | The popup URL is built as: ```text /lovelace/home?more-info-entity-id= ``` ## Open once [Section titled “Open once”](#open-once) Open the popup and exit: ```bash doorbell-popup --open-only ``` Keep it open instead of scheduling the auto-close timer: ```bash doorbell-popup --open-only --no-auto-close ``` Focus the popup after opening or repositioning: ```bash doorbell-popup --open-only --focus-popup ``` ## Watch mode [Section titled “Watch mode”](#watch-mode) Run without `--open-only` to watch the motion entity: ```bash doorbell-popup ``` Watch mode uses: ```bash go-automate ha bridge watch entity --bar-json --icon '' input_boolean.doorbell ``` When the emitted JSON has class `on`, the popup opens or repositions. ## Positioning [Section titled “Positioning”](#positioning) `doorbell-popup` chooses a monitor in this order: * The explicit `--monitor ` if present and found. * The monitor that owns the target workspace. * The currently focused monitor. Hyprland reports monitor geometry in raw pixels while `movewindowpixel` and `resizewindowpixel` use logical coordinates, so the script divides by monitor scale before positioning. It also accounts for reserved monitor areas. ## Useful overrides [Section titled “Useful overrides”](#useful-overrides) ```bash doorbell-popup --open-only --monitor DP-1 --width 640 --height 640 doorbell-popup --entity input_boolean.doorbell --camera-entity camera.front_door_snapshot doorbell-popup --base-url http://homeassistant.local:8123 --workspace 1 doorbell-popup --duration 30 --margin 20 --bottom-margin 12 ``` Numeric values must be positive integers. ## Test without a real event [Section titled “Test without a real event”](#test-without-a-real-event) Simulate one on event: ```bash doorbell-popup --simulate-event on --simulate-exit ``` Force the startup simulation path: ```bash doorbell-popup --force-motion-true --simulate-exit ``` ## State [Section titled “State”](#state) The script stores the last popup address at: ```text ${XDG_RUNTIME_DIR:-/tmp}/doorbell-popup.address ``` If that address still exists, the script repositions the existing popup instead of opening a duplicate. If the address is stale, it removes the file. ## Recovery flow [Section titled “Recovery flow”](#recovery-flow) 1. Test with `doorbell-popup --open-only` first. 2. Add `--monitor`, `--width`, and `--height` until placement is right. 3. Test the event path with `--simulate-event on --simulate-exit`. 4. Run watch mode only after the open-once path works. ## Troubleshooting [Section titled “Troubleshooting”](#troubleshooting) If the script exits immediately, check required commands: ```bash command -v go-automate hyprctl jq omarchy-launch-webapp ``` If placement is on the wrong monitor, pass `--monitor ` and verify monitor names with: ```bash hyprctl -j monitors ``` If no event opens the popup, check the entity stream directly: ```bash go-automate ha bridge watch entity --bar-json --icon '' input_boolean.doorbell ``` If the popup keeps reusing a dead address, remove the runtime file: ```bash rm -f "${XDG_RUNTIME_DIR:-/tmp}/doorbell-popup.address" ``` # FIDO2 Security Key Auth > Set up Omarchy FIDO2 authentication for sudo, polkit, and Hyprlock with touch-first daily prompts. This setup uses a FIDO2 security key through `pam-u2f`. The key becomes the preferred local authentication path for `sudo`, polkit prompts, and Hyprlock, while the account password stays available as fallback. The daily path is touch-only. Do not add `pinverification=1` unless you want the security-key PIN on every `sudo`, `pkexec`, and Hyprlock authentication. It does not change LUKS disk decryption. Boot still uses the LUKS passphrase unless a separate LUKS token setup is configured. Keep a fallback Keep an unlocked terminal open while editing PAM files. Do not remove the password fallback unless you have a separate recovery path. ## Start with the Omarchy menu [Section titled “Start with the Omarchy menu”](#start-with-the-omarchy-menu) Use Omarchy’s built-in FIDO2 setup first: 1. Open the Omarchy menu. 2. Go to **Setup**. 3. Go to **Security**. 4. Choose **Fido2**. 5. Touch the security key when prompted. 6. Let the script test `sudo` before closing the terminal. The setup installs `libfido2` and `pam-u2f`, registers the key with `pamu2fcfg`, stores the mapping at `/etc/fido2/fido2`, and adds `pam_u2f.so` to `sudo` and `polkit-1`. The default Omarchy setup is touch-based. Keep that behaviour for daily use, then add Hyprlock manually. ## Confirm sudo and polkit [Section titled “Confirm sudo and polkit”](#confirm-sudo-and-polkit) Use this touch-only line in `/etc/pam.d/sudo` and `/etc/pam.d/polkit-1`: ```text auth sufficient pam_u2f.so cue [cue_prompt=Touch your security key] authfile=/etc/fido2/fido2 ``` Keep the existing password lines below it. With `sufficient`, a successful security-key auth skips the password prompt; failure falls through to the password fallback. ## Add Hyprlock [Section titled “Add Hyprlock”](#add-hyprlock) Hyprlock uses its own PAM service. Omarchy’s FIDO2 setup does not add this line automatically, so prepend it to `/etc/pam.d/hyprlock`: ```text auth sufficient pam_u2f.so cue [cue_prompt=Touch your security key] authfile=/etc/fido2/fido2 ``` Leave the default `auth include login` line below it so the normal password unlock still works. ## Update the lock-screen prompt [Section titled “Update the lock-screen prompt”](#update-the-lock-screen-prompt) Hyprlock config is stowed from the dotfiles repo. Edit the active host source, not Omarchy’s upstream config directory: ```text ~/.config/dotfiles/hypr/.config/hypr/hosts//hyprlock.conf ``` Use generic security-key wording so the config works with non-Yubico keys too: ```ini input-field { placeholder_text = Touch Security Key or Type Password check_text = Touch your security key } ``` If the fingerprint setup script was run on a machine without a fingerprint reader, disable Hyprlock fingerprint auth in the same file: ```ini auth { fingerprint:enabled = false } ``` Apply the stowed config: ```bash dot stow hyprctl configerrors ``` ## Remove fingerprint leftovers [Section titled “Remove fingerprint leftovers”](#remove-fingerprint-leftovers) If Omarchy’s fingerprint setup was run by mistake, remove its PAM lines and packages: ```bash pkexec sed -i '/pam_fprintd\.so/d' /etc/pam.d/sudo /etc/pam.d/polkit-1 pkexec pacman -Rns fprintd libfprint-git ``` Keep `fingerprint:enabled = false` in the stowed Hyprlock config. ## PIN mode [Section titled “PIN mode”](#pin-mode) `pinverification=1` is stricter, but `pam-u2f` prompts for the security-key PIN on every PAM authentication. It does not cache the PIN for the whole login session. Use PIN mode only if that tradeoff is intentional: ```text auth sufficient pam_u2f.so cue [cue_prompt=Touch your security key] pinverification=1 authfile=/etc/fido2/fido2 ``` ## Test order [Section titled “Test order”](#test-order) Test each layer before relying on it: 1. Run `sudo -k`, then `sudo true`. 2. Touch the security key when prompted. 3. Trigger a polkit prompt if convenient. 4. Lock the screen with Hyprlock while another session or terminal remains available. 5. Test password fallback by trying without the security key. ## Rollback [Section titled “Rollback”](#rollback) Restore the backed-up PAM files, or remove only the added `pam_u2f.so` line from `/etc/pam.d/hyprlock` if the lock screen is the only broken part. Do not delete `/etc/fido2/fido2` unless you are fully removing FIDO2 auth. # GitHub Dotenv Secrets > Import simple .env keys into GitHub Actions repository secrets with gh. `gh-import-dotenv-to-secrets` is a small helper for copying simple `.env` entries into GitHub Actions repository secrets. Use it only in the repository that should receive the secrets. It has no dry-run mode and `gh secret set` overwrites secrets with matching names. Read the file first Inspect `.env` before running this helper. Do not use it on untrusted files or in the wrong repository. ## Input format [Section titled “Input format”](#input-format) The script reads `.env` from the current directory: ```text KEY=value QUOTED="value" SINGLE_QUOTED='value' ``` It skips empty keys and lines whose key starts with `#`. For each remaining line, it strips one leading and trailing single or double quote from the value, then runs: ```bash gh secret set "$key" -b"$value_no_quotes" ``` ## Run it [Section titled “Run it”](#run-it) From the target GitHub repository: ```bash gh auth status gh repo view --json nameWithOwner gh-import-dotenv-to-secrets ``` Verify the resulting secret names: ```bash gh secret list ``` ## What it is not [Section titled “What it is not”](#what-it-is-not) This helper is not a full dotenv parser. Avoid using it for: * Multiline values. * `export KEY=value` syntax. * Values containing unescaped `=` that need exact dotenv parsing semantics. * Environment or organisation secrets. * Selective import. For those cases, use `gh secret set` directly. ## Safer manual alternative [Section titled “Safer manual alternative”](#safer-manual-alternative) For one or two secrets, prefer setting them explicitly: ```bash gh secret set MY_SECRET -b"$MY_SECRET" ``` That keeps the target secret name and value source obvious. ## Troubleshooting [Section titled “Troubleshooting”](#troubleshooting) If the command writes to the wrong repository, stop and rotate or replace the affected secrets in GitHub. Then rerun from the correct repository. If a value imports with quotes still attached, set that secret manually with `gh secret set`. This wrapper only strips a simple matching quote at the beginning and end. If `gh secret set` fails, check GitHub authentication and repository permissions: ```bash gh auth status gh repo view --json nameWithOwner ``` # Hyprsunset Dimming > Use gamma-only dimming on the laptop without changing colour temperature. The laptop host has a gamma-only dimming layer built around `hyprsunset`. It is separate from normal panel brightness and does not enable a warm night-light profile by default. Use it when the display is still too bright at low hardware brightness, especially in a dark room. ## Host scope [Section titled “Host scope”](#host-scope) The dimming key bindings are in the laptop host override: ```text ~/.config/hypr/host/bindings.conf ``` The public source is: ```text ~/.config/dotfiles/hypr/.config/hypr/hosts/laptop/bindings.conf ``` The shared and desktop `hyprsunset.conf` keep an identity profile so `hyprsunset` does nothing to the screen unless a helper changes gamma. ## Controls [Section titled “Controls”](#controls) | Binding | Action | | --------------------- | ---------------------------------------------- | | `SUPER+CTRL+D` | Toggle dim mode. | | `SUPER+CTRL+-` | Dim down. | | `SUPER+CTRL+=` | Dim up. | | `CTRL+BrightnessDown` | Dim down. | | `CTRL+BrightnessUp` | Dim up. | | `BrightnessDown` | Clear dimming, then lower hardware brightness. | | `BrightnessUp` | Clear dimming, then raise hardware brightness. | Normal brightness keys clear dim mode first so a screen is not accidentally left gamma-dimmed after increasing hardware brightness. ## State files [Section titled “State files”](#state-files) The helper scripts keep state under: ```text ~/.config/hypr/.state/ ``` | File | Meaning | | ------------------------ | --------------------------------------- | | `hyprsunset-dim-enabled` | Present when dim mode is active. | | `hyprsunset-dim-level` | Last gamma level written by the helper. | The default toggle level is `50`. Dim steps move by `5`, clamped between `5` and `100`. ## Commands [Section titled “Commands”](#commands) Toggle dim mode: ```bash ~/.config/hypr/bin/hyprsunset-toggle-dim ``` Dim down or up: ```bash ~/.config/hypr/bin/hyprsunset-dim-step down ~/.config/hypr/bin/hyprsunset-dim-step up ``` Clear dim mode: ```bash ~/.config/hypr/bin/hyprsunset-clear-dim ``` Each helper starts `hyprsunset` with the active host config if it is not already running. ## Check current state [Section titled “Check current state”](#check-current-state) ```bash pgrep -x hyprsunset hyprctl hyprsunset gamma ls ~/.config/hypr/.state ``` If `hyprctl hyprsunset gamma` reports `100`, dim mode is effectively off. ## Troubleshooting [Section titled “Troubleshooting”](#troubleshooting) If the keys do nothing, confirm the active host is `laptop` and the host symlink points at the laptop overrides. See [Host Overrides](/omarchy/host-overrides/). If dim mode gets stuck, clear it explicitly: ```bash ~/.config/hypr/bin/hyprsunset-clear-dim ``` If `hyprsunset` is not running after login, check the laptop autostart override. It starts: ```text uwsm app -- hyprsunset --config ~/.config/hypr/host/hyprsunset.conf ``` ## Night-light profiles [Section titled “Night-light profiles”](#night-light-profiles) The laptop host config includes commented examples for temperature or scheduled gamma profiles, but they are not active. Keep them commented unless you want automatic colour or gamma changes in addition to the manual dim controls. # Resume Recovery > Refresh Waybar, git caches, Twitch notifications, and update prompts after suspend. `on-resume` is the post-suspend recovery hook used by the Hypr host overrides. It restarts small desktop services that tend to go stale after sleep, refreshes git-related bar caches, and optionally opens a dotfiles update prompt. ## Where it runs [Section titled “Where it runs”](#where-it-runs) Both desktop and laptop host `hypridle.conf` files call `on-resume` from `after_sleep_cmd` after waking the display: ```text after_sleep_cmd = sleep 1 && omarchy-system-wake && on-resume ``` The laptop host also re-arms keyboard backlight handling before `on-resume`. You can run the recovery manually with the shared binding: ```text SUPER+SHIFT+W ``` Or from a terminal: ```bash on-resume ``` ## What it refreshes [Section titled “What it refreshes”](#what-it-refreshes) `on-resume` detaches itself, writes a fresh log, then: * Stops `twitch-notifications`. * Clears Waybar git module cache files under `${XDG_CACHE_HOME:-~/.cache}/waybar`. * Clears the dot upstream fetch cache under `${XDG_CACHE_HOME:-~/.cache}/dot/fetch-upstream`. * Restarts Waybar through `uwsm-app`. * Restarts `twitch-notifications` after a short delay. * Runs `on-resume-update-prompt --launch` unless the caller passed `--post-update`. The log is written to: ```text ${XDG_STATE_HOME:-~/.local/state}/on-resume.log ``` ## Update prompt [Section titled “Update prompt”](#update-prompt) `on-resume-update-prompt --launch` runs a bounded update check: ```bash dot update --check ``` When core or system repos are behind, it opens a floating terminal running: ```bash on-resume-update-prompt --interactive ``` The interactive prompt shows the behind repos, asks before running `dot update`, and leaves the terminal open afterwards. When everything is current, it sends a low-urgency desktop notification instead. ## Manual recovery flow [Section titled “Manual recovery flow”](#manual-recovery-flow) Use this when the machine wakes but the bar or desktop helpers look stale: 1. Press `SUPER+SHIFT+W`, or run `on-resume`. 2. Wait for Waybar to disappear and return. 3. Check for the update prompt or up-to-date notification. 4. If something still looks wrong, read `~/.local/state/on-resume.log`. ## Avoid duplicate prompts after updates [Section titled “Avoid duplicate prompts after updates”](#avoid-duplicate-prompts-after-updates) Every `dot update` mode that reaches the end triggers a post-update refresh. That path calls: ```bash on-resume --post-update ``` The `--post-update` flag skips the update prompt so a successful update does not immediately ask to update again. ## Troubleshooting [Section titled “Troubleshooting”](#troubleshooting) If Waybar does not return, run it directly to surface errors: ```bash uwsm-app -- waybar ``` If git status in the bar stays stale, remove the caches and run recovery again: ```bash rm -f ~/.cache/waybar/git-*-waybar.json ~/.cache/waybar/git-*-waybar.json.tmp rm -rf ~/.cache/dot/fetch-upstream on-resume ``` If the update prompt never appears, run the launcher directly: ```bash on-resume-update-prompt --launch ``` The launcher stays silent for update-check errors so resume is never blocked. # System Health Triage > Collect a short health report for freezes, slowdowns, thermal issues, and noisy logs. Use `system-health-check` when the machine feels slow, hot, network-stuck, or unstable and you want one report to inspect before guessing. The command samples system signals, scans recent logs for known failure words, prints a friendly verdict, and saves the full output to a timestamped report. For the reference summary of utility commands, see [System Utilities](/dot/utilities/). ## Quick run [Section titled “Quick run”](#quick-run) ```bash system-health-check ``` Reports are saved under: ```text ${XDG_STATE_HOME:-~/.local/state}/system-health-check/ ``` The default run collects five snapshots, fifteen seconds apart, and scans the last fifteen minutes of user and kernel journal logs. ## Faster focused checks [Section titled “Faster focused checks”](#faster-focused-checks) Run only the sections you need: ```bash system-health-check --only cpu,memory,psi --samples 3 --interval 5 system-health-check --only thermal --samples 4 --interval 10 system-health-check --only logs --known-logs-minutes 60 ``` Valid sections are: | Section | What it checks | | --------- | --------------------------------------------------------------------- | | `cpu` | Load average and CPU busy percentage. | | `memory` | Available memory and swap growth. | | `psi` | Linux pressure stall information for CPU, memory, and IO. | | `network` | Primary interface traffic and TCP socket growth. | | `disk` | Root filesystem usage. | | `thermal` | Thermal zone readings and temperature rise. | | `logs` | Recent user and kernel journal lines matching known failure patterns. | ## OpenCode handoff [Section titled “OpenCode handoff”](#opencode-handoff) When you want immediate AI follow-up, run: ```bash system-health-check --open-opencode ``` After saving the report, the script opens an interactive OpenCode session with a prompt that points to the report path. Use this when you want diagnosis and next steps in the same flow. Without an interactive TTY, the script prints a warning instead of trying to open OpenCode. ## Triage flow [Section titled “Triage flow”](#triage-flow) 1. Run `system-health-check` while the problem is happening or soon after it happens. 2. Read the `Friendly Summary` section first. 3. Treat `Watch` as a signal to monitor and `Stressed` as a signal to investigate immediately. 4. Use the report path from the final line for follow-up analysis. 5. If the problem is narrow, rerun with `--only` for that subsystem. ## Interpreting the verdict [Section titled “Interpreting the verdict”](#interpreting-the-verdict) `Healthy` means the sampled window looked stable. `Watch` means one or more signals crossed a moderate threshold, such as elevated CPU pressure, noticeable memory drop, high disk usage, thermal rise, or noisy logs. `Stressed` means at least one stronger threshold was crossed, such as very high CPU busy, sharp swap growth, high PSI, critical disk usage, high thermal readings, or many known log matches. These are heuristics, not proof of root cause. Use them to decide where to inspect next. ## Login doctor notification [Section titled “Login doctor notification”](#login-doctor-notification) The repo also ships a user timer for a delayed `dot doctor` check at login: ```text ~/.config/systemd/user/dot-doctor-startup.timer ~/.config/systemd/user/dot-doctor-startup.service ``` The timer runs `dot-doctor-notify` sixty seconds after startup. Use it as a passive startup check; run `dot doctor` directly when you need an immediate health result. Enable it if you want a startup warning for broken dotfiles state: ```bash systemctl --user enable --now dot-doctor-startup.timer ``` ## Related update checks [Section titled “Related update checks”](#related-update-checks) For broader machine updates, use the `topgrade` wrapper documented in [System Utilities](/dot/utilities/). It logs the full session to: ```text ${XDG_STATE_HOME:-~/.local/state}/topgrade.log ``` Keep health triage and update runs separate: collect a health report first when debugging instability, then update once you know whether the machine is already under stress. # Twitch Desktop Tools > Use the Twitch menu, channel picker, and notification recovery scripts. The Twitch scripts wrap `twitch-notifications` with a Walker menu, channel picker, and detached restart/recheck helpers. ## Autostart [Section titled “Autostart”](#autostart) The shared Hyprland autostart starts Twitch notifications for both desktop and laptop in UWSM’s background graphical slice: ```bash uwsm-app -s b -- twitch-notifications ``` The shared resume hook also restarts Twitch notifications after suspend. See [Resume Recovery](/knowledge-base/resume-recovery/). ## Bindings [Section titled “Bindings”](#bindings) | Binding | Action | | ------------------ | ------------------------------------------------ | | `CTRL+ALT+T` | Open the main Twitch menu. | | `CTRL+ALT+SHIFT+T` | Open the channel picker directly. | | `SUPER+ALT+T` | Open the Twitch following live page as a webapp. | ## Main menu [Section titled “Main menu”](#main-menu) Run the menu directly: ```bash twitch-menu ``` The menu offers: * Recheck notifications. * Restart notifications. * Open following. * Open following live. * Open channel picker. On the `desktop` host, URL opening prefers `xdg-open` when available. Other hosts use `omarchy-launch-webapp`. ## Channel picker [Section titled “Channel picker”](#channel-picker) Open the channel picker directly: ```bash twitch-menu channels ``` The picker reads configured channels from: ```text ${XDG_CONFIG_HOME:-~/.config}/twitch-notifications/channels.yml ``` It checks live state with: ```bash twitch-notifications --status-bar-json ``` Live channels are shown before offline channels. Picking an offline channel opens its archives page: ```text https://twitch.tv//videos?filter=archives&sort=time ``` The **Open all live autolaunch** action runs: ```bash twitch-notifications --recheck --open ``` ## Recheck notifications [Section titled “Recheck notifications”](#recheck-notifications) ```bash twitch-notifications-recheck ``` The helper detaches from the caller. If `twitch-notifications --status` reports `active`, it runs `twitch-notifications --recheck`. Otherwise it falls back to the restart helper. ## Restart notifications [Section titled “Restart notifications”](#restart-notifications) ```bash twitch-notifications-restart ``` The helper detaches, stops matching `twitch-notifications` processes, waits one second, then relaunches through: ```bash uwsm-app -s b -- twitch-notifications ``` ## Troubleshooting [Section titled “Troubleshooting”](#troubleshooting) If the channel menu is empty, check that the channels file exists and contains `- name: ...` entries: ```bash ls ~/.config/twitch-notifications/channels.yml ``` If live state looks stale, run: ```bash twitch-notifications-recheck ``` If the process is wedged, run: ```bash twitch-notifications-restart ``` If the menu opens but choosing a channel does nothing, test the launcher path directly: ```bash twitch-menu channels omarchy-launch-webapp https://twitch.tv/directory/following/live ``` # URL Routing and Webapps > Route matching URLs to Omarchy webapps while keeping the normal browser fallback. The custom URL handler makes `http` and `https` links choose between two launch paths: * Matching URLs open as standalone Omarchy webapps. * Everything else opens in Chromium as a normal browser tab or window. This keeps common app-like sites in dedicated windows without making every link a webapp. ## Files [Section titled “Files”](#files) The handler is part of the stowed Hypr package: | Path | Purpose | | -------------------------------------------------------- | ---------------------------------------- | | `~/.config/hypr/bin/timmo-url-handler` | Runtime URL router. | | `~/.config/hypr/bin/timmo-setup-url-handler` | Idempotent install/remove helper. | | `~/.config/hypr/url-handler/patterns.conf` | Routing rules. | | `~/.config/hypr/url-handler/omarchy-url-handler.desktop` | Desktop entry used by xdg mime handling. | Edit the source files in the dotfiles repo, then run `dot stow`: ```text ~/.config/dotfiles/hypr/.config/hypr/ ``` ## Install the handler [Section titled “Install the handler”](#install-the-handler) Run the setup helper after the Hypr package is stowed and `~/.config/hypr/bin` is on `PATH`: ```bash timmo-setup-url-handler ``` The setup helper: * Creates or updates the desktop file. * Symlinks it into `~/.local/share/applications/`. * Sets it as the default handler for `http`, `https`, `about`, and `unknown` schemes in `~/.config/mimeapps.list`. * Backs up `mimeapps.list` before changing it. * Runs `update-desktop-database` when that command is available. ## Pattern rules [Section titled “Pattern rules”](#pattern-rules) Rules live in: ```text ~/.config/hypr/url-handler/patterns.conf ``` Each non-comment line starts with an action and a glob pattern: ```text webapp:discord.com webapp:*.youtube.com browser:*.gitlab.com ``` Patterns are checked against both the full URL and the extracted domain. The first matching rule wins. If nothing matches, the default action is `browser`. ## Add a webapp route [Section titled “Add a webapp route”](#add-a-webapp-route) 1. Edit `~/.config/dotfiles/hypr/.config/hypr/url-handler/patterns.conf`. 2. Add a `webapp:` line above any broader browser rule. 3. Run `dot stow`. 4. Test with `timmo-url-handler `. Example: ```text webapp:calendar.google.com webapp:*.calendar.google.com ``` ## Force a normal browser route [Section titled “Force a normal browser route”](#force-a-normal-browser-route) Use `browser:` when a site should not become a webapp: ```text browser:gitlab.com browser:*.gitlab.com ``` Browser routes launch Chromium directly through `uwsm-app` so the default handler does not recurse back into itself. ## Test routing [Section titled “Test routing”](#test-routing) Run the handler directly: ```bash timmo-url-handler https://github.com timmo-url-handler https://gitlab.com ``` To check the desktop default: ```bash xdg-mime query default x-scheme-handler/https ``` Expected output: ```text omarchy-url-handler.desktop ``` ## Remove the handler [Section titled “Remove the handler”](#remove-the-handler) ```bash timmo-setup-url-handler remove ``` The remove path deletes the applications symlink and desktop file. If the setup backup exists, it restores `~/.config/mimeapps.list` from that backup. If no backup exists, clean up `mimeapps.list` manually. ## Troubleshooting [Section titled “Troubleshooting”](#troubleshooting) If the setup script cannot find `timmo-url-handler`, check that the Hypr bin directory is on `PATH` and run `dot stow` again. If a URL opens in the browser when it should be a webapp, put the more specific `webapp:` rule before broader `browser:` rules and test the exact URL with `timmo-url-handler`. If every browser launch loops, check that the `browser` branch still launches `/usr/bin/chromium` directly rather than calling `xdg-open`. # Work Browser Launchers > Launch work Chrome, Slack, and Discord into predictable Hyprland workspaces. The work launchers isolate a Google Chrome work profile and place work apps on known workspaces. They are used directly by Hypr bindings and indirectly by workspace setup/restore flows. ## Bindings [Section titled “Bindings”](#bindings) | Binding | Action | | --------------- | -------------------- | | `SUPER+ALT+B` | Launch work browser. | | `SUPER+SHIFT+S` | Launch Slack. | | `SUPER+D` | Launch Discord. | ## Work Chrome profile [Section titled “Work Chrome profile”](#work-chrome-profile) All three launchers use `google-chrome-stable` with the work profile data directory: ```text $HOME/.config/google-chrome-work ``` The shared Chrome flags include: ```text --ozone-platform=wayland --force-device-scale-factor=0.8 --profile-directory=Profile 1 ``` The work browser also sets: ```text --class=work-browser ``` ## Work browser [Section titled “Work browser”](#work-browser) Launch a new work browser window on workspace `3`: ```bash launch-work-browser ``` Open a URL in the work browser: ```bash launch-work-browser https://example.com ``` Open as a tab instead of using the workspace-placement helper: ```bash launch-work-browser --tab https://example.com ``` Window mode uses: ```bash launch-on-workspace 3 '^(work-browser|google-chrome)$' '' ``` ## Slack and Discord [Section titled “Slack and Discord”](#slack-and-discord) Slack launches as a Chrome app window on workspace `1`: ```bash launch-work-slack ``` Discord launches as a Chrome app window on workspace `1`: ```bash launch-work-discord ``` They match these Hyprland classes after launch: | App | Class regex | | ------- | --------------------------------- | | Slack | `^chrome-app\.slack\.com__client` | | Discord | `^chrome-discord\.com__app` | ## Relationship to workspace recovery [Section titled “Relationship to workspace recovery”](#relationship-to-workspace-recovery) `workspace-setup` uses equivalent commands for the work slots. `workspace-restore` also knows how to relaunch Slack, Discord, and the work browser from captured client classes. If a work app does not restore correctly, test the launcher directly before debugging restore logic. ## Troubleshooting [Section titled “Troubleshooting”](#troubleshooting) If a window launches but stays on the current workspace, inspect its class: ```bash hyprctl -j clients ``` If Chrome opens the wrong profile, check that no external launcher is overriding `--user-data-dir` and that the work profile directory exists: ```bash ls ~/.config/google-chrome-work ``` If `--tab` opens in an unexpected existing Chrome instance, use the default window mode instead. The `--tab` path does not use `launch-on-workspace`; it asks Hyprland to execute the Chrome command directly. # Workspace Relayout > Apply and capture ratio-based Hyprland layouts for the active workspace. `workspace-relayout` applies saved layout presets to the active Hyprland workspace. It works on tiled windows only, using ratio-based split trees instead of fixed pixels, so the same preset can fit different monitors, scales, gaps, and bars. Use it when a workspace has the right windows but the split tree is wrong. ## Key bindings [Section titled “Key bindings”](#key-bindings) The shared Hypr bindings are: | Binding | Action | | --------------- | ------------------------------------------------------------------ | | `SUPER+TAB` | Apply a saved layout preset for the active workspace window count. | | `SUPER+ALT+TAB` | Edit presets by capturing the current layout. | | `SUPER+ALT+W` | Open `workspace-menu`, which includes the relayout action. | ## Presets [Section titled “Presets”](#presets) Presets are stowed from the dotfiles repo to: ```text ~/.local/share/workspace-relayout/presets.json ``` They are grouped by tiled window count under `layouts.`. Each preset has a name and a generic split tree: ```json { "name": "1 top / 2 bottom", "tree": { "dir": "tb", "ratio": 75.4, "a": "w", "b": { "dir": "lr", "ratio": 40.67, "a": "w", "b": "w" } } } ``` The checked-in presets cover workspaces with two to five tiled windows. Preset names do not need to be unique: Walker appends a rounded ratio signature, such as `1 top / 4 bottom [76/24, 16/16/16/52]`, to distinguish variants. The script writes back through the stowed symlink when you edit presets, keeping the symlink in place. ## Apply a layout [Section titled “Apply a layout”](#apply-a-layout) 1. Focus the workspace to relayout. 2. Keep at least two tiled, mapped, non-hidden windows on that workspace. 3. Press `SUPER+TAB`. 4. Choose a preset from Walker. 5. Let the script move windows through the temporary workspace and rebuild the split tree. The script restores focus to the previously active window when it can. ## Capture a new preset [Section titled “Capture a new preset”](#capture-a-new-preset) Use edit mode when the current workspace already has the layout you want to save: ```bash workspace-relayout --edit ``` Or press: ```text SUPER+ALT+TAB ``` Edit mode reconstructs the current layout into a split tree. You can overwrite an existing preset for the same window count, or add a new one using the generated description or a custom name. ## Temporary workspace [Section titled “Temporary workspace”](#temporary-workspace) Relayout rebuilds the split tree by moving windows through a temporary workspace. The default temporary workspace is `99`. Override it only when workspace `99` is already used for something important: ```bash WORKSPACE_RELAYOUT_TEMP_WS=98 workspace-relayout ``` The temp workspace must be a positive numeric workspace id and must not match the active workspace. ## Requirements [Section titled “Requirements”](#requirements) `workspace-relayout` requires: * `hyprctl` * `jq` * `awk` * `omarchy-launch-walker` * The presets file at `~/.local/share/workspace-relayout/presets.json` If a requirement is missing, the script sends a desktop notification and exits. ## Troubleshooting [Section titled “Troubleshooting”](#troubleshooting) If the menu says there are no presets, the active workspace has a window count that is not present in `presets.json`. Use edit mode to save the current arrangement for that count. If the script says it needs at least two windows, make sure the windows are tiled. Floating windows are ignored. If a layout applies but the order feels wrong, rearrange the windows manually and save a preset in edit mode. The assignment logic keeps windows near their current target positions, but windows are still treated as interchangeable leaves. ## Reset [Section titled “Reset”](#reset) There is no persistent Hyprland state to reset. To recover from a bad relayout, use Hyprland’s normal move/split controls, apply another preset, or restore a saved workspace session from [Workspace Session Recovery](/knowledge-base/workspace-session-recovery/). # Workspace Session Recovery > Capture and restore Hyprland window sessions after restarts, crashes, or layout experiments. The workspace session scripts save the current Hyprland clients to JSON, then restore the latest capture by moving existing windows back to their saved workspaces and relaunching the supported missing apps. Use this before risky layout work, before restarting Hyprland, or when you want a quick recovery point for open workspaces. ## Capture a session [Section titled “Capture a session”](#capture-a-session) Capture every visible workspace: ```bash workspace-capture ``` Capture only the active workspace: ```bash workspace-capture --current-workspace ``` By default captures are written to: ```text ~/.local/state/workspace-sessions/workspace-.json ``` The script also writes a capture log to: ```text ~/.local/state/workspace-sessions/capture.log ``` To write a named capture: ```bash workspace-capture --output=~/workspace-before-restart.json ``` ## Restore safely [Section titled “Restore safely”](#restore-safely) Start with a dry run. It prints the restore plan without launching or moving windows: ```bash workspace-restore --dry-run ``` Restore the newest capture from the state directory: ```bash workspace-restore ``` Restore a specific file: ```bash workspace-restore --file=~/workspace-before-restart.json ``` Search a different state directory for the newest capture and write `restore.log` there: ```bash workspace-restore --state-dir=~/somewhere ``` The restore log is written to: ```text ~/.local/state/workspace-sessions/restore.log ``` ## What gets restored [Section titled “What gets restored”](#what-gets-restored) The restore script reads `hyprctl -j clients` and tries these paths in order: * Reuse a still-running window by saved address. * Match an existing window by class and workspace. * Launch a supported missing app, then move it to the saved workspace. * Restore floating geometry or tiled size when the saved client has enough geometry data. * Switch back to the saved active workspace at the end. Supported relaunch paths are encoded in `workspace-restore` and cover Chromium, work Chrome app windows, Slack, Discord, Twitch webapps, generic Chrome webapps with captured URLs, and Ghostty terminals. Ghostty launches through `ghostty-host-config` to keep the active `config.$OMARCHY_HOST` override, and passes `--working-directory` when the saved directory still exists. Captured browser URLs are passed to the Hyprland launcher as one shell-quoted argument, so query strings and shell metacharacters are preserved as URL data rather than interpreted as commands. Unsupported classes are skipped with a reason in the restore output. ## Browser URLs [Section titled “Browser URLs”](#browser-urls) `workspace-capture` can attach a real browser URL when the browser URL state file exists: ```text ${XDG_STATE_HOME:-~/.local/state}/browser-urls.json ``` When that file is missing, Chromium windows can still be matched or relaunched by class, but generic webapp URL recovery is limited. ## Workspace menu [Section titled “Workspace menu”](#workspace-menu) The Walker menu wraps the common actions: ```bash workspace-menu ``` The shared Hypr binding is: ```text SUPER+ALT+W ``` It offers capture, dry-run restore, restore, and relayout actions. On the `desktop` host it also exposes the host-specific workspace setup action. ## Recovery flow [Section titled “Recovery flow”](#recovery-flow) 1. Run `workspace-capture` before the risky change. 2. Make the change, restart Hyprland, or recover from the crash. 3. Run `workspace-restore --dry-run` and read the plan. 4. Run `workspace-restore` when the plan looks safe. 5. Check `restore.log` for skipped windows. ## Troubleshooting [Section titled “Troubleshooting”](#troubleshooting) If nothing restores, check that a capture exists: ```bash ls ~/.local/state/workspace-sessions ``` If restore launches too much, try moving only existing windows: ```bash workspace-restore --no-launch ``` If restore launches apps but leaves current placement alone: ```bash workspace-restore --no-move ``` If you want to inspect one capture directly: ```bash jq '.clients[] | {workspace: .workspace.id, class, title, browser_url}' ~/.local/state/workspace-sessions/workspace-*.json ``` ## Rollback [Section titled “Rollback”](#rollback) The restore script only moves, resizes, and launches windows. There is no persistent layout state to undo. Move windows manually or rerun a better capture file with `--file=...`. # Workspace Setup > Rebuild the desktop host's work and non-work workspace layout. `workspace-setup` is the desktop host’s opinionated workspace arranger. It launches or reuses the expected apps, tags them by slot, moves them to fixed workspaces, and rebuilds the main workspace split tree. Use it when the desktop workspace set has drifted, after login, or after a restart where capture/restore is not the right tool. ## Entry points [Section titled “Entry points”](#entry-points) The desktop host autostarts setup after Hyprland starts: ```text exec-once = workspace-setup --sleep=5 ``` On the `desktop` host, `workspace-menu` also exposes a **Setup workspace** action. The shared menu binding is: ```text SUPER+ALT+W ``` You can also run it directly: ```bash workspace-setup ``` ## Work-time mode [Section titled “Work-time mode”](#work-time-mode) The script branches on `is-work-time`, which returns success Monday to Friday from `07:00` through `16:59` local time. During work time, setup prepares: | Workspace | Slots | | --------- | ------------------------------------------------------------------------------- | | `1` | Slack, personal Chromium, Ghostty in the Home Assistant frontend repo, Discord. | | `2` | Ghostty in the Home Assistant frontend repo. | | `3` | Work browser. | Outside work time, setup prepares: | Workspace | Slots | | --------- | ------------------------------------------ | | `1` | Two personal Chromium windows and Ghostty. | | `2` | Ghostty. | After setup, it switches to workspace `2`. Terminal slots launch through `ghostty-host-config`, so they keep the active `config.$OMARCHY_HOST` override. Work-time terminal slots also pass the Home Assistant frontend checkout as `--working-directory`. ## How slots are matched [Section titled “How slots are matched”](#how-slots-are-matched) Each slot has a Hyprland tag such as `wssetup-ws1-slack` or `wssetup-ws1-term`. Setup prefers an existing tagged window, then an existing matching candidate, then launches the command for that slot. Before tagging a window, it removes other `wssetup-*` tags from that window and clears the target tag from any older window. This keeps each slot bound to one current address. ## Debug a setup run [Section titled “Debug a setup run”](#debug-a-setup-run) Use step-through mode when you need to see where the arrangement goes wrong: ```bash workspace-setup --step-through ``` Run faster when you are iterating and Hyprland is behaving reliably: ```bash workspace-setup --fast ``` Slow it down when windows are not ready before the script tries to place them: ```bash workspace-setup --speed-multiplier=2.5 ``` Delay startup logic after login: ```bash workspace-setup --sleep=10 ``` ## Logs [Section titled “Logs”](#logs) By default logs are written under: ```text ~/.local/state/workspace-setup/runs/ ``` Override the log path for one run: ```bash WORKSPACE_SETUP_LOG_FILE=/tmp/workspace-setup.log workspace-setup --step-through ``` The script removes `workspace-setup-*.log` files older than seven days from the default log directory. ## Temporary workspace [Section titled “Temporary workspace”](#temporary-workspace) Setup moves windows through a numeric temporary workspace while rebuilding split trees. The default is `99`. Override it if workspace `99` is in use: ```bash WORKSPACE_SETUP_TEMP_WS=98 workspace-setup ``` The temp workspace must be a positive integer. ## Move dispatcher [Section titled “Move dispatcher”](#move-dispatcher) The default move dispatcher is `movetoworkspace`, because `movetoworkspacesilent` has caused Hyprland crashes in this flow. Use the silent dispatcher only when intentionally testing it: ```bash WORKSPACE_SETUP_MOVE_DISPATCHER=movetoworkspacesilent workspace-setup ``` Valid values are `movetoworkspace` and `movetoworkspacesilent`. ## Recovery flow [Section titled “Recovery flow”](#recovery-flow) 1. Run `workspace-setup --step-through`. 2. Watch the log output for the slot that fails to resolve. 3. Check whether the app window class matches the slot regex. 4. If timing is the issue, rerun with a higher `--speed-multiplier` or `--sleep`. 5. If placement goes wrong, move windows manually or restore a capture from [Workspace Session Recovery](/knowledge-base/workspace-session-recovery/). ## Troubleshooting [Section titled “Troubleshooting”](#troubleshooting) If a terminal slot reuses an OpenCode terminal, the setup script filters titles starting with `OC |` for terminal candidates that should not be reused. If the startup browser should become the main browser slot, focus a Chromium window before running setup. The script prefers the focused startup Chromium address for that slot. If the non-work layout puts the blank tab in the wrong slot, setup tries to detect blank Chromium tabs and swap the top/main browser tags. # Omarchy & Hyprland > Managed Omarchy repos and stowed host overrides. These dotfiles run on [Omarchy](https://omarchy.org). Some Omarchy components are tracked as managed git repos that `dot` keeps in sync, while [Hyprland](https://hyprland.org) and Ghostty config are stowed dotfiles packages with per-host overrides. [Host Overrides](/omarchy/host-overrides/)Managed Omarchy repos and stowed host config. [Controls](/omarchy/controls/)The dot omarchy desktop controls menu. ## Managed Omarchy repos [Section titled “Managed Omarchy repos”](#managed-omarchy-repos) * `waybar` and `uwsm` are single-branch Omarchy repos expected on `main`. * `bootstrap` is expected on `distro/omarchy`. * `dot update` syncs these by default; `dot doctor` verifies their worktree branches. ## Hyprland [Section titled “Hyprland”](#hyprland) Hyprland config is **not** a tracked Omarchy repo. It is a stowed dotfiles package (`hypr/.config/hypr/`, conf-only) laid down with `--no-folding`, with host-specific overrides selected by a runtime symlink. See [Host Overrides](/omarchy/host-overrides/). ## Ghostty [Section titled “Ghostty”](#ghostty) Ghostty config is also stowed from `ghostty/.config/ghostty/`. The stowed launcher loads `config.$OMARCHY_HOST` when a host override exists. # Controls > The dot omarchy desktop controls menu. ## `dot omarchy` [Section titled “dot omarchy”](#dot-omarchy) Opens the Omarchy desktop controls menu. Pass a submenu path to jump straight to it, or chain a path to execute an action directly. ```bash dot omarchy # open the controls menu (TUI) dot omarchy theme # jump to the Theme submenu dot omarchy theme set # execute theme set directly ``` ## Available submenus [Section titled “Available submenus”](#available-submenus) | Submenu | Controls | | ------------ | ------------------------------- | | `theme` | Theme management | | `font` | Font management | | `toggle` | Toggle system features | | `capture` | Screenshots and recordings | | `system` | Lock, logout, reboot, shutdown | | `launch` | Launch applications | | `refresh` | Refresh system components | | `restart` | Restart system services | | `install` | Install software and tools | | `remove` | Remove software and features | | `packages` | Package management | | `share` | Share clipboard, files, folders | | `reminder` | Reminders | | `setup` | DNS, security setup | | `snapshot` | System snapshots | | `brightness` | Display and keyboard brightness | | `power` | Power profiles | ## Power profiles [Section titled “Power profiles”](#power-profiles) Power-profile control has two entrypoints: * `dot omarchy power` opens the Omarchy power-profile submenu from the `dot` TUI. * `SUPER+CTRL+P` runs `power-profile-menu`, a Walker picker that shows the current profile and selects one of the profiles reported by `omarchy-powerprofiles-list`. The menu writes the selected profile with `powerprofilesctl set`, so the available choices and final state come from `power-profiles-daemon` rather than a dot-specific state file. ### Laptop automation [Section titled “Laptop automation”](#laptop-automation) The `laptop` Hypr host starts `power-profile-daemon` from `~/.config/hypr/host/autostart.conf`. It replaces Omarchy’s AC udev auto-switching, which otherwise forces `performance` on AC. On laptops, the daemon keeps the profile conservative by default: * Startup sets `balanced`, unless the machine is on battery during the 01:00-07:00 local night window or below 20% battery. * Unplugging from AC drops `performance` to `balanced`; it leaves existing `balanced` and `power-saver` choices alone. * Plugging into AC relaxes `power-saver` back to `balanced`; it leaves `balanced` and `performance` alone. * While on battery, the daemon switches to `power-saver` once when the night window starts or when battery drops below 20%. * Manual changes after an automatic night switch are respected. At the end of the night window, the daemon only returns to `balanced` if it is still on the auto-applied `power-saver` profile and the battery is not below the low threshold. The daemon keeps a single-instance pidfile under `${XDG_RUNTIME_DIR:-/tmp}/power-profile-daemon.pid` and polls AC/time/battery state every two seconds. It sends best-effort desktop notifications through `omarchy notification send`. ### Troubleshooting [Section titled “Troubleshooting”](#troubleshooting) Use the underlying tools to verify state before changing the dotfiles: ```bash powerprofilesctl get omarchy-powerprofiles-list pgrep -af power-profile-daemon ``` If `SUPER+CTRL+P` opens no choices, check that `omarchy-powerprofiles-list` prints profile IDs. If the laptop policy is not running, confirm the active host symlink points at the laptop overrides and that Hyprland sourced `~/.config/hypr/host/autostart.conf`; see [Host Overrides](/omarchy/host-overrides/). # Host Overrides > Managed Omarchy repos and stowed host configuration. ## Managed Omarchy repos [Section titled “Managed Omarchy repos”](#managed-omarchy-repos) `dot` tracks a small set of Omarchy components as git repos and keeps them on the expected branch: * `waybar` and `uwsm` — single-branch Omarchy repos expected on `main`. * `bootstrap` — expected on `distro/omarchy`. `dot init` clones these into `~/.config/{bootstrap,waybar,uwsm}`. If a stock Omarchy config directory already exists there and is not a git repo, init moves it aside with a `.dot-init-backup-*` suffix before cloning. `dot update` syncs them, and `dot doctor` verifies their worktree branches. ## Ghostty host overrides [Section titled “Ghostty host overrides”](#ghostty-host-overrides) Ghostty config is a stowed dotfiles package (`ghostty/.config/ghostty/`), not a tracked Omarchy repo. The stowed `ghostty-host-config` launcher checks `OMARCHY_HOST` and loads `~/.config/ghostty/config.$OMARCHY_HOST` when present, falling back to the default `~/.config/ghostty/config` otherwise. `dot install`, `dot init`, and `dot stow` back up the retired `timmo001/omarchy-ghostty` clone at `~/.config/ghostty` before linking the stowed config. ## Hyprland host overrides [Section titled “Hyprland host overrides”](#hyprland-host-overrides) Hyprland config is a stowed dotfiles package (`hypr/.config/hypr/`, conf-only), not a tracked repo. Host-specific overrides live under `~/.config/hypr/hosts/$OMARCHY_HOST`, selected by the runtime `~/.config/hypr/host` symlink. * `dot stow` lays down the Hypr package with `--no-folding` and creates/repairs `~/.config/hypr/host` to point at the active host. * `dot init` selects the Hypr host early (via `--host `, defaulting to `OMARCHY_HOST` or `desktop`), and the stow phase creates the `host` symlink. * `dot doctor` checks the host link and flags any leftover legacy `omarchy-hypr` clone at `~/.config/hypr`. * Shared Hyprland-loaded config files wrap host override `source = ~/.config/hypr/host/*.conf` lines in Hyprland’s `hyprlang noerror` guard, so a missing host override during stow, update, or migration does not leave Hyprland in an error loop. Shared Hypr autostart lives in `~/.config/hypr/autostart.conf` and runs on every host before the selected host override is sourced. Host-only services stay in `~/.config/hypr/host/autostart.conf`. KDE Connect is shared, so `kdeconnect-indicator` starts on both desktop and laptop sessions. Retired omarchy-hypr clone A machine with the retired `~/.config/hypr` `omarchy-hypr` clone halts `dot update` until the clone is backed up and re-stowed. Hyprland config is a stowed package, not a cloned repo. ## Environment [Section titled “Environment”](#environment) * `OMARCHY_HOST` — the Hypr host override name (e.g. `desktop`, `laptop`). * `OMARCHY_REPO_BASE_DIR` — Omarchy repo base path (default `~/.config`). * `DOT_OMARCHY_BRANCH` / `DOT_BOOTSTRAP_BRANCH` — branch overrides during sync. See [Environment Variables](/configuration/environment/) for the full list. # OpenCode & Agents > Shared OpenCode agents, commands, skills, and plugins. The repo ships a shared [OpenCode](https://opencode.ai) configuration: agents, slash commands, skills, and lifecycle plugins. The source lives in `agents/.config/opencode/` (agents, commands, plugins, and shared `lib/` modules) and `agents/.agents/skills/` (skills exposed through the shared `~/.agents/skills/` path). These are generated from this dotfiles repo and published automatically to [`timmo001/opencode-config`](https://github.com/timmo001/opencode-config) so they can be browsed, imported, and installed independently of the full dotfiles repo. [Agents](/reference/agents/)Agent catalogue with links to each execution posture. [Commands](/reference/commands/)Slash commands that route to agents and skills. [Skills](/reference/skills/)Reusable workflows and behavioural contracts. [Plugins](/reference/plugins/)Context, evidence, and enforcement hooks. [MCP Servers](/opencode/mcp/)Model Context Protocol servers wired into the config. [Agents / LLMs](/agents-llms/)llms.txt bundles for loading these docs into AI-assisted sessions. ## How it fits together [Section titled “How it fits together”](#how-it-fits-together) * **Graduated agent permissions** - agents range from workspace-read-only (`reviewer`, `ask`) through ask-gated (`build-ask`) to edit-capable (`refactorer`). Read-only primary agents use native task allowlists, while `general-readonly` and `researcher-readonly` are terminal subagents with task delegation denied. The interactive `researcher` can fan out once without allowing recursive research chains. * **Comparative primary-source research** - `/research` answers direct facts from the source that owns them. When judgement is involved, it compares relevant project policy, maintainer and contributor practice, independent evidence, and credible disagreement claim by claim rather than ranking people by reputation. Research agents can inspect indexed local agent history through the read-only `ctx` status, source, search, show, locate, docs, and SQL commands; shell output flags remain blocked across these read-only agents. * **Workflow failure diagnosis** - `/fix-workflows` inspects recent GitHub Actions failures for the current branch, or a named workflow or run, reproduces the failing path locally where possible, applies the smallest fix, and verifies it without committing, pushing, or rerunning workflows automatically. * **Skill-based routing** - commands are thin wrappers that name an agent, declare required skills, and state whether branch context is needed. The workflow logic lives in skills and plugins. * **Question-led stress-testing** - `/grill` supports Light and Full intensity through one shared workflow. Phrases such as “lightly grill me” or “ask me a couple” select a short pass directly; when the requested intensity is unclear, it asks once before proceeding. * **Staged implementation** - `/plan` identifies one active stage, records separate reviewable stages as deferred, and makes no edits. It recommends one numbered handoff per deferred reviewable phase. In a new repository it tries handoffs first, then proposes one temporary, all-in-one repository-local working Markdown plan when repository notes are not available yet; that document tracks numbered phases and updates their status at every checkpoint. During execution, the `staged-implementation` skill defines shared contracts before delegation, uses targeted checks while iterating, runs one focused review before full validation, and pauses at validated checkpoints between separate review units unless the user requested one combined delivery. * **Visual plan and code review** - Plannotator opens plan review from OpenCode’s `plan` agent and provides `/plannotator-review`, `/plannotator-annotate`, and `/plannotator-last` for manual review. Its CLI is pinned through mise’s GitHub backend because it is not available from Arch, AUR, or the Aqua registry. * **Branch context injection** - commands registered with the `branch-context` plugin receive pre-computed git and PR state as structured XML instead of running their own `git` or `gh` calls. The plugin consumes the standalone [`context`](https://context.timmo.dev) CLI (`context git --json`), preserves explicit unresolved default-branch state, and keeps the plugin-specific injection rules here. `/commit`, `/commit-push`, and `/update-docs` query the Context MCP server’s `git_context` tool directly when they need branch or recent-change state. * **Codebase stack injection** - the `stack-context` plugin injects a deterministic tech-stack summary (languages, ecosystems, and frameworks with their general locations) computed by [`context stack --json`](https://context.timmo.dev/context/stack/), including structured notices when safety limits make a section partial. It injects automatically on the first message of a session inside a git repository, and on demand via `/inject-stack` or (alongside branch context) `/inject-context`. * **Repository notes**: the `repo-notes` plugin injects the current repository’s notes path, the `notes` MCP server owns vault reads and writes, and `notes-guard` blocks direct file or shell access to the notes vault. See [Notes & Handoffs](/dot/notes/) and [MCP Servers](/opencode/mcp/). * **Secret protection** - the `env-protection` plugin blocks reads of `.env` files (except `.env.example`). * **Generated artefact protection** - the `generated-artifact-guard` plugin blocks direct mutation of generated dotfiles artefacts and names the canonical regeneration command. Read-only inspection (`cat`, `git diff`, `rg`, and similar) is allowed. The guard activates only inside this dotfiles repository layout. | Generated artefact | Regenerate with | | --------------------------------------------------------------------- | ---------------------------- | | `docs/src/content/docs/dot/commands.md` | `mise run docs:gen:cli` | | `docs/src/content/docs/reference/{agents,commands,skills,plugins}.md` | `mise run docs:gen:opencode` | | `bash/.local/share/bash-completion/completions/dot` | `dot completions bash` | | `fish/.config/fish/completions/dot.fish` | `dot completions fish` | | `zsh/.local/share/zsh/site-functions/_dot` | `dot completions zsh` | | `scripts/.local/bin/dot` | `mise run dot:build` | | `docs/public/og.png` | `mise run docs:og` | * **Background dev servers** - starting a long-running dev server follows a precedence: the project’s own `AGENTS.md` workflow first, then framework-native background mode (Astro 7+ self-detaches `astro dev` under an agent), then pitchfork as the fallback. The `pitchfork-dev-server-guard` plugin covers only the pitchfork tier, redirecting foreground dev commands to `serve:*` or `pitchfork start` when a project declares `pitchfork.toml`, and it leaves `astro dev` to Astro’s native mode. * **Contextual notifications** - top-level task completion and permission events ring BEL, send an Omarchy-formatted desktop notification when `omarchy` is available, and play the freedesktop message sound when `paplay` is available. When the plugin starts under Hyprland, it captures the active window address so clicking a notification can return focus to that window. Background subagent completions stay silent. ## Tooling [Section titled “Tooling”](#tooling) * `opencode` is installed through mise’s Aqua backend. The explicit `c` alias resolves to the same binary and keeps the GitHub MCP bearer scoped to the launched harness process. * `dot agents-sync` — mirror `~/.config/opencode/AGENTS.md` into agent harness instruction files. Runs automatically at the end of full `dot update` and `dot init`. * `opencode debug ` — inspect resolved OpenCode config, paths, skills, and agents directly. * `DOT_CONTEXT_CAPTURE=1` - capture assembled system-prompt segments and tool definitions for starter-context profiling. See [Environment Variables](/configuration/environment/#debugging-and-output). * `dot skill-updates` / `dot skill-check`: check/apply upstream skill updates and validate branch-context command wiring. * `dot is-agent` — detect whether dot is running under an AI agent, from agent environment variables with a Linux `/proc` ancestry fallback (exit `0`/`1`, so scripts can branch with `if dot is-agent`). `DOT_AGENT=1`/`0` overrides detection. When an agent (or a non-interactive stdout) invokes a `dot` command that would open the TUI, dot refuses and points at the machine-readable equivalent instead. Publishing to `opencode-config` happens automatically via GitHub Actions on push. The Agents, Commands, Skills, and Plugins pages above are generated by `mise run docs:gen:opencode` from the live assets, so they always match what ships — edit the source assets, not the generated pages. See also the generated [`dot` Command Reference](/dot/commands/). # MCP Servers > The Model Context Protocol servers wired into the OpenCode config, and a sanitised opencode.json example. The OpenCode setup wires in a set of [Model Context Protocol](https://modelcontextprotocol.io) servers. They give agents documentation lookups, code search, browser control, system data, and dev-server management without shelling out for everything. ## Servers in use [Section titled “Servers in use”](#servers-in-use) | Server | Transport | Purpose | | ----------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `answer-overflow` | remote | Searchable archive of programming Discord help channels. Community troubleshooting context. | | `astro-docs` | remote | Search the official Astro framework docs. Loaded only in Astro projects (an `astro.config.*` marker, see below). | | `chrome-devtools` | local | Drive Chrome DevTools for frontend debugging: page snapshots, console, network, Lighthouse, performance traces. Loaded only in frontend projects (an `index.html` or web-framework/bundler config marker, see below). | | `context` | local | Branch and tech-stack context for the current repository (`git_context`, `stack_context`, `command_help`). Runs `context mcp` from the `context-git` package installed by `dot init`. | | `context7` | remote | Up-to-date library and framework documentation with code examples. Needs an API key. | | `convex` | local | Convex backend tooling: query data, run functions, inspect deployments. Loaded only in Convex projects (a `convex.json` or `convex/` marker, see below). | | `fallow` | local | Codebase intelligence for JavaScript and TypeScript: unused code, duplication, circular deps, complexity. Opt-in (held out of default tools) and loaded only in JS/TS repos (a `package.json` marker, see below). | | `github` | remote | Read-only GitHub access: issues, PRs, Actions, code scanning, Dependabot, discussions, projects. Needs a bearer token. | | `grep` | remote | Search real-world code across public GitHub repos via [grep.app](https://grep.app). | | `notes` | local | Repository notes vault (`note_read`, `note_list`, `note_write`, `note_delete`) and notes context. Runs `notes mcp` from the `repo-notes-git` package installed by `dot init`. | | `pitchfork` | local | Manage long-running dev-server daemons: start, stop, restart, status, logs. Loaded only in repos with a `pitchfork.toml` (see below). | | `system-bridge` | local | System Bridge: system info modules (cpu, memory, disks, media) and media control. | Remote servers connect over HTTP to a hosted endpoint. Local servers are launched on demand over stdio (`opencode x`, `npx`, or an installed binary). Chrome DevTools tools can execute browser-context JavaScript. The `subagent-chrome-devtools-guard` plugin keeps them available only in top-level sessions, so delegated subagents cannot use DevTools as a research path around web, GitHub, or repository-reading tools. The `system-bridge` server runs the `system-bridge-mcp` binary from the `system-bridge-git` AUR package. That package is listed in the public `.dot-public-packages` manifest and installed by `dot init`, so the MCP command is available on a fully set-up machine without a separate install step. The `context` server runs `context mcp` from the `context-git` AUR package (also in `.dot-public-packages`). Repository context tools and schemas live entirely in the standalone [`context`](https://context.timmo.dev) project. See [Context Integration](/git/context/) for how OpenCode plugins consume its JSON output. The `notes` server runs `notes mcp` from the `repo-notes-git` package (also in `.dot-public-packages`). Repository note commands use it for vault reads, writes, and deletes; the `repo-notes` OpenCode plugin supplies the current repository’s note context. ## Generated from one spec [Section titled “Generated from one spec”](#generated-from-one-spec) Every harness’s MCP config is generated from a single private spec, `~/.config/dotfiles-private/mcp.yml`, by `dot mcp-sync`. One edit to the spec regenerates each harness’s native config in the stowed source tree, so the harnesses stay aligned instead of drifting apart by hand. Active harnesses (generated): * **OpenCode** (`agents/.config/opencode/opencode.json`, `mcp` block) * **Cursor** (`agents/.cursor/mcp.json`, `mcpServers`) * **VS Code** (`agents/.config/Code/User/mcp.json`, `servers`) * **Copilot CLI** (`agents/.copilot/mcp-config.json`, `mcpServers`) The spec defines each server once and enables it for every active harness, so all four expose the same set. Enablement is written out as an explicit per-harness matrix, so any single cell can be flipped later. A canonical `{env:VAR}` reference is rewritten to each harness’s native syntax (`{env:VAR}`, `${env:VAR}`, or `${VAR}`), and commands that differ by harness (such as the OpenCode `opencode x` runner for `chrome-devtools`) are carried as per-harness overrides. The OpenCode config is written as a full catalogue: every server appears with an explicit `enabled: true` or `enabled: false`, so a server can be turned off in place while staying documented. The other harnesses list only their enabled servers. Two more harnesses are kept as documented stubs, not generated: * **Gemini CLI** would need an `mcpServers` block in `~/.gemini/settings.json` using `$VAR` env syntax. * **Claude Code** is special: `~/.claude.json` is a live runtime state file Claude rewrites, so it is wired with `claude mcp add`, not file generation. Run `dot mcp-sync` after editing the spec, then `dot stow`. `dot update` runs it automatically before re-stowing. ## Context gating [Section titled “Context gating”](#context-gating) Two kinds of gating keep sessions light without hiding tools you actually want. **Opt-in servers.** Fallow is registered but held out of the default tools with a `tools` glob, so it never runs automatically on a TypeScript edit: ```json { "tools": { "fallow*": false } } ``` It runs only when invoked by name or through a `/fallow-*` command. The `tools` glob only holds Fallow’s tools out of the default set; the server itself still connects wherever it is enabled, so it is also repo-gated below to stop it connecting outside JS/TS repos. **Per-repo servers.** Some servers are only useful in repos with a matching marker. The `mcp-repo-gate` plugin prunes them from the merged config at startup when none of their markers are present, so their tools do not load where they are irrelevant. Each server maps to one or more markers (files or directories); any one, found in the project directory, an ancestor, or a nearby descendant (up to two levels down, so a monorepo whose project sits in a subdirectory still counts), keeps the server. For example, `pitchfork` is dropped in any repo without a `pitchfork.toml`, `fallow` outside JS/TS repos, `convex` outside Convex projects, `astro-docs` outside Astro projects, and `chrome-devtools` (\~27 tools, \~4.3k tokens of schema) outside frontend projects: ```ts const REPO_REQUIRED_MARKERS: Record = { pitchfork: ["pitchfork.toml"], fallow: ["package.json"], convex: ["convex.json", "convex"], "astro-docs": [ "astro.config.mjs", "astro.config.ts", "astro.config.mts", "astro.config.js", "astro.config.cjs", ], // Any one frontend signal keeps chrome-devtools loaded (static entry point, // web-framework config, bundler config, task runner, or Storybook setup). // Attach it from a non-frontend directory by restarting OpenCode there. "chrome-devtools": [ "index.html", "astro.config.mjs", "vite.config.ts", "next.config.js", "nuxt.config.ts", "svelte.config.js", "vue.config.js", "angular.json", "webpack.config.js", "rspack.config.ts", "rollup.config.mjs", "gulpfile.js", ".storybook", // ...plus the remaining astro/vite/next/bundler config extensions ], }; ``` The plugin is deliberately conservative: only servers listed in that map are ever removed, and only when none of their markers are found upward to the filesystem root or in a short downward scan (which skips hidden and build/vendor directories). Every other server stays on everywhere, so no tool is hidden where it might be wanted. ## Example config [Section titled “Example config”](#example-config) A trimmed, sanitised `opencode.json`. Machine-specific repository paths are removed from the permission allow-lists, and secrets are `{env:...}` references with generic `FOO`/`BAR` placeholders standing in for real variable names. Adjust the `permission` allow-lists to your own trusted paths. In the real generated file every server also carries an explicit `"enabled": true` (or `false`), which is omitted here for brevity. ```json { "$schema": "https://opencode.ai/config.json", "autoupdate": false, "shell": "/bin/zsh -l", "permission": { "external_directory": { "~/.config/dotfiles/**": "allow", "/tmp/**": "allow", "**/.ssh/**": "deny", "**/.aws/**": "deny", "**/.gnupg/**": "deny", "**/.kube/**": "deny", "~/.docker/config.json": "deny", "~/.config/gh/hosts.yml": "deny", "~/.local/share/opencode/mcp-auth.json": "deny" }, "read": { "/tmp/**": "allow", "**/.env.example": "allow", "**/.env": "deny", "**/.env.*": "deny", "*.pem": "deny", "*.key": "deny", "**/.ssh/**": "deny", "**/.gnupg/**": "deny" }, "bash": { "git commit": "deny", "git commit *": "deny", "git commit --amend": "ask", "dot": "allow", "dot *": "allow" }, "lsp": "allow", "webfetch": "allow", "websearch": "allow" }, "lsp": true, "tools": { "fallow*": false }, "mcp": { "answer-overflow": { "type": "remote", "url": "https://www.answeroverflow.com/mcp" }, "astro-docs": { "type": "remote", "url": "https://mcp.docs.astro.build/mcp" }, "chrome-devtools": { "type": "local", "command": ["opencode", "x", "chrome-devtools-mcp@latest"] }, "context": { "type": "local", "command": ["context", "mcp"] }, "context7": { "type": "remote", "url": "https://mcp.context7.com/mcp", "headers": { "CONTEXT7_API_KEY": "{env:FOO}" } }, "convex": { "type": "local", "command": ["npx", "-y", "convex@latest", "mcp", "start"] }, "notes": { "type": "local", "command": ["notes", "mcp"] }, "fallow": { "type": "local", "command": ["npx", "-y", "--package", "fallow@latest", "fallow-mcp"] }, "github": { "type": "remote", "url": "https://api.githubcopilot.com/mcp/x/all/readonly", "oauth": false, "headers": { "Authorization": "Bearer {env:BAR}" } }, "grep": { "type": "remote", "url": "https://mcp.grep.app" }, "pitchfork": { "type": "local", "command": ["pitchfork", "mcp"] }, "system-bridge": { "type": "local", "command": ["system-bridge-mcp"] } } } ``` # Agents > OpenCode agents defined in this repo. Agents set the execution posture (permissions, tool access, delegation) for OpenCode sessions. They are published to [`opencode-config`](https://github.com/timmo001/opencode-config) and loaded from `~/.config/opencode/agents/`. | Agent | Description | | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | | [`ask`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/agents/ask.md) | Ask clarifying questions before taking action | | [`build-ask`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/agents/build-ask.md) | Build agent that executes clear tasks and relies on permissions for write actions | | [`general-readonly`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/agents/general-readonly.md) | General-style parallel subagent that researches with read-only tools and a narrow shell inspection allowlist (for delegation from read-only primaries). | | [`grill`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/agents/grill.md) | Read-only planning stress-test agent for light or full one-question-at-a-time grilling | | [`refactorer`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/agents/refactorer.md) | Refactor code while preserving behavior and following local command and skill workflows | | [`researcher-readonly`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/agents/researcher-readonly.md) | Primary-source research subagent that compares claim-specific evidence and cannot delegate further | | [`researcher`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/agents/researcher.md) | Interactive primary-source research agent that compares claim-specific evidence and may delegate one layer of read-only legwork | | [`reviewer`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/agents/reviewer.md) | Reviews code for quality, bugs, security, and best practices | # Commands > OpenCode slash commands defined in this repo. Commands are thin routing prompts: they name an agent, declare required skills or injected context, and define the output shape. They are loaded from `~/.config/opencode/commands/`. | Command | Description | Agent | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | ------------ | | [`/all-lit-skills`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/all-lit-skills.md) | Apply all Lit rendering skills in current git scope | `default` | | [`/all-ts-skills`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/all-ts-skills.md) | Apply all TypeScript-specific skills in current git scope | `default` | | [`/check-skill-updates`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/check-skill-updates.md) | Check imported skills for upstream updates | `default` | | [`/code-review`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/code-review.md) | Review current branch work with the code-review skill and BranchContextPlugin context | `reviewer` | | [`/commit-push`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/commit-push.md) | Commit current changes via the dot git-commit gateway, then push the branch for this explicit request only | `default` | | [`/commit`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/commit.md) | Commit current changes via the dot git-commit gateway in the maintainer’s one-line style | `default` | | [`/debug-frontend`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/debug-frontend.md) | Debug browser-specific UI issues with Chrome DevTools tools first | `ask` | | [`/explore-codebase`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/explore-codebase.md) | Explore a codebase topic with the task explore subagent | `ask` | | [`/fallow-audit`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/fallow-audit.md) | Audit changed JavaScript or TypeScript code with Fallow | `fallow` | | [`/fallow-project-analyse`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/fallow-project-analyse.md) | Analyse a JavaScript or TypeScript project with Fallow | `fallow` | | [`/fix-workflows`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/fix-workflows.md) | Diagnose and fix recent GitHub Actions failures, optionally scoped to a workflow or run | `default` | | [`/grill`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/grill.md) | Stress-test a proposed change with light or full one-question-at-a-time grilling | `grill` | | [`/handoff`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/handoff.md) | Write a handoff document for the next agent session | `default` | | [`/handoffs-list`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/handoffs-list.md) | List handoff notes for the current repository | `default` | | [`/home-assistant/all-frontend-skills`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/home-assistant/all-frontend-skills.md) | Apply all Home Assistant frontend skills in current git scope | `default` | | [`/home-assistant/lazy-context`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/home-assistant/lazy-context.md) | Review and fix Home Assistant frontend lazy-context and memoization usage in current git scope | `default` | | [`/home-assistant/list-components`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/home-assistant/list-components.md) | Migrate Home Assistant list components from MWC to new primitives in current git scope | `default` | | [`/home-assistant/lit-rendering`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/home-assistant/lit-rendering.md) | Review and fix Home Assistant Lit rendering and picker callback-shape patterns in current git scope | `default` | | [`/home-assistant/replace-spacing`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/home-assistant/replace-spacing.md) | Replace hardcoded spacing values with ha-space tokens from core.globals.ts | `default` | | [`/import-external-skill`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/import-external-skill.md) | Import or review external skills for the local skill library | `default` | | [`/improve-codebase-architecture`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/improve-codebase-architecture.md) | Review a codebase area for architectural friction and focused structural improvements | `plan` | | [`/inject-context`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/inject-context.md) | Inject branch and codebase stack context and optionally execute an instruction | `default` | | [`/inject-stack`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/inject-stack.md) | Inject codebase stack context and optionally execute an instruction | `default` | | [`/investigate`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/investigate.md) | Investigate a topic, issue, or area without editing by default | `ask` | | [`/note-append`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/note-append.md) | Append new notes to an existing note file for the current repository | `default` | | [`/note-create`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/note-create.md) | Create a new note for the current repository in your Obsidian notes vault | `default` | | [`/note-reference`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/note-reference.md) | Load one or more notes, relevant skills, and next steps for the current repository | `default` | | [`/notes-list`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/notes-list.md) | List notes for the current repository, optionally filtered by tag | `default` | | [`/notes-search`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/notes-search.md) | Search notes for the current repository by topic, keyword, or tag | `default` | | [`/plan`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/plan.md) | Manual entrypoint to native plan mode from the current conversation context | `plan` | | [`/plannotator-annotate`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/plannotator-annotate.md) | Open interactive annotation UI for a file, folder, or URL | `default` | | [`/plannotator-last`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/plannotator-last.md) | Annotate the last assistant message | `default` | | [`/plannotator-review`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/plannotator-review.md) | Open interactive code review for current changes or a PR URL; pass —git to force Git in JJ workspaces | `default` | | [`/refactor-cleanup-variables`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/refactor-cleanup-variables.md) | Refactor - inline and remove unnecessary variables from current git scope | `refactorer` | | [`/refactor-current-work`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/refactor-current-work.md) | Refactor current branch work while preserving behaviour | `refactorer` | | [`/refactor-enforce-types`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/refactor-enforce-types.md) | Refactor - enforce TypeScript type safety in current git scope | `refactorer` | | [`/refactor-remove-single-use`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/refactor-remove-single-use.md) | Refactor - inline and remove safe single-use functions from current git scope | `refactorer` | | [`/research`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/research.md) | Research a topic from primary sources and compare evidence where judgement is involved | `researcher` | | [`/reset-branch-reapply`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/reset-branch-reapply.md) | Reset branch to default and reapply current diff staged | `build` | | [`/update-docs`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/commands/update-docs.md) | Keep documentation current with recent code changes, via Context MCP and delegated investigation | `default` | # Plugins > OpenCode lifecycle plugins defined in this repo. Plugins provide context, evidence, or enforcement hooks for OpenCode. They are loaded from `~/.config/opencode/plugins/`. | Plugin | Description | | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ | | [`branch-context`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/plugins/branch-context.ts) | Injects branch-context blocks into command prompts before execution | | [`context-capture`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/plugins/context-capture.ts) | Opt-in capture of the assembled starter context for token profiling | | [`env-protection`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/plugins/env-protection.ts) | Blocks direct access to .env files to prevent leaking secrets | | [`generated-artifact-guard`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/plugins/generated-artifact-guard.ts) | Blocks direct mutation of generated dotfiles artefacts | | [`mcp-repo-gate`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/plugins/mcp-repo-gate.ts) | Per-repo MCP server gating for OpenCode | | [`notes-guard`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/plugins/notes-guard.ts) | Blocks direct file and shell access to the repository notes vault | | [`notification`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/plugins/notification.ts) | Sends contextual desktop notifications and terminal attention for agent events | | [`pitchfork-dev-server-guard`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/plugins/pitchfork-dev-server-guard.ts) | Enforces a project’s declared pitchfork dev-server workflow for agents | | [`readonly-subagent-shell-guard`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/plugins/readonly-subagent-shell-guard.ts) | Rejects shell syntax that can turn read-only subagent commands into writes | | [`repo-notes`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/plugins/repo-notes.ts) | Injects repo-note context into OpenCode note commands | | [`stack-context`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/plugins/stack-context.ts) | Injects codebase stack-context blocks into prompts | | [`subagent-chrome-devtools-guard`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/plugins/subagent-chrome-devtools-guard.ts) | Blocks Chrome DevTools tools from delegated subagent sessions | | [`tui-dot-git-diff`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/plugins/tui-dot-git-diff.ts) | Registers a TUI keybinding (ctrl+shift+g) to open `dot git-diff` | | [`tui-lazygit`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.config/opencode/plugins/tui-lazygit.ts) | Registers a TUI keybinding to open lazygit | # Skills > OpenCode skills defined in this repo, including imported ones. Skills own reusable workflows and behavioural contracts. They are exposed via `~/.agents/skills/` and published to [`opencode-config`](https://github.com/timmo001/opencode-config). ## Skills [Section titled “Skills”](#skills) | Skill | Description | | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | [`branch-context-consumer`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/branch-context-consumer/SKILL.md) | Consume BranchContextPlugin injections in commands. Use when a command depends on an injected block for its scope. | | [`check-skill-updates`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/check-skill-updates/SKILL.md) | Check imported skills for upstream changes and apply updates. Use when reviewing whether externally imported skills have new upstream content, or when `dot skill-updates` reports available changes. | | [`cleanup-unnecessary-variables`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/cleanup-unnecessary-variables/SKILL.md) | Safe removal of unnecessary variables during code review and refactoring. Use when simplifying code, inlining temporary or single-use variables, or removing redundant aliases, while preserving runtime behaviour, evaluation order, and variables kept for readability or debugging. | | [`code-review`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/code-review/SKILL.md) | Review code changes along two axes - Standards (does it follow the repo’s conventions, plus a Fowler code-smell baseline?) and Spec (does it implement what the originating issue or spec asked for?). Use when reviewing a pull request, a branch, work-in-progress changes, or a diff. | | [`dotfiles-stow`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/dotfiles-stow/SKILL.md) | REQUIRED when changing configs managed by \~/.config/dotfiles or \~/.config/dotfiles-private. Enforces editing stow source paths (not ad-hoc live paths) and using the dot command for stow/update/validation workflows. | | [`fallow-coexistence`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/fallow-coexistence/SKILL.md) | Guidance for using Fallow alongside code-quality and framework skills without conflict. Use when running Fallow or acting on its findings — applying fix/suppress suggestions, interpreting dead-code or complexity output, or analysing Effect, Lit, or Home Assistant code — to decide what to apply, what to verify first, and how to configure Fallow. | | [`git-commit`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/git-commit/SKILL.md) | Commit workflow using the dot git-commit gateway in the maintainer’s concise one-line style. Use only after the user explicitly requests a commit or push, including /commit or /commit-push. Never infer repeat authorisation from an earlier commit or push; never run raw git commit. | | [`git-context`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/git-context/SKILL.md) | Patterns for working with git branches, remotes, diffs against the default branch, and rebases. Use when resolving rebase conflicts, continuing interactive rebases, amending commits, or any git operation that would open an interactive editor. | | [`handoff`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/handoff/SKILL.md) | Compact the current conversation into a handoff document for another agent to pick up. | | [`home-assistant-frontend`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/home-assistant-frontend/SKILL.md) | Home Assistant frontend development with Lit Web Components and TypeScript. Use when working in the Home Assistant frontend repo, editing ha-\* components, reviewing HA PRs, or applying HA-specific conventions (localization, theming, dialogs, panels, cards). | | [`home-assistant-lazy-context`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/home-assistant-lazy-context/SKILL.md) | Home Assistant frontend lazy-context, memoization, and `hass` removal guidance. Use when migrating Lit components from `hass!: HomeAssistant`, `.hass=${...}`, or broad `hass` access to context slices. | | [`home-assistant-list-components`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/home-assistant-list-components/SKILL.md) | Home Assistant list component migration and usage guidance. Use when editing ha-list, ha-list-item, ha-md-list, or migrating to ha-list-nav, ha-list-selectable, ha-list-item-button, ha-list-item-option, or ha-list-item-base. | | [`home-assistant-lit-rendering`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/home-assistant-lit-rendering/SKILL.md) | Home Assistant Lit rendering extensions for HA components and context-aware picker callback shape. | | [`import-external-skill`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/import-external-skill/SKILL.md) | Import skills from external repos into the local dotfiles skill library. Use when pulling in a skill from a public repo, reviewing an external skill set for useful additions, or adapting external skill content into existing local skills. | | [`lit-rendering`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/lit-rendering/SKILL.md) | Lit rendering and picker callback-shape guidance for editing and reviewing Lit components. | | [`maintain-docs`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/maintain-docs/SKILL.md) | Keep documentation current and accurate with recent code changes, across in-code docs (docstrings, annotations, comments), in-repo docs sites, and external docs repositories. Use when asked to update docs, check docs accuracy, keep documentation current, document recent changes, refresh docstrings or annotations, or catch documentation up with the codebase. Matches the codebase’s existing documentation density and stops before commit. | | [`pitchfork-dev-servers`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/pitchfork-dev-servers/SKILL.md) | Manage long-running local dev servers by precedence - the project’s own AGENTS.md workflow first, framework-native background mode next, then pitchfork as the fallback. Use when starting, stopping, restarting, checking, or tailing development servers, background servers, `pitchfork.toml`, pitchfork MCP tools, or local AGENTS/mise tasks that mention pitchfork. | | [`pkexec-root`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/pkexec-root/SKILL.md) | Use pkexec first for commands that need root directly or indirectly. | | [`remove-single-use-functions`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/remove-single-use-functions/SKILL.md) | Safe inlining and removal of single-use functions during code review and refactoring. Use when a local, non-exported helper has exactly one real call site and inlining preserves behaviour and readability. | | [`research`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/research/SKILL.md) | Investigate a topic against primary sources and return cited findings, comparing credible maintainer and contributor perspectives when judgement is involved. Use when the user wants a topic researched, docs, API, or spec facts gathered, an external library or GitHub behaviour verified, competing views compared, or reading legwork delegated to a background agent. | | [`safe-process-signals`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/safe-process-signals/SKILL.md) | Safe process killing and signal handling for agent/subprocess contexts. Use when running pkill, killall, kill, or any process termination command from a shell subprocess, automated script, or coding agent. | | [`shared-workflows`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/shared-workflows/SKILL.md) | Use, configure, maintain, or create reusable GitHub Actions workflows for personal and organisation repositories. Use when a task mentions shared workflows, reusable workflows, `workflow_call`, cross-repository workflow `uses:`, or the personal workflows repository; do not use for repository-specific or proof-of-concept CI unless evaluating whether it should be shared. | | [`staged-implementation`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/staged-implementation/SKILL.md) | Execute broad changes one coherent, independently verifiable stage at a time. Use when work spans multiple independently reviewable changes, or when contracts, producer-consumer migrations, generated artefacts, or release packaging create an ordered multi-stage rollout; skip small single-purpose changes. | | [`types-enforce-ts`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/types-enforce-ts/SKILL.md) | TypeScript type-safety guidance for editing and reviewing `.ts`, `.tsx`, `.mts`, and `.cts` files. | | [`writing-dot-skills`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/writing-dot-skills/SKILL.md) | Craft for authoring skills that select reliably and stay lean - writing the description for correct auto-selection, matching instruction freedom to task fragility, deciding when to split into references or add scripts, and running quality and anti-pattern checks. Use when creating or revising a skill’s content or structure. For the file schema, frontmatter fields, and placement, use customize-opencode. | | [`writing-style`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/writing-style/SKILL.md) | Write commit messages, PR and issue text, docs (README), code comments, and user-facing strings (notifications, UI labels, toasts, error messages) in the project owner’s voice: concise, human, UK English, no em-dashes, no robotic or marketing tone. Use when authoring or editing any of these. Defer to a repo’s established house style when it has one; otherwise this sets the default voice. | ## Imported Skills [Section titled “Imported Skills”](#imported-skills) These skills were imported from other repos and tracked with an `# origin:` marker. Some are used as-is; others are adapted for local workflows. | Skill | Description | Origin | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | | [`ask-questions-if-underspecified`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/ask-questions-if-underspecified/SKILL.md) | Ask minimal clarifying questions only when ambiguity materially changes implementation. Use for routine underspecification; do not use for user-requested light or full grilling, plan stress-testing, or broad design interviews. | [trailofbits/skills](https://github.com/trailofbits/skills/tree/main/plugins/ask-questions-if-underspecified/skills/ask-questions-if-underspecified) | | [`codebase-design`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/codebase-design/SKILL.md) | Shared vocabulary for designing deep modules. Use when the user wants to design or improve a module’s interface, find deepening opportunities, decide where a seam goes, make code more testable or AI-navigable, or when another skill needs the deep-module vocabulary. | [mattpocock/skills](https://github.com/mattpocock/skills/tree/main/skills/engineering/codebase-design) | | [`css-motion-systems`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/css-motion-systems/SKILL.md) | CSS motion design and implementation for web interfaces. Use when designing or building transitions, animations, `linear()` easing, transform strategy, View Transitions API patterns, motion tokens, or reviewing motion quality and accessibility. | [stolinski/s-stack](https://github.com/stolinski/s-stack/tree/main/skills/css-motion-systems) | | [`ctx-agent-history-search`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/ctx-agent-history-search/SKILL.md) | Use ctx to search local coding-agent history before acting. Use when prior agent sessions may contain relevant insights, decisions, attempts, or transcript context. | [ctxrs/ctx](https://github.com/ctxrs/ctx/tree/main/skills/ctx-agent-history-search) | | [`diagnose`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/diagnose/SKILL.md) | Disciplined workflow for diagnosing bugs - hard bugs, regressions, flaky behavior, and performance issues. Use when behavior is broken, failing, intermittent, or slower than expected and the agent needs a reproducible feedback loop before fixing. | [mattpocock/skills](https://github.com/mattpocock/skills/tree/main/skills/engineering/diagnosing-bugs) | | [`domain-modeling`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/domain-modeling/SKILL.md) | Build and sharpen a project’s domain model. Use when the user wants to pin down domain terminology or a ubiquitous language, challenge or record a design decision, or when another skill needs to maintain the domain model. | [mattpocock/skills](https://github.com/mattpocock/skills/tree/main/skills/engineering/domain-modeling) | | [`effect`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/effect/SKILL.md) | Opinionated guide for building production TypeScript applications with Effect v4. Use when implementing Effect workflows, services, layers, schemas, configuration, schedules, caches, streams, HTTP clients, or tests. | [kitlangton/skills](https://github.com/kitlangton/skills/tree/main/skills/effect) | | [`fallow`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/fallow/SKILL.md) | Codebase intelligence for JavaScript and TypeScript. Free static layer finds unused code (files, exports, types, dependencies), code duplication, circular dependencies, complexity hotspots, architecture boundary violations, and feature flag patterns. Runtime coverage merges production execution data into the same health report for hot-path review, cold-path deletion confidence, and stale-flag evidence - a single local capture is free, while continuous/cloud runtime monitoring is paid. 94 framework plugins, zero configuration, sub-second static analysis. Use when asked to analyze code health, find unused code, detect duplicates, check circular dependencies, audit complexity, check architecture boundaries, detect feature flags, clean up the codebase, auto-fix issues, merge runtime coverage, or run fallow. | [fallow-rs/fallow-skills](https://github.com/fallow-rs/fallow-skills/tree/main/fallow/skills/fallow) | | [`grill-questions`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/grill-questions/SKILL.md) | Stress-test a plan or proposed change through focused one-question-at-a-time grilling, with light and full intensity. Use when the user says grill, grill me, grill me lightly, ask me a couple of questions, stress-test this plan, or wants question-led scrutiny before planning. | [mattpocock/skills](https://github.com/mattpocock/skills/tree/main/skills/productivity/grilling) | | [`herdr`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/herdr/SKILL.md) | Control herdr from inside it. Manage workspaces and tabs, split panes, spawn agents, read output, and wait for state changes — all via CLI commands that talk to the running herdr instance over a local unix socket. Use when running inside herdr (HERDR\_ENV=1). | [ogulcancelik/herdr](https://github.com/ogulcancelik/herdr/blob/master/SKILL.md) | | [`html`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/html/SKILL.md) | Writes and reviews semantic, accessible HTML and template markup that stays readable and low-noise. Use when creating or refactoring HTML or Svelte templates, cleaning up div soup, choosing better elements, improving form markup, fixing heading or landmark structure, or replacing custom controls with native HTML. | [stolinski/s-stack](https://github.com/stolinski/s-stack/tree/main/skills/html) | | [`hunk-review`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/hunk-review/SKILL.md) | Interacts with live Hunk diff review sessions via CLI. Inspects review focus, navigates files and hunks, reloads session contents, and adds inline review comments. Use when the user has a Hunk session running or wants to review diffs interactively. | [modem-dev/hunk](https://github.com/modem-dev/hunk/tree/main/skills/hunk-review) | | [`improve-codebase-architecture`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/improve-codebase-architecture/SKILL.md) | Scan a codebase for deepening opportunities, present them as a visual HTML report, then grill through whichever one you pick. | [mattpocock/skills](https://github.com/mattpocock/skills/tree/main/skills/engineering/improve-codebase-architecture) | | [`motion-choreography-patterns`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/motion-choreography-patterns/SKILL.md) | Use when orchestrating multi-element UI motion, stagger systems, list reorder/insert/remove flows, modal and overlay stacks, gesture-driven transitions, and route-level choreography that preserves hierarchy and attention. | [stolinski/s-stack](https://github.com/stolinski/s-stack/tree/main/skills/motion-choreography-patterns) | | [`opentui`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/opentui/SKILL.md) | Build terminal UIs with OpenTUI. Covers the core API, native audio, keymaps, React and Solid bindings, components, layout, keyboard input, plugins, and testing. | [anomalyco/opentui](https://github.com/anomalyco/opentui/tree/main/packages/web/src/content) | | [`prototype`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/prototype/SKILL.md) | Build a throwaway prototype to answer a design question. Use when the user wants to sanity-check whether a state model or logic feels right, or explore what a UI should look like. | [mattpocock/skills](https://github.com/mattpocock/skills/tree/main/skills/engineering/prototype) | | [`vercel-cli`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/vercel-cli/SKILL.md) | Vercel CLI expert guidance. Use when deploying, managing environment variables, linking projects, viewing logs, querying metrics, managing domains, or interacting with the Vercel platform from the command line. | [vercel/vercel-plugin](https://github.com/vercel/vercel-plugin/tree/c9b1d8ff9351d90d20c0cf1e3d051d0ee100541d/skills/vercel-cli) | | [`vercel-deployments-cicd`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/vercel-deployments-cicd/SKILL.md) | Vercel deployment and CI/CD expert guidance. Use when deploying, promoting, rolling back, inspecting deployments, building with —prebuilt, or configuring CI workflow files for Vercel. | [vercel/vercel-plugin](https://github.com/vercel/vercel-plugin/tree/c9b1d8ff9351d90d20c0cf1e3d051d0ee100541d/skills/deployments-cicd) | | [`vercel-env-vars`](https://github.com/timmo001/dotfiles/blob/distro/arch-omarchy/agents/.agents/skills/vercel-env-vars/SKILL.md) | Vercel environment variable expert guidance. Use when working with .env files, vercel env commands, OIDC tokens, or managing environment-specific configuration. | [vercel/vercel-plugin](https://github.com/vercel/vercel-plugin/tree/c9b1d8ff9351d90d20c0cf1e3d051d0ee100541d/skills/env-vars) |