Omahub
← All plugins
R

AgentsView

by Ricardo Liberato

AgentsView in the Omarchy bar — the sessions running now, today's scoreboard, search across every past session, and a click to resume any of them in luvus.

Security review

Potentially dangerous behavior detected · 5 findings

Deterministic scan — not a security guarantee

High
Risk level
High
Analyzed commit
c7d8f15
Scanned
1 month ago
  • high destructive_filesystem tests/model.test.js:136

    Destructive operation on the root filesystem or a block device.

    rm -rf /home`).reason, /not on the allowlist: rm/)
  • high destructive_filesystem tests/model.test.js:138

    Destructive operation on the root filesystem or a block device.

    rm -rf /`).reason, /will not type: a;/)
  • high destructive_filesystem tests/model.test.js:139

    Destructive operation on the root filesystem or a block device.

    rm -rf /`).reason, /will not type/)
  • high destructive_filesystem tests/model.test.js:186

    Destructive operation on the root filesystem or a block device.

    rm -rf /'), Model.DEFAULT_URL)
  • Docs persistence README.md:172

    Bundles a systemd unit file.

    [Unit]

Automated analysis only — not a security guarantee.

AI advisory review

No obvious issues detected

Language-model assessment · ~deepseek/deepseek-v4-flash-latest — advisory only

Low
AI risk level
Low
Recommendation
install
Model
~deepseek/deepseek-v4-flash-latest
Analyzed commit
c7d8f15
Reviewed
1 month ago

The deterministic scan's high rating comes from false positives: the `rm -rf` strings are string literals inside unit-test assertions that verify the resume parser rejects hostile commands, and the systemd `[Unit]` block is documentation in the README, not an installed service. The runtime code is carefully hardened with validated URLs, bounded reads, strict parsing, and an allowlist for resumed agent commands, and no malicious behavior was found.

  • The `rm -rf /home` and `rm -rf /` snippets flagged by the scanner appear only as test inputs in tests/model.test.js to confirm Model.parseResume rejects them; they are never executed by the plugin.
  • The systemd unit flagged as persistence is an optional user-service example in README.md for keeping AgentsView running; the plugin itself creates no files and installs no service.
  • The plugin does execute shell helpers and can run agent CLIs via luvus, but the resume path is restricted to an allowlist and shell-inert tokens, and network inputs are bounded and validated.
How this check works

This review combines the deterministic scan (the rule-based results above) with an independent look at the plugin's code by a language model. The model reads a trimmed sample of the repository's files, the manifest, and the README, then gives a plain-language risk level and a recommendation: install (no notable danger), review (look closer first), or avoid (clearly dangerous).

It runs on the same analyzed commit as the deterministic scan and is strictly advisory — it is not a security guarantee and never blocks a plugin by itself. A human moderator still reviews plugins before they are listed.

AI advisory only — automated analysis, not a security guarantee.

Install
$ omarchy plugin add https://github.com/riclib/omarchy-agentsview --enable
Developer Tools #bar #quickshell #ai

omarchy-agentsview

An Omarchy shell plugin for AgentsView: your coding-agent sessions in the bar — what is running now, today's scoreboard, search across every session you have ever had, and a click to resume any of them in luvus, in its own project.

One glyph and one number. While anything is active the number is how many, in the accent colour; otherwise it is today's count, quietly.

󰋚 3      three sessions active right now
󰋚 11     nothing active, eleven sessions today
󰋚 ×      AgentsView is not running

Click for the panel. Middle click to refresh. Right click to open AgentsView itself.

<p align="center"> <img src="preview.png" alt="The AgentsView widget in the Omarchy bar with its panel open: a search box, today's scoreboard, the sessions active now, and today's sessions grouped by project" width="420"> </p>

Requires

  • AgentsView 0.41 or newer, running as a server this plugin can reach — agentsview serve, or better, supervised so it never idle-exits (systemd --user unit: see Keeping the server up). Tested against v0.41.1.
  • luvus, for the resume button, and jq (already on Omarchy) for the one place a script reads luvus's JSON. Everything else works without either.
  • The Omarchy shell, and a Nerd Font for the glyphs — Omarchy's bar font already is one.

The only other programs it runs are curl, and the ones that bound what the server is allowed to hand back and how long it may outlive the bar — timeout, head, fold and stdbuf from coreutils, setpriv from util-linux — all of which are already on any machine running Omarchy.

Install

omarchy plugin add https://github.com/riclib/omarchy-agentsview.git --enable
omarchy restart shell

--enable places the widget for you and writes ~/.config/omarchy/shell.json itself. To place it later, or to move it:

omarchy plugin enable riclib.agentsview --section center

Omarchy plugins are unsandboxed code running inside the long-lived shell process. Read the source before installing this or any other one.

Update

omarchy plugin update riclib.agentsview --yes
omarchy restart shell

Remove

omarchy plugin remove riclib.agentsview
omarchy restart shell

That is the whole removal. The plugin creates no files, writes no configuration of yours, installs no service and stores nothing on disk — it reads AgentsView and draws. AgentsView itself, its archive and its server are untouched.

The panel

Top to bottom:

  • Search — type, press Enter, and every session AgentsView has is searched, including the agents' own replies. One row per session, however many messages matched, with the count. / focuses the box from anywhere in the panel; Escape clears it, then closes.
  • Today — sessions, agent time, output tokens and cost so far today, with the peak number of agents running at once and the all-time totals under it. These are AgentsView's own numbers, from its activity report, in your local timezone.
  • Active now — every session that wrote anything in the last 15 minutes (the activeMinutes setting), across every agent AgentsView knows.
  • Sessions today — grouped by project, most recent first. Each row is the session's first prompt, then agent, branch and how many prompts you gave it. The badge on the left is AgentsView's health grade for the session; a dot means it is active.

Clicking any row opens that session in AgentsView, as an Omarchy web app. The button on the right takes you to it in luvus: ↗ when luvus already has it on screen (the click focuses that pane), 󰐊 when it does not (the click resumes it in a fresh one).

Keys, while the panel has focus: / search, r refresh, o open AgentsView, Escape close.

Resuming a session in luvus

luvus reports the agent session id of every pane it hosts, and the panel reads that list with every refresh — so a session that is already open, even one working right now, is never opened a second time beside itself. Its button shows ↗, and clicking it is luvus pane focus. The spawn path below checks again on its way, for a pane that appeared since the last refresh.

For a session that is not on screen, the button asks AgentsView for the command that would resume the session — claude --resume <id>, or whatever the agent's own flag is; AgentsView knows — and takes it to luvus in three steps:

luvus workspace open <the session's directory>   # opens the project, or focuses it if already open
luvus pane split --no-focus                      # a fresh pane in it
luvus pane run <that pane> cd '<dir>' && <agent> <args…>   # the agent comes back, mid-conversation

The server's command is never run as it came. luvus pane run types its words into a shell, so the plugin takes AgentsView's answer apart and only rebuilds it if every piece passes: the shape must be exactly cd '<dir>' && <agent> <args…> with <dir> the very directory the same answer reports; <agent> must be a bare name from a built-in allowlist of agent CLIs (claude, codex, gemini, grok, opencode, copilot, kimi, omp, cursor-agent, amp, droid, pi, crush, ori, agy, qwen, goose, aider, cline — extend it with the resumeAgents setting); and every argument must be a word a shell passes through untouched — no quotes, spaces, ;, $, |, &, > or globs. Anything else is refused with the reason shown, including a shape AgentsView might adopt in a later version. A compromised server, or a wrong serverUrl, can therefore make the button do nothing — not run something.

So a session from a project you do not currently have open gets its workspace created on the way. The outcome — or the reason it failed — appears at the bottom of the panel.

luvus focuses the new pane inside its TUI but cannot raise the terminal window that hosts it; nothing running inside a terminal can. Set focusWindowClass to that terminal's Hyprland class (find it with hyprctl clients) and the plugin raises the window too.

luvus's own agent resume is not used here, on purpose: it only knows the sessions luvus itself has watched, and AgentsView knows every session on the disk.

Settings

All of these are also editable in the shell's widget settings UI.

Key Type Default Meaning
serverUrl string http://127.0.0.1:8080 Where AgentsView is listening. Change it only for a remote or proxied server.
token string (empty) Only for a server running with require_auth. Sent as a bearer header, carried in the environment rather than on a command line.
activeMinutes integer 15 A session counts as active if it wrote anything this recently.
pushUpdates boolean true Hold the server's event stream open and refresh the moment its data changes. Off falls back to polling alone.
hideWhenIdle boolean false Show the widget only while a session is active. It stays visible while the panel is open, and while the server is unreachable.
resumeAgents string (empty) Extra agent CLIs the resume button may run, comma-separated bare names, on top of the built-in allowlist.
luvusBin string luvus Resolved on PATH as a bare name. Set an absolute path if resume says the binary is missing while your terminal finds it — the shell does not always inherit a login PATH.
focusWindowClass string (empty) The Hyprland class of the terminal hosting luvus. See above.

Keeping the server up

AgentsView's CLI starts a detached daemon on demand, and that daemon exits after an idle timeout. A bar widget pointed at a port with nothing behind it shows ×, which is honest but not useful. A supervised server never creates that idle tracker — upstream documents this — so run it as a user service:

# ~/.config/systemd/user/agentsview.service
[Unit]
Description=AgentsView — local viewer for AI agent sessions
After=graphical-session-pre.target

[Service]
ExecStart=/usr/bin/agentsview serve --no-browser
Restart=on-failure

[Install]
WantedBy=default.target
systemctl --user enable --now agentsview.service

It reads port, bind address and sync roots from ~/.agentsview/config.toml like any other launch, and agentsview daemon status recognises it as the daemon.

How it stays current

Two ways in, deliberately:

  • bin/agentsview-snapshot — the whole truth, on demand: four HTTP reads in one process, one answer for the panel to reason about.
  • GET /api/v1/events — a held-open server-sent-events stream that says when to ask again. The server broadcasts data_changed with a scope and nothing else, coalesced to one every ten seconds, so events are a doorbell here, not a data source.

Both are bounded before the answer reaches the shell rather than after it arrives: the read through timeout and head -c, the stream through fold, which caps how long a single line can grow. The bar is one widget inside a shell that draws the whole desktop, and a line that never ends is otherwise buffered in that shell's memory while it waits for a newline that may never come. Neither outlives the bar: both carry a parent-death signal, so closing the stream — or the shell quitting, or crashing — takes curl with it.

A 60-second timer sits behind all of it. It is not the update mechanism; it is the thing that notices the doorbell has stopped working. When the subscription is down the panel says so.

Lineage

The service, the bar slot and most of the panel's shape are taken from omarchy-luvus, which in turn took its panel from io.github.fabean.herdr (MIT, Josh Fabean). The bounding of what a server may hand a shell, and the process-lifecycle handling, were learned there the hard way and are carried over whole.

License

MIT.