An opencode plugin that turns permission prompts and questions into persistent, actionable notifications for the exact Ptyxis tab where attention is needed.
Ptyxis doesn't expose tab IDs publicly, and AppArmor blocks plain notify-send actions. This plugin works around that by using Ptyxis's own notification pipeline.
- On a
permission.askedevent, the plugin briefly emits VTE shell markers (vte.shell.preexec/vte.shell.precmd) so Ptyxis generates its own "Command completed" notification. - It reads the tab UUID off that notification from the D-Bus bus (
org.gtk.Notifications.AddNotification). - It replaces it with an urgent OC Deck-owned "OpenCode permission" notification, which remains visible until the permission is answered. Keeping notification ownership separate from Ptyxis prevents notification actions from opening blank terminals.
- A
question.askedevent creates its own urgent OpenCode question tile with an Open question action. It remains until the question is answered or dismissed. - The Allow once and Always allow buttons grant permissions through opencode. Clicking any permission or question notification focuses the exact tmux-backed Ptyxis window through the OC Deck GNOME extension, with the captured Ptyxis tab UUID as a fallback.
- If the tmux session has no viewer, clicking opens a viewer attached to that exact session instead of launching a blank terminal.
Super+N(physicalCapsLock+Nwhen Caps Lock is remapped to Super) runs a native C client, which asks a resident C AT-SPI listener to focus the visible permission banner's Always allow control without activating it.- Permission actions are ordered Always allow, Allow once, then the notification body.
TabandShift+Tabmove between controls;Enteractivates the focused item and focuses the exact requesting tmux-backed Ptyxis window. Super+Vopens the full notification list when you need to move between multiple notification tiles.
The workstation uses a GNOME custom keybinding for Super+N because GNOME 50's stock focus-active-notification handler focuses the banner container instead of an action button. The resident listener caches notification controls as they appear, so the keypress does not launch Python or traverse the accessibility tree. It also observes notification activation and maps the notification ID to the owning permission state before requesting exact tmux focus. The stock binding is left empty to avoid an accelerator conflict.
GNOME Shell controls notification placement. To keep the label at the top right, use a compatible notification-position extension and select Top and Right. The plugin's urgent priority controls how long the label remains visible, not its screen position.
Copy plugins/permission-notify.js to ~/.config/opencode/plugins/ and restart opencode:
mkdir -p ~/.config/opencode/plugins
rm -f ~/.config/opencode/plugins/permission-notify.js
rm -f ~/.config/opencode/plugins/permission-notify-v2.js
rm -f ~/.config/opencode/plugins/permission-notify-v3.js
rm -f ~/.config/opencode/plugins/permission-notify-v4.js
rm -f ~/.config/opencode/plugins/permission-notify-v5.js
rm -f ~/.config/opencode/plugins/permission-notify-v6.js
cp plugins/permission-notify.js ~/.config/opencode/plugins/permission-notify-v7.js
install -Dm644 plugins/org.local.OCDeckSwitch.desktop \
~/.local/share/applications/org.local.OCDeckSwitch.desktop- Ptyxis terminal (50.x) with shell integration markers supported
- GNOME Shell session (
org.gtk.Notificationson the session bus) - GLib and AT-SPI runtime libraries for the native notification-control focus service
gdbusandbusctlon PATH