插件开发指南
Eidos Lite 插件可以为各类文件提供自定义编辑器与查看器、在侧边栏挂载独立页面,或在命令面板中添加快捷指令。插件拥有完整的本地文件系统访问能力(ctx.fs)、私有存储、受限网络请求与宿主交互接口。
快速上手:创建你的第一个插件工程
Section titled “快速上手:创建你的第一个插件工程”1. 准备环境
Section titled “1. 准备环境”确保已安装 Node.js 22.12 或更新版本以及常用的包管理器(npm、pnpm 或 yarn)。同时安装 Eidos Lite 用于本地运行和调试。
2. 初始化工程
Section titled “2. 初始化工程”通过官方脚手架初始化插件:
npx @eidos.space/plugin-tools create my-plugincd my-pluginnpm install # 或 pnpm install生成的标准目录结构如下:
my-plugin/├── plugin.json # 声明插件元数据、视图与入口的清单文件├── package.json # 项目依赖与 npm scripts├── tsconfig.json # 严格模式 TypeScript 配置└── src/ ├── main.tsx # 视图挂载入口源码 └── style.css # 样式表脚手架已在 package.json 中配置好官方工具链:
@eidos.space/plugin-sdk: 插件 1.0 的完整 TypeScript 规范与接口类型。npm run check: 执行静态语法、类型与清单校验(eidos-plugin check .)。npm run pack:plugin: 打包输出用于分发的自包含离线安装包(.eidos-plugin)。
3. 在 Eidos Lite 中即时加载与调试
Section titled “3. 在 Eidos Lite 中即时加载与调试”调试插件无需提前打包或 build,Eidos Lite 内置编译器支持实时动态编译:
- 启动 Eidos Lite,进入任意 Space。
- 点击顶部工具栏中的 Plugins 图标(位于搜索框与更多菜单之间)。
- 点击 Load development source…(加载开发源码),选中项目的
plugin.json。 - 确认权限声明并在当前 Space 中启用。
- 在 Space 中找到对应扩展名的文件,右键点击并选择 Open with → 你的插件视图。
当你在代码编辑器中修改 src/ 下的代码并保存时,Eidos Lite 会自动重编译并热重载视图!
核心能力实战
Section titled “核心能力实战”1. 自定义文件视图 (context: "file")
Section titled “1. 自定义文件视图 (context: "file")”文件视图可以接管任意文件格式(如文本、音视频、自定义二进制文件或 .eidos SQLite 数据包)的展示与交互。
在 plugin.json 中声明:
{ "apiVersion": 1, "id": "example.file-viewer", "name": "Custom File Viewer", "version": "0.1.0", "views": [ { "id": "viewer", "title": "Custom Viewer", "entry": "./src/main.tsx", "context": "file", "access": "write" } ], "placements": [ { "location": "file/open", "view": "viewer", "extensions": [".json", ".dat", ".mp4"] } ]}在 src/main.tsx 中挂载 React 界面:
import type { ViewContext } from "@eidos.space/plugin-sdk"import React, { useEffect, useState } from "react"import { createRoot } from "react-dom/client"import "./style.css"
function App({ ctx }: { ctx: ViewContext }) { const [content, setContent] = useState<string>("") const file = ctx.file!
useEffect(() => { // 使用 ctx.fs 读取当前文件文本或二进制 ctx.fs.readText(file.path).then(setContent).catch(console.error) }, [file.path])
const handleSave = async () => { await ctx.fs.writeText(file.path, content) await ctx.ui.notify("文件保存成功!") }
return ( <div className="viewer-container"> <header className="header"> <h3>{file.name} ({file.size} bytes)</h3> <button onClick={handleSave}>保存</button> </header> <textarea value={content} onChange={(e) => setContent(e.target.value)} /> </div> )}
export default function mount(ctx: ViewContext, root: HTMLElement) { const reactRoot = createRoot(root) reactRoot.render(<App ctx={ctx} />)
return { dispose() { reactRoot.unmount() }, }}2. 文件系统操作与伴随文件 (ctx.fs)
Section titled “2. 文件系统操作与伴随文件 (ctx.fs)”ctx.fs 向插件提供完备的本地文件操作能力。在文件视图中,支持直接读写二进制数据、伴随文件探测与流式多媒体播放。
① 二进制读写与大文件处理
Section titled “① 二进制读写与大文件处理”ctx.fs.readBinary(path) 与 ctx.fs.writeBinary(path, data) 支持最高 16 MiB 的二进制数据,直接处理图片、音视频分片或自定义二进制数据包:
// 读取二进制数据const bytes = await ctx.fs.readBinary("assets/logo.png")
// 写入二进制数据const payload = new Uint8Array([0x89, 0x50, 0x4e, 0x47])await ctx.fs.writeBinary("data/output.bin", payload)② 伴随媒体文件探测与流式播放
Section titled “② 伴随媒体文件探测与流式播放”针对音视频与字幕伴随场景,使用 ctx.fs.getUrl() 与 ctx.fs.list():
// 1. 获取音视频的高性能特权协议流式地址(支持 206 Partial Content 范围拖拽播放)const streamUrl = await ctx.fs.getUrl("movie.mp4")
// 2. 枚举同级目录下的伴随字幕文件const companions = await ctx.fs.list(undefined, { extensions: [".srt", ".vtt"] })
// 3. 读取伴随字幕内容if (companions.length > 0) { const srtText = await ctx.fs.readText(companions[0].path)}③ 文件变更实时监听 (watch)
Section titled “③ 文件变更实时监听 (watch)”const watcher = await ctx.fs.watch("data", () => { console.log("目录内文件发生变更,自动重新加载数据")})
// 自动随页面卸载注销监听ctx.subscriptions.add(watcher)3. 快捷命令与动作 (actions)
Section titled “3. 快捷命令与动作 (actions)”通过命令面板(Cmd+K)或快捷键触发操作。
在 plugin.json 中声明:
{ "extension": "./src/extension.ts", "actions": [ { "id": "stat-workspace", "title": "统计 Space 文件总览", "context": "workspace" } ], "placements": [ { "location": "command-palette", "action": "stat-workspace" }, { "location": "keybinding", "action": "stat-workspace", "key": "Mod+Alt+S" } ]}在 src/extension.ts 中实现:
import type { ExtensionContext } from "@eidos.space/plugin-sdk"
export default function activate(ctx: ExtensionContext) { ctx.actions.register("stat-workspace", async ({ fs, ui }) => { const files = await fs.list() await ui.notify(`当前 Space 根目录包含 ${files.length} 个文件。`) })}4. 独立功能页面 (context: "page")
Section titled “4. 独立功能页面 (context: "page")”用于在 Space 侧边栏构建常驻的看板或工具应用。
在 plugin.json 中声明:
{ "workspace": { "files": true }, "views": [ { "id": "dashboard", "title": "日记管理看板", "context": "page", "entry": "./src/dashboard.tsx" } ], "placements": [ { "location": "navigation", "view": "dashboard" } ]}页面挂载后将显示在 Space 左侧主导航中。声明了 workspace: { "files": true } 的页面可以使用 ctx.fs 在全 Space 范围内索引或创建文件(例如自动创建每日日记)。
5. 校验与打包发布
Section titled “5. 校验与打包发布”在工程根目录下执行静态类型与规范检查:
npm run check打包生成 .eidos-plugin 离线分发文件:
npm run pack:plugin打包完成后,产物位于 dist/<plugin-id>-<version>.eidos-plugin。用户可以直接双击或在 Eidos Lite 插件管理器中拖拽安装该归档。