@xiongtao.xt/tau-plugins 0.31.1 → 0.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/README.md +2 -2
- package/client/{chunk-ECEBBIHP.js → chunk-SVY5LBAT.js} +44 -0
- package/docs/README.md +43 -0
- package/docs/ai.md +169 -0
- package/docs/backend.md +168 -0
- package/docs/editor.md +457 -0
- package/docs/excerpts.md +126 -0
- package/docs/flashcards.md +127 -0
- package/docs/getting-started.md +134 -0
- package/docs/mcp.md +173 -0
- package/docs/plugin-basics.md +209 -0
- package/docs/providers/README.md +108 -0
- package/docs/providers/images.md +65 -0
- package/docs/providers/publish.md +144 -0
- package/docs/providers/sync.md +75 -0
- package/docs/providers/tts.md +62 -0
- package/docs/providers/upload.md +77 -0
- package/docs/providers/video.md +118 -0
- package/docs/release.md +130 -0
- package/docs/services.md +159 -0
- package/docs/site-data.md +90 -0
- package/docs/skills.md +129 -0
- package/docs/storage-and-network.md +62 -0
- package/docs/ui.md +335 -0
- package/docs/user-data.md +389 -0
- package/docs/whiteboard.md +290 -0
- package/package.js +1 -1
- package/package.json +1 -1
- package/publish-artifacts.js +1 -1
- package/types/packages/plugins/src/categories.d.ts +3 -0
- package/types/packages/plugins/src/contract.d.ts +0 -2
- package/types/packages/plugins/src/index.d.ts +0 -1
- package/types/packages/plugins/src/package.d.ts +2 -0
- package/types/packages/ui/src/primitives/Tabs.d.ts +1 -3
- package/AI.md +0 -116
- package/API.md +0 -881
- package/BACKEND.md +0 -68
- package/DEVELOPMENT.md +0 -173
- package/EDITOR.md +0 -192
- package/FLASHCARDS.md +0 -92
- package/IMAGES.md +0 -16
- package/MCP.md +0 -118
- package/NOTIFICATIONS.md +0 -48
- package/PUBLISH-DATA.md +0 -48
- package/PUBLISH.md +0 -50
- package/SERVICES.md +0 -119
- package/SYNC.md +0 -37
- package/TTS.md +0 -20
- package/UPLOAD.md +0 -35
- package/VIDEO.md +0 -65
- package/WHITEBOARD.md +0 -115
- package/types/packages/plugins/src/skills.d.ts +0 -8
package/BACKEND.md
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
# 本机后台开发
|
|
2
|
-
|
|
3
|
-
后台入口需要 SDK 0.25.0 及支持包格式 2 的客户端构建。不要只修改版本号就认为客户端已经具备运行能力。普通渲染插件仍使用格式 1。使用 Node 内置模块前执行 `pnpm add -D @types/node@24.0.0 --save-exact` 安装类型声明。
|
|
4
|
-
|
|
5
|
-
仓库提供完整双入口样本:`scripts/plugins/fixtures/backend-system.tsx` 为界面,`backend-system.ts` 为后台。在宿主仓库运行 `node scripts/plugins/verify-backend-author.mjs`,会打包 SDK,在仓库外安装 tarball、类型检查、构建双入口 ZIP,并用真实 Electron utilityProcess 调用样本。结果位于 `output/plugin-backend-sdk/`;该命令不安装到用户目录、不发布到市场。
|
|
6
|
-
|
|
7
|
-
在 manifest.json 中将 formatVersion 设为 2,保留 main.js,并增加 backend:
|
|
8
|
-
|
|
9
|
-
```json
|
|
10
|
-
{
|
|
11
|
-
"entry": "backend.js",
|
|
12
|
-
"runtime": "node",
|
|
13
|
-
"apiVersion": 1,
|
|
14
|
-
"scope": "application",
|
|
15
|
-
"activation": "app-ready",
|
|
16
|
-
"lifetime": "persistent",
|
|
17
|
-
"reason": "连接本机设备并向插件页面提供设备状态",
|
|
18
|
-
"systemAccess": ["network"]
|
|
19
|
-
}
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
模板从 src/backend.ts 构建独立的 backend.js。Node 内置模块可直接引用,第三方 JS 依赖打入 bundle;仅 @tau/plugins/backend 由宿主提供。不打包 node_modules,不运行安装脚本,不让前端入口引用后台文件。main、后台及样式的摘要由构建生成。
|
|
23
|
-
|
|
24
|
-
application 作用域支持 on-demand、app-ready;workspace 支持 on-demand、workspace-ready。lifetime 为 idle 或 persistent,常驻直到所属作用域结束。安装不等于启用,声明不等于授权;无授权的自动启动进入等待处理状态。系统用途字段用于用户知情和审核,不是操作系统沙箱。
|
|
25
|
-
|
|
26
|
-
pnpm build 生成整包 ZIP,pnpm install:local 仍只用于首次开发安装且拒绝覆盖既有目录。后台新版本与界面同包更新,不能只替换 backend.js。
|
|
27
|
-
|
|
28
|
-
## 定义后台方法
|
|
29
|
-
|
|
30
|
-
```ts
|
|
31
|
-
import { defineBackend } from "@tau/plugins/backend";
|
|
32
|
-
import { platform } from "node:os";
|
|
33
|
-
|
|
34
|
-
export default defineBackend({
|
|
35
|
-
create() {
|
|
36
|
-
return {
|
|
37
|
-
activate(ctx) {
|
|
38
|
-
ctx.rpc.register(
|
|
39
|
-
"system.platform",
|
|
40
|
-
{
|
|
41
|
-
input: {
|
|
42
|
-
parse(value: unknown) {
|
|
43
|
-
if (value !== null) throw new Error("此方法不接受参数");
|
|
44
|
-
return null;
|
|
45
|
-
},
|
|
46
|
-
},
|
|
47
|
-
output: {
|
|
48
|
-
parse(value: unknown) {
|
|
49
|
-
if (typeof value !== "string") throw new Error("平台结果无效");
|
|
50
|
-
return value;
|
|
51
|
-
},
|
|
52
|
-
},
|
|
53
|
-
},
|
|
54
|
-
() => platform()
|
|
55
|
-
);
|
|
56
|
-
},
|
|
57
|
-
};
|
|
58
|
-
},
|
|
59
|
-
});
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
渲染入口通过 `await ctx.backend.call("system.platform", null, { signal })` 调用。请求和结果必须为有限 JSON,普通消息最多 1 MiB。后台必须提供输入、输出解析器,异常返回调用方。`ctx.rpc.emit(name, value)` 与 `ctx.backend.subscribe(name, listener)` 用于事件;订阅返回可回收句柄。停用或切库后旧连接失效。
|
|
63
|
-
|
|
64
|
-
外部程序通过 `ctx.process.run(toolId, args, { signal })` 执行,返回 exitCode/stdout/stderr。同时在 backend.systemAccess 声明 process,并以 backend.tools 列出 `{ id, command, args? }`。参数以数组传递,不自动经过 Shell;stdout/stderr 合计最多 512 KiB,单次执行 30 秒。Windows 只接受可解析到唯一 EXE 的工具,使用宿主 Job Object;Unix 使用进程组监督。需要取消时把 RPC 的 request.signal 继续传给工具。
|
|
65
|
-
|
|
66
|
-
不要在模块顶层启动任务。计时器、订阅等使用 `ctx.register` 清理;后台长期任务应响应 `ctx.signal`。主进程扫描不会执行后台,客户端会在首次运行前要求本机代码执行授权。独立进程不会限制 Node 对本机文件、网络的实际权限。
|
|
67
|
-
|
|
68
|
-
插件中心每个后台版本都需人工重点审核,审核者本人的 CI 提交也不自动批准。更新后本机授权重新确认;有在途任务、订阅或插件 MCP 连接时先结束这些工作。已知撤回的中心版本禁止执行;离线只能依据上次已获取的发布状态。原始 stdout/stderr 不写宿主日志,管理页展示有界错误、启动耗时、失败/超时次数及进程资源采样。
|
package/DEVELOPMENT.md
DELETED
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
# Tau 插件开发指南
|
|
2
|
-
|
|
3
|
-
用 TypeScript 和 React 为 Tau 桌面端开发插件。模板自带一个可运行的计数器,演示命令、页面、侧边栏入口、设置和数据保存,可以在它的基础上改出自己的插件。
|
|
4
|
-
|
|
5
|
-
## 准备
|
|
6
|
-
|
|
7
|
-
- Node.js 22 或更高版本
|
|
8
|
-
- pnpm 11.9.0
|
|
9
|
-
- Tau 桌面客户端 0.59.0 或更高版本
|
|
10
|
-
|
|
11
|
-
模板锁定公开 SDK `@xiongtao.xt/tau-plugins@0.29.0` 和 UI `@xiongtao.xt/tau-ui@0.1.1`,通过 npm 别名安装为 `@tau/plugins`、`@tau/ui`。SDK 提供类型契约,运行实现由 Tau 注入;新领域能力还需包含相应实现的客户端构建,不能只依据客户端版本号判断。
|
|
12
|
-
|
|
13
|
-
## 跑通示例
|
|
14
|
-
|
|
15
|
-
在 GitHub 点击 **Use this template** 创建自己的仓库,克隆后在项目目录执行:
|
|
16
|
-
|
|
17
|
-
```sh
|
|
18
|
-
pnpm install
|
|
19
|
-
pnpm build
|
|
20
|
-
pnpm install:local
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
打开 Tau 的插件管理,点击「刷新列表」,启用「计数器示例」。然后点击侧边栏「日常」分组下的「计数器」,或按 Ctrl+K 执行「打开计数器」,点「增加并保存」。重启客户端后再打开,计数仍然保留。
|
|
24
|
-
|
|
25
|
-
## 改成自己的插件
|
|
26
|
-
|
|
27
|
-
1. 修改 `manifest.json` 的 `id`、`name`、`version`、`description`。`id` 用你自己的唯一名称,例如 `yourname.counter`。
|
|
28
|
-
- `categories` 决定插件在插件中心出现在哪些分类下,可多选,也可不填:`sync` 同步、`upload` 资源上传、`editor` 编辑器、`whiteboard` 白板、`blog-template` 博客模板、`blog-publish` 博客发布、`ai` AI(Skill、MCP、聊天工具渲染、AI 功能、图片)、`voice` 语音、`video` 在线视频、`page` 页面(页面与侧边栏入口)。只提供命令或设置的插件可以不填。
|
|
29
|
-
- `keywords` 最多 5 个、每个不超过 20 字,只用于插件中心搜索,例如 S3 插件可写 `MinIO`、`R2`。
|
|
30
|
-
2. 修改 `package.json` 的项目名称和版本。
|
|
31
|
-
3. 在 `src/index.tsx` 中实现功能,在 `src/styles.css` 中编写样式。
|
|
32
|
-
4. 把 `README.md` 改成给用户看的介绍和使用步骤;需要版本记录时再加 `CHANGELOG.md`。
|
|
33
|
-
5. 执行 `pnpm build`,按下文的方法安装到 Tau 中测试。
|
|
34
|
-
|
|
35
|
-
| 文件 | 用途 |
|
|
36
|
-
| --------------------------------- | ---------------------------------------------------- |
|
|
37
|
-
| `manifest.json` | 插件身份、版本和最低客户端版本 |
|
|
38
|
-
| `README.md` / `CHANGELOG.md` | 随插件包发布,显示在插件详情的「说明」和「更新日志」 |
|
|
39
|
-
| `src/index.tsx` | 插件入口,以及示例页面、设置与命令 |
|
|
40
|
-
| `src/styles.css` | 插件样式 |
|
|
41
|
-
| `src/CounterIcon.tsx` | 侧边栏 SVG 图标示例,使用 currentColor 跟随主题 |
|
|
42
|
-
| `API.md` | 命令、页面、侧边栏、设置、存储、网络等接口 |
|
|
43
|
-
| `EDITOR.md` | 在文档中添加自定义块、源码预览块和插件 Skill |
|
|
44
|
-
| `AI.md` | AI 功能声明、用户模型分配、流式对话和统一用量审计 |
|
|
45
|
-
| `MCP.md` | 注册 MCP、聊天工具渲染,复用工具开关与服务器管理 |
|
|
46
|
-
| `BACKEND.md` | 显式声明本机后台、启动策略与独立产物构建 |
|
|
47
|
-
| `FLASHCARDS.md` | 闪卡读写权限、宿主制卡窗口、插件 AI 与正文来源引用 |
|
|
48
|
-
| `NOTIFICATIONS.md` | 应用内、独立窗口通知、自动分流与生命周期清理 |
|
|
49
|
-
| `WHITEBOARD.md` | 静态白板扩展、工具与发布边界 |
|
|
50
|
-
| `SYNC.md` | 同步存储提供方、配置视图与取消 |
|
|
51
|
-
| `UPLOAD.md` | 图片与附件上传、上传提供方与配置 |
|
|
52
|
-
| `TTS.md` | 语音合成、音色复刻与多账号配置 |
|
|
53
|
-
| `IMAGES.md` | 图片生成、参考图编辑与插件账号配置视图 |
|
|
54
|
-
| `VIDEO.md` | 视频来源的链接解析、播放源与账号配置视图 |
|
|
55
|
-
| `PUBLISH.md` | 博客发布提供方、文件上传与 Git 快照 |
|
|
56
|
-
| `PUBLISH-DATA.md` | 独立站点读取发布数据与公开子入口的构建边界 |
|
|
57
|
-
| `SERVICES.md` | Tailwind、Markdown、FFmpeg 编译转换服务 |
|
|
58
|
-
| `AGENTS.md` | 给 AI 编程助手的项目指引 |
|
|
59
|
-
| `build.mjs` / `install-local.mjs` | 打包与本地安装脚本,日常开发通常不需要修改 |
|
|
60
|
-
|
|
61
|
-
插件详情页的名称、简介和版本取自 `manifest.json`,介绍取自 `README.md`,无需在网站上另外填写。`API.md`、`AGENTS.md` 等开发文档不会打进插件包。
|
|
62
|
-
|
|
63
|
-
## 升级 SDK 与同步旧模板
|
|
64
|
-
|
|
65
|
-
GitHub 模板创建的仓库不会自动跟随模板更新。已有项目先提交或备份自己的改动,再按需同步 [上游模板](https://github.com/LastKnightCoder/tau-plugin-template) 的构建脚本、开发文档和 `.github/workflows/release.yml`,保留自己的插件 ID、入口、用户说明与版本记录。
|
|
66
|
-
|
|
67
|
-
先在 `pnpm-workspace.yaml` 的 `minimumReleaseAgeExclude` 中增加新 SDK 的精确例外 `@xiongtao.xt/tau-plugins@0.29.0`,暂时保留旧锁文件所需的已核实例外,再更新依赖及锁文件:
|
|
68
|
-
|
|
69
|
-
```sh
|
|
70
|
-
pnpm add @tau/plugins@npm:@xiongtao.xt/tau-plugins@0.29.0 --save-exact
|
|
71
|
-
pnpm install --frozen-lockfile
|
|
72
|
-
pnpm build
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
成功后移除已不再使用的旧版例外,再运行一次 `pnpm install --frozen-lockfile`,提交 `package.json`、`pnpm-lock.yaml` 和 `pnpm-workspace.yaml`。先移除旧版例外会使 pnpm 在读取旧锁文件时拒绝升级。发布等待例外只针对已核实的 SDK/UI 版本,不关闭全部依赖的供应链策略;保留 `allowBuilds.esbuild: true`。React 继续使用模板锁定的版本,避免和宿主的共享实例不兼容。
|
|
76
|
-
|
|
77
|
-
从旧 SDK 升级时,重点核对:
|
|
78
|
-
|
|
79
|
-
| 版本 | 变化与对应文档 |
|
|
80
|
-
| ------------- | ------------------------------------------------------------------------------------------------------ |
|
|
81
|
-
| 0.17.0 | 行内源码接口,见 EDITOR.md |
|
|
82
|
-
| 0.18.0 | 图片生成与编辑提供方,见 IMAGES.md |
|
|
83
|
-
| 0.19.0–0.20.0 | 发布数据子入口、站点级数据归清单、分类与关键词,见 PUBLISH-DATA.md 与 API.md |
|
|
84
|
-
| 0.21.0 | 博客发布提供方、配置与 Git 快照服务,见 PUBLISH.md |
|
|
85
|
-
| 0.22.0 | 视频提供方与视频页面信息查询,见 VIDEO.md |
|
|
86
|
-
| 0.23.0 | 删除 `ffmpeg.probe` 与 `MediaInfo`;`ffmpeg.run` 保留,见 SERVICES.md |
|
|
87
|
-
| 0.24.0 | 删除 `services.typst`;Typst 编译由独立插件实现,见 SERVICES.md |
|
|
88
|
-
| 0.25.0 | 数据读写与权限、正文组件、插件实体、宿主动作、存储随库同步,见 API.md;本机后台双入口见 BACKEND.md |
|
|
89
|
-
| 0.26.0 | 闪卡创建、读写授权、插件 AI 制卡与 contentRef 来源引用,见 FLASHCARDS.md |
|
|
90
|
-
| 0.27.0 | 通用 requestCapability 开放全部内置大模型功能分配,分别以 ai:<能力名> 授权;闪卡复用同一机制,见 AI.md |
|
|
91
|
-
| 0.28.0 | 通知发送、应用内或独立窗口展示、焦点自动分流与生命周期清理,见 NOTIFICATIONS.md |
|
|
92
|
-
| 0.29.0 | 页面通过 pageContext.register 提供任意 JSON 上下文,现有 get_current_context 读取,见 API.md |
|
|
93
|
-
|
|
94
|
-
更早版本的完整变更见已安装包的 `node_modules/@tau/plugins/CHANGELOG.md`。需要本地媒体元数据时自行实现,不能把视频页面解析当作本地文件探测。SDK 根入口、白板/同步契约、UI 和 React 由 Tau 提供,保持模板的 external 配置;普通第三方库由构建打入 ZIP。独立站点数据子入口的用途另见 PUBLISH-DATA.md。
|
|
95
|
-
|
|
96
|
-
构建通过后,在对应客户端验证启用、功能执行、保存、停用与重启;涉及静态编辑器或白板扩展时也验证重启后的贡献,以及发布内容的回退。构建成功只证明类型和打包通过。
|
|
97
|
-
|
|
98
|
-
## 打包与安装
|
|
99
|
-
|
|
100
|
-
`pnpm build` 先检查类型,再生成 `dist/<id>-<version>.zip`。这个 ZIP 就是完整的插件包,分享时不需要附带源码或 node_modules。
|
|
101
|
-
|
|
102
|
-
**开发调试首次安装**:`pnpm install:local` 把 ZIP 解压到 `~/.editor/plugins/<id>/`。正式用户从插件中心安装;作者也可以手动解压调试,最终结构应为:
|
|
103
|
-
|
|
104
|
-
```text
|
|
105
|
-
~/.editor/plugins/yourname.counter/
|
|
106
|
-
manifest.json
|
|
107
|
-
main.js
|
|
108
|
-
main.css # 使用 CSS 时生成
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
**更新**:提高 `manifest.json` 的 `version` 并重新构建,正式版本提交插件中心审核后由用户更新;开发版客户端可从插件页的 ZIP 入口调试。新版本在下次完全退出并重新启动后生效,生效前可以「取消待更新」;新版本启用失败时可以「恢复上一版」。恢复只换回代码,不回退已保存的数据,所以存储结构变化时要让新旧版本都能读懂。
|
|
112
|
-
|
|
113
|
-
`pnpm install:local` 只用于首次安装,目标目录已存在时会拒绝覆盖。插件 ID 不变,已保存的数据就会保留;改了 ID 会被当作另一个插件。
|
|
114
|
-
|
|
115
|
-
## 写更新日志
|
|
116
|
-
|
|
117
|
-
`CHANGELOG.md` 显示在插件详情的「更新日志」里,发布时也会作为 GitHub Release 的说明,读者是使用插件的人,不是开发者。
|
|
118
|
-
|
|
119
|
-
- 每个版本以 `## 1.2.0` 开头,下面逐条写;发布时取与 tag 版本相同的小节,找不到时才用 GitHub 自动生成的提交列表。
|
|
120
|
-
- 写用户能感知的变化:新增了什么能力、修好了什么问题、升级后要注意什么。用界面上的叫法,比如「设置 → 同步」。
|
|
121
|
-
- 不写 SDK 版本、构建方式、仓库迁移、测试或内部字段。确实没有可感知的变化,就写「维护更新,使用上没有变化」。
|
|
122
|
-
|
|
123
|
-
```markdown
|
|
124
|
-
## 1.2.0
|
|
125
|
-
|
|
126
|
-
- 书架可以按「有笔记」筛选了。
|
|
127
|
-
- 修复同步中途断网后,部分划线不显示的问题。
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
## 自动发布到 GitHub Release
|
|
131
|
-
|
|
132
|
-
模板内置 `.github/workflows/release.yml`。将版本 tag 推送到 GitHub 后,Actions 会冻结安装 pnpm 依赖、运行项目的 test 脚本(若已定义)、执行构建,再把 `dist/<id>-<version>.zip` 上传到对应 Release。
|
|
133
|
-
|
|
134
|
-
先同步修改 `manifest.json` 和 `package.json` 的版本并提交,再打 tag:
|
|
135
|
-
|
|
136
|
-
```sh
|
|
137
|
-
git add manifest.json package.json
|
|
138
|
-
git commit -m "chore: release 1.1.0"
|
|
139
|
-
git tag v1.1.0
|
|
140
|
-
git push origin HEAD
|
|
141
|
-
git push origin v1.1.0
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
tag 支持 `v1.1.0` 或 `1.1.0`,必须与两个文件的版本一致,否则发布失败。`v1.1.0-beta.1` 等预发布版本会自动标为 Pre-release。只在本机打 tag 不触发,必须推送到 GitHub。
|
|
145
|
-
|
|
146
|
-
无需配置额外密钥,工作流使用仓库自带的 GITHUB_TOKEN。仓库需启用 Actions,并允许工作流申请 contents:write 权限。发布结果和失败日志在 Actions 页面查看;修复临时错误后可重新运行失败任务,已有 Release 会更新同名 ZIP。代码修复应提高版本并发布新 tag,不移动已发布的版本 tag。
|
|
147
|
-
|
|
148
|
-
Release 的说明取自 `CHANGELOG.md` 中对应版本的小节。Release 发布后,工作流会把同一个 ZIP 提交到插件中心:用 GitHub Actions 的短期身份令牌证明发布来自哪个仓库,不需要配置任何密钥。
|
|
149
|
-
|
|
150
|
-
- **首次发布**仍需在 [插件中心](https://plugins.taunote.app) 网页上传并提交一次,用来把插件 ID 绑定到你的仓库。未绑定时这一步只给出提醒,不让工作流失败。
|
|
151
|
-
- **之后每次推送 tag**,新版本自动进入审核队列,不用再打开网页;插件 ID 只接受来自已绑定仓库的提交,fork 无法冒充。
|
|
152
|
-
- 预发布版本(如 `v1.1.0-beta.1`)只发 GitHub Release,不提交插件中心。
|
|
153
|
-
- 同一 tag 重跑是安全的;同一版本号换了内容会被拒绝,需要提高版本号。
|
|
154
|
-
|
|
155
|
-
从旧模板创建的仓库不会自动获得新文件,需要同步该 workflow(包括 `id-token: write` 权限)。此流程不发布 npm 包。
|
|
156
|
-
|
|
157
|
-
## 常用命令
|
|
158
|
-
|
|
159
|
-
| 命令 | 用途 |
|
|
160
|
-
| -------------------- | ---------------------- |
|
|
161
|
-
| `pnpm check` | 检查 TypeScript 类型 |
|
|
162
|
-
| `pnpm build` | 检查类型并生成 ZIP |
|
|
163
|
-
| `pnpm install:local` | 首次安装最近构建的 ZIP |
|
|
164
|
-
|
|
165
|
-
## 排错
|
|
166
|
-
|
|
167
|
-
- **列表里没有插件**:点「刷新列表」,确认解压后没有多套一层目录,再看插件管理里的错误提示。
|
|
168
|
-
- **提示目标已存在**:提高插件版本后,在开发版客户端使用 ZIP 更新;正式用户使用插件中心更新。
|
|
169
|
-
- **修改没有生效**:重新构建并安装,然后刷新列表并启用。
|
|
170
|
-
- **启用失败**:查看错误提示,检查 `activate` 是否抛出异常;客户端提示需要重启时先重启再启用。
|
|
171
|
-
- **类型检查通过但功能异常**:类型检查不能代替实际测试,至少在 Tau 中试一遍启用、执行命令、保存数据、停用和重启。
|
|
172
|
-
|
|
173
|
-
本模板采用 [MIT 许可](LICENSE)。
|
package/EDITOR.md
DELETED
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
# 编辑器扩展
|
|
2
|
-
|
|
3
|
-
在文档中添加自己的块:比如交互演示、图表、特殊格式的卡片。本文还介绍源码预览块和插件 Skill。需要 Tau 0.59.0 或更高版本。
|
|
4
|
-
|
|
5
|
-
## 定义一个块
|
|
6
|
-
|
|
7
|
-
先在 `manifest.json` 中加入 `"editor": true`(完整示例见下文),然后在插件定义里声明 `editorExtensions`:
|
|
8
|
-
|
|
9
|
-
```tsx
|
|
10
|
-
import { useState } from "react";
|
|
11
|
-
import { definePlugin, defineEditorElement, defineEditorExtension } from "@tau/plugins";
|
|
12
|
-
|
|
13
|
-
interface CounterElement {
|
|
14
|
-
type: "example.counter";
|
|
15
|
-
initial: number;
|
|
16
|
-
children: { type: "formatted"; text: string }[];
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
declare module "@tau/plugins" {
|
|
20
|
-
interface EditorElementMap {
|
|
21
|
-
"example.counter": CounterElement;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function Counter({ initial }: { initial: number }) {
|
|
26
|
-
const [count, setCount] = useState(initial);
|
|
27
|
-
return (
|
|
28
|
-
<div contentEditable={false}>
|
|
29
|
-
<button onMouseDown={event => event.preventDefault()} onClick={() => setCount(n => n + 1)}>
|
|
30
|
-
计数:{count}
|
|
31
|
-
</button>
|
|
32
|
-
</div>
|
|
33
|
-
);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export default definePlugin({
|
|
37
|
-
id: "example.counter",
|
|
38
|
-
name: "计数块",
|
|
39
|
-
version: "1.0.0",
|
|
40
|
-
editorExtensions: [
|
|
41
|
-
defineEditorExtension({
|
|
42
|
-
id: "example.counter",
|
|
43
|
-
elements: [
|
|
44
|
-
defineEditorElement<CounterElement>({
|
|
45
|
-
type: "example.counter",
|
|
46
|
-
kind: "block",
|
|
47
|
-
isVoid: true,
|
|
48
|
-
render: ({ attributes, element, children }) => (
|
|
49
|
-
<div {...attributes}>
|
|
50
|
-
<Counter initial={element.initial} />
|
|
51
|
-
{children}
|
|
52
|
-
</div>
|
|
53
|
-
),
|
|
54
|
-
}),
|
|
55
|
-
],
|
|
56
|
-
}),
|
|
57
|
-
],
|
|
58
|
-
});
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
几点说明:
|
|
62
|
-
|
|
63
|
-
- 节点上的字段(如 `initial`)是文档数据,会随文档保存;组件里的 `useState` 只是本次显示的状态,不会改动原文。不要把文档内容放进插件私有存储。
|
|
64
|
-
- `editorExtensions` 与插件定义一起静态导出。只提供编辑器扩展的插件可以省略 `create`;同时有命令、页面或设置时照常提供 `create/activate`。
|
|
65
|
-
- 扩展可声明 `elements`、`commands`、`hotkeys`、`menu`、`blockPanel`、`behaviorsFor`,至少包含一个节点类型。`blockPanel` 的 `onClick` 会收到当前编辑器,可用来插入节点。
|
|
66
|
-
- 节点类型和扩展 ID 使用自己的命名空间(如 `yourname.chart`),不要与内置或其他插件的类型重名。
|
|
67
|
-
|
|
68
|
-
完整的 manifest 示例:
|
|
69
|
-
|
|
70
|
-
```json
|
|
71
|
-
{
|
|
72
|
-
"formatVersion": 1,
|
|
73
|
-
"id": "example.counter",
|
|
74
|
-
"name": "计数块",
|
|
75
|
-
"description": "在文档中放入交互计数块。",
|
|
76
|
-
"version": "1.0.0",
|
|
77
|
-
"minAppVersion": "0.59.0",
|
|
78
|
-
"apiVersion": 1,
|
|
79
|
-
"platform": "desktop",
|
|
80
|
-
"format": "cjs",
|
|
81
|
-
"main": "main.js",
|
|
82
|
-
"editor": true
|
|
83
|
-
}
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
`styles`、`integrity` 由构建脚本生成,不用手写。
|
|
87
|
-
|
|
88
|
-
## 启用、停用与卸载
|
|
89
|
-
|
|
90
|
-
- 编辑器插件的启用、停用和升级在完整重启 Tau 后生效。
|
|
91
|
-
- 停用后,文档里已有的节点会保留,并显示为不可用占位,不会被删除;重新启用后恢复显示。
|
|
92
|
-
- 卸载正在使用的编辑器插件前,需要先停用并重启。
|
|
93
|
-
|
|
94
|
-
## 块会在哪里显示
|
|
95
|
-
|
|
96
|
-
块显示在桌面编辑器和用户发布的博客中,两处直接使用 `elements.render` 中的同一个组件,不需要另写入口。移动端与浏览器扩展不加载插件,遇到插件节点保留原数据并显示通用占位。因此渲染代码要满足:
|
|
97
|
-
|
|
98
|
-
- 模块顶层和渲染组件能在浏览器中运行,不导入 Electron、Node 或 Tau 客户端内部路径。
|
|
99
|
-
- 不依赖 `activate` 中才赋值的变量,也不调用 `context` 的存储、页面、服务等桌面能力。
|
|
100
|
-
- React、ReactDOM、`@tau/plugins`、`@tau/ui` 由 Tau 提供,保持模板的 external 配置;其他浏览器兼容的 npm 依赖会打进 `main.js`。
|
|
101
|
-
- JS 与 CSS 自包含,图片等静态资源内联为 data URL。
|
|
102
|
-
- 样式使用插件自己的类名前缀,不覆盖 `body` 或 Tau 自身组件的样式。
|
|
103
|
-
- 只读场景下文档不可编辑,但组件自己的交互(按钮、图表缩放等)照常可用。
|
|
104
|
-
|
|
105
|
-
## Markdown
|
|
106
|
-
|
|
107
|
-
在插件定义中提供 `editorCodecs`(类型为 `EditorMarkdownCodec[]`),让自定义节点支持 Markdown 导入导出、复制和搜索摘要。序列化与反序列化需要成对设计,只写输出函数不会自动获得导入能力。
|
|
108
|
-
|
|
109
|
-
codec 会在后台转换时单独加载,不经过 `create/activate`,所以必须是纯转换函数,模块顶层不能访问 `window`、`document` 或激活后的上下文。
|
|
110
|
-
|
|
111
|
-
## 源码预览块
|
|
112
|
-
|
|
113
|
-
`SourceBlockEditor` 复用 Tau 的源码预览组件,包括编辑、全屏、错误条、删除与相邻块导航。它不是第二份渲染入口,放在同一 `elements.render` 组件中使用。
|
|
114
|
-
|
|
115
|
-
```tsx
|
|
116
|
-
import type { ReactNode } from "react";
|
|
117
|
-
import { SourceBlockEditor, useSourceBlock } from "@tau/plugins";
|
|
118
|
-
import { Code } from "lucide-react";
|
|
119
|
-
|
|
120
|
-
interface SourceElement {
|
|
121
|
-
type: "example.source";
|
|
122
|
-
content: string;
|
|
123
|
-
children: { type: "formatted"; text: string }[];
|
|
124
|
-
}
|
|
125
|
-
declare module "@tau/plugins" {
|
|
126
|
-
interface EditorElementMap {
|
|
127
|
-
"example.source": SourceElement;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
function SourceView({ element, children }: { element: SourceElement; children: ReactNode }) {
|
|
132
|
-
const { update } = useSourceBlock(element);
|
|
133
|
-
return (
|
|
134
|
-
<SourceBlockEditor
|
|
135
|
-
element={element}
|
|
136
|
-
mode="jsx"
|
|
137
|
-
title="示例"
|
|
138
|
-
icon={Code}
|
|
139
|
-
initValue={element.content}
|
|
140
|
-
onChange={content => update({ content })}
|
|
141
|
-
>
|
|
142
|
-
{children}
|
|
143
|
-
</SourceBlockEditor>
|
|
144
|
-
);
|
|
145
|
-
}
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
| API | 用途 |
|
|
149
|
-
| ------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
|
|
150
|
-
| `SourceBlockEditor` | `element/mode/title/icon/initValue/onChange` 为必填;`center/extend/fluid` 控制预览布局,`children` 是预览内容 |
|
|
151
|
-
| `useSourceBlock(element)` | 返回当前主题 `theme`、可选样式编译器 `compiler` 与节点字段更新函数 `update`;只能在编辑器内调用 |
|
|
152
|
-
| `useReportPreviewError(message, {stale})` | 向源码预览块上报错误,传 null 清除;stale 表示是否保留了上次预览 |
|
|
153
|
-
| `insertSourceBlock(editor, element, line?)` | 插入或替换空段落并聚焦源码,返回插入路径;不能插入时返回 undefined |
|
|
154
|
-
| `sourceBlockParagraphBehavior(type)` | 放入扩展 `behaviorsFor.paragraph`,支持段首退格聚焦前一源码块 |
|
|
155
|
-
|
|
156
|
-
`theme` 提供 `isDark` 和 `token(word)`,渲染应响应主题变化。`compiler.compile({source, language})` 返回 Tailwind CSS,language 为 html 或 tsx;它只在桌面编辑器中可用,其他场景读不到编译器,需配合下文的 `styleSources` 使用。这些组件和 hook 由 Tau 提供,不要打包自己的编辑器、Slate React 或源码编辑器实例。
|
|
157
|
-
|
|
158
|
-
## 动态样式与静态导出
|
|
159
|
-
|
|
160
|
-
SDK 0.17.0 提供 `useInlineSource(element)`:返回 readOnly、可选 compiler、update(properties) 与 remove(),只读、停驻、卸载及旧目标回调不会写入文档。行内源码组件通过 `InlineSourceBoundary` 复用宿主的浏览器边界处理;菜单用 `insertInlineSource(editor, element)` 插入节点。行内输入弹层由插件通过公共 UI 组件承载,只读时只显示预览,不打开编辑器。
|
|
161
|
-
|
|
162
|
-
静态导出也按 styleSources 编译节点字段并向导出 CSS 收集器提供样式;插件只负责把节点序列化为 HTML,宿主不维护具体节点类型的样式名单。
|
|
163
|
-
|
|
164
|
-
若节点源码中包含动态 Tailwind 类名,在同一个扩展上声明字段:
|
|
165
|
-
|
|
166
|
-
```ts
|
|
167
|
-
defineEditorExtension({
|
|
168
|
-
id: "example.demo",
|
|
169
|
-
elements: [/* 当前扩展的元素定义 */],
|
|
170
|
-
styleSources: [{ type: "example.demo", field: "content", language: "tsx" }],
|
|
171
|
-
});
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
在无法运行时编译的场景(如发布的网页),Tau 会据此读取这些节点的 `content` 字段,预先生成样式。源码字段须为字符串,只能登记本插件声明的节点类型。拼接出来的类名(如 `` `bg-${color}` ``)扫描不到,类名要完整写在源码里。
|
|
175
|
-
|
|
176
|
-
可选 `htmlSerializers: [{type, toHtml(element)}]` 用于复制 HTML、HTML/EPUB 等静态导出,返回 HTML 字符串并自行转义文本。它只用于静态导出,网页显示仍使用 `elements.render`。不声明时按未知节点的默认规则导出,交互式组件在 EPUB 中不会执行。
|
|
177
|
-
|
|
178
|
-
## 插件 Skill
|
|
179
|
-
|
|
180
|
-
在 `definePlugin` 的 `skills` 数组中声明 `{id, name, description, content, invocation?}`,为 AI 提供与你的插件配套的写作规范:
|
|
181
|
-
|
|
182
|
-
| 字段 | 说明 |
|
|
183
|
-
| ------------- | ------------------------------------------------------ |
|
|
184
|
-
| `id` | 插件内唯一标识;AI 以 `插件ID:技能ID` 引用 |
|
|
185
|
-
| `name` | Skill 页面显示的名称 |
|
|
186
|
-
| `description` | AI 据此判断何时加载,写清适用场景 |
|
|
187
|
-
| `content` | 完整的 SKILL.md 正文 |
|
|
188
|
-
| `invocation` | 默认 `auto`(AI 自行加载),设为 `manual` 则仅手动点名 |
|
|
189
|
-
|
|
190
|
-
插件启用后 Skill 才可用,停用时自动移除。Skill 页面会标明它来自你的插件,用户可以调整调用方式、停用或复制到自己的 Skill 目录。目前每个 Skill 只有一份正文,不支持脚本和附件。
|
|
191
|
-
|
|
192
|
-
正文可以写在单独的 SKILL.md 中,构建时用 esbuild 的 `.md: text` loader 作为字符串导入。
|
package/FLASHCARDS.md
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
# 闪卡能力
|
|
2
|
-
|
|
3
|
-
本文对应 SDK 0.27.0 和支持闪卡接口的 Tau 0.59.0 客户端构建。能力通过激活时的 `context.flashcards` 使用,绑定本次激活的数据库;停用、切库后旧调用失效。旧客户端可用 `if (!context.flashcards)` 检查是否支持。
|
|
4
|
-
|
|
5
|
-
## 权限与 AI 配置
|
|
6
|
-
|
|
7
|
-
直接查询卡组需在 manifest 声明 `flashcards:read`,直接创建卡组、闪卡及自动保存需声明 `flashcards:write`;使用时由用户授权,可在插件详情页撤销。引用已有正文还需对应实体的读取权限;本插件自有正文沿用免业务权限规则。打开宿主窗口必须来自用户点击或按键,窗口内的创建由用户确认,不需要闪卡读写权限。
|
|
8
|
-
|
|
9
|
-
AI 制卡直接复用应用「闪卡生成」已分配的模型,不需要声明插件自己的 AI 功能或再次选择模型。在 manifest 中声明要申请的能力:
|
|
10
|
-
|
|
11
|
-
```json
|
|
12
|
-
{ "permissions": ["flashcards:read", "flashcards:write", "ai:flashcardGeneration"] }
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
内部通过通用的 `context.ai.requestCapability("flashcardGeneration")` 申请“使用闪卡制作 AI”,可在插件的「权限」页撤销,撤权会取消在途生成。主进程读取应用现有模型分配,按插件身份记录用量并限制并发和每日额度;额度可在插件 AI 设置中调整。应用未配置闪卡模型时明确报错。申请其他内置模型分配或声明自己的 AI 功能见 AI.md。
|
|
16
|
-
|
|
17
|
-
## 打开宿主制卡窗口
|
|
18
|
-
|
|
19
|
-
```ts
|
|
20
|
-
const result = await context.flashcards.openCreate({
|
|
21
|
-
mode: "ai", // manual 为手动制卡,缺省为 manual
|
|
22
|
-
content: "牛顿第二定律:F = ma。", // Markdown 或 Descendant[]
|
|
23
|
-
title: "力学笔记",
|
|
24
|
-
// deckId: 123, // 可选;省略时先选择卡组,也可以现场新建卡组
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
// result.status 为 completed 或 cancelled;cards 包含本次窗口已经保存的记录。
|
|
28
|
-
// 取消不会撤销「保存并新建」等已提交的记录。
|
|
29
|
-
console.log(
|
|
30
|
-
result.status,
|
|
31
|
-
result.cards.map(card => card.id)
|
|
32
|
-
);
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
AI 模式自动开始生成并展示预览,可选择、编辑后保存;手动模式预填题干和参考资料,支持连续创建。未指定 references 时,content 作为自定义参考资料保存,title 用于来源标题;指定 `references: []` 可省略来源。
|
|
36
|
-
|
|
37
|
-
引用 Tau 中已有正文时,显式传入来源,避免复制正文作为参考资料:
|
|
38
|
-
|
|
39
|
-
```ts
|
|
40
|
-
await context.flashcards.openCreate({
|
|
41
|
-
mode: "ai",
|
|
42
|
-
content: sourceContent,
|
|
43
|
-
references: [{ refType: "content", contentRef: sourceContentRef, title: "原文" }],
|
|
44
|
-
});
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
`sourceContentRef` 来自 `context.data` 的实体或 `context.entities`,不可解析或用正文数字 ID 代替。宿主核对正文身份与读取权限,失效或未获准的引用拒绝保存。
|
|
48
|
-
|
|
49
|
-
窗口操作返回的 Promise 等待用户完成。必须在按钮或其他用户操作中调用;后台和定时器调用会被拒绝,不要在 `activate()` 中等待用户操作。同一窗口仅允许一个制卡会话,重复打开明确报错。
|
|
50
|
-
|
|
51
|
-
所有创建方式返回的卡片都沿用 `PluginFlashcardDraft` 的字段:自定义参考正文为 `references[].customContent`,已有正文引用为 `references[].contentRef`。可以将返回卡片传给 `createCard` 创建副本,仍需写入和来源读取权限;已失效的引用不会出现在返回结果中。创建后来源窗口的卡组、闪卡和计数会自动刷新。
|
|
52
|
-
|
|
53
|
-
## 直接创建卡组与闪卡
|
|
54
|
-
|
|
55
|
-
```ts
|
|
56
|
-
const decks = await context.flashcards.listDecks();
|
|
57
|
-
const deck = await context.flashcards.createDeck({ name: "力学", description: "基础概念" });
|
|
58
|
-
const card = await context.flashcards.createCard({
|
|
59
|
-
deckId: deck.id,
|
|
60
|
-
type: "qa",
|
|
61
|
-
prompt: [{ type: "paragraph", children: [{ text: "牛顿第二定律的表达式是什么?" }] }],
|
|
62
|
-
data: { answer: "F = ma" },
|
|
63
|
-
tags: ["力学"],
|
|
64
|
-
difficulty: "foundation",
|
|
65
|
-
});
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
题型包括 `qa/boolean/cloze/single-choice/multiple-choice`,答案结构见 `PluginFlashcardData`。调用前必须确认用户意图;这些方法直接写入用户当前数据库,记录属于用户,不随插件卸载删除。API 不提供删除或修改已有闪卡的权限。
|
|
69
|
-
|
|
70
|
-
## 生成草稿与自动保存
|
|
71
|
-
|
|
72
|
-
```ts
|
|
73
|
-
// 只生成,插件可进一步筛选,再逐张 createCard。
|
|
74
|
-
const drafts = await context.flashcards.generate({
|
|
75
|
-
content: "需要学习的内容",
|
|
76
|
-
title: "资料",
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
// 只有明确调用此方法才绕过预览,直接保存。
|
|
80
|
-
const result = await context.flashcards.generateAndSave({
|
|
81
|
-
content: "需要学习的内容",
|
|
82
|
-
title: "资料",
|
|
83
|
-
deckId: deck.id,
|
|
84
|
-
});
|
|
85
|
-
// result.cards:成功保存的记录;result.failed:失败项的零基下标和 message。
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
AI 沿用应用的闪卡制作模型,不读取或导出密钥。没有模型配置、未授权、额度不足或内容为空时明确失败,不自动选择其他模型;AI 模型变更后下一次调用使用新分配,已经进入准备过程的请求若发现分配改变会拒绝并要求重试。
|
|
89
|
-
|
|
90
|
-
自动保存先校验全部草稿,再逐张写入;不承诺整批事务。不要对整个自动保存调用盲目重试,否则会重复创建成功项。需要精确重试时,使用 `generate` 保留草稿并逐张 `createCard`。取消与切库阻止后续写入,已发出的写入可能已在原库提交,不能将取消理解为事务回滚。
|
|
91
|
-
|
|
92
|
-
这些 API 面向已激活的桌面插件;静态内容组件、博客与移动端没有此宿主能力。
|
package/IMAGES.md
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
# 图片生成与编辑提供方
|
|
2
|
-
|
|
3
|
-
需要 SDK 0.18.0 和支持图片插件接口的客户端。通过 `context.images.register({ id: context.pluginId, name, create })` 注册,每个插件一个提供方,可由用户配置多个账号实例。
|
|
4
|
-
|
|
5
|
-
`create(config, modelId)` 同步创建任务实例,不发网络请求。配置结构由插件解释和校验,不读取宿主 store,也不将账号凭据放进插件共享 storage。实例至少实现一个方法:
|
|
6
|
-
|
|
7
|
-
- `generate({ prompt, options? }, signal)`:文本生成图片。
|
|
8
|
-
- `edit({ prompt, options?, images }, signal)`:基于一张或多张参考图编辑。
|
|
9
|
-
|
|
10
|
-
输入图片为 `{ name, mimeType, content: Uint8Array }`。输出为相同结构的数组,可附加 `revisedPrompt`。宿主支持 PNG/JPEG/WebP,单次最多 16 张、输入和输出总大小分别不超过 128 MiB。提供方返回临时 URL 时自行下载为字节,下载时不要将 API 凭据自动传给其他域名。
|
|
11
|
-
|
|
12
|
-
`options` 包含 `size/quality/outputFormat/background/count`,仅在显式传入时映射到服务商请求。无法等价支持的参数应报告错误,不忽略、不隐式多次调用凑数量。协议、鉴权、超时、重试和轮询由插件负责;网络使用 `context.fetch` 并传入方法的 signal,轮询等待也响应取消。宿主负责文件解析、最终资源上传和正文插入。
|
|
13
|
-
|
|
14
|
-
配置视图通过 `context.settings.register({ id, title, target: "images", component })` 注册。组件接收 `PluginSettingsProps.imageConfig`:`instanceId`、`value`、`modelId`、`save(value, modelId)`。字段、布局、验证和错误提示由插件决定;保存失败保留草稿,成功后才提示已保存。模型标识也由插件表单填写。不要把正在编辑的账号误当成全局当前账号。
|
|
15
|
-
|
|
16
|
-
生成和编辑仍使用用户选择的同一个当前账号;不支持的方法不显示对应入口。停用、重载、切库或调用窗口退出会关闭任务,后续上传和保存不得接收迟到结果。取消不保证撤销远端已发生的任务或费用。图片插件不自动安装、启用或切换资源存储。
|