fix: persistent completion notifications + suppress phantom OK text#1
Conversation
Detects busy->idle transition in session.status events and sends a "Done: Session completed" notification with attention flag. This creates an unread notification badge similar to Claude Code behavior.
Add a 5-second cooldown to prevent completion notifications from flashing and disappearing immediately when OpenCode rapidly transitions between states.
Track completed sessions with a 'completed' flag. When a session transitions from busy to idle, mark it as completed and show a persistent 'Done' status in the sidebar that stays until the session is cleared (on new session or deletion). This mimics the Claude Code behavior where completion notifications remain until you switch to that workspace/terminal.
Fix indentation bug that was causing notify() and sync() to always execute regardless of the busy->idle transition condition, potentially causing phantom notifications.
Prevent phantom 'Done' notifications by resetting the completed flag when a session transitions from idle to busy (starting new work). This ensures completion notifications only appear for actual work completion, not for every idle state transition.
Remove accidentally duplicated code block that was causing the plugin to stop processing events after session.status handling, which broke all other event types (permissions, questions, etc.).
Clear waiting text when transitioning from idle to busy state (starting work or resuming from permission/question) to prevent phantom notifications from stale waiting text.
cmux CLI commands (set-status, notify, clear-notifications, clear-status) print 'OK' to stdout on success. When executed via Bun Shell's $ tagged template, this output leaks into the terminal causing phantom 'OK' notifications and TUI flickering. Use Bun Shell's .quiet() method to suppress stdout/stderr while still executing commands normally.
|
@coygeek your original manaflow-ai#1426 was a great PR, I wanted to just add a few more bells-and-whistles in.
and
are the final effect. What do you think? |
coygeek
left a comment
There was a problem hiding this comment.
Tested locally — node tests/test_opencode_plugin_runtime.js passes. Logic looks correct: busy→idle completion detection, .quiet() suppression, flag management all work as described.
A few nits for a follow-up (non-blocking):
-
Mixed indentation: Original file was consistently 2-space. This PR introduces 3-space in
ensure(),desiredStatus(), and parts ofCmuxIntegrationPlugin, whileclearNotifications,setStatus,clearStatusstay at 2-space. The} else {block insetStatus(around line 110) is also misaligned. -
Duplicate condition (lines 164–170): The two
if (prevState === "idle" && state.state !== "idle")blocks could be merged into one. -
Missing test for the new feature: The busy→idle "Done" completion detection is the main feature but isn't exercised by the test. Worth adding a sequence like:
session.created→session.status(busy)→session.status(idle)and asserting the "Done" status + notification.
None of these block the merge — the functional changes are solid. LGTM.


Summary
Builds on the OpenCode status integration from manaflow-ai#1426 with two key improvements:
cmuxCLI commands using Bun Shell's.quiet()method, preventing "OK" text from leaking into the terminal TUIChanges
Plugin (
opencode-cmux-plugin.js)completedflag on sessions. When a session transitions frombusy→idle, marks it completed and sends a "Done" notification with persistent attention state.completedand clearswaitingtext on idle→busy transitions (starting new work).session.statushandler that causednotify()andsync()to always execute regardless of conditions..quiet()on all$calls: EverycmuxCLI command (set-status,notify,clear-notifications,clear-status) returns "OK" to stdout. Without.quiet(), Bun Shell's$tagged template echoes this to the terminal, causing phantom "OK" notifications and cursor flickering.Tests (
test_opencode_plugin_runtime.js)$mock to return a chainable promise with.quiet(),.nothrow(), and.text()methods, matching the Bun Shell API that OpenCode provides to plugins.Testing
node tests/test_opencode_plugin_runtime.js