Fix opencode session binding, state accuracy, and TUI CPU burn - #70
Merged
Conversation
Five related fixes, all around full-screen agent TUIs: - Two OpenCode sessions in one directory reported identical tokens, context and state: both watchers bound to the newest db session there. Watchers now claim a distinct one and release it when their session goes away — the watcher thread outlived its session and kept stealing the binding from the next opencode started in the same directory. - Sessions got stuck on WAITING indefinitely. A permission dialog is only visible to terminal patterns, so it has to outrank the watcher's Running/Thinking — but it was never given up, and the watcher only re-reported on a change. WAITING now releases when the dialog leaves the screen, when input is sent, or when the watcher reports the turn finished (re-asserted every 5s rather than 30s). Relatedly, a freshly started TUI session sat on RUNNING forever because the idle timeout keyed off the last completed output line, which a TUI that repaints via cursor positioning never produces. - Ever-worsening CPU burn: ~20% of a core per idle OpenCode session and still climbing. The PTY reader's unterminated-line buffer had no bound, and a TUI can repaint for minutes without a newline, so it grew without limit while being ANSI-stripped and regex-scanned every 20ms. The tail is now capped, unchanged tails are not re-scanned, and off-screen sessions skip the screen-change hash. Measured flat at ~8% of a core for two sessions afterwards. - Claude permission dialogs were not detected as WAITING: the dialog is drawn in a box, so lines arrive behind a border glyph, and the box often arrives as one blob with no newlines — neither of which the start-anchored patterns matched. - Removed the WAITING preview row under a waiting session in the status panel. The WAITING state itself is unchanged. Co-Authored-By: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Five related fixes, all around full-screen agent TUIs:
Two OpenCode sessions in one directory reported identical tokens, context and state: both watchers bound to the newest db session there. Watchers now claim a distinct one and release it when their session goes away — the watcher thread outlived its session and kept stealing the binding from the next opencode started in the same directory. Addresses bug: multiple opencode sessions share same context size #65
Sessions got stuck on WAITING indefinitely. A permission dialog is only visible to terminal patterns, so it has to outrank the watcher's Running/Thinking — but it was never given up, and the watcher only re-reported on a change. WAITING now releases when the dialog leaves the screen, when input is sent, or when the watcher reports the turn finished (re-asserted every 5s rather than 30s). Relatedly, a freshly started TUI session sat on RUNNING forever because the idle timeout keyed off the last completed output line, which a TUI that repaints via cursor positioning never produces. Addresses opencode waiting #66
Ever-worsening CPU burn: ~20% of a core per idle OpenCode session and still climbing. The PTY reader's unterminated-line buffer had no bound, and a TUI can repaint for minutes without a newline, so it grew without limit while being ANSI-stripped and regex-scanned every 20ms. The tail is now capped, unchanged tails are not re-scanned, and off-screen sessions skip the screen-change hash. Measured flat at ~8% of a core for two sessions afterwards. Addresses opencode can cause high cpu usage #69
Claude permission dialogs were not detected as WAITING: the dialog is drawn in a box, so lines arrive behind a border glyph, and the box often arrives as one blob with no newlines — neither of which the start-anchored patterns matched.
Removed the WAITING preview row under a waiting session in the status panel. The WAITING state itself is unchanged.