← 返回文档总览

@wegirl/sdk 唯一通道规范(宿主能力接入铁律)

版本:2026-09-14 起 生效 · 真相源:宿主 src/plugins/hostSdk.js(createHostSdk)+ plugins/scripts/shims/sdk.js(编译器 shim)+ electron/plugins/build-lib.cjs(SHIMS + 构建守卫) 本文是插件访问宿主能力的唯一规范;API 逐项细节见 PLUGIN_DEVELOPMENT.md §8。


1. 铁律:只有一种方式

插件源码访问宿主能力,只允许经 @wegirl/sdk 导入。

// ✅ 唯一正确姿势(推荐默认导入——永不怕 shim 导出面滞后)
import sdk from '@wegirl/sdk';
const { useModal, actions, wegirlFetch } = sdk;

// ✅ 具名导入也可以(shim 已列出的稳定字段)
import { useModal, getDesktopDashboardState, actions } from '@wegirl/sdk';

禁止清单(宿主构建期守卫会扫描并告警/报错):

禁止写法 是什么 应改为
window.__WEGIRL__ / globalThis.__WEGIRL__ 宿主运行时内部交接点(react/sdk/cap/ui/editors/panels) 一律 @wegirl/sdk;editors/panels 也在 sdk.editors / sdk.panels
window.api.* / globalThis.api.* preload 原生桥(IPC 通道裸面) sdk.fs / sdk.invoke / sdk.app / getCapability(...) 等语义化能力
运行时兜底 globalThis.__WEGIRL__?.sdk 旧编译器 shim 缺导出时的历史绕行(cross-border 插件曾用) 已废除。升级编译器包即可;shim 默认导出永远指向运行时最新 sdk 单例,不存在滞后

__WEGIRL__ 全局只允许出现在宿主自有代码里(hostRuntime 注入 + shim 文本),它是宿主实现细节,不是插件 API。

2. 为什么默认导入优先

shim 的具名导出是构建期快照(export const useModal = sdk.useModal),编译器包落后于宿主时新字段拿不到;而 export default sdk 是对运行时单例的直通引用——宿主加什么能力,sdk.xxx 立即可用,升级宿主不需要升级编译器。

结论:默认导入为主,具名导入仅用于 shim 清单里明确列出的字段(清单见 PLUGIN_DEVELOPMENT.md §8.2.1)。

3. 常用能力速查

需求 写法
当前项目(快照) sdk.getCurrentProject()(回调/事件里用;宿主已封装本地 find + 云端回退)
当前项目(响应式) const project = sdk.useCurrentProject()(组件里用,切换项目自动重渲染)
响应式读状态 sdk.useDesktopDashboardStore(s => ...)
打开编辑器条目 sdk.actions.openEditorItemForProject(projectId, node)
打开/关闭文件 sdk.actions.openAndLoadFile(projectId, node) / closeFileForProject
调用插件主进程 sdk.invoke(pluginId, method, payload)(桌面 IPC / 云端代理自动路由)
调用主进程 cap(原样信封) sdk.getCapability(capId).method(...)
调用主进程 cap(解包+抛错) await sdk.callCap(capId, method, payload)(SDK 内置,推荐)
订阅主进程推送事件 sdk.events.on(channel, cb)(返回解绑函数;webContents.send 的通道)
直发网关 REST(带宿主鉴权) sdk.wegirlFetch(url, { skipErrorModal: true })
模块化网关请求(R 解包) sdk.apiClient.get/post/postForm(module, path, opts)
弹窗 sdk.useModal / sdk.showModal / sdk.showConfirmModal
宿主编辑器组件 sdk.editors.EditorShell / sdk.editors.DesktopImagePreview …(活 getter)
宿主面板组件 sdk.panels(活 getter)
AI 行动按钮 sdk.AIButton(旧名 SparkleButton 为兼容别名)
文件读写 sdk.fs.readFile / writeFile / exists / remove
图片查看器 sdk.app.openImageViewer(payload)
插件热重载 sdk.reloadPlugin(pluginId)

4. 获取「当前项目」标准范式

首选宿主封装好的派生 getter(本地 find + 云端回退规则在宿主侧维护,插件不必了解 store 形状):

import sdk from '@wegirl/sdk';

// 回调 / 事件里(非响应式快照):
const project = sdk.getCurrentProject();
const projectId = project?.id || '';

// 组件里(响应式 hook,切换项目自动重渲染):
const project = sdk.useCurrentProject();

需要项目以外的 store 字段时才下沉到原始 store 访问:

const st = sdk.getDesktopDashboardState();               // 快照
const v = sdk.useDesktopDashboardStore(s => s.xxx);       // 响应式

云端项目注意:selectedProjectId 会被置为云端项目 id,但 projects 数组里没有云端项目对象,宿主的 getCurrentProject / useCurrentProject 已内建回退 selectedCloudProject,不要再手写这段逻辑。

5. 构建期守卫

宿主 build-lib.cjshostGlobalsGuardPlugin 会扫描插件源码(shim 文本不在扫描范围):

6. 存量代码迁移对照表

旧写法(已废除) 新写法
const sdk = globalThis.__WEGIRL__?.sdk import sdk from '@wegirl/sdk'
window.__WEGIRL__?.editors sdk.editors
window.__WEGIRL__?.panels sdk.panels
window.__WEGIRL__?.actions(宿主本就无此字段,恒 null) sdk.actions
window.api.plugins.invoke(id, method, payload) 兜底 sdk.invoke(id, method, payload)(桌面/云端已自动路由,无需兜底)
window.api.desktop.readFile sdk.fs.readFile
window.api.cap.callCap(...) sdk.callCap(capId, method, payload)(SDK 内置)或 sdk.getCapability(capId).method(...)

7. 适配本规范的宿主侧配套(2026-09-14)