Quellcode durchsuchen

VSCode: Fixed drag&drop file in Remote-SSH on Windows and Linux

paviko vor 2 Monaten
Ursprung
Commit
8d8baacdb3

+ 4 - 1
hosts/jetbrains-plugin/src/main/kotlin/paviko/opencode/util/ResourceExtractor.kt

@@ -29,8 +29,11 @@ object ResourceExtractor {
         // Read resource into memory so we can check size before writing
         val bytes = stream.use { it.readBytes() }
 
-        if (!dest.exists() || dest.length() != bytes.size.toLong()) {
+        try {
             dest.writeBytes(bytes)
+        } catch (e: Exception) {
+            // Binary may be in use – continue with existing copy
+            logger.info("Could not overwrite binary (may be in use): ${e.message}")
         }
 
         dest.setExecutable(true)

+ 4 - 16
hosts/vscode-plugin/src/backend/ResourceExtractor.ts

@@ -33,11 +33,11 @@ export class ResourceExtractor {
     await fs.promises.mkdir(stableDir, { recursive: true })
     const destPath = path.join(stableDir, binaryName)
 
-    const srcStats = await fs.promises.stat(binaryPath)
-    const needsCopy = await this.needsRecopy(destPath, srcStats.size)
-
-    if (needsCopy) {
+    try {
       await fs.promises.copyFile(binaryPath, destPath)
+    } catch (e: any) {
+      // Binary may be in use – continue with existing copy
+      console.log(`[ResourceExtractor] Could not overwrite binary (may be in use): ${e?.code || e}`)
     }
 
     if (osType !== "windows") {
@@ -50,18 +50,6 @@ export class ResourceExtractor {
     return destPath
   }
 
-  /**
-   * Check whether the destination binary needs to be (re-)copied.
-   */
-  private static async needsRecopy(destPath: string, srcSize: number): Promise<boolean> {
-    try {
-      const destStats = await fs.promises.stat(destPath)
-      return destStats.size !== srcSize
-    } catch {
-      return true
-    }
-  }
-
   /**
    * Remove stale opencode-* temp files/dirs left by older plugin versions.
    */

+ 13 - 7
hosts/vscode-plugin/src/ui/WebviewController.ts

@@ -139,30 +139,36 @@ export class WebviewController {
         uris.map(async (u) => {
           try {
             const uri = vscode.Uri.parse(u)
-            const filePath = uri.fsPath
+            // For non-file URIs (e.g. vscode-remote://ssh-remote+host/path),
+            // fsPath includes the authority as a UNC prefix (//ssh-remote+host/path)
+            // which is not a valid filesystem path. Use uri.path instead.
+            const filePath = uri.scheme === "file" ? uri.fsPath : uri.path
+            // For vscode.workspace.fs operations, keep the original URI so the
+            // remote extension host resolves the file on the correct machine
+            // (works for file://, vscode-remote://, wsl://, etc.)
+            const fileUri = uri
 
-            // Check if it's a file or directory
             try {
-              const stat = await vscode.workspace.fs.stat(uri)
+              const stat = await vscode.workspace.fs.stat(fileUri)
               if (stat.type === vscode.FileType.File) {
                 filePaths.push(filePath)
               } else if (stat.type === vscode.FileType.Directory) {
                 directoryPaths.push(filePath)
               }
-            } catch (statError) {
+            } catch {
               // If stat fails, assume it's a file
               filePaths.push(filePath)
             }
 
             // Create webview-safe URI for direct display
-            const webviewUri = this.webview.asWebviewUri(uri)
+            const webviewUri = this.webview.asWebviewUri(fileUri)
 
             // Optionally read file contents as base64 for fallback
             let data: string | undefined
             try {
-              const buf = await vscode.workspace.fs.readFile(uri)
+              const buf = await vscode.workspace.fs.readFile(fileUri)
               data = Buffer.from(buf).toString("base64")
-            } catch (readError) {
+            } catch {
               // File reading failed, but webviewUri might still work
             }
 

+ 2 - 1
packages/opencode/webgui/src/lib/dnd.ts

@@ -3,8 +3,9 @@
 function fileUrlToPath(uri: string): string | null {
   try {
     const u = new URL(uri)
-    if (u.protocol !== "file:") return null
+    // Accept file://, vscode-remote://, wsl:// and similar IDE schemes
     const raw = decodeURIComponent(u.pathname)
+    if (!raw || raw === "/") return null
     // Normalize Windows drive-letter paths like "/C:/foo" -> "C:/foo" while
     // leaving POSIX paths ("/home/user") untouched.
     if (/^\/[A-Za-z]:[\\/]/.test(raw)) return raw.slice(1)