Skip to content

fix(tui): keep usage state and polling in plugin setup - #5

Merged
PentSec merged 1 commit into
PentSec:mainfrom
Zorato:fix/tui-state-lifecycle
Nov 3, 2026
Merged

PentSec merged 1 commit into
PentSec:mainfrom
Zorato:fix/tui-state-lifecycle

Conversation

@Zorato

@Zorato Zorato commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

Problem

Usage state and polling currently belong to Panel. When the host unmounts and remounts the panel, usage state resets to loading and a new refresh starts.

The existing refresh deadline does not prevent this reset.

Changes

  • Move usage state, polling, and the countdown clock into plugin setup.
  • Let Panel render shared state through accessors.
  • Preserve in-flight refresh cycles across panel remounts.
  • Retain the existing deadline, overlap protection, and error handling.
  • Clear intervals, suppress late results, and unregister the slot during plugin cleanup.
  • Extract refresh logic into a small module for focused tests.

This PR does not change credential resolution, sidebar layout, or pace indicators.

Behavior change

Polling now follows the plugin lifetime rather than the panel lifetime. It continues while the plugin is active, even when the panel is not mounted.

The deadline still ends the wait without cancelling the underlying load.

Verification

  • npm test: 15 tests pass.
  • npm run typecheck: passes for production sources.
  • Four lifecycle tests exercise the actual plugin setup and slot callback with a fake host and the real OpenTUI renderer.
  • All four lifecycle tests fail against the upstream implementation.
  • Tests cover state retention, in-flight refresh retention, countdown updates, and cleanup.
  • Eleven refresh tests cover deadlines, overlap protection, errors, and disposal.

Tests use synthetic responses, not live credentials or API requests. This reproduction demonstrates panel-remount behavior; it does not establish the cause of every reported loading issue.

Preserve usage state and in-flight refresh cycles across panel remounts. Keep existing refresh deadlines and overlap protection.

Stop polling and release the slot during plugin cleanup. Add lifecycle reproductions with the OpenTUI renderer and focused refresh tests.
@PentSec

PentSec commented Nov 3, 2026

Copy link
Copy Markdown
Owner

Approved. Moving state and polling into setup is the right call, and the lifecycle tests against the real renderer are convincing: they fail on upstream and pass here. Definition.setup returning a Cleanup is part of the public contract, so the design holds.

Two small notes, no changes required here:

  • withDeadline uses undefined as the timeout sentinel, so a load that legitimately resolves undefined reads as a timeout. fetchUsage never does, but the module is generic and exported.
  • The tests import type { Context } from "@opencode/plugin/tui", which is not exported (only Plugin.Context or the /tui/plugin subpath). It is erased at runtime, but it will fail once tests are typechecked.

We will wire a bun test job into CI on our side.

@PentSec
PentSec merged commit 37a1b04 into PentSec:main Nov 3, 2026
@Zorato
Zorato deleted the fix/tui-state-lifecycle branch November 3, 2026 19:43
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