插件 API 参考
文件模板与 Dashboard
Section titled “文件模板与 Dashboard”Lite 插件 API 3.2 的 fileTemplates 可向“新建文件”添加格式选项。每项声明
id、title、extension、view、content,content 为最多 256 KiB 的静态 UTF-8 文本。
view 必须具有 document 能力及匹配扩展名的 file/open 放置。宿主以不覆盖方式创建文件,并打开对应 View。
具有 workspace.files.read 权限的 file View 可以检测可选的
ctx.capabilities.ui.resources。listViews(relativePath) 列出另一份 .eidos
文件的表和已保存视图;mount(element, { kind: "eidos-view", path, tableId, viewId })
将其挂载到矩形容器。普通文本、Markdown、图片使用 { kind: "file", path }。
GPX 等普通文件的 listViews 返回已启用且匹配的插件 View 与内置预览,结构为
{ kind: "file", editor, name, type };将选中的 editor 加入 file source 即可保存展示方式。
返回句柄应加入 subscriptions,支持 refresh() 和 dispose()。
路径相对于当前配置文件解析,必须位于同一 Space。最多 12 个只读资源,
不支持嵌套 dashboard、变换或重叠交互控件。宿主管理渲染和独立授权,
子插件通过 ctx.presentation?.mode === "embedded" 精简界面。
该能力目前由 Lite 提供。
在代码中使用 import type 从 @eidos.space/plugin-sdk 导入类型。Eidos 在调用 mount 或 activate 时提供上下文。
views 中每个视图都需要 id、title、entry 和 kind。kind 为 page 或 file;access 为 read 或 write,默认 read。
文件视图在 capabilities 中声明需要的数据接口:document 用于文本编辑;eidos/schema、eidos/table、eidos/config 分别用于文件结构、当前表格和插件配置,可以组合声明。直接读取文件或播放媒体时,通过 fs 访问文件,capabilities 可以省略。文本和 Eidos 接口适用于不同文件格式,不能混合声明。
使用 placements 指定入口:navigation 与 plugin/settings 打开 page;file/open 根据扩展名打开 file;table/view 在表格内部打开声明了 eidos/table 能力的 file。
在 Lite 中,侧栏底部依次显示设置、插件和最多三个已启用插件的独立页面。页面默认按原有顺序排列。超过三个页面时,「…」菜单列出全部页面,支持固定和拖拽排序;拖拽手柄也支持键盘操作。最多固定三个页面,保证它们占据可见位置,其余位置按保存的顺序补齐。固定状态和顺序按 Space 保存在本机。窄侧栏下显示图标,悬停可查看名称。专用于 plugin/settings 或 sidebar/explorer 的页面不会出现在此处,除非同时声明了 navigation 挂载点。显示入口不会加载页面内容。
requires.pluginApi 声明插件要求的 API,本文示例使用 "3.0.0"。apiVersion 固定为 1,插件自己的 version 用于标识发布版本。
可以在清单中添加 description,说明插件的具体用途。使用非空的单行纯文本,
最多 1024 个 UTF-16 码元。Lite 在插件列表和详情中显示该摘要,本地安装的插件
也适用。缺失时,如果插件市场有对应描述,则使用市场描述。
"description": "Keep Markdown filenames and existing leading H1 headings in sync."当前文件与页面
Section titled “当前文件与页面”在使用 binding 前检查 kind。page 提供 route,file 提供 file 元数据,并可通过 location 描述表格位置。
if (ctx.binding.kind === "page") { root.textContent = ctx.binding.route} else { root.textContent = ctx.binding.file.name ?? "File"}FileRef 的 path、name、size 等成员按运行环境提供。id 用于识别当前上下文中的文件;需要持久引用时,请使用你的业务数据中的稳定标识。
读取和编辑文本
Section titled “读取和编辑文本”声明 capabilities: ["document"] 后,通过 ctx.capabilities.document 使用以下方法。写入还需要 access: "write"。
| 方法 | 用途 |
|---|---|
read() |
获取包含 text、version、dirty 等信息的快照 |
observe(listener, onError?) |
获取初始快照并订阅后续变化 |
edit({ text, expectedVersion }) |
修改未保存内容,返回 applied 或 stale |
save() |
保存到文件,返回 saved 或 conflict |
undo() / redo() |
撤销或重做编辑并返回快照 |
下面的函数体将当前文本转成大写并保存:
const document = ctx.capabilities.documentif (!document) throw new Error("Document capability required")const current = await document.read()const result = await document.edit({ text: current.text.toUpperCase(), expectedVersion: current.version,})if (result.status === "stale") { await ctx.capabilities.ui.notify( "The text changed. Review it before editing again." ) return}const saved = await document.save()if (saved.status === "conflict") { await ctx.capabilities.ui.notify( "The file changed on disk. Your draft is still available." )}expectedVersion 使用读取时的版本。遇到 stale 时保留用户输入并让用户处理较新的内容;遇到 conflict 时保留草稿并提示磁盘变更。连续输入的编辑器应串行提交 edit,避免多个请求使用同一个旧版本。
读取文件和播放媒体
Section titled “读取文件和播放媒体”Lite 的 ctx.capabilities.fs 提供 readText/writeText、readBinary/writeBinary、list/stat、delete/rename、getUrl 和 watch。文本读取上限为 2 MiB,二进制 I/O 上限为 16 MiB;播放较大的媒体文件使用 getUrl 返回的流地址。
const fs = ctx.capabilities.fsif (!fs) throw new Error("Filesystem access is required")const video = document.createElement("video")video.controls = truevideo.src = await fs.getUrl()root.append(video)文件视图的文件访问受当前文件及其目录范围约束;访问整个 Space 需要 workspace.files。写入同时需要贡献项的 write 权限。已有工作副本的路径在直接写入、删除或重命名时会返回 BUSY;编辑文本时使用 document 接口处理保存和冲突。
Lite 文件属性
Section titled “Lite 文件属性”Lite API 3.1 通过 ctx.capabilities.filemeta 读取和修改原生 namespace 属性,底层由 sqlite-fs-meta 实现。声明需要访问的 namespace;写入同时要求 View 或 Action 的 access: "write"。Page 浏览 Space 文件还需要 workspace 文件读权限。
{ "workspace": { "files": { "read": true }, "filemeta": { "namespaces": ["space.eidos.meta"], "write": true } }}const filemeta = ctx.capabilities.filemeta!const metadata = await filemeta.read("notes/example.md", "space.eidos.meta")await filemeta.patch("notes/example.md", "space.eidos.meta", { set: { rating: 4, tags: ["review"], custom: { checked: true } }, remove: ["obsolete"],})读取返回完整 JSON 对象,包括 files.eidos 未定义的键;namespace 不存在时返回 {}。patch 保留其他键,null 是值,remove 删除键。路径相对 Space;未声明 workspace 文件读权限时,只能访问绑定文件。属性写权限不授予文件内容写权限。损坏的 JSON、符号链接、非普通文件会报错。属性最多 1 MiB,文件系统可能有更小限制。操作立即作用于文件系统;多个进程修改同一 namespace 时应串行协调写入。Linux 不需要安装 attr 命令行软件包。
替换 Lite 侧边栏目录树
Section titled “替换 Lite 侧边栏目录树”声明 page View,放到 sidebar/explorer,并使用 plugin API 3.1.0:
{ "requires": { "pluginApi": "3.1.0" }, "workspace": { "files": { "read": true } }, "views": [ { "id": "tree", "title": "我的目录树", "kind": "page", "entry": "./src/tree.ts" } ], "placements": [{ "location": "sidebar/explorer", "view": "tree" }]}安装和启用插件后,进入「插件 → 选择文件浏览器」选用。选择按 Space 保存。插件接管完整探索器区域,包括标题、路径、搜索、排序和文件操作工具栏;宿主不会在插件上方绘制内置 Space 标题。窗口导航与应用控制属于宿主外壳,位于此贡献点之外。通过插件管理页可返回内置探索器;插件失败时,宿主恢复内置标题和目录树,并提供重试与恢复入口。
此位置提供 ctx.capabilities.explorer.read(),返回当前 rootDirectory、activePath 和 sort。root 为 null 表示 Space,activePath 为 null 表示未打开文件。explorer.watch(listener) 订阅变化,返回可释放订阅,不提供初始回调。它只提供展示状态,文件权限单独校验。通过 fs.list(rootDirectory ?? "", { recursive: false, includeDirectories: true }) 逐层浏览,包括空目录;FileStat.modifiedAtMs 可用于时间排序。默认 list 行为保留递归文件索引。通过 fs.watch 刷新;用户点击文件时调用 ui.openFile(relativePath),宿主在主区域使用已配置的文件 View 打开。插件在侧边栏沙箱内负责导航、选中样式和已授权文件操作。全局 Space 文本搜索会临时覆盖探索器,保留插件挂载与浏览状态。普通 navigation Page 不提供 explorer 上下文。
使用 Eidos 文件
Section titled “使用 Eidos 文件”ctx.capabilities.eidos 包含按需声明的 schema、table 和 config。例如,一个需要读取结构和保存本插件配置的表格视图可以声明:
{ "id": "board", "title": "Board", "kind": "file", "entry": "./src/board.ts", "capabilities": ["eidos/schema", "eidos/table", "eidos/config"], "access": "write"}为此视图添加 table/view 入口。每项声明只提供对应接口;声明顺序不影响行为。
浏览文件结构
Section titled “浏览文件结构”声明 eidos/schema,使用 ctx.capabilities.eidos.schema.listTables() 获取文件内的表格列表,再用 readTable(tableId) 读取字段。文件浏览器通过匹配 .eidos 的 file/open 入口打开;表格视图也可以读取所在文件的结构。
查询当前表格
Section titled “查询当前表格”声明 eidos/table 并从 table/view 打开后,使用 ctx.capabilities.eidos.table:readContext 读取当前表格结构和视图信息,readRows 分页读取记录,aggregate 聚合数据,setViewConfig 完整替换当前视图的插件配置,openRecord 打开记录,watch 订阅失效通知。先读取结构,再用字段 ID 查询;这些方法始终作用于当前绑定表格。
保存插件配置
Section titled “保存插件配置”声明 eidos/config,通过 ctx.capabilities.eidos.config 的 read、write、watch 使用保存在文件中的本插件配置。文件浏览器可指定文件内的表格 ID;表格视图使用当前绑定的表格 ID。
const { table, config } = ctx.capabilities.eidos ?? {}if (!table || !config) throw new Error("Table and config capabilities required")const current = await config.read(table.tableId)await config.write(table.tableId, { value: { ...current.value, compact: true }, expectedVersion: current.version,})写入需要 access: "write" 和读取时的版本。版本过期时重新读取并处理冲突,避免覆盖他人的修改。config.watch(tableId, listener) 返回订阅,不发送初始值;先读取配置,收到通知后再次读取。通知可能包含其他数据变化,释放订阅后停止接收。
Lite 支持以上三个接口。CLI Serve 提供 eidos/table;需要同时支持 Serve 时,只声明该宿主提供的能力,并通过 check --target cli 验证。
设置、存储和通知
Section titled “设置、存储和通知”Lite 视图通过 capabilities.settings.get(key) 读取插件设置;普通动作还可调用 set/reset。capabilities.storage 提供按 key 存取私有二进制数据的 list/read/write/delete,配额通过 manifest.storage.maxBytes 声明。这些私有数据保存在设备本地。
capabilities.ui.notify(message) 显示通知。在支持导航的环境中,ui.openFile(relativePath) 打开文件,ui.navigate(viewId, route?) 打开页面。可选方法在调用前检查其是否存在。
View 可以通过可选的 capabilities.ui.exportFile({ name, mimeType, data }) 导出生成文件,
无需文件系统写入权限。name 是不含目录的文件名,mimeType 如 image/png,data 是不超过
16 MiB 的 Uint8Array。Lite 打开保存对话框,返回 { status: "saved" } 或
{ status: "cancelled" };CLI Serve 发起浏览器下载后返回
{ status: "download-started" }。调用前检查方法是否存在,并向用户显示导出失败原因。
目前移动端与 Action 上下文不提供此操作。
capabilities.network.read(src/content/docs/zh-cn/plugins/api.mdx) 向 browser.networkOrigins 声明的 HTTPS 来源发起有界请求。需要凭据的请求通过 ctx.capabilities.connections 的 isConfigured(connectionId) 和 request({ connection, body }) 调用已声明连接。连接可用于页面、文件视图和普通动作,由用户在 Eidos 中配置连接信息和密钥;动作结束时请求会被取消。
注册命令与格式化器
Section titled “注册命令与格式化器”本地文件修改后自动执行
Section titled “本地文件修改后自动执行”插件 API 3.3.0 支持 hooks 声明,字段为
{ id, title, event, extensions, access? }。event 是 document.saved 或
file.renamed;需要 extension 入口和对应的 requires.pluginApi。
在 activate 中调用 ctx.capabilities.hooks.register(id, handler),并将返回的
disposable 加入 ctx.subscriptions。
处理器接收 { event, settings, signal }。event 提供 Space 相对 path、operationId、
source 和 document: { text, version };保存另有 previousText,重命名另有 previousPath。
写 hook 声明 access: "write",返回当前文档的 { text?, name? } 或不返回计划。
name 保留目录与扩展名。宿主校验版本和同名冲突,并维护 Markdown 引用。
失败保留已经成功的保存或重命名。多个插件按 ID、声明顺序执行,第一个有效写计划生效。
只在本地操作成功后触发;打开、启用、云同步、局域网更新以及 hook 自身的修改不触发。 hook 使用可跨平台 JavaScript,不提供文件系统、数据库、网络、DOM 或 Node API。 settings 是插件配置的当前快照。Lite 支持可编辑文本文件,Android、iOS 支持 Markdown; CLI Serve 不支持 hook。
在扩展的 activate 中使用 capabilities.actions.register(id, handler) 注册声明过的动作。handler 接收自己的上下文,通过 capabilities 执行操作。
格式化器通过 capabilities.formatters.register(id, provider) 注册。provider.format 接收 { text, path, signal } 并返回 { text },由 Eidos 应用可撤销的文本编辑。
批量处理表格记录
Section titled “批量处理表格记录”使用 capabilities.actions.registerTableProvider(id, provider) 注册表格动作。getItems 接收 capabilities.eidos.table、只读的 capabilities.eidos.config 和 signal,返回供用户选择的菜单项;run 还可使用 capabilities.target、task 和 connections。
target.count 表示本次目标总数,target.readRows 分页读取记录。使用返回的 readToken 调用 target.update。开始写入前,调用 task.declareOutputs 提交真实输出样本并等待校验完成,它用于确定允许写入的字段。调用 task.report 报告进度,在每批操作之间检查 signal。取消会保留已经完成的记录修改。
释放资源与处理错误
Section titled “释放资源与处理错误”把订阅加入 ctx.subscriptions,使用 ctx.signal 中止异步操作,并在 mount 返回的 dispose 中释放界面资源。
常见错误包括 PERMISSION_DENIED(访问范围不足)、INSTANCE_CLOSED(上下文已关闭)、STALE_REVISION(数据已变化)、BUSY(资源正在被管理)、TOO_LARGE(超过限制)和 TIMEOUT(请求超时)。向用户说明失败原因,保留尚未保存的输入。