import type { AssistantBridge, BrowserStateEvent, RevealEvent, ViewMode, ViewportMessage } from '../electron/shared'; declare global { interface Window { assistant?: AssistantBridge; } } // 没有 Electron(在普通浏览器里调试界面)时退回到直接请求后端 const FALLBACK_PORT = 8788; const FALLBACK_BASE = `http://127.0.0.1:${FALLBACK_PORT}/api`; async function fetchJson(method: string, path: string, body?: unknown): Promise { const response = await fetch(FALLBACK_BASE + path, { method, headers: { 'Content-Type': 'application/json' }, body: body === undefined ? undefined : JSON.stringify(body), }); const data = (await response.json().catch(() => ({}))) as Record; if (!response.ok) { const detail = typeof data.detail === 'string' ? data.detail : response.statusText; throw new Error(detail); } return data as T; } const noop = (): (() => void) => () => undefined; const fallback: AssistantBridge = { get: path => fetchJson('GET', path), post: (path, body) => fetchJson('POST', path, body ?? {}), put: (path, body) => fetchJson('PUT', path, body ?? {}), del: path => fetchJson('DELETE', path), openPath: async () => '当前为浏览器预览,请在桌面端打开本地文件。', meta: async () => ({ apiPort: FALLBACK_PORT, cdpPort: 0, controlPort: 0, version: 'browser-dev' }), browser: { viewport: async () => undefined, mode: async () => undefined, onState: noop, onReveal: noop, onHide: noop, onUserInput: noop, }, }; const bridge: AssistantBridge = window.assistant ?? fallback; export const isElectron = Boolean(window.assistant); export const api = { get: (path: string): Promise => bridge.get(path) as Promise, post: (path: string, body?: unknown): Promise => bridge.post(path, body) as Promise, put: (path: string, body?: unknown): Promise => bridge.put(path, body) as Promise, del: (path: string): Promise => bridge.del(path) as Promise, openPath: (filePath: string): Promise => bridge.openPath(filePath), appMeta: () => bridge.meta(), browser: { viewport: (message: ViewportMessage): Promise => bridge.browser.viewport(message), mode: (taskId: string, mode: ViewMode): Promise => bridge.browser.mode(taskId, mode), onState: (handler: (event: BrowserStateEvent) => void): (() => void) => bridge.browser.onState(handler), onReveal: (handler: (event: RevealEvent) => void): (() => void) => bridge.browser.onReveal(handler), onHide: (handler: (event: RevealEvent) => void): (() => void) => bridge.browser.onHide(handler), onUserInput: (handler: (event: RevealEvent) => void): (() => void) => bridge.browser.onUserInput(handler), }, }; export function errorText(error: unknown): string { return error instanceof Error ? error.message : String(error); }