Browse Source

Cache buster

paviko 1 month ago
parent
commit
7be9bedd1d

+ 20 - 1
hosts/jetbrains-plugin/src/main/kotlin/paviko/opencode/ui/ChatToolWindowFactory.kt

@@ -1,6 +1,10 @@
 package paviko.opencode.ui
 
+
+import com.intellij.ide.plugins.PluginManagerCore
+import com.intellij.ide.plugins.PluginUtil
 import com.intellij.openapi.diagnostic.Logger
+
 import com.intellij.openapi.project.DumbAware
 import com.intellij.openapi.project.Project
 import com.intellij.openapi.util.Disposer
@@ -17,6 +21,7 @@ import java.awt.Font
 import java.io.BufferedReader
 import java.io.InputStreamReader
 import java.net.URI
+import java.net.URLEncoder
 import java.nio.charset.StandardCharsets
 import javax.swing.*
 
@@ -24,6 +29,20 @@ class ChatToolWindowFactory : ToolWindowFactory, DumbAware {
     private var connectionInfo: ConnInfo? = null
     private val logger = Logger.getInstance(ChatToolWindowFactory::class.java)
 
+    private fun pluginVersion(): String {
+        // Use pluginDescriptor.version without hardcoding plugin id.
+        // PluginUtil ties a classloader back to the hosting plugin.
+        val pluginId = PluginUtil.getPluginId(javaClass.classLoader) ?: return "dev"
+        val descriptor = PluginManagerCore.getPlugin(pluginId) ?: return "dev"
+        return descriptor.version
+    }
+
+    private fun withCacheBuster(url: String, version: String): String {
+        val encodedVersion = URLEncoder.encode(version, StandardCharsets.UTF_8)
+        val sep = if (url.contains("?")) "&" else "?"
+        return if (url.contains("v=")) url else "${url}${sep}v=${encodedVersion}"
+    }
+
     override fun createToolWindowContent(project: Project, toolWindow: ToolWindow) {
         // vertical=true => top/bottom split; top takes 100% initially (logs collapsed)
         val mainPanel = JPanel(BorderLayout())
@@ -116,7 +135,7 @@ class ChatToolWindowFactory : ToolWindowFactory, DumbAware {
                                         } catch (_: Throwable) {}
                                         val browser = JBCefBrowser.createBuilder()
                                             .setClient(client)
-                                            .setUrl(appUrl)
+                                            .setUrl(withCacheBuster(appUrl, pluginVersion()))
                                             .build()
 
                                         // Store browser reference for path insertion (context actions)

+ 15 - 1
hosts/vscode-plugin/src/extension.ts

@@ -6,6 +6,15 @@ import { ActivityBarProvider } from "./ui/ActivityBarProvider"
 import { ErrorCategory, errorHandler, ErrorSeverity } from "./utils/ErrorHandler"
 import { logger } from "./globals"
 
+function withCacheBuster(url: string, version: string): string {
+  if (url.includes("v=")) {
+    return url
+  }
+
+  const sep = url.includes("?") ? "&" : "?"
+  return `${url}${sep}v=${encodeURIComponent(version)}`
+}
+
 /**
  * Main extension entry point - equivalent to ChatToolWindowFactory.kt
  * Handles extension activation, deactivation, and component coordination
@@ -169,8 +178,10 @@ class OpenCodeExtension {
 
       logger.appendLine("Opening OpenCode panel...")
 
+      const context = this.context
+
       // Create webview panel with settings manager
-      this.webviewManager.createWebviewPanel(this.context, this.settingsManager)
+      this.webviewManager.createWebviewPanel(context, this.settingsManager)
 
       // Show loading progress
       await vscode.window.withProgress(
@@ -186,6 +197,9 @@ class OpenCodeExtension {
             // Launch backend process with error handling
             const connection = await this.backendLauncher!.launchBackend(undefined, { forceNew: opts?.forceNewBackend })
 
+            // Cache busting: force web UI reload after extension updates
+            connection.uiBase = withCacheBuster(connection.uiBase, context.extension.packageJSON.version)
+
             progress.report({ increment: 50, message: "Loading web UI..." })
 
             // Load web UI with connection info

+ 12 - 0
hosts/vscode-plugin/src/ui/ActivityBarProvider.ts

@@ -4,6 +4,15 @@ import { SettingsManager } from "../settings/SettingsManager"
 import { errorHandler } from "../utils/ErrorHandler"
 import { WebviewController } from "./WebviewController"
 
+function withCacheBuster(url: string, version: string): string {
+  if (url.includes("v=")) {
+    return url
+  }
+
+  const sep = url.includes("?") ? "&" : "?"
+  return `${url}${sep}v=${encodeURIComponent(version)}`
+}
+
 /**
  * Webview view provider for the OpenCode activity bar view.
  */
@@ -56,6 +65,9 @@ export class ActivityBarProvider implements vscode.WebviewViewProvider {
           const connection = await this.backendLauncher.launchBackend()
           this.connection = connection
 
+          // Cache busting: force web UI reload after extension updates
+          connection.uiBase = withCacheBuster(connection.uiBase, this.context.extension.packageJSON.version)
+
           progress.report({ increment: 50, message: "Loading web UI..." })
           this.controller = new WebviewController({
             webview: webviewView.webview,