跳转到内容

插件 API 参考

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

在插件项目中安装官方类型包:

终端窗口
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
requires?: { pluginApi: string }
// 功能贡献声明
views?: ViewDeclaration[]
actions?: ActionDeclaration[]
formatters?: FormatterDeclaration[]
placements?: Placement[]
// 扩展与后台入口
extension?: string
// 权限与资源配置
workspace?: {
files?: boolean | { read?: boolean; write?: boolean }
}
settings?: Record<string, SettingDeclaration>
storage?: { maxBytes: number }
browser?: {
workers?: boolean
networkOrigins?: string[]
}
connections?: Record<
string,
{ title: string; url: string; configurable?: boolean }
>
// 独立宿主主题
kind?: "theme"
theme?: ThemeDeclaration
}
字段 类型 说明
apiVersion 1 宿主 API 规范版本,目前为 1。
id string 插件全局唯一标识(建议采用小写反向域名,如 com.example.viewer)。
name string 插件对外展示的名称。
version string 遵循语义化版本格式(如 0.1.0)。
icon PluginIconDefinition 插件图标(SVG 路径对象、相对文件路径或 Data URL)。
requires.pluginApi string 最低宿主 API 契约版本。当前 Lite 可执行插件必须声明 "2.0.0",纯 "1.6.0" 主题继续兼容。
extension string 后台扩展逻辑源码入口(如 "./src/extension.ts")。存在 actions 或 formatters 时必填。
views ViewDeclaration[] 界面视图贡献列表。
actions ActionDeclaration[] 快捷操作与命令贡献列表。
formatters FormatterDeclaration[] 文档格式化程序列表。
placements Placement[] 贡献点挂载位置列表。
workspace.files boolean | { read?: boolean; write?: boolean } 声明在当前 Space 范围内的文件读写授权。
settings Record<string, SettingDeclaration> 声明展示在插件设置详情面板中的配置项。
storage.maxBytes number 插件私有持久化存储容量上限(字节,最大 1 GiB)。
browser.networkOrigins string[] 允许网络请求的受信任精确 HTTPS 来源白名单。
kind / theme "theme" / ThemeDeclaration 声明独立的 Eidos Lite 宿主主题(不包含可执行代码)。

export interface ViewDeclaration {
id: string
title: string
entry: string
context: "file" | "page" | "table" | "document" | "media" | "eidos"
access?: "read" | "write"
icon?: PluginIconDefinition
configuration?: ViewConfiguration
}
  • context: 视图的物理目标。推荐统一使用 "file"(接管工作区文件)与 "page"(独立面板)。"document"、"media"、"eidos" 保持平滑兼容。
  • access: 文件访问级别("read" 或 "write",默认 "read")。
  • configuration: 仅限 context: "table" 时使用,声明保存在 view.properties.plugin 的视图配置 Schema。
export interface ActionDeclaration {
id: string
title: string
context: "workspace" | "file" | "document" | "table"
access?: "read" | "write"
extensions?: string[]
icon?: PluginIconDefinition
}
  • context: 动作绑定的目标。"workspace" 为全局 Space 级命令,"file" 为特定文件右键或上下文操作。
  • extensions: 当动作限定在特定文件格式时声明(如 [".md", ".txt"])。
export type Placement =
| { location: "command-palette"; action: string }
| { location: "file/open"; view: string; extensions: string[] }
| { location: "navigation"; view: string }
| { location: "table/view"; view: string }
| { location: "file/context"; action: string }
| { location: "table/context"; action: string }
| { location: "view/toolbar"; view: string; action: string }
| { location: "keybinding"; action: string; key: string; mac?: string; linux?: string }
| { location: "plugin/settings"; view: string }
Location 入口 绑定目标 说明
"command-palette" Action 注册到全局快捷命令面板(Cmd+K / Ctrl+K)。
"file/open" View 挂载到文件右键菜单 打开方式(Open with),接管 extensions 匹配的文件。
"navigation" View 挂载到 Space 侧边栏主导航中,作为独立一级面板。
"table/view" View 挂载到数据表内部的视图切换栏中(新建视图)。
"file/context" Action 挂载到工作区文件列表的右键菜单中。
"table/context" Action 挂载到数据表格右键或选区菜单中(支持动态表格动作)。
"view/toolbar" Action 挂载到特定视图的顶部工具栏。
"keybinding" Action 绑定快捷键(如 "Mod+Alt+F")。
"plugin/settings" View 嵌入到当前插件的详情配置面板。

所有视图上下文(ViewContext)与动作上下文(ActionContext)均完整继承 CommonContext:

export interface CommonContext extends Lifetime {
readonly fs: PluginFileSystem
readonly storage: PluginStorage
readonly network: PluginNetwork
readonly settings: Settings
readonly ui: HostUI
}
export interface Lifetime {
readonly signal: AbortSignal
readonly subscriptions: { add<T extends Disposable>(value: T): T }
}

所有插件均在本地沙箱运行。ctx.fs 提供完整的文件系统原语:

export interface PluginFileSystem {
/** 读取文件的文本内容(受 2 MiB 预览上限保护)。 */
readText(path: string): Promise<string>
/** 向文件写入文本内容。缺失的父目录会自动创建。 */
writeText(path: string, content: string): Promise<void>
/** 读取文件的二进制内容(支持最高 16 MiB 图像、音视频、模型等二进制数据)。 */
readBinary(path: string): Promise<Uint8Array>
/** 向文件写入二进制数据(最高 16 MiB)。缺失的父目录会自动创建。 */
writeBinary(path: string, content: Uint8Array): Promise<void>
/** 删除 Space 内的指定文件。 */
delete(path: string): Promise<void>
/** 在 Space 内重命名或移动普通文件;目标已存在时返回 ALREADY_EXISTS。 */
rename(oldPath: string, newPath: string): Promise<void>
/**
* 枚举目录中的文件。
* 在文件视图中若省略 folder,默认枚举当前文件同级目录。
* 可选通过 options.extensions 过滤扩展名。
*/
list(folder?: string, options?: { extensions?: string[] }): Promise<FileStat[]>
/** 查询文件或目录元数据。若不存在则返回 null。 */
stat(path: string): Promise<FileStat | null>
/**
* 获取用于媒体流式播放的原生协议 URL (eidos-space-media:)。
* 支持 HTTP Range 范围请求与瞬间拖拽定位。在文件视图中若省略 path,默认指向当前打开的文件。
*/
getUrl(path?: string): Promise<string>
/** 监听文件或目录的变化。页面关闭或调用 dispose() 时自动解除。 */
watch(pathOrFolder: string, listener: () => void): Promise<Disposable>
}
  • 伴随文件安全域:在未声明 workspace.files 的文件视图或动作中,ctx.fs 严格限制在当前文件同级目录及伴随文件内(如 movie.mp4 旁边的 movie.srt)。
  • Space 全局读写:声明 workspace.files: true 后,插件可在整个 Space 内自由读写、检索与监听任意文件。
  • 沙箱隔离:严禁 .. 越界路径遍历,禁止访问内部实现目录(.graft)。
export interface HostUI {
/** 在宿主右上角弹出气泡通知。 */
notify(message: string): Promise<void>
/** 弹出模态选择列表。 */
select(options: {
title: string
options: Array<{ id: string; label: string }>
}): Promise<{ status: "selected"; id: string } | { status: "cancelled" }>
/** 弹出模态确认对话框。 */
confirm(options: {
title: string
message: string
}): Promise<{ status: "confirmed" | "cancelled" }>
/** 请求宿主在对应编辑器或视图中打开 Space 内的相对路径文件。 */
openFile(relativePath: string): Promise<void>
/** 在插件的 Page 视图间进行内部导航。 */
navigate(viewId: string, route?: string): Promise<void>
}

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

export interface PluginStorage {
write(key: string, value: Uint8Array): Promise<void>
read(key: string): Promise<Uint8Array | null>
list(prefix?: string): Promise<Array<{ key: string; size: number }>>
remove(key: string): Promise<void>
}

向 browser.networkOrigins 声明的白名单域名发起受限 HTTPS 请求:

export interface PluginNetwork {
read(request: {
url: string
range?: { offset: number; length: number }
}): Promise<{ data: Uint8Array; status: number; etag?: string }>
}

读取并更新在清单 settings 中声明的插件配置(按 Space 独立持久化):

export interface Settings {
get(key: string): Promise<SettingValue>
update(key: string, value: SettingValue): Promise<void>
reset(key: string): Promise<void>
observe(
listener: (values: Record<string, SettingValue>) => void,
onError?: ObserverErrorHandler
): Promise<{ values: Record<string, SettingValue>; subscription: Disposable }>
}

每个视图入口文件导出默认的 mount 函数:

import type { ViewContext, Disposable } from "@eidos.space/plugin-sdk"
export default function mount(
ctx: ViewContext,
root: HTMLElement
): void | Disposable | Promise<void | Disposable> {
root.textContent = "Hello View"
return {
dispose() {
root.replaceChildren()
},
}
}
export interface ViewContext extends CommonContext {
readonly binding: ViewBinding
// 根据当前打开的物理文件类型附加:
readonly file?: FileContext // 所有文件视图均提供
readonly editor?: TextDocument // 文本文件打开时提供
readonly table?: TableContext // .eidos 数据表打开时提供
readonly eidos?: EidosFileContext // .eidos 文件打开时提供
}

任何通过 file/open 打开的文件视图均可直接读取:

export interface FileContext {
readonly path: string // 相对于 Space 根目录的路径(如 "notes/todo.md")
readonly name: string // 完整文件名(如 "todo.md")
readonly baseName: string // 去除扩展名的文件名(如 "todo")
readonly extension: string // 扩展名(如 ".md")
readonly size: number // 文件字节大小
readonly mimeType?: string // 可选媒体 MIME 类型
}

当打开文本类文件时,ctx.editor 提供内存工作副本与草稿同步机制:

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>
}

数据表与 .eidos 文件能力 (ctx.table & ctx.eidos)

Section titled “数据表与 .eidos 文件能力 (ctx.table & ctx.eidos)”

当视图打开 .eidos SQLite 数据文件或作为 table/view 挂载时提供:

export interface TableContext {
readonly tableId: string
readonly viewId: string
readonly pluginConfig: TablePluginConfig
read(): Promise<TableViewSnapshot>
getPage(options: { offset: number; limit: number }): Promise<EidosFileRowPage>
aggregate(options: TableAggregateOptions): Promise<TableAggregateResult>
updateProperties(properties: Record<string, unknown>): Promise<void>
openRecord(rowId: string): Promise<void>
observe(listener: () => void): Disposable
}
export interface EidosFileContext {
listTables(): Promise<Array<{ id: string; name: string }>>
readTable(tableId: string): Promise<{ fields: EidosFileFieldInfo[] }>
readPluginConfig(tableId: string): Promise<TablePluginConfigSnapshot>
writePluginConfig(tableId: string, input: { value: JsonObject | null; expectedVersion: string }): Promise<TablePluginConfigSnapshot>
}

动作与扩展入口 (activate & ActionContext)

Section titled “动作与扩展入口 (activate & ActionContext)”

包含 Action 或 Formatter 的插件需在 plugin.json 中配置 extension:

import type { ExtensionContext } from "@eidos.space/plugin-sdk"
export default function activate(ctx: ExtensionContext) {
// 注册普通动作
ctx.actions.register("format-markdown", async (actionCtx) => {
// actionCtx 具备完整 CommonContext
})
}
export interface ExtensionContext extends Lifetime {
readonly actions: {
register(id: string, handler: (ctx: ActionContext) => void | Promise<void>): Disposable
registerTableProvider(id: string, provider: TableActionProvider): Disposable
}
readonly formatters: {
register(id: string, provider: FormatterProvider): Disposable
}
readonly settings: Settings
}
export interface ActionContext extends CommonContext {
readonly binding: ActionBinding
readonly file?: FileContext
readonly editor?: TextDocument
readonly table?: TableContext
}
export interface FormatterProvider {
format(input: { text: string; path: string; signal: AbortSignal }): { text: string } | Promise<{ text: string }>
}

当用户在编辑器中触发 格式化文档(Shift+Option+F / Shift+Alt+F)时自动执行。