Omahub
← All plugins
Y

Snake

by yamz8

Play snake, in the bar or fullscreen

Security review

Potentially dangerous behavior detected · 2 findings

Deterministic scan — not a security guarantee

High
Risk level
High
Analyzed commit
cb93a45
Scanned
1 month ago

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
cb93a45
Reviewed
1 month ago

The deterministic scan's high-risk finding is a false positive: the `rm -rf /` string at tests/rules.test.mjs:181 is a test input passed to verify the high-score writer rejects non-numeric scores (asserting exit status 64), not an executed command. The `eval(k)` at line 23 is likewise confined to the node test harness for loading the module under test. The plugin itself is a straightforward snake game with clean, well-commented QML/JS, no network access, no obfuscation, and a single high-score file write path that is implemented with notably defensive security practices (symlink refusal, file-descriptor pinning, 0600 permissions).

  • The high-score persistence uses `sh -c` with shell scripts constructed at runtime; while the code appears to handle this carefully (parameterized args, path validation), the complexity of the shell-based I/O is the only surface worth a human eye.
  • The `eval(k)` in the test harness is acceptable but could be replaced with a safer module-loading approach.
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/yamz8/omarchy-snake --enable
Other #bar #quickshell #games

Snake

A snake game as a native Omarchy shell plugin.

It runs inside the same long-lived omarchy-shell Quickshell process that draws your bar, and offers two surfaces:

  • a bar widget that drops the game into a standard popup panel
  • a fullscreen overlay summoned by a keybind

Both host the same board, so there is one implementation of the rules and one set of high scores. Colours come from the shell's theme singletons, so the game follows whatever theme you are on.

Install

omarchy plugin add https://github.com/yamz8/omarchy-snake.git --enable

That clones the repo into ~/.config/omarchy/plugins/yamz8.snake/, validates it, and offers to place the bar widget. To update later:

omarchy plugin update yamz8.snake

Remove

omarchy plugin remove yamz8.snake

That deletes ~/.config/omarchy/plugins/yamz8.snake/ and drops the plugin's entry from ~/.config/omarchy/shell.json, taking the bar widget with it.

Two things it does not touch, so remove them by hand if you want them gone:

  • your high scores, at ~/.local/state/omarchy/snake.json
  • any keybind you added to ~/.config/hypr/bindings.lua

Requirements

Omarchy 4 (Quattro) or newer. No external dependencies, no packages to install, no network access, and no privileged operations — the plugin is QML and JavaScript running inside the existing omarchy-shell process, and uses only the shell's own qs.Ui and qs.Commons modules.

The only file it writes is its own high-score file above.

node is needed to run the test suite, but never to use the plugin.

A keybind for the fullscreen overlay

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

o.bind("SUPER + CTRL + G", "Snake", "omarchy-shell shell toggle yamz8.snake")

Playing

Arrows, WASD, or hjkl to move. Space pauses, Enter restarts, Esc closes. The panel accepts arrows and hjkl because that is what Omarchy's PanelKeyCatcher already emits — the panel's native navigation is the controls.

Edges wrap around by default. Walls are opt-in.

Configuration

Settings live on the plugin's entry in ~/.config/omarchy/shell.json and apply the moment you save the file. The entry is in bar.layout when the widget is placed in the bar, and in plugins[] when only the overlay is enabled; either location works.

{ "id": "yamz8.snake", "wrap": false, "speed": "fast" }
Key Values Default Meaning
wrap true / false true false makes the walls deadly
speed slow / normal / fast normal How fast the game starts and how low it plateaus

An unrecognised speed falls back to normal — a typo should not make the game unplayable — and the header shows the mode the game is actually running, not the string you typed. shell.json is hand-edited and its value reaches a text label, so it is resolved to one of the three names before anything displays it.

Wrap and walls keep separate high scores, since wrap is materially easier and a shared best would permanently bury the harder mode's. They are stored in ~/.local/state/omarchy/snake.json.

That path is predictable and sits in a directory anything running as you can write, while the shell reading it is a long-lived process shared by the whole desktop. So the file is treated as untrusted input: the read refuses symlinks and anything that is not a regular file, opens non-blocking so a planted FIFO cannot stall the shell, and stops at 512 bytes; the write builds a fresh 0600 file and renames it over the destination, which replaces a symlink instead of following it.

The directory gets the same treatment as the file, since a symlink planted at ~/.local/state/omarchy — or at any parent — would redirect the whole operation no matter how carefully the last name is checked. Both helpers walk the chain refusing a symlink at every step, then hold the directory open and work through that descriptor, so nothing swapped in afterwards can move the read or the write.

Development

manifest.json      kinds, entry points, bar widget metadata
SnakeGame.js       the rules — pure functions, no QML types
Board.qml          the game: state, timer, rendering. Hosted by both surfaces
Panel.qml          bar widget + popup panel
Snake.qml          fullscreen overlay
tests/             node tests for the rules and the score-file handling

Run the tests:

node tests/rules.test.mjs

SnakeGame.js is deliberately free of QML types so the rules can be exercised under plain node without a running shell.

Editing QML requires omarchy restart shell. Saving a plugin file logs a reload, but a keepLoaded surface keeps serving the old instance from Qt's component cache. Config changes in shell.json are live and need no restart.

License

MIT — see LICENSE.