From 7b0f25953ecdbf76f1161cde78cb92cc20e60eab Mon Sep 17 00:00:00 2001 From: Alphons Jaimon Date: Thu, 27 Aug 2026 23:58:08 +0530 Subject: [PATCH] fix: stop the auto-refresh timer on unmount `intervalId` and `stopAuto()` are declared inside `mount()`'s closure, but `unmount()` is a separate top-level export with no access to them. It clears the container's innerHTML and removes the injected styles, but never calls `clearInterval`. The 10s auto-refresh timer therefore survives unmount and keeps calling fetchSessions(), which re-renders into the `container` element captured by the closure. CloudCLI reuses one container for the active tab plugin, so a few seconds after switching away from Sessions the timer repaints the session table over whichever plugin is now mounted there. Reproduced with the PRISM plugin: select Sessions, switch to PRISM, and within 10s PRISM's panel is replaced by the Claude Sessions table. Removing this plugin made PRISM render correctly again, confirming the source. Fix: hold the closure's stopAuto in a module-scoped `activeStopAuto` and invoke it from unmount(). dist/index.js is a verbatim copy of src/index.js (no build step), so both are updated. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_011WfoF1z5anUFtH61ECn1ZF --- dist/index.js | 7 +++++++ src/index.js | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/dist/index.js b/dist/index.js index 4e46fd0..6bdc515 100644 --- a/dist/index.js +++ b/dist/index.js @@ -87,6 +87,11 @@ function toast(msg, duration = 3500) { // ── Main plugin ──────────────────────────────────────────────────────── +// Set by mount() so unmount() can stop the auto-refresh timer, which +// otherwise keeps firing and re-rendering into a container the host has +// already handed to another plugin. +let activeStopAuto = null; + export function mount(container, api) { let sessions = []; let loading = false; @@ -356,9 +361,11 @@ export function mount(container, api) { render(); fetchSessions(); if (autoRefresh) startAuto(); + activeStopAuto = stopAuto; } export function unmount(container) { + if (activeStopAuto) { activeStopAuto(); activeStopAuto = null; } container.innerHTML = ''; const styles = document.getElementById('sm-styles'); if (styles) styles.remove(); diff --git a/src/index.js b/src/index.js index 4e46fd0..6bdc515 100644 --- a/src/index.js +++ b/src/index.js @@ -87,6 +87,11 @@ function toast(msg, duration = 3500) { // ── Main plugin ──────────────────────────────────────────────────────── +// Set by mount() so unmount() can stop the auto-refresh timer, which +// otherwise keeps firing and re-rendering into a container the host has +// already handed to another plugin. +let activeStopAuto = null; + export function mount(container, api) { let sessions = []; let loading = false; @@ -356,9 +361,11 @@ export function mount(container, api) { render(); fetchSessions(); if (autoRefresh) startAuto(); + activeStopAuto = stopAuto; } export function unmount(container) { + if (activeStopAuto) { activeStopAuto(); activeStopAuto = null; } container.innerHTML = ''; const styles = document.getElementById('sm-styles'); if (styles) styles.remove();