跳转到内容

插件 API 参考

本文档提供 @eidos.space/plugin-sdk(Plugin 1.0)的所有核心接口、类型定义与方法参考。

在插件项目中安装类型声明:

终端窗口
pnpm add -D @eidos.space/plugin-sdk

每个插件必须在 plugin.json 中声明其能力与入口(单文件插件则在 .ts / .js 中导出 manifest 对象)。

export interface PluginManifest {
apiVersion: 1
id: string
name: string
version: string
icon?: PluginIconDefinition
extension?: string
views?: ViewDeclaration[]
actions?: ActionDeclaration[]
formatters?: FormatterDeclaration[]
placements?: Placement[]
browser?: {
workers?: boolean
networkOrigins?: string[]
}
storage?: {
maxBytes: number
}
}
字段 类型 必填 说明
apiVersion 1 宿主 API 版本,目前固定为 1
id string 插件全局唯一标识(建议采用反向域名,如 com.example.counter)。
name string 在 Eidos Lite 中展示的可读名称。
version string 遵循语义化版本的版本号(如 0.1.0)。
icon PluginIconDefinition 插件图标(SVG 路径对象或相对文件路径)。
extension string 后台扩展逻辑入口文件(如 ./src/extension.ts)。
views ViewDeclaration[] 自定义 UI 界面声明列表。
actions ActionDeclaration[] 快捷指令与命令声明列表。
formatters FormatterDeclaration[] 文本/文档格式化工具声明列表。
placements Placement[] 界面注入位置,定义动作与视图在 UI 中的入口。
browser.networkOrigins string[] 允许访问的精确 HTTPS 来源白名单。
browser.workers boolean 是否启用包内打包的 Blob Web Worker(默认 false)。
storage.maxBytes number 插件私有持久化存储配额(字节数,上限 1 GiB / 1073741824)。

用于定义插件品牌 Logo、视图专属图标以及动作命令图标:

export type PluginIconDefinition =
| string
| { paths: string[] }
| { src: string }
| { file: string }
  • 内联单色 SVG 路径对象{ paths: ["M12 2L2 7l10 5 10-5-10-5z..."] },由宿主使用当前主题色渲染,支持像素级自适应。
  • 本地相对路径:如 "./icon.svg""./assets/view.png",打包时自动内联为 Data URL。
  • Data URL 字符串:如 "data:image/svg+xml;base64,..."

用于在 plugin.jsonviews 列表中声明 UI 页面或编辑器视图:

export interface ViewDeclaration {
id: string
title: string
entry: string
context: "page" | "document" | "table"
access?: "read" | "write"
icon?: PluginIconDefinition
configuration?: ViewConfiguration
}
  • id: 视图在插件内的唯一标识。
  • title: 界面上展示给用户的标题名称。
  • entry: 界面挂载源码入口(如 ./src/main.ts)。
  • context: 视图挂载的上下文类型("page" 独立页面、"document" 文本文档、"table" 表格视图)。
  • access: 文件访问权限级别("read""write")。
  • icon: 视图专属功能图标(用于文件右键「打开方式」、视图 Tab 栏)。未声明时自动回退至插件 manifest.icon

用于在 plugin.jsonactions 列表中声明快捷指令或命令操作:

export interface ActionDeclaration {
id: string
title: string
context: "workspace" | "document" | "table"
access?: "read" | "write"
extensions?: string[]
icon?: PluginIconDefinition
multiple?: boolean
}
  • icon: 动作命令在快捷命令面板(Command Palette)中展示的功能图标。

Placement 用于将声明的 View 或 Action 关联到宿主界面的交互入口:

export type Placement =
| { location: "command-palette"; action: string }
| {
location: "keybinding"
action: string
key: string
mac?: string
linux?: string
}
| { location: "file/open"; view: string; extensions: string[] }
| { location: "navigation"; view: string }
| { location: "table/view"; view: string }
| { location: "plugin/settings"; view: string }
Location 入口 关联目标 说明
"command-palette" Action 注入到快捷命令面板(Cmd+K)。
"keybinding" Action 绑定全局/局部快捷键(如 Mod+Alt+C)。
"file/open" View 注入到文件右键菜单 Open with 中,接管指定扩展名文件。
"navigation" View 注入到 Space 侧边栏导航列表中。
"table/view" View 注入到表格视图菜单中的 新建视图 列表。
"plugin/settings" View 嵌入到 Space 插件管理器的插件详情配置页面中。

包含 Action 或 Formatter 的插件需在 plugin.json 中配置 extension,指向默认导出 activate 函数的模块:

import type { ExtensionContext } from "@eidos.space/plugin-sdk"
export default function activate(
ctx: ExtensionContext
): void | { dispose(): void } {
// 在这里注册 action 和 formatter
}
export interface ExtensionContext {
readonly actions: {
register(
id: string,
handler: (ctx: ActionContext) => void | Promise<void>
): Disposable
}
readonly formatters: {
register(id: string, provider: FormatterProvider): Disposable
}
readonly signal: AbortSignal
readonly subscriptions: {
add<T extends Disposable>(value: T): T
}
}

Action 注册的回调函数接收一个 ActionContext 上下文对象:

export interface ActionContext {
readonly binding: ActionBinding
readonly ui: HostUI
readonly signal: AbortSignal
readonly subscriptions: { add<T extends Disposable>(value: T): T }
}
export type ActionBinding =
| { kind: "workspace" }
| { kind: "document"; document: TextDocument }
| { kind: "table"; table: TableContext; rowId?: string }
  • binding.kind === "workspace": 工作区级全局命令,不依赖当前打开的文件。
  • binding.kind === "document": 在打开的文本文档上下文中触发,提供 binding.document
  • binding.kind === "table": 在数据表视图上下文中触发,提供 binding.table 与可选的 rowId

通过 ctx.formatters.register(id, provider) 注册:

export interface FormatterProvider {
format(input: FormatterInput): { text: string } | Promise<{ text: string }>
}
export interface FormatterInput {
text: string
path: string
signal: AbortSignal
}

当用户执行 格式化文档(快捷键 Shift+Option+F / Shift+Alt+F)时触发,返回修改后的 { text }


每个声明的 View 都通过 entry 指定一个默认导出 mount 函数的文件:

import type { ViewContext } from "@eidos.space/plugin-sdk"
export default function mount(
ctx: ViewContext,
root: HTMLElement
): void | { dispose(): void } | Promise<void | { dispose(): void }> {
root.textContent = "你好,视图"
return {
dispose() {
root.replaceChildren()
},
}
}
export interface ViewContext {
readonly binding: ViewBinding
readonly ui: HostUI
readonly storage: PluginStorage
readonly network: PluginNetwork
readonly signal: AbortSignal
readonly subscriptions: {
add<T extends Disposable>(value: T): T
}
}
export type ViewBinding =
| { kind: "page"; route: string }
| { kind: "document"; document: TextDocument }
| { kind: "table"; table: TableContext }

在 Action 和 View 的 ctx.ui 上均可使用:

export interface HostUI {
/** 在宿主右上角展示气泡通知 */
notify(message: string): Promise<void>
/** 弹出模态确认对话框 */
confirm(options: {
title: string
message: string
}): Promise<{ status: "confirmed" | "cancelled" }>
/** 弹出快速选择模态列表 */
select(options: {
title: string
options: Array<{ id: string; label: string }>
}): Promise<{ status: "selected"; id: string } | { status: "cancelled" }>
/** 导航到当前插件声明的某个页面及其子路由 */
navigate(viewId: string, route?: string): Promise<void>
}

binding.kind === "document" 时,可在 ctx.binding.document 上调用:

export interface TextDocument {
/** 读取当前文档的快照内容 */
read(): Promise<TextSnapshot>
/** 监听来自宿主或其他编辑器的修改 */
observe(
listener: (state: TextSnapshot) => void
): Promise<{ snapshot: TextSnapshot; subscription: Disposable }>
/** 应用内存草稿编辑(基于版本号乐观并发控制) */
edit(change: {
text: string
expectedVersion: string
label?: string
}): Promise<{ status: "applied" | "stale"; snapshot: TextSnapshot }>
/** 显式将草稿写回磁盘 */
save(): Promise<{ status: "saved" | "conflict"; snapshot: TextSnapshot }>
/** 撤销上一步编辑 */
undo(): Promise<TextSnapshot>
/** 重做上一步撤销 */
redo(): Promise<TextSnapshot>
}
export interface TextSnapshot {
text: string
version: string
encoding: "utf-8" | "utf-16le" | "utf-16be"
bom: boolean
dirty: boolean
conflicted: boolean
}

binding.kind === "table" 时,可在 ctx.binding.table 上调用:

export interface TableContext {
readonly tableId: string
readonly viewId: string
/** 读取绑定视图的元数据、列名及字段定义 */
read(): Promise<TableViewSnapshot>
/** 分页拉取数据行(使用宿主当前的筛选、排序与搜索条件) */
getPage(options: { offset: number; limit: number }): Promise<EidosFileRowPage>
/** 执行 SQLite 服务端加速的分组聚合计算 */
aggregate(options: TableAggregateOptions): Promise<TableAggregateResult>
/** 更新保存到 view.properties.plugin 的自定义视图配置 */
updateProperties(properties: Record<string, unknown>): Promise<void>
/** 在宿主界面中弹窗打开指定行记录卡片 */
openRecord(rowId: string): Promise<void>
/** 监听数据表记录修改 */
observe(listener: () => void): Disposable
}

分组聚合参数 (TableAggregateOptions)

Section titled “分组聚合参数 (TableAggregateOptions)”
export interface TableAggregateOptions {
groupBy?: {
fieldId: string
dateInterval?: "exact" | "day" | "month" | "year"
}
metric: {
fieldId?: string
op: "count" | "sum" | "average" | "min" | "max"
}
sort?: "label" | "value-desc" | "value-asc"
}

当前设备上该插件专用的二进制持久化键值存储(同设备所有 Space 共享):

export interface PluginStorage {
/** 写入二进制 Uint8Array 数据 */
write(key: string, value: Uint8Array): Promise<void>
/** 读取二进制数据,不存在时返回 null */
read(key: string): Promise<Uint8Array | null>
/** 列出匹配前缀的键名及文件大小 */
list(prefix?: string): Promise<Array<{ key: string; size: number }>>
/** 删除键 */
remove(key: string): Promise<void>
}
  • 键名:最长 100 字符的 ASCII 字符串。
  • 单个对象上限:4 MiB。
  • 总容量:由清单中的 storage.maxBytes 约束(最高 1 GiB)。

用于向白名单域名发起匿名的受限 HTTPS 请求:

export interface PluginNetwork {
read(request: {
url: string
range?: { offset: number; length: number }
}): Promise<{ data: Uint8Array; status: number; etag?: string }>
}
  • 请求的 URL 必须精确匹配 browser.networkOrigins 中声明的域名。
  • 超时时间:20 秒。
  • 单次响应体上限:4 MiB。