Omahub
← All plugins
K

Nook

by Katsari

A bar drawer for when too many plugins have cluttered your bar. Collapse the ones you rarely touch into a tray that opens below the bar rather than along it, so nothing on the bar gets covered or moved. Drag widgets in and out.

Security review

Review recommended · 4 findings

Deterministic scan — not a security guarantee

Medium
Risk level
Medium
Analyzed commit
5bd4cc1
Scanned
3 weeks ago
  • medium package_manager …/workflows/tests.yml:21

    System package manager operation.

    apt-get update -qq
  • medium package_manager …/workflows/tests.yml:22

    System package manager operation.

    apt-get install -y --no-install-recommends qt6-declarative-dev-tools
  • Command runs with sudo, elevating the process beyond the plugin environment.

    sudo apt-get update -qq
  • Command runs with sudo, elevating the process beyond the plugin environment.

    sudo apt-get install -y --no-install-recommends qt6-declarative-dev-tools

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
5bd4cc1
Reviewed
3 weeks ago

This is a QML bar widget whose runtime behavior is limited to hosting widgets in a drawer/tray and rewriting the Omarchy shell layout config when users drag widgets in or out. The deterministic scan's medium findings are from sudo/apt-get in the GitHub Actions workflow, which is CI-only and never runs during plugin install or runtime. No shell execution by the plugin, credential access, obfuscation, or destructive persistence behavior was found.

  • The plugin writes to ~/.config/omarchy/shell.json automatically; this is documented behavior, but a bug could disrupt the user's layout config.
  • It relies on undocumented Omarchy bar internals and bar adoption heuristics, which is fragile and may misbehave across host updates, though it is not itself a security exploit.
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/Katsari/nook --enable
Widgets #bar #quickshell

Nook

A bar drawer for Omarchy, for when too many plugins have cluttered your bar. Collapse the ones you rarely touch into a tray that opens below the bar rather than along it, so nothing on the bar gets covered or moved. Drag widgets in and out.

Nook open, with several widgets in the tray

Install

omarchy plugin add https://github.com/Katsari/nook.git --enable

Update

omarchy plugin update io.github.katsari.nook
omarchy restart shell

The restart is needed because a rescan does not replace a plugin's already-compiled code. The same applies after editing Nook's code by hand.

Usage

Hover the chevron to open the tray. Click it to pin the tray open, and click again to put it away. Click a widget inside to use it as you would on the bar.

Drag a widget off the bar onto the chevron to file it away, drag one inside the tray to reorder it, and drag one out to put it back on the bar. A caret marks where it will land. A press too short to become a drag stays a click.

Every move rewrites ~/.config/omarchy/shell.json.

Settings

Settings live on Nook's bar.layout entry in ~/.config/omarchy/shell.json.

Key Default Meaning
items [] The widgets inside, as layout entries
trigger "hover" "hover" opens on pointer-over; anything else means click-only
duration 180 Reveal animation, in milliseconds

The tray's layer surface is named nook, for Hyprland layer rules.

Custom modules work too. An entry with exec runs its command on an interval and shows the output, the same as on the bar; one with source loads that QML file. Neither is a plugin, so neither needs a plugins[] entry.

Each item takes the same shape as a bar layout entry, so per-widget settings go on the item:

{
  "id": "io.github.katsari.nook",
  "trigger": "hover",
  "items": [
    { "id": "some.widget" },
    { "id": "another.widget", "format": "short" }
  ]
}

Editing items by hand needs a second step: add each widget to the top-level plugins[] array as well, or it stays disabled and never renders. Dragging does both for you.

Commands

omarchy-shell io.github.katsari.nook toggle            # also: open, close
omarchy-shell io.github.katsari.nook absorb <id>       # move a widget in
omarchy-shell io.github.katsari.nook eject <id>        # put one back on the bar
omarchy-shell io.github.katsari.nook reorder <from> <to>
omarchy-shell io.github.katsari.nook status            # what it thinks it is doing

reorder takes positions among the widgets the tray draws, counting from zero. to is an insertion index measured before the move, so reorder 0 3 puts the first widget third.

Read status when a gesture misbehaves: it separates a wrong state from a pointer that never arrived.

Tests

tests/all.sh

GitHub Actions runs the node tests and the source checks on every push. The lint and harness legs need the omarchy shell source and a Wayland session, so they skip themselves there and only run locally.

tests/layoutmodel.test.js runs every shell.json edit in LayoutModel.js under node. tests/qml.test.sh lints BarWidget.qml, checks that the QML and the library agree, and loads the real widget in a throwaway quickshell instance against a mock bar to drive absorb, reorder, eject, and both reconcile paths end to end.

tests/drag.test.py drives the real pointer, so it is opt-in:

tests/all.sh --drag

It drags a widget off the bar into the drawer, hovers the chevron and checks the widget is actually drawn below the bar, then drags it back out. It takes over the mouse for about twenty seconds. Build the pointer once with tests/tools/vptr/build.sh. shell.json is snapshotted first and restored at the end, pass or fail.

Remove

omarchy plugin remove io.github.katsari.nook

Whatever the tray held stays in items on that entry, so removing Nook while it is full leaves those widgets off your bar. Drag them out first, or eject each one.

Known limits

Built for Omarchy 4.0.3. Beyond the widget contract every plugin uses, Nook reaches into the bar's widget registry, its slot and click-target bookkeeping, and its drag state. No plugin API covers those. 4.0.3 stopped handing third-party widgets the real bar, so Nook now adopts it from a first-party widget on the same bar; on a bar without any first-party widget it sits inert. A future update can break it again.

  • One Nook per bar. The manifest sets allowMultiple false, so the bar will not add a second. A hand-written one would still load, and both would write to the first entry they find.
  • Bottom and right bars can misroute a bar click. Bar.moduleClickTargetAt maps a click into every registered target's geometry without checking which window the target is in, and on those two edges the tray overlaps the bar's coordinate range. The chevron is covered; other bar widgets are not.
  • The bar's own tooling does not see inside the tray. omarchy bar set, omarchy bar move and omarchy-shell shell listPlugins all read bar.layout, so a hosted widget reads as absent, and listPlugins reports it disabled. Eject it to configure it from the command line.
  • Panel numbers skip hosted widgets. omarchy-shell shell togglePanelAt counts the panels visible in a bar section, so the tray's contents are not in the count. Toggling a panel by id works: omarchy-shell shell summon <id> opens the tray and its panel with it.