fix: open external links in VS Code runtime

Route shared URL opening through VS Code host instead of webview window APIs
Add a VS Code runtime URL-open API and bridge handler using vscode.env.openExternal
Keep shared URL helper behavior unchanged for desktop and web
This commit is contained in:
Bohdan Triapitsyn
2026-03-20 19:22:43 +02:00
parent 7356090e3d
commit 36793d00a4
5 changed files with 37 additions and 1 deletions
+1
View File
@@ -619,6 +619,7 @@ export interface EditorAPI {
export interface VSCodeAPI {
executeCommand(command: string, ...args: unknown[]): Promise<unknown>;
openAgentManager(): Promise<void>;
openExternalUrl(url: string): Promise<void>;
}
export interface PushSubscribePayload {
+12
View File
@@ -1,3 +1,5 @@
import { getRegisteredRuntimeAPIs } from '@/contexts/runtimeAPIRegistry';
/**
* Utility for opening external URLs with Tauri shell support.
* In desktop runtime, uses tauri.shell.open() for proper system browser handling.
@@ -55,6 +57,16 @@ export const openExternalUrl = async (url: string): Promise<boolean> => {
const normalizedTarget = parsed.toString();
const runtimeApis = getRegisteredRuntimeAPIs();
if (runtimeApis?.runtime?.isVSCode && runtimeApis.vscode?.openExternalUrl) {
try {
await runtimeApis.vscode.openExternalUrl(normalizedTarget);
return true;
} catch {
return false;
}
}
const tauri = (window as unknown as { __TAURI__?: TauriShell }).__TAURI__;
if (tauri?.shell?.open) {
try {
+15
View File
@@ -3139,6 +3139,21 @@ export async function handleBridgeMessage(message: BridgeRequest, ctx?: BridgeCo
}
}
case 'vscode:openExternalUrl': {
const { url } = (payload || {}) as { url?: string };
const target = typeof url === 'string' ? url.trim() : '';
if (!target) {
return { id, type, success: false, error: 'URL is required' };
}
try {
await vscode.env.openExternal(vscode.Uri.parse(target));
return { id, type, success: true, data: { opened: true } };
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
return { id, type, success: false, error: errorMessage };
}
}
case 'notifications:can-notify': {
return { id, type, success: true, data: true };
}
+4
View File
@@ -138,6 +138,10 @@ export async function executeVSCodeCommand(command: string, args?: unknown[]): P
return sendBridgeMessage<{ result?: unknown }>('vscode:command', { command, args });
}
export async function openVSCodeExternalUrl(url: string): Promise<void> {
await sendBridgeMessage('vscode:openExternalUrl', { url });
}
type CommandHandler = (payload: unknown) => void;
const commandHandlers = new Map<string, CommandHandler>();
+5 -1
View File
@@ -1,5 +1,5 @@
import type { VSCodeAPI } from '@openchamber/ui/lib/api/types';
import { executeVSCodeCommand } from './bridge';
import { executeVSCodeCommand, openVSCodeExternalUrl } from './bridge';
export const createVSCodeActionsAPI = (): VSCodeAPI => ({
async executeCommand(command: string, ...args: unknown[]): Promise<unknown> {
@@ -10,4 +10,8 @@ export const createVSCodeActionsAPI = (): VSCodeAPI => ({
async openAgentManager(): Promise<void> {
await executeVSCodeCommand('openchamber.openAgentManager');
},
async openExternalUrl(url: string): Promise<void> {
await openVSCodeExternalUrl(url);
},
});