Omahub
← All plugins
P

Voice Notes

by Pieter Geutjens

Dictate into a file-backed inbox, preview recent notes, and open the target in your default editor.

Security review

Potentially dangerous behavior detected · 1 finding

Deterministic scan — not a security guarantee

High
Risk level
High
Analyzed commit
6277c10
Scanned
1 month ago
  • high destructive_filesystem bin/voice-notes:1062

    Low-level disk manipulation or write command.

    dd of="$target" oflag=append,nonblock conv=notrunc status=none

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

The plugin is a well-structured voice-note recorder that appends transcribed text to a user-selected file. The flagged `dd` command is used for safe, nonblocking append operations on validated regular files, not destructive disk manipulation. The plugin performs no network requests, installs no packages, and only modifies Hyprland configuration when the user explicitly chooses a keybinding.

  • The deterministic scan flagged `dd` as destructive, but it is used only to append to a user-selected regular file with `oflag=append,nonblock` and `conv=notrunc`, which is safe and non-destructive.
  • The plugin can modify `~/.config/hypr/bindings.lua` and create a managed bindings file, but only when the user explicitly records a keybinding through the panel, and it is reversible.
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/pjgeutjens/omarchy-voicenote --enable
Productivity #Hyprland #bar #quickshell

Voice Notes for Omarchy

A compact Omarchy bar plugin for a file-backed voice-note inbox.

  • Set the active target file and per-line output template.
  • Start fresh installations with - [ ] {text} for Markdown checklist notes.
  • Set the push-to-talk recording keybinding from the panel.
  • Preview the most recent notes as literal plain text.
  • Choose how many recent notes to show.
  • Open the target in the editor selected through Omarchy.
  • Keep ordinary F9 cursor dictation separate from voice-note capture.
  • Show the capture lifecycle in the bar: idle, recording, transcribing, success, no-note, or failure.

Current requirements

  • Omarchy Quattro
  • An editor selected through omarchy default editor
  • A running Voxtype transcription engine
  • jq and flock, both available in the normal Omarchy environment

The plugin checks these prerequisites in its panel. Its voice-notes and live-edit helpers are bundled and run directly from the installed plugin, so they do not need to be present on PATH.

Install

The complete plugin installs through Omarchy without an install hook:

omarchy plugin add https://github.com/pjgeutjens/omarchy-voicenote.git --enable --yes

Omarchy clones, validates, and enables the plugin. Voice Notes does not install packages, create command links, or modify Voxtype or Hyprland during that flow. Choosing a recording keybinding later is the explicit action that installs its managed Hyprland integration.

Update an installed copy with:

omarchy plugin update io.github.pjgeutjens.voicenotes

Optional terminal commands

The plugin works without global commands. To additionally make voice-notes and the general-purpose live-edit command available under ~/.local/bin, run:

~/.config/omarchy/plugins/io.github.pjgeutjens.voicenotes/bin/install-cli

Existing command names are never replaced silently. In an interactive terminal, the installer offers to back up a collision; in automation it refuses unless the explicit --replace option is supplied. Before removing the plugin, remove the owned links and restore any backups with:

~/.config/omarchy/plugins/io.github.pjgeutjens.voicenotes/bin/uninstall-cli

Local development installation

To validate a working tree without installing from GitHub:

./scripts/install-local.sh

The local installer validates and copies the complete self-contained plugin into ~/.config/omarchy/plugins, then enables it on the right side of the bar. Pass --cli to explicitly request terminal command links, or --replace-cli after reviewing a reported collision. It does not overwrite the user's existing target or line template and never modifies Voxtype configuration. A fresh install does not modify Hyprland either. Local validation uses qmltestrunner from the qt6-declarative package and reports that dependency explicitly when it is absent.

Capture ownership

Voxtype never receives the selected inbox path. Each recording goes to a private file under ~/.local/state/voice-notes/captures; after Voxtype returns to idle, Voice Notes applies the configured line template and serializes an append to the selected target. Failed captures are retained with a visible error instead of being discarded or overwriting the target.

The panel displays read-only prerequisite checks and discloses the locations Voice Notes can write. In particular, Voice Notes does not require a Voxtype profile and does not depend on Voxtype's global file_mode.

Targets must be absent or regular files; directories, FIFOs, devices, sockets, and other special files are rejected both when selected and again before an append. The append descriptor is also opened nonblocking so a path replacement cannot strand the detached finalizer. Recent-note previews read at most 64 KiB from the target and cap each displayed line at 4 KiB before state is serialized for the panel.

Use

  • Left-click the microphone button to open the panel.
  • Right-click the button to open the target in the configured Omarchy editor.
  • Middle-click to refresh.
  • In the panel, press O to open, R to refresh, T to edit the target, or P to edit the line template. Press B to record a new keybinding. Press ? or click ? about in the footer to toggle About and permissions.
  • Target and line-template edits save on Enter or when focus leaves the field; Escape restores the previous value.
  • While editing the target, Shift+Enter opens Omarchy's native desktop file selector. Choosing a file makes it the active target; cancelling changes nothing. When the selector closes, the panel returns with the Target File row selected.
  • After opening from the bar, j/k or Up/Down immediately move between the target, line template, recording keybinding, recent count, open-file row, and About. Enter edits or opens; on Recent Notes it toggles the note list. h/l adjust the recent count, up to 10. The disclosure control beside the count also shows or hides the list, and that choice is remembered. If the selected notes do not fit, only the Recent Notes body scrolls; the surrounding controls remain in place.
  • Select the recording-keybinding row and press the desired chord once. It saves immediately; Escape cancels. During capture, a temporary Hyprland submap prevents the chord from also triggering an existing global action.
  • Choose Clear beside an active keybinding, or focus its row and press X, to return Voice Notes to the unbound state.
  • Unmodified function keys and modified letter, number, navigation, or function keys are accepted. A fresh install remains unbound until the user chooses one.
  • If a chord is occupied, Voice Notes identifies the existing action and asks whether to cancel or override it. Cancel is selected by default. Override is reversible: the original owner's configuration is not edited, and its action returns when the Voice Notes keybinding changes.
  • The generated bindings file is replaced rather than appended on every panel change. Consequently, a previous hl.unbind cannot trail behind after moving Voice Notes to another keybinding.
  • voice-notes binding --clear returns the plugin to its unbound state and restores any action that its previous keybinding temporarily overrode.
  • Hold the configured recording keybinding to record a note with the current target and line template.
  • The bar icon changes from the idle quote to an urgent microphone while recording, a transcription indicator after release, and a theme-accented check for two seconds after a successful append. If Voxtype returns to idle without producing any text, Voice Notes shows 󰜺 for one second and creates no note. A failed capture shows an urgent cross until the panel is opened or another recording begins. Opening the panel acknowledges only the icon; the recoverable error remains visible.

Line templates

Every line template must contain {text} exactly once. The template is applied independently to each non-empty transcription line:

Template Result
{text} Plain dictated text
- [ ] {text} Markdown checklist item
{text} #inbox Text with a trailing tag
> {text} Markdown quote
[{date}] {text} Date-prefixed note
{datetime:%Y-%m-%dT%H:%M} {text} Custom GNU date format

{date} defaults to %Y-%m-%d; {datetime} defaults to %Y-%m-%d %H:%M. Their timestamp is captured when recording starts. A custom format that errors, is empty, or produces control characters is omitted without discarding the dictated text. Existing pre-0.6 line-prefix state is migrated to <old prefix>{text}, preserving its output.

Voice Notes asks Omarchy which editor the user selected. GUI editors such as Visual Studio Code open normally and retain their native file-watching behavior. When Neovim is selected, Voice Notes launches the user's normal Neovim through the bundled live-edit adapter, which adds only safe external-append reconciliation. Neovim remains in control of configuration, layout, Markdown presentation, navigation, editing, saving, and closing; Voice Notes does not install or modify Neovim configuration.

voice-notes open-bindings remains available as a CLI-only diagnostic escape hatch. The panel intentionally does not offer direct editing of its generated bindings file.

Dependencies and permissions

Voice Notes requires Omarchy Quattro, a ready Voxtype transcription engine, jq, and flock. Neovim is needed only when it is the selected editor. The plugin installs no packages, requires no privileged access or secrets, makes no network requests, and starts no persistent daemon. A short-lived background finalizer waits for each stopped recording to finish transcribing.

The panel discloses the files Voice Notes may write. A fresh installation writes only under ~/.local/state/voice-notes when initialized. Recording appends to the chosen target. Choosing a keybinding explicitly creates ~/.config/hypr/voice-notes-bindings.lua and adds one loader statement to ~/.config/hypr/bindings.lua; it does not modify Voxtype configuration.

Remove

Before removing the plugin, remove its managed Hyprland integration while the bundled helper is still available:

plugin="$HOME/.config/omarchy/plugins/io.github.pjgeutjens.voicenotes"
"$plugin/bin/voice-notes" binding --remove-integration
"$plugin/bin/uninstall-cli"
omarchy plugin remove io.github.pjgeutjens.voicenotes

The cleanup removes only the recognized Voice Notes binding file, its exact loader lines, and Voice Notes-owned optional CLI links. It refuses to delete an unrecognized replacement file. The target file and ~/.local/state/voice-notes are preserved so notes, preferences, and failed captures are not silently discarded.

Display boundary

Recent notes are rendered only in plugin-owned Text.PlainText elements. Raw note text, paths, line templates, or errors are never passed into shared Omarchy hero/meta or tooltip sinks, which may interpret markup and do not expose their text mode to plugins.

Validate

./scripts/validate.sh

Validation includes the complete capture pipeline and the bar presentation for every lifecycle phase.