Omahub
← All plugins
E

Nordstart

by espen

Workspace launcher with pinned apps, an installed-app search, an app store, session actions, and shortcuts to Nordtema and Nordsettings

Security review

Potentially dangerous behavior detected · 6 findings

Deterministic scan — not a security guarantee

High
Risk level
High
Analyzed commit
c82598e
Scanned
1 week ago
  • high destructive_filesystem tests/store-model.test.js:243

    Destructive operation on the root filesystem or a block device.

    rm -rf /"))
  • high destructive_filesystem tests/nordstart-model.test.js:662

    Destructive operation on the root filesystem or a block device.

    rm -rf /", false, false), "")
  • Dynamic code execution via eval().

    eval(): the input is whatever the user
  • medium sudo StoreModel.js:8

    Command runs with sudo, elevating the process beyond the plugin environment.

    sudo prompt — this plugin
  • Docs sudo README.md:210

    Command runs with sudo, elevating the process beyond the plugin environment.

    sudo
  • Docs sudo CLAUDE.md:93

    Command runs with sudo, elevating the process beyond the plugin environment.

    sudo prompt — **this plugin

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
c82598e
Reviewed
1 week ago

The deterministic scan's high-risk findings are false positives: the `rm -rf /` strings appear only in unit tests that verify the model does not execute destructive commands, and the `eval()` and `sudo` hits are comments/documentation, not executable code. The plugin itself is a well-structured bar widget that launches apps, manages workspaces, and provides an app store that delegates install/remove actions to Omarchy's own curated commands and floating-terminal sudo prompts, with no privilege escalation or destructive operations in the runtime code.

  • The app store feature runs package install/remove commands via Omarchy's own mechanisms, which is user-initiated and documented, but a human should verify the catalog sources and command construction are safe.
  • The plugin reads and executes commands from Omarchy's menu files; if those files are tampered with, the plugin would run whatever they contain, but that is an inherent trust in the host system, not a plugin vulnerability.
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/ekrist1/nordstart --enable
Desktop #bar #workspaces

Nordstart

An Omarchy shell plugin that replaces the stock workspace numbers with compact number-and-app-icon pills and keeps a 3×3 grid button for opening the full workspace launcher.

The modal has two halves:

  • Workspaces — a 3×3 grid of workspaces 1–9. Occupied workspaces show the name of the app running there; empty ones read empty.
  • Pinned apps — a list of favorite apps with a dot that lights up when the app is already open. Click a running app to jump to its workspace, or a closed one to launch it on the first empty workspace.

Open it and start typing: the search finds apps, recently opened files, sums and unit conversions (=2*21, =12 km to mi), and falls back to a web search. Digits typed into an empty search still switch workspaces, so Super+N, 3 goes straight to workspace 3.

Behind those sit full-width views: the all-apps list (Ctrl+A), the window switcher (Ctrl+W), an overview of every workspace as a thumbnail (Ctrl+O), and the app store (Ctrl+S), where you can install, update and uninstall software. Press ? for every shortcut.

Prefer single-letter shortcuts? Set Keyboard to Shortcuts first and the actions become bare letters (a, w, o, s, ...), with q or / to search — the way Nordstart worked before.

Click a workspace, press 1–9, or move with the arrow keys and press Enter. Tab and Shift+Tab move to the next or previous bar panel.

Disclaimer

This plugin is made with Grok AI. The code is not guaranteed to be correct and may require manual review and testing. Use at your own risk.

Install

omarchy plugin add https://github.com/ekrist1/nordstart.git --enable --yes
omarchy restart shell

From this folder, without git:

omarchy plugin validate .
mkdir -p ~/.config/omarchy/plugins
rsync -a --delete --exclude .git ./ ~/.config/omarchy/plugins/io.github.ekrist1.nordstart/
omarchy-restart-shell
omarchy plugin enable io.github.ekrist1.nordstart --yes

Nordstart uses Omarchy's supported clonedFrom mechanism to take the stock workspace widget's position. There is no separate omarchy bar move step, and another plugin that also replaces omarchy.workspaces should not be enabled at the same time.

When upgrading an already-enabled Nordstart installation from a release before the workspace pills, reapply the clone once so the old workspace entry is removed:

omarchy plugin disable io.github.ekrist1.nordstart
omarchy plugin enable io.github.ekrist1.nordstart
omarchy restart shell

Re-syncing after an edit needs omarchy-restart-shell, not omarchy-shell shell rescanPlugins: the latter reloads the plugin entry but the QML engine keeps its already-compiled Panel.qml, so the running shell quietly carries on with the old code.

Omarchy 4.0.3 compatibility

Nordstart falls back to its own desktop-app catalog and Quickshell icon lookup when Omarchy does not expose shell.appLibrary to bar widgets. App search keeps the same scoring and hidden-entry filtering. Older hosts that expose the library continue to use it. With the fallback, newly installed themed icons may require a shell restart if Qt has cached the icon theme.

Keyboard shortcut

Add this to ~/.config/hypr/bindings.lua:

o.bind(
  "SUPER + N",
  "Nordstart",
  "omarchy-shell shell toggle io.github.ekrist1.nordstart"
)

Hyprland reloads the file on save. SUPER+N is free in stock Omarchy; SUPER+SHIFT+N stays bound to the editor.

You can also toggle it from a terminal:

omarchy-shell shell toggle io.github.ekrist1.nordstart

Opening a view directly

Each view has its own IPC call, so a binding can land straight in it. Calling the view that is already showing closes it, so one key toggles, the way Mission Control and Task View do. Esc from a view opened this way closes the launcher rather than dropping to the grid.

omarchy-shell io.github.ekrist1.nordstart overview   # every workspace as a thumbnail
omarchy-shell io.github.ekrist1.nordstart windows    # window switcher
omarchy-shell io.github.ekrist1.nordstart apps       # all apps
omarchy-shell io.github.ekrist1.nordstart store
omarchy-shell io.github.ekrist1.nordstart help       # the shortcut sheet
omarchy-shell io.github.ekrist1.nordstart search "firefox"

macOS / Windows-style workspace switching

workspace steps through the 3×3 grid: left/right walk 1 → 9 in a line, up/down jump a row, next/prev wrap. With the switch overlay on (the default), every switch flashes a small map of the grid so you can see where you landed.

-- Ctrl+Alt+arrows: GNOME's long-standing workspace keys, and free in Omarchy.
-- (Ctrl+Super+Left/Right, the Windows keys, move group focus in Omarchy, and
-- plain Ctrl+arrows jump words in text fields.)
o.bind("CTRL + ALT + LEFT",  "Workspace left",  "omarchy-shell io.github.ekrist1.nordstart workspace left")
o.bind("CTRL + ALT + RIGHT", "Workspace right", "omarchy-shell io.github.ekrist1.nordstart workspace right")
o.bind("CTRL + ALT + UP",    "Workspace up",    "omarchy-shell io.github.ekrist1.nordstart workspace up")
o.bind("CTRL + ALT + DOWN",  "Workspace down",  "omarchy-shell io.github.ekrist1.nordstart workspace down")
-- Mission Control / Task View
o.bind("SUPER + GRAVE", "Workspace overview", "omarchy-shell io.github.ekrist1.nordstart overview")

On a laptop, the closest thing to the macOS gesture is Hyprland's own three-finger swipe, which Omarchy ships commented out in ~/.config/hypr/input.lua. The overlay flashes for swipes too.

Use

  • Just type. The launcher opens with the search focused (Keyboard: Search first). The first letter swaps the grid for results; deleting back to nothing brings the grid back. Results can include:

    • apps, ranked by how much you use them;
    • a calculator — =2*21, =sqrt(2), =(4+5)^2; Enter copies the answer;
    • unit conversion — =12 km to mi, =100 f to c, =1 GiB to MB (length, mass, volume, data, time, speed, temperature; no currency, which needs live rates); Enter copies it;
    • recent files from GTK's recently-used list; Enter opens one;
    • a web search as the last row.

    Start maths with =: a digit typed into an empty search switches workspace. Actions are Ctrl+letter while typing: Ctrl+A all apps, Ctrl+W windows, Ctrl+O overview, Ctrl+S store, Ctrl+M move, Ctrl+P pin, Ctrl+N new window, Ctrl+T theme, Ctrl+C Hyprland settings. ? or F1 shows them all.

  • Scroll over the workspace pills to walk through them.

  • Each tile in the launcher's grid shows the icons of the windows on it. Click an icon to go to that window; drag it onto another tile to move the window there (you stay where you are, unless Follow moved windows is on).

  • Press o / Ctrl+O (or click overview) for the overview: every workspace as a thumbnail with its window icons. Arrows or digits pick one, Enter goes there, and dragging icons between tiles moves windows, as in Mission Control.

  • Click a workspace pill to switch to it. Each occupied pill shows the primary app's icon; by default unused workspaces stay hidden so the bar remains compact. Hover a pill for its window list and click a row to focus that exact window. The hover card can optionally include a live graphical preview.

  • Hover or click the grid icon beside the workspace pills to open the launcher.

  • Click a workspace, or press its number, to switch to it. With workspace preview on, the right side shows a live view of that workspace's window.

  • Click a pinned app to go to it if it is running, or to start it if it is not. When an app has several windows open, activating it again walks through them in turn rather than always landing on the same one.

  • Press n (or Shift-click) to start another copy of the selected app, on the workspace you are already on — that is how you get two terminals side by side, or a second window of an app that is already running. While the search box has focus a plain n types a letter, so use Ctrl+N there (the same way Ctrl+P pins while typing). Shift+Enter also works there.

  • The all-apps list puts the apps you actually launch at the top, weighted by how recently you used them (a two-week half-life, so three launches today beat forty from six months ago). When you type, the text match still decides — usage only breaks ties between equally good matches. Set appOrder to Alphabetical to turn this off.

  • Running apps in the all-apps list carry a dot and the workspace they are on, and the selected row spells out what its keys will do — ↵ go to 2 · n new for something already running, ↵ open · n new for something that is not.

  • In Shortcuts first mode, press q or / to jump to search, or a to open the all-apps list. Click search apps... or all apps for the same. Type to filter, Enter to launch, Esc to return to workspaces (Esc again closes the launcher). Press p (or click pin / unpin) to pin the selected app to the launcher, or to take it off. That writes pinnedApps in shell.json.

  • Press s (or click store) for the app store. It lists Omarchy's curated app catalog grouped by category — browsers, editors, terminals, AI, gaming, services, dev environments — with each row marked install or installed. Type to filter; a query that curated apps do not cover also searches the Arch repos. Enter installs the selected app, x uninstalls it (with a confirmation). When updates are pending, an Update system row appears at the top and the footer shows store •.

  • The store also lists your installed Omarchy plugins under Plugins, with the state of each one: update · 2 commits, up to date, local checkout (a plugin that is not a git checkout, so there is nothing to pull), or check failed. Enter on a plugin that is behind opens a floating terminal running omarchy plugin update, which shows you the real diff and asks before applying it, then restarts the shell so the new code actually runs. Press r to check again right away; otherwise it checks every 6 hours and the footer shows store • when anything is behind.

    Installs and removals open in a floating terminal, which is where the sudo password prompt and the progress output appear. Nordstart itself never asks for a password and never runs a package command directly. The panel closes when the terminal takes over; reopen it to see the updated state.

  • The footer icons log out immediately, and ask for confirmation before reboot or power off (Enter confirms, Esc cancels). To the left of those sit Theme (t) and Hyprland (c). Theme opens Nordtema's variant / bar-style / day-night menu. Hyprland opens Nordsettings' look-and-feel panel (and puts it on the bar if it is installed but not enabled yet). If either companion is missing, the same button offers to install it from git in a floating terminal — Nordstart never clones or enables anything itself.

  • Press w (or click windows) for the window switcher: every open window across every workspace, most recently used first, with its title, its app and the workspace it is on. This is the one thing the workspace grid and the app list cannot do — with two editor windows open, the grid only tells you that something is on workspace 1, and the app list only takes you to whichever window it picked first. Type to filter on title, app or class; a text match always wins over recency. Enter focuses that exact window.

  • Press m to move a window to another workspace, then a digit for where it goes (0 for the scratchpad). In the window switcher it moves the selected window; anywhere else it moves the one you are focused on. Shift-click a workspace cell does the same with the mouse. Esc cancels.

    It is m and then a digit rather than Shift+digit because the host hands panels the typed character, so Shift+1 arrives as ! — or ", or something else again, depending on your keyboard layout.

  • The scratchpad chip under the grid shows what is in Hyprland's special workspace, which is otherwise invisible: SUPER+S toggles a window you cannot see or count. Press 0 or click the chip to toggle it, m then 0 to stash the focused window there.

  • Name your workspaces with workspaceNames (1=code,2=web,3=mail). A named empty workspace reads as its name rather than empty, so the grid stays a map of where things belong even when nothing is running yet; a busy one shows the name beside the app.

  • The store's Web apps section turns any URL into a launcher via omarchy-webapp-install, and removes them again — both in a floating terminal, like every other store action.

  • Escape or a click outside the modal closes it. Tab and Shift+Tab move to the next or previous bar panel (clock, weather, and so on), including panels in other bar sections.

Settings

Tune the widget from the bar settings panel, or inline in ~/.config/omarchy/shell.json:

{
  "id": "io.github.ekrist1.nordstart",
  "hoverOpen": true,
  "keyboardMode": "Search first",
  "workspaceSwitchOverlay": true,
  "searchRecentFiles": true,
  "webSearchUrl": "https://duckduckgo.com/?q=%s",
  "workspaceBarStyle": "Workspace pills",
  "workspaceBarVisibility": "First five and occupied",
  "workspaceHoverPreview": "Window list",
  "workspaceIconStyle": "Monochrome",
  "showLauncherButton": true,
  "showWorkspacePreview": true,
  "workspaceCount": 9,
  "workspaceNames": "",
  "moveFollowsWindow": false,
  "showScratchpad": true,
  "launchWorkspace": "Current workspace",
  "pinnedApps": "firefox,code,thunderbird,tableplus,onlyoffice-desktopeditors",
  "appNames": "",
  "appAliases": "",
  "appOrder": "Recent first",
  "appStoreEnabled": true,
  "appStoreSearchAur": false,
  "pluginUpdateCheck": "On"
}

workspaceBarStyle switches between the new pills and Nordstart's original grid-only entry. workspaceBarVisibility defaults to empty pills for 1–5 plus any occupied higher workspace; it can instead show only active/occupied or all configured workspaces. workspaceIconStyle switches between monochrome foreground-tinted icons and original app colors, on the bar pills, the launcher's workspace tiles and overview, and the switch overlay alike. workspaceHoverPreview accepts Window list, Live preview, or Off; showLauncherButton controls the 3×3 button when pills are enabled.

keyboardMode is Search first (the default: type to search, actions on Ctrl+letter) or Shortcuts first (single-letter actions, q or / to search).

workspaceSwitchOverlay flashes a small map of the grid whenever the workspace changes. searchRecentFiles adds recently opened files to the search. webSearchUrl is the last search result's destination, with %s for the query; leave it empty to drop the row. Only http(s) addresses are used.

launchWorkspace decides where an app opens when you start it: Current workspace (the default) leaves you where you are, First empty workspace jumps to the first unoccupied one. The n / Shift-click "another copy" action ignores this and always opens on the current workspace, since asking for a second window is asking for it beside the first.

workspaceNames labels the grid: 1=code,2=web,3=mail, or an equivalent JSON object. Unnamed workspaces are unaffected.

moveFollowsWindow decides what happens after m sends a window somewhere. Off (the default) leaves you where you are, the same way launching an app does — moving a window off your workspace is usually tidying, not relocating. On takes you with it.

showScratchpad hides the scratchpad chip if you do not use Hyprland's special workspace.

appOrder chooses between Recent first (the default) and Alphabetical for the all-apps list. Usage is recorded in appUsage as id:count:timestamp triples, capped at 60 apps; clear that value to reset the ordering, or set appOrder to Alphabetical to stop recording it entirely.

pluginUpdateCheck controls the plugin section and its update check. Off removes the section and stops all of its network traffic. The check runs one git fetch per installed plugin, caching the result under ~/.cache/nordstart/ so opening the panel never waits on the network.

appStoreEnabled turns the store view (and its s key) on or off. appStoreSearchAur adds AUR results to store searches through yay; it is off by default because AUR searches need the network and AUR packages are unvetted.

pinnedApps is a comma-separated list of desktop entry ids. Installed apps are resolved with a few aliases (code also matches VS Code / Codium, files matches Nautilus). Apps that are not installed are skipped. Pin or unpin from the all-apps list to update this list in shell.json. A blank value falls back to the default pins; none means no pins.

Nautilus windows show as Files. Other common desktop classes (Chrome, Telegram, Spotify, Settings, and so on) have built-in friendly names too.

Adding your own apps to the store

The store reads Omarchy's menu catalog, so anything you add to ~/.config/omarchy/extensions/omarchy-menu.jsonc shows up in it. Rows are matched by id: an install.<category>.<name> entry becomes a store row, and a matching remove.<category>.<name> entry gives that row an uninstall action.

{
  "install.editor.micro": {
    "icon": "",
    "label": "Micro",
    "when": "! omarchy-pkg-present micro",
    "action": "omarchy-install-app Micro micro"
  },
  "remove.editor.micro": {
    "icon": "",
    "label": "Micro",
    "when": "omarchy-pkg-present micro",
    "action": "omarchy-launch-floating-terminal-with-presentation 'omarchy-pkg-drop micro'"
  }
}

The when condition is what tells the store whether the app is installed. Both files are watched, so a saved edit shows up without restarting the shell.

Custom names and aliases

Override a display name, or add ids of your own, from the bar settings panel or in shell.json:

{
  "id": "io.github.ekrist1.nordstart",
  "appNames": "org.gnome.Nautilus=Files,firefox=Web,my.custom.app=Notes",
  "appAliases": "notes=my.custom.app|com.example.Notes"
}

appNames also accepts a JSON object:

"appNames": { "org.telegram.desktop": "Telegram", "Alacritty": "Term" }

User names always win over the built-in map. appAliases is for pinning and for matching a running window to a pinned row (id=alias|alias).

Tests

The naming, alias, workspace, and pinned-app logic lives in NordstartModel.js, and the store's catalog, guard, search-parsing and command logic lives in StoreModel.js — both as plain functions, so they can be checked without the desktop session:

node --test tests/*.test.js

That also runs tests/source-lint.test.js, a static pass over the QML and JS that checks the things unit tests here cannot: invalid string escape sequences, per-line handling of unbounded process output, and settings declared in the QML but missing from manifest.json.

That is the right kind of test for this plugin: it locks down labels, user overrides, terminal subtitles, and workspace cursor movement. Full UI open/click/hover coverage still belongs to using the plugin on the bar — QML here depends on omarchy-shell, Hyprland, and layer-shell, which a headless unit test cannot see.

Remove

omarchy plugin remove io.github.ekrist1.nordstart

That takes the widget off the bar and removes the plugin folder.

License

MIT