Omahub
← All plugins
E

Theme modes

by esemczak

Separate light and dark Omarchy themes with per-mode backgrounds, manual switching, and optional automatic mode by schedule or battery.

Security review

Review recommended · 1 finding

Deterministic scan — not a security guarantee

Low
Risk level
Low
Analyzed commit
9af6a0a
Scanned
1 month ago

Flagged patterns appear only in documentation files (README / docs) — descriptive examples, not executable code.

  • Docs external_hosts README.md:49

    Downloads or connects to an external HTTP(S) host.

    git clone https://github.com/esemczak/omarchy-theme-modes.git \

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

The plugin is a theme switcher that executes local Omarchy CLI commands with strict input validation, bounded I/O, and path anchoring. The deterministic finding about an external host refers only to a documented git clone in the README, not runtime code. No malicious behavior, persistence, or destructive actions were found.

  • The deterministic scan flagged the README's `git clone` command as an external host, but this is documentation only and not part of the plugin's executable code.
  • The plugin runs unsandboxed inside omarchy-shell, but it only invokes local theme commands and writes a state file; no network access or remote code execution occurs at runtime.
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/esemczak/omarchy-theme-modes --enable
Widgets #bar

omarchy-theme-modes

Separate light and dark Omarchy themes with per-mode backgrounds, manual switching, and optional automatic mode by schedule or battery.

Panel — General tab (automatic battery rules)

Pick different themes for day and night, choose a background for each, and switch with one click — or let Omarchy follow the clock or power source.

Light theme picker with backgrounds

Dark theme picker with backgrounds

Note: Configure themes and backgrounds in this plugin's panel. Omarchy's native theme/background switchers do not update these presets (by design — no polling, no global hooks).

Features

  • Dual presets — independent light and dark theme + background pairs
  • Tabbed panel — General · Light themes · Dark themes
  • Theme carousel — infinite scroll, size highlights selection, debounced apply
  • Background picker — thumbnails for each theme's bundled backgrounds
  • Panel preview — active theme background fades in from the top-right
  • Manual mode — pick light or dark yourself
  • Automatic mode — schedule (light/dark times) or battery (dark on battery, light on power)
  • Bar shortcuts
    • Left-click — open panel
    • Right-click — toggle light ↔ dark (applies saved theme + background)
    • Middle-click — follow automatic rules

Requirements

  • Omarchy with shell plugin support (Quattro)
  • bash, jq
  • Omarchy CLI tools: omarchy theme, omarchy theme bg, omarchy-theme-switcher (preview cache)

No additional packages, sudo, or network access are required at runtime.

Install

From git (recommended)

omarchy plugin add https://github.com/esemczak/omarchy-theme-modes.git --enable --yes
omarchy restart shell

Manual copy

git clone https://github.com/esemczak/omarchy-theme-modes.git \
  ~/.config/omarchy/plugins/esemczak.theme-modes

omarchy plugin validate ~/.config/omarchy/plugins/esemczak.theme-modes
omarchy plugin enable esemczak.theme-modes --section right
omarchy restart shell

Remove

omarchy plugin disable esemczak.theme-modes
omarchy plugin remove esemczak.theme-modes --yes
omarchy restart shell

Optional — delete saved plugin state:

rm -f ~/.local/state/omarchy/settings/theme-modes.json

Removing the plugin does not revert themes or backgrounds already applied through Omarchy.

Usage

  1. Click the bar icon (sun/moon) to open the panel.
  2. General — set current mode, manual vs automatic, schedule or battery rules.
  3. Light themes / Dark themes — scroll the carousel to pick a theme; click a background thumbnail below.
  4. Right-click the bar icon anytime to flip between your saved light and dark setups.

Settings persist in:

~/.local/state/omarchy/settings/theme-modes.json

The plugin only writes that state file and invokes Omarchy theme commands when you change settings. It does not modify Hyprland, shell defaults, or other user configuration without explicit action in the panel or bar shortcuts.

IPC

Target: esemczak.theme-modes

omarchy-shell esemczak.theme-modes toggle          # toggle light/dark mode
omarchy-shell esemczak.theme-modes followAutomatic # switch to automatic rules
omarchy-shell esemczak.theme-modes status          # JSON status
omarchy-shell esemczak.theme-modes refreshThemes    # reload theme catalog

Validate before publishing

omarchy plugin validate ./omarchy-theme-modes

Project layout

omarchy-theme-modes/
├── manifest.json      # Plugin metadata (id: esemczak.theme-modes)
├── preview.png        # Marketplace listing preview
├── Panel.qml          # Bar widget + panel UI
├── Service.qml        # State, theme apply, auto timers
├── Model.js           # State parse/serialize, auto logic
├── lib/
│   ├── security.sh      # Slug/path validation helpers (bash)
│   └── security_core.py # Descriptor-safe I/O and bounded subprocess reads
├── bootstrap-state.sh   # Safe read of plugin state + current theme
├── safe-write-state.sh  # Atomic bounded write of plugin state
├── catalog.sh           # Theme list + preview paths
├── theme-list-fallback.sh # Bounded fallback theme catalog JSON
├── backgrounds.sh       # Background list for a theme slug
├── docs/screenshots/  # README screenshots
├── LICENSE
└── CHANGELOG.md

Screenshots

Real desktop captures at 1200 px wide. The root preview.png matches the light-themes shot for marketplace listings.

Preview Description
panel-general.png General tab — automatic battery rules
panel-light-themes.png Light theme carousel + backgrounds
panel-dark-themes.png Dark theme carousel + backgrounds

See docs/screenshots/README.md for capture notes.

Development

The plugin hot-reloads when files under ~/.config/omarchy/plugins/ are saved. Otherwise:

omarchy restart shell

Test validation after changes:

omarchy plugin validate ~/.config/omarchy/plugins/esemczak.theme-modes

Security

Plugins run as unsandboxed code inside omarchy-shell. Review the source before installing.

This plugin executes local Omarchy CLI commands and reads theme/background directories on your machine; it does not download or execute remote code.

Hardening measures in this release:

  • Theme slugs are validated against a strict allowlist before any shell command or path construction runs.
  • Plugin state and the current theme name are read through no-follow, regular-file helpers with byte limits; state is written atomically into a verified private directory.
  • Theme/background catalog helpers run under timeout, cap stdout before QML parsing, and only expose image paths that resolve under anchored Omarchy theme/background or cache roots after no-follow regular-file checks.
  • Catalog and background helpers enforce producer-side ceilings on input line bytes, field/path bytes, record counts, and total emitted JSON bytes; QML collectors terminate processes once stdout exceeds the matching limit during streaming.
  • Descriptor-safe helpers open private directories once, perform atomic writes via dir_fd, read regular files through bounded loops, materialize validated images into a private cache bound to the validated fd, and read theme lists from child pipes incrementally with deadlines.

License

MIT — see LICENSE.

Author

esemczak