Infomarchy
Omarchy plugin: your wallpaper becomes a live, clickable information desk — every running AI agent (Claude Code, Codex, Grok, Ollama), 7-day heatmap, rate limits, recent prompts, machine stats. Theme-driven.
Infomarchy
Your wallpaper, promoted to information desk.
Every AI agent running on your machine, what it's doing, what it cost you, and how the box is holding up —
drawn live on the Omarchy desktop in your current theme, one glance away, one click to jump in.
The public preview is the real plugin rendered on an empty Omarchy desktop using Infomarchy's explicit, transient demo-data mode. It contains no live prompt, hostname, username, network, path, process, or session data.
Want to see the plain desktop? After configuring the shortcuts, press
SUPER + Ito hide the Infomarchy cards and reveal your wallpaper. PressSUPER + Iagain to bring the dashboard back.
#Why
You run Claude Code in three terminals, Codex in a fourth, Grok is poking at a repo somewhere, Ollama is warming a model, and your weekly limit is quietly at 86%. The only way to know any of that is to go look — tab through windows, read titles, run nvidia-smi, open a dashboard.
Infomarchy puts all of it on the one surface you always have open and never use: the wallpaper. It's not a widget in the bar and not another window to manage. It's the desk itself, and it's always current.
#What you get
#🟡 Live AI sessions — who is working right nowOne card per running agent — Claude Code, Codex, Cursor, Grok, Grok Bot, Gemini, Hermes, opencode, aider, Ollama chats — detected straight from Zombies. A session nobody is attached to (background, or no window and nothing to attach to) that is not busy and has had no prompt for six hours gets a STALE · idle Nh tag on its card. Right-click it: a background Claude session offers STOP SESSION ( Cursor. Both ways of running it get a card. A worker lives as long as its Cursor window, not as long as a conversation — so unlike a terminal agent you close when you are done, a Cursor card can sit on the desk for days. That is why the STALE tag and quiet grouping matter more here than for anything else; liveness is the process, and decay is the last prompt. History comes from Cursor's own transcripts at Which chat a worker is on comes from the newest transcript under its own directory. That has to be read rather than inferred: the generic inference only accepts a prompt within half an hour of launch, which fits a terminal agent prompted right after starting and not a worker that outlives any one conversation. Cursor is also the one provider with a real busy signal instead of a terminal-title guess: a transcript ends with Grok Bot. The xAI desktop app runs every bot in its roster inside one Electron process, so Grouping quiet sessions. A roster that size costs a card per bot, and ten of them alone trip the dense layout (> 8 sessions), shrinking every Claude and Codex card on the desk to pay for bots nobody has touched in weeks. So a provider's quiet sessions group into one card that names a few of them with their idle times — still clickable, right-click still opens that individual bot in the inspector — and the chip expands the rest. On the desk this was written for that took SESSIONS from fifteen cards to six and turned dense mode off, giving the surviving cards their working directory, host, git and pid lines back. The three attention states are deliberately not treated alike: waiting (an agent blocked on your answer) and blocked (a conflict, crash or failure) are requests, a request does not expire, and neither ever groups at any age. done — ready for review, or a bot holding unread replies — is a notification, and one nobody has looked at for a month has stopped being news, so it groups once past the window (an hour by default) and the card says Each card also attributes live CPU, resident RAM, process-tree size, and—when Only the full per-session cards appear in Live AI Sessions; there is no duplicate compact workspace-card strip. Each large card includes its workspace number. In the session inspector, workspace buttons 1–10 can move that exact agent window silently; the current workspace is highlighted and disabled. Window thumbnails are opt-in: right-click a large session card, toggle PREVIEWS OFF/ON in its inspector, then hover a live card. Infomarchy captures only that exact address after a short delay, downsizes it to 160×90, applies a heavy blur, and displays a 320×180 still. The raw capture moves through bounded in-memory streams from Cards also show the repository branch, clean/changed state, ahead/behind counts, and merge conflicts. A Needs You strip calls out agents that appear blocked, waiting for input, or finished for review, plus repositories being shared by multiple live agents. Active Needs You signals get a faint breathing outline (the module chip glows too if the card is removed). Click the signal to focus it, 10M to snooze it for ten minutes, or × to dismiss that signal for the lifetime of its process. Snoozes and dismissals persist between the wallpaper and fullscreen overlay. The card's alert controls send deduplicated Omarchy notifications when an agent is blocked, waiting for an answer, ready for review, or ends — and, when the terminal title says so, when it has crashed (Infomarchy reads titles and Click a Needs You signal → jump straight to that agent's terminal. From the fullscreen overlay, Infomarchy closes itself after focusing the session. Click a card → Infomarchy focuses the terminal window hosting that agent. It walks the process tree up to the Hyprland client, so it works through Right-click a card → inspect it in place. The centered inspector shows its window, shortened session identity, workspace, uptime, pid, and repository state. From there you can focus the existing window or open a fresh terminal in the project directory; paths are passed as process arguments, never evaluated as shell text. |
#🟢 Usage & limits — what it's costing youAbove the limit meters sits a 7-day trend: one line per provider, tokens processed per day, three gridlines, hover any day for the exact figures. The TOKENS / ≈ $ VALUE chip switches the same lines to an estimated API value — what those tokens would have cost at published API prices — and each provider row shows today's and lifetime estimates, the share of lifetime tokens that were cache reads, and the session count. Prices come from a pinned, attributed LiteLLM snapshot ( Session (5-hour) and weekly (7-day) rate-limit meters with time-to-reset, today's prompt count and token volume, per subscription. Meters turn yellow past 60% and red past 85%, in your theme's yellow and red. Provider chips filter the card interactively. Toggle PERCENT / FORECAST to project each recognized 5-hour or 7-day meter to reset from its elapsed-window pace; young or malformed windows say Infomarchy reuses the cache that Omarchy's own #🟢 Local AIOllama up/down, every loaded model with its VRAM, GPU utilisation / memory / temperature, and lifetime totals per provider. Arrow controls select any locally installed model and show its parameter count, quantization, and disk size. LOAD pins the selected model in memory; each loaded row has its own UNLOAD action. Models at least 8 GiB—or larger than currently available accelerator/system memory—require a second CONFIRM click. Model changes go through a bounded stdin-framed helper. It validates the model name against Ollama's live |
#🟢 FLEET — other machines' AI agents
One row per host named in INFOMARCHY_FLEET_HOSTS (a comma-separated list of ssh aliases — the same aliases you'd already use typing ssh <alias> yourself; user, identity file and proxy jump stay in ~/.ssh/config, never in this variable). Each host gets a status dot, provider chips for whatever it's running, and a relative "checked Ns ago" time. Invisible until you configure at least one host — the same "no tag until you run it" rule every other provider already follows.
Detection is one bounded, read-only ps call over ssh -o BatchMode=yes per host per refresh (30 s), matched against the identical providerOf() regex table local detection already uses — a remote Hermes, Claude, Codex, or anything else PROVIDERS recognises is identified exactly the way a local process is, just seen over a different channel. An unreachable host reads unreachable, never fabricated. INFOMARCHY_SKIP_FLEET=1 disables it from the collector's environment.
When a host is running Hermes, USAGE & LIMITS gains a Hermes row too — no second API key to manage, since everything comes from files Hermes already keeps on that host. Token counts and the per-model breakdown come from Hermes's own local billing ledger (~/.hermes/state.db, read with sqlite3 -readonly); the dollar figures and a MONTHLY limit bar come from Hermes's cached snapshot of OpenRouter's own key-usage API (~/.hermes/workspace/openrouter_key_usage.json) when present. That split matters: the local ledger is only as old as Hermes's current session-tracking window, not real lifetime spend — verified live, where it undercounted true lifetime cost by roughly 30× — so the ledger's own per-row estimate is a fallback only, used when the key-usage file isn't there. The card's status line says which source produced the number you're looking at. Token counts and the per-model breakdown are model-agnostic — nothing is keyed to Deepseek or any other specific model, so switching Hermes's model shows up correctly on its own. The dollar figure currently assumes that model is still billed through OpenRouter, though: it's an account-level total, not scoped per model, so a model billed through a different provider entirely would need its own fix to be counted (see docs/fleet-remote-hosts.md).
#🟡 Activity · last 7 days — when you actually work
An hour-by-hour heatmap of prompts across every provider, newest day at the bottom, with a red tick at now. The dominant provider colours each cell; intensity is volume. Cells are local wall-clock hours, so on the two DST nights a year one hour is doubled up (fall) or absent (spring). Hover a cell for the exact breakdown ("Tue 18 Aug 16:00 · 8 prompts (Claude 6, Codex 2)"). Click an hour to filter Recent Tasks to that hour; click a provider in the legend to combine a provider filter. The selected cell and provider stay outlined, and clicking either again—or clear—removes that part of the filter. The header carries today/week counts per provider.
#🟢 GitHub · last 7 days — what actually landed
Beside ACTIVITY is the identical grid fed from GitHub: commits, PRs, reviews, issues, comments and everything else (releases, forks, stars, branch creates) as other, each cell coloured by its dominant kind, the same red tick at now. Hover a cell for the breakdown plus the repositories involved ("Fri 4 Sep 23:00 · 9 events · commits 7 · PRs 2 · infomarchy, blip"). The header carries today/week counts per kind. There is no list to filter here, so a click pins a cell (its breakdown stays in the status line) and clicking a kind in the legend recolours the grid to that kind alone; clear or the overlay's A key resets all activity filters. In the overlay the module answers to key 4 (ACTIVITY is 3; the modules after it shift by one and 0 reaches the tenth).
Data comes through the already-authenticated GitHub CLI (gh), nothing else: commits from search/commits by author date (one row per commit, default branches only — a push to a feature branch shows once it lands), everything else from your own events feed, private repositories included. GitHub caps a search at 1000 rows and 30 calls a minute, so the week is filled in incrementally — one step a minute until the oldest day is covered (the status line says filling in older days meanwhile), then a five-minute refresh. Rows are cached in a private state file written by the wallpaper collector and read by the overlay, so a restart or a dropped connection shows the cached grid rather than an empty card — marked stale once fetches have been failing for fifteen minutes, with retries backing off to five minutes. Every six hours the week is walked again so a commit merged days after it was authored still lands in its hour. Switching gh accounts starts the store over. Without gh, or before gh auth login, the card says exactly that. INFOMARCHY_SKIP_GITHUB=1 in the collector's environment disables the fetch entirely. The enabled heatmap cards share the row and stack at smaller widths; hide any card using the module strip.
#Gitea · last 7 days
GITEA uses the same seven-day heatmap, theme colors, hover details, pinned cells, and kind filters as GITHUB. It appears beside GITHUB and can be hidden with the GITEA module chip. Existing numbered module shortcuts keep their assignments; A clears all activity filters.
Configure a server with tea login add. Infomarchy reads ${XDG_CONFIG_HOME:-~/.config}/tea/config.yml, using the default login or the sole login. With multiple accounts, set INFOMARCHY_GITEA_LOGIN in the shell's environment to the exact tea login name. No dashboard-specific copy of the token is stored. HTTP and HTTPS servers, custom ports, and subdirectory installations are supported; HTTPS is the default for an address without a scheme. Requests never follow redirects with credentials.
Alternatively, supply both GITEA_HOST (the server base URL, without /api/v1) and GITEA_TOKEN. A host alone selects its matching tea login; a token alone is rejected so it cannot be sent to the wrong server. INFOMARCHY_SKIP_GITEA=1 disables the feed. Tokens must allow reading the authenticated user and their activity feed, including repository access for private activity.
The feed counts your own pushes, PR events, reviews, issue events, comments, and other supported activity. A push is one event, even if it contains several commits. This differs from GitHub's commit-search count. Gitea's activity retention and permissions determine the available history. Servers must provide /api/v1/users/{username}/activities/feeds.
The wallpaper collector refreshes every five minutes and fills older pages incrementally once a minute; the overlay reads the same private cache. Each attempt reads at most two pages, requests time out after four seconds, and the cache holds up to 6,000 recent events. Only timestamps, event IDs, kinds, and repository names are retained; commit messages, issue bodies, and credentials are discarded. Changing the configured account starts a new cache. Failed fetches back off and show cached data as stale after fifteen minutes. The whole window is reconciled every six hours.
#⚪ Recent tasks — what got asked
The newest prompts across all providers — time ago, provider tag, project, and the prompt itself — so the question "what was I doing an hour ago?" has an answer on the wall. The list keeps up to 80 rows in a scrollable history, with a search box that matches prompt text, project, or provider (filtered searches can show up to 200 matches). Prompts whose exact agent session is still running stay bright and clickable; click one to jump to its terminal. Supported closed sessions are dimmed but remain interactive: hover for RESUME, then click to reopen that exact Claude, Codex, Grok, or OpenCode session in a terminal at its project directory.
Right-click a prompt for its action drawer: copy, pin/unpin, open the project, and review up to five recent prompts from the same session. Pins persist and sort above ordinary recency without changing the underlying history. Wheel and touchpad deltas are handled directly by the row beneath the pointer, and the wider scrollbar track can be clicked or dragged.
#🔵 Operations intelligence — what changed, what needs you, what is healthy
Three compact cards sit beneath the live sessions:
- What Changed fingerprints each active repository and highlights it until you inspect the newest state. It summarizes staged, untracked, test, addition/deletion, and commit data; expand a row to copy changed paths or open the project.
- Next Actions turns terminal state into a short reason and an exact control: Answer, Resolve, Review, Resume, or Open Project. Permission/approval prompts, conflicts, failures, questions, and completed work no longer share one vague warning.
- Project Health combines live agent count, branch, clean/dirty state, ahead/behind and conflicts, the last commit, and the newest GitHub Actions result when authenticated
ghis available. Click a repository to filter sessions, prompts, changes, and action signals across the whole dashboard; click the project chip at the top to clear it.
All three cards are independently removable. Drag their headers left or right to reorder them; they snap into place and the order persists. The layout compacts automatically when one or two cards are hidden.
#🟢🟡🔵 Machine — the boring numbers, in the corner where they belong
| Meter | Colour | Detail |
|---|---|---|
| CPU | theme blue | % busy, 1-min load, hottest thermal zone |
| RAM | theme green | used / total, % |
| Disk | theme yellow | used / total per mount (btrfs subvolume twins collapsed) |
| Wi-Fi | theme green | SSID, signal in dBm (bar = link quality), IPv4 |
| WAN | theme cyan | cached external IPv4/IPv6 |
| ↓ ↑ throughput | green | real-time bits/s (Kb/Mb/Gb) on the default route interface, wired or wireless |
| ⇄ latency | green / yellow / red | live ping to Cloudflare 1.1.1.1 — red on timeout |
| Battery | — | % and charging state, hidden on desktops |
Any meter goes red when it's genuinely in trouble (RAM > 90%, disk > 90%, CPU > 85%, ping dead).
The three right-column cards—Usage, Local AI, and Machine—also have draggable headers. Drag one far enough up or down to swap it with its neighbor; the card snaps into place and the order persists across overlay and shell restarts. Every section can still be removed and restored from the module strip.
#⌨️ Two surfaces, one dashboard
The wallpaper is interactive wherever no window covers it (double-click or right-click the empty desk opens Omarchy's wallpaper switcher, as stock does). After configuring the shortcuts, press SUPER + I to hide the wallpaper dashboard and see the clean desktop; press it again to restore the cards. When you're buried in terminals, SUPER + D shows the desktop on top of everything — the wallpaper exactly as the desk paints it, with the dashboard when SUPER+I has it visible and the plain photo when it doesn't; Esc or a click on the backdrop dismisses it.
The module strip doubles as a keyboard command strip in the overlay: 1–9 toggle modules, J/K (or arrows) select a live session, Enter focuses it, A clears activity filters, and Esc closes. The selected session gets a bright outline.
#Local development apps (optional)
Enable APPS in the module strip to register existing development commands and control their systemd user services: stable ports, HTTP readiness, checkout and branch, Open, Start/Stop, Restart, logs and configuration editing while an app is stopped. App package scripts stay unchanged. The helper uses the existing Bun runtime; no extra daemon or agent configuration is required. See Development apps for setup and CLI usage.
#Install
sudo pacman -S --needed bun # the collector runs on bun; Omarchy does not ship it omarchy plugin add https://github.com/nixfred/infomarchy.git --enable --yes omarchy restart shell # first time only: services load at shell start
If bun is missing the desk says so in red at the top and in the sessions card, and fills in on the next refresh after you install it — no restart needed.
The plugin declares itself as a clone of omarchy.background, so Omarchy hands it the wallpaper role. Your chosen wallpaper is still there — dimmed to 32% behind the glass — and omarchy theme bg set … keeps working.
#Configure keyboard shortcuts
Installing or enabling the plugin does not create Hyprland keybindings. The dashboard's SUPER+I and SUPER+D hints assume you have added the bindings below.
Check your existing shortcuts with omarchy menu keybindings --print, then add the fullscreen overlay and wallpaper-dashboard toggle to ~/.config/hypr/bindings.lua. Pick free chords; if you intentionally replace an existing binding, add hl.unbind("SUPER + I") or hl.unbind("SUPER + D") before its replacement.
o.bind("SUPER + D", "Infomarchy: AI info desk", "omarchy-shell shell toggle nixfred.infomarchy '{}'")
-- Hide the cards to see the plain desktop; press again to restore them.
o.bind("SUPER + I", "Infomarchy: toggle wallpaper dashboard", "omarchy-shell infomarchy toggleDashboard")
Reload and check for configuration errors:
hyprctl reload hyprctl configerrors
Press SUPER+I to hide the dashboard, then press it again to restore it. If nothing happens, try the same action directly:
omarchy-shell infomarchy toggleDashboard
If this hides or restores the cards, the plugin is working; check that your binding was added to the loaded Hyprland config and that hyprctl configerrors is empty. This command toggles visibility too, so run it again if you want to restore the previous state.
If the command works from a terminal but the key still does nothing, the two are looking for the shell in different places. omarchy-shell finds the running shell by $OMARCHY_PATH, and a keybinding inherits Hyprland's copy of that variable, not your terminal's. After omarchy dev link (or anything else that changes OMARCHY_PATH), Hyprland keeps the old value until you log out or reboot, so the key asks for a shell that is not there and fails silently. Compare the two:
echo "$OMARCHY_PATH" tr '\0' '\n' < /proc/$(pgrep -x Hyprland)/environ | grep '^OMARCHY_PATH='
If they differ, log out and back in (or reboot).
Manual install
git clone https://github.com/nixfred/infomarchy.git ~/.config/omarchy/plugins/nixfred.infomarchy omarchy-shell shell rescanPlugins omarchy plugin enable nixfred.infomarchy omarchy restart shell
Then configure the keyboard shortcuts above.
#Remove
Remove Infomarchy and return to the stock wallpaper service with:
omarchy plugin remove nixfred.infomarchy --yes
omarchy restart shell
#Requirements
Omarchy Quattro with third-party shell plugin support, bun (not part of the Omarchy base install — sudo pacman -S bun), iw, iproute2, and ping. Optional: nvidia-smi (GPU row hides without it), authenticated GitHub CLI gh (for the latest CI result and the GITHUB heatmap), a tea login or Gitea environment credentials (for the GITEA heatmap), the omarchy.agents bar widget (for the usage card), Ollama (for the local-AI card), Herdr/Boomux/tmux when those hosts are actually used, and ssh/sqlite3 when INFOMARCHY_FLEET_HOSTS names a remote host. Infomarchy does not start or configure a multiplexer. Hyprland 0.56+ (Lua dispatch) and older (focuswindow) are both handled.
#It follows your theme
There are no colours in this plugin. Infomarchy reads the active theme's colors.toml — green, yellow, red, blue, cyan, magenta, foreground, background — and falls back to Omarchy's Color singleton for anything a theme leaves out. Fonts and spacing come from Omarchy's Style, so omarchy display text size scales the desk too. Switch themes and the desk re-skins in place.
The screenshots above are the Last Call theme. A theme gallery is on the roadmap — PRs with your theme's screenshot are very welcome.
#How it works
┌──────────────────────────────┐ every 4 s ┌────────────────────────────────────┐
│ collector.ts (bun, ~0.2 s) │ ───── JSON ────────▶ │ InfoModel.qml │
│ /proc /sys hyprctl │ │ runs collector · parses snapshot │
│ ~/.claude/history.jsonl │ │ reads theme colors.toml │
│ ~/.codex/*.jsonl │ └──────────────┬─────────────────────┘
│ ~/.grok/active_sessions.json│ │ desk: InfoModel
│ ~/.local/share/opencode/*.db│ │
│ Ollama /api/ps /api/tags │ ┌─────────────────────┴───────────────────┐
│ omarchy agents usage cache │ │ InfoView.qml (cards, heatmap, meters) │
│ git · gh CI · gh activity │ └───────┬───────────────────────┬─────────┘
│ iw · ip · ping · nvidia-smi │ │ │
└──────────────────────────────┘ │ │
Infomarchy.qml ◀──┘ └──▶ Overlay.qml
service · WlrLayer.Background overlay · SUPER+D
(clonedFrom omarchy.background) WlrLayer.Overlay
collector.tsbuilds one snapshot. It readsargvfor every pid (cheap), then lazily opens only agent processes and their ancestors, so a 1 000-process box costs ~0.2 s warm. Local files are opened once with no-follow/nonblocking semantics, must be regular files, and are read under byte/time limits. Rate baselines use private, atomic state files under$XDG_STATE_HOME/infomarchy/prev-<instance>.json. It never parses the multi-hundred-MB Claude/Codex session transcripts — only the small history/index files and OpenCode's local SQLite history.gitea-activity.tsreads the selected tea login and keeps a bounded private cache of the authenticated user’s Gitea activity for the same heatmap.github-activity.tskeeps the 7-day GitHub row store: incrementalsearch/commitsand events fetches throughgh, keyed by sha and event id, pruned to the window, turned into the same 7×24 cells as the prompt heatmap.fleet-remote.tsprobesINFOMARCHY_FLEET_HOSTSoverssh -o BatchMode=yes, one bounded read-onlypscall per host, matched againstproviderOf()(passed in by reference, not duplicated) for the FLEET card.hermes-usage.tsreads Hermes's local billing ledger (~/.hermes/state.db) over the same ssh hosts with one boundedsqlite3 -readonly -jsoncall, for the USAGE & LIMITS Hermes row.resume-session.tsmaps each supported provider to its installed CLI resume syntax and launches it throughxdg-terminal-exec. Provider, ID, and project are separate process arguments; prompt text is never executed.ollama-control.tsaccepts one bounded JSON frame over stdin, validates the requested model against Ollama's inventory, and performs only explicit load/unload operations.notification-events.tsderives bounded, stable attention and lifecycle events. The background service sends them through Omarchy's notification interface after persistent deduplication; the overlay never sends a duplicate copy.InfoModel.qmlowns the timer, the parse, the theme colours, and helpers (focusWindow, formatting).InfoView.qmlis pure presentation, hosted twice: on the background layer byInfomarchy.qml, and on the overlay layer byOverlay.qml. The background host keeps thebackgroundIPC target so Omarchy's wallpaper tooling is unaffected.
#Portable by design
No usernames, hostnames or absolute paths are hardcoded anywhere. The collector honours HOME, XDG_STATE_HOME, XDG_DATA_HOME, CLAUDE_CONFIG_DIR, CODEX_HOME, OLLAMA_HOST and INFOMARCHY_FLEET_HOSTS; every source is optional and degrades to "not present" rather than failing. If you don't use Grok or OpenCode, its tag just never appears.
#Tuning
omarchy-shell infomarchy refresh # wallpaper collector now omarchy-shell shell call nixfred.infomarchy refresh # overlay collector (only while summoned) omarchy-shell infomarchy setWallpaperOpacity 0.5 # 0 = solid theme bg omarchy-shell infomarchy toggleDashboard # hide/show cards; keep wallpaper omarchy-shell infomarchy setDashboardVisible true # explicit on/off control omarchy-shell infomarchy toggleSection machine # remove/restore one dashboard card omarchy-shell infomarchy setSection recent true # explicit section visibility omarchy-shell infomarchy toggleNotifications # all Infomarchy alerts on/off omarchy-shell infomarchy geometry # live layout widths as JSON (view, columns, LOCAL AI card/body/rows) omarchy-shell infomarchy toggleQuietHours # fixed quiet window, 22:00–08:00 omarchy-shell infomarchy setDemo true # sanitized screenshot data; transient omarchy-shell infomarchy setDemo false # return to live local data
| Knob | Where | Default |
|---|---|---|
| poll interval | refreshMs in Infomarchy.qml / Overlay.qml |
4000 / 3000 ms |
| wallpaper dim | wallpaperOpacity in Infomarchy.qml |
0.32 |
| wallpaper dashboard | SUPER+I or wallpaper IPC above; state survives shell/plugin restarts |
visible |
| session notifications | Next Actions card or wallpaper IPC above | on |
| notification quiet hours | Next Actions card or wallpaper IPC above | off (22:00–08:00 when enabled) |
| space left for the bar | topInset in InfoView.qml |
40 px × font scale |
| provider colours | providerColor() in InfoModel.qml |
theme ANSI roles |
| add a provider | one regex in PROVIDERS in collector.ts |
— |
| fleet hosts | INFOMARCHY_FLEET_HOSTS env var, comma-separated ssh aliases |
unset (disabled) |
| fleet/Hermes-usage refresh interval | FLEET_REFRESH_MS / HERMES_USAGE_REFRESH_MS in fleet-remote.ts / hermes-usage.ts |
30 000 / 60 000 ms |
#Data handling
Prompt and session data stays on the machine, with the one documented exception of automatic topic refinement described below. Prompt text is stored as a 140-character redacted excerpt; the drawer's COPY EXCERPT and the search box operate on that excerpt, not the full prompt. Network checks are limited to the existing ping to 1.1.1.1, the Ollama API, a Cloudflare trace request for the public IP at most once every 15 minutes per dashboard surface, and—only when authenticated gh is installed—the newest GitHub Actions run for each active repository, cached for ten minutes. Automatic topic refinement sends recent prompt text to Ollama only when OLLAMA_HOST is loopback; pointing it at another machine disables refinement unless you set INFOMARCHY_ALLOW_REMOTE_OLLAMA=1 in the shell's environment, because that is prompt text leaving the machine. That test reads the address, not the destination: an SSH port forward to a remote Ollama answers on 127.0.0.1, passes the check, and refinement then posts prompt text off the machine. A forward cannot be told from a local socket by its address, so the remedy is a switch rather than a smarter test — set INFOMARCHY_SKIP_REFINEMENT=1 to disable automatic refinement outright, checked before both the loopback test and the opt-in. That check reads the address and not the destination, so an SSH port forward to a remote Ollama answers on loopback and passes it. Set INFOMARCHY_SKIP_REFINEMENT=1 to refuse automatic refinement outright — it is checked before both the loopback test and the opt-in. It must be in the environment of the running shell, not merely exported in a terminal: the wallpaper and overlay collectors inherit their environment at launch, so restart the shell to apply it, and it does not cancel a request already in flight. It governs automatic refinement only; inventory checks and explicit LOAD/UNLOAD still reach Ollama, the latter with an empty prompt to set model residency. Explicit LOAD/UNLOAD clicks still target whatever host you configured. Ollama state changes happen only after an explicit card action and can only load or unload a model already present in the corresponding local inventory. Notifications are sent to the local Omarchy notification service; no session data is relayed to a remote notification provider. Multiplexer reporting reads only documented Herdr/Boomux/tmux identity variables; tmux inventory commands run only while tmux is already present, and Infomarchy never invokes Herdr or Boomux control APIs. Recent task text is credential-redacted before it reaches QML (token prefixes, KEY=value style assignments, authenticated URLs, PEM blocks, JWTs and common cloud key shapes — best effort, not a guarantee). Attention states come from terminal-title heuristics and are only evaluated while an agent is idle; a title that merely mentions "permission" or "failed" while it is still working does not raise a signal. Hover previews (off by default) capture the screen region the window occupies, so an occluded window previews whatever is drawn on top of it. Collector JSON is depth/node/byte bounded and streamed to QML in capped frames. Desktop stream privacy masks host/network details, GitHub and Gitea logins, home paths, window titles (account, host and home path), window previews, and recent-task text after its first four words. Project names and session topics stay visible; COPY EXCERPT still copies the full stored excerpt. This is a display mask, not a change to the local collector snapshot. The explicit setDemo true screenshot mode replaces the whole snapshot with documentation-only sample data and resets off whenever the shell restarts.
Prompt and session data stays on the machine. Prompt text is stored as a 140-character redacted excerpt; the drawer's COPY EXCERPT and the search box operate on that excerpt, not the full prompt. Activity cards contact GitHub through authenticated gh and Gitea at the explicitly configured server, without sending prompt or session content. Other network checks are limited to the existing ping to 1.1.1.1, the Ollama API, a Cloudflare trace request for the public IP at most once every 15 minutes per dashboard surface, and—only when authenticated gh is installed—the newest GitHub Actions run for each active repository, cached for ten minutes. Automatic topic refinement sends recent prompt text to Ollama only when OLLAMA_HOST is loopback; pointing it at another machine disables refinement unless you set INFOMARCHY_ALLOW_REMOTE_OLLAMA=1 in the shell's environment, because that is prompt text leaving the machine. Explicit LOAD/UNLOAD clicks still target whatever host you configured. Ollama state changes happen only after an explicit card action and can only load or unload a model already present in the corresponding local inventory. Notifications are sent to the local Omarchy notification service; no session data is relayed to a remote notification provider. Multiplexer reporting reads only documented Herdr/Boomux/tmux identity variables; tmux inventory commands run only while tmux is already present, and Infomarchy never invokes Herdr or Boomux control APIs. Recent task text is credential-redacted before it reaches QML (token prefixes, KEY=value style assignments, authenticated URLs, PEM blocks, JWTs and common cloud key shapes — best effort, not a guarantee). Attention states come from terminal-title heuristics and are only evaluated while an agent is idle; a title that merely mentions "permission" or "failed" while it is still working does not raise a signal. Hover previews (off by default) capture the screen region the window occupies, so an occluded window previews whatever is drawn on top of it. Collector JSON is depth/node/byte bounded and streamed to QML in capped frames. Desktop stream privacy masks host/network details, GitHub and Gitea logins, home paths, window titles (account, host and home path), window previews, and recent-task text after its first four words. Project names and session topics stay visible; COPY EXCERPT still copies the full stored excerpt. This is a display mask, not a change to the local collector snapshot. The explicit setDemo true screenshot mode replaces the whole snapshot with documentation-only sample data and resets off whenever the shell restarts.
Use omarchy-shell infomarchy togglePrivacy or bind it to SUPER+SHIFT+I for stream privacy. One press enables it; three presses, with no more than two seconds between presses, disable it. The chip shows unlock progress, and the overlay ignores key repeat. omarchy-shell infomarchy setPrivacy false explicitly clears it in one call. The setting persists across restarts.
Observational Git commands disable filesystem monitors, hooks, external diffs, text conversion, and credential helpers, and ignore global/system Git configuration. GitHub CI polling resolves a github.com origin to owner/repo and calls gh --repo outside the agent working directory; INFOMARCHY_SKIP_GITHUB=1 skips both CI and activity fetching. Herdr focus requires the matching socket. Recent-task redaction also recognizes GitHub fine-grained, xAI, GitLab, Hugging Face, Stripe, and npm token prefixes, including Grok Bot text before markdown flattening. Resume uses the same project-directory guard as Open Project.
LOCAL AI can persist a server origin with omarchy-shell infomarchy setOllamaHost http://127.0.0.1:11434; getOllamaHost reads it and an empty value restores environment/default behavior. Both the model inventory and explicit load/unload actions use the selected origin. URLs containing credentials, paths, queries, or fragments are rejected. Topic refinement retains its loopback-only default unless INFOMARCHY_ALLOW_REMOTE_OLLAMA=1 is explicitly set.
FLEET dials nothing unless INFOMARCHY_FLEET_HOSTS names a host, and reads only that host — never a scan, never a discovery step. Each host gets one ssh -o BatchMode=yes -o ConnectTimeout=4 <host> <fixed commands> call per refresh; an unknown host key or a password prompt fails the probe instead of hanging or falling back to interactive auth, and the remote commands are fixed strings, never built from INFOMARCHY_FLEET_HOSTS beyond the host argument itself, so there is nothing in that variable for an entry to inject into. Presence detection runs ps -eo pid=,args=, bounded on both ends. Hermes usage reads two files in the same SSH call — ~/.hermes/state.db with sqlite3 -readonly, and ~/.hermes/workspace/openrouter_key_usage.json with a bounded cat — both read-only, both bounded. No OpenRouter or other third-party API is called by Infomarchy directly, and no API key is stored anywhere for this feature; the key-usage file is itself just Hermes's own cache of a call Hermes already made. INFOMARCHY_SKIP_FLEET=1 disables both probes.
Still and animated image wallpapers share one image surface. Supported animated GIF/WebP files play their own frames; still files remain still. The overlay pauses playback and rendering while closed. Existing video wallpaper handling is unchanged.
#Media controls
A hideable, reorderable MEDIA CONTROLS card uses the local MPRIS service for title, artist, album, player identity, and previous/play-pause/next actions. A playing player is preferred, and playerctld is used only when no other player exists. Metadata is bounded plain text; album art is never fetched. Demo mode shows sample metadata and disables actions.
Pi sessions are detected from the pi process and ~/.pi/agent/sessions JSONL history. Recent Tasks includes Pi prompts, activity, and resume via pi --session <id>. The recent-task window reserves space for quieter providers while retaining pinned-first and newest-first display order.
#Containers
An optional CONTAINERS card joins the right column, with Docker (/usr/bin/docker) preferred over Podman. It shows up to eight rows and explicit start/stop toggles. Each action checks a fresh ps -a inventory and passes the matched name as a separate argument. The bounded snapshot retains only id, name, display label, compose service/project, short image, state, running status and health; it excludes compose working directories, env files, commands, mounts and ports. Hide/reorder the card through the existing module controls; INFOMARCHY_SKIP_CONTAINERS=1 skips collection.
#FAQ
Does it drain my battery? One bun run every 4 s (~0.2 s of CPU warm), no idle animation except the busy-dot pulse — a few percent of one core at most. Raise refreshMs if you want it lower.
The desk is black / empty. You changed QML and the shell didn't reload the service — run omarchy restart shell. (collector.ts changes are picked up live.)
Clicking a card doesn't focus anything. The card says no window — the agent isn't under a Hyprland client (SSH session, systemd service, or started from a launcher that already exited). That's expected.
Can I keep the stock wallpaper behaviour too? Yes: disable nixfred.infomarchy and Omarchy restores omarchy.background. Or keep it enabled and set wallpaperOpacity to taste.
Two monitors? One desk per screen, each sized to its own resolution.
#Roadmap
- Per-card show/hide in the plugin settings schema (no QML editing)
- Task board from Claude Code
TaskCreate/ Codex goals, with completed-task history - Memory / vector-store growth sparkline (qdrant, LMF, …)
- Theme gallery in this README — send yours
#Contributing
Issues and PRs welcome. The one rule: nothing machine-specific — if it needs your username, your path or your hostname, it needs to come from an env var or /proc. Adding a provider is a regex in collector.ts plus a colour/label in InfoModel.qml; please include a redacted sample of the data you're reading.
#Credits
Built on the Omarchy shell by DHH and contributors, Quickshell, and Hyprland. The usage card stands on the shoulders of Omarchy's omarchy.agents widget.
Made by Fred Nix with Larry, Atlanta, 2026.