插件 API 参考
本文档提供 @eidos.space/plugin-sdk 的所有核心接口、类型定义与方法参考。
在插件项目中安装官方类型包:
pnpm add -D @eidos.space/plugin-sdk插件清单 (PluginManifest)
Section titled “插件清单 (PluginManifest)”每个插件必须在 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 宿主主题(不包含可执行代码)。 |
贡献声明与位置 (Placements)
Section titled “贡献声明与位置 (Placements)”视图声明 (ViewDeclaration)
Section titled “视图声明 (ViewDeclaration)”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。
动作声明 (ActionDeclaration)
Section titled “动作声明 (ActionDeclaration)”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"])。
挂载位置 (Placement)
Section titled “挂载位置 (Placement)”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 | 嵌入到当前插件的详情配置面板。 |
通用基础能力 (CommonContext)
Section titled “通用基础能力 (CommonContext)”所有视图上下文(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)
Section titled “文件系统操作 (ctx.fs)”所有插件均在本地沙箱运行。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>}安全与作用域规则
Section titled “安全与作用域规则”- 伴随文件安全域:在未声明
workspace.files的文件视图或动作中,ctx.fs严格限制在当前文件同级目录及伴随文件内(如movie.mp4旁边的movie.srt)。 - Space 全局读写:声明
workspace.files: true后,插件可在整个 Space 内自由读写、检索与监听任意文件。 - 沙箱隔离:严禁
..越界路径遍历,禁止访问内部实现目录(.graft)。
宿主交互界面 (ctx.ui)
Section titled “宿主交互界面 (ctx.ui)”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>}插件私有存储 (ctx.storage)
Section titled “插件私有存储 (ctx.storage)”当前设备上该插件专用的二进制键值存储(同设备所有 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>}网络请求 (ctx.network)
Section titled “网络请求 (ctx.network)”向 browser.networkOrigins 声明的白名单域名发起受限 HTTPS 请求:
export interface PluginNetwork { read(request: { url: string range?: { offset: number; length: number } }): Promise<{ data: Uint8Array; status: number; etag?: string }>}配置管理 (ctx.settings)
Section titled “配置管理 (ctx.settings)”读取并更新在清单 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 }>}视图接口 (ViewContext & mount)
Section titled “视图接口 (ViewContext & mount)”每个视图入口文件导出默认的 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() }, }}ViewContext 结构
Section titled “ViewContext 结构”export interface ViewContext extends CommonContext { readonly binding: ViewBinding
// 根据当前打开的物理文件类型附加: readonly file?: FileContext // 所有文件视图均提供 readonly editor?: TextDocument // 文本文件打开时提供 readonly table?: TableContext // .eidos 数据表打开时提供 readonly eidos?: EidosFileContext // .eidos 文件打开时提供}文件元信息 (ctx.file)
Section titled “文件元信息 (ctx.file)”任何通过 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)
Section titled “文本编辑器能力 (ctx.editor)”当打开文本类文件时,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 })}ExtensionContext
Section titled “ExtensionContext”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}ActionContext
Section titled “ActionContext”export interface ActionContext extends CommonContext { readonly binding: ActionBinding readonly file?: FileContext readonly editor?: TextDocument readonly table?: TableContext}文档格式化程序 (FormatterProvider)
Section titled “文档格式化程序 (FormatterProvider)”export interface FormatterProvider { format(input: { text: string; path: string; signal: AbortSignal }): { text: string } | Promise<{ text: string }>}当用户在编辑器中触发 格式化文档(Shift+Option+F / Shift+Alt+F)时自动执行。