Skip to content

fix: persistent completion notifications + suppress phantom OK text#1

Merged
coygeek merged 8 commits intocoygeek:feat/opencode-status-integrationfrom
ericmjl:feat/opencode-completion-notification
Mar 23, 2026
Merged

fix: persistent completion notifications + suppress phantom OK text#1
coygeek merged 8 commits intocoygeek:feat/opencode-status-integrationfrom
ericmjl:feat/opencode-completion-notification

Conversation

@ericmjl
Copy link
Copy Markdown

@ericmjl ericmjl commented Mar 21, 2026

Summary

Builds on the OpenCode status integration from manaflow-ai#1426 with two key improvements:

  • Persistent completion notifications: Detects busy→idle state transitions and shows a "Done" notification that persists (with blue ring) until acknowledged, matching Claude Code behavior
  • Phantom "OK" fix: Suppresses stdout from cmux CLI commands using Bun Shell's .quiet() method, preventing "OK" text from leaking into the terminal TUI

Changes

Plugin (opencode-cmux-plugin.js)

  1. Completion detection: Tracks completed flag on sessions. When a session transitions from busyidle, marks it completed and sends a "Done" notification with persistent attention state.
  2. Flag management: Resets completed and clears waiting text on idle→busy transitions (starting new work).
  3. Fixed indentation bug: Corrected indentation in session.status handler that caused notify() and sync() to always execute regardless of conditions.
  4. Removed duplicate code: Eliminated duplicate completion detection blocks that caused early returns.
  5. .quiet() on all $ calls: Every cmux CLI 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)

  • Updated $ mock to return a chainable promise with .quiet(), .nothrow(), and .text() methods, matching the Bun Shell API that OpenCode provides to plugins.

Testing

  • All existing tests pass: node tests/test_opencode_plugin_runtime.js
  • Manually verified in tagged cmux debug builds (v1 through v10):
    • Status pills work correctly (Running/Needs input/Error/Idle/Done)
    • Blue ring indicators appear when OpenCode needs attention
    • Notification panel shows notifications properly
    • Completion notifications persist until acknowledged
    • No phantom "OK" text or TUI flickering

ericmjl added 8 commits March 21, 2026 12:50
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.
@ericmjl
Copy link
Copy Markdown
Author

ericmjl commented Mar 21, 2026

@coygeek your original manaflow-ai#1426 was a great PR, I wanted to just add a few more bells-and-whistles in.

image

and

image

are the final effect.

What do you think?

Copy link
Copy Markdown
Owner

@coygeek coygeek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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):

  1. Mixed indentation: Original file was consistently 2-space. This PR introduces 3-space in ensure(), desiredStatus(), and parts of CmuxIntegrationPlugin, while clearNotifications, setStatus, clearStatus stay at 2-space. The } else { block in setStatus (around line 110) is also misaligned.

  2. Duplicate condition (lines 164–170): The two if (prevState === "idle" && state.state !== "idle") blocks could be merged into one.

  3. 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.createdsession.status(busy)session.status(idle) and asserting the "Done" status + notification.

None of these block the merge — the functional changes are solid. LGTM.

@coygeek coygeek merged commit 29d6277 into coygeek:feat/opencode-status-integration Mar 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants