@xiongtao.xt/tau-plugins 0.30.0 → 0.31.1
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/AI.md +116 -116
- package/BACKEND.md +68 -68
- package/CHANGELOG.md +10 -0
- package/EDITOR.md +192 -192
- package/FLASHCARDS.md +92 -92
- package/IMAGES.md +16 -16
- package/LICENSE +21 -21
- package/NOTIFICATIONS.md +48 -48
- package/PUBLISH-DATA.md +48 -47
- package/PUBLISH.md +50 -48
- package/SERVICES.md +119 -119
- package/SYNC.md +37 -37
- package/TTS.md +20 -20
- package/UPLOAD.md +35 -35
- package/VIDEO.md +65 -65
- package/WHITEBOARD.md +115 -115
- package/client/{chunk-R3YIHOWT.js → chunk-ECEBBIHP.js} +1 -1
- package/package.js +1 -1
- package/package.json +1 -1
- package/publish-artifacts.js +1 -1
- package/publish-client.js +3 -1
- package/types/packages/plugins/src/categories.d.ts +1 -1
- package/types/packages/plugins/src/publish-data.d.ts +2 -5
- package/types/packages/ui/src/primitives/Tabs.d.ts +3 -1
package/AI.md
CHANGED
|
@@ -1,116 +1,116 @@
|
|
|
1
|
-
# AI 服务
|
|
2
|
-
|
|
3
|
-
自定义 AI 功能需要 SDK 0.7.0;申请应用已有的模型分配需要 SDK 0.27.0。两者都需要包含对应实现的 Tau 客户端。
|
|
4
|
-
|
|
5
|
-
自定义 AI 功能由插件声明,用户在插件详情的「设置 → AI 配置」分配已有模型并开启授权。全局「大语言模型」设置管理服务商和密钥;这类功能通过 `ctx.ai` 请求模型,接口不返回密钥、连接地址或用户的聊天历史。
|
|
6
|
-
|
|
7
|
-
## 使用应用已有模型分配
|
|
8
|
-
|
|
9
|
-
无需声明 `ai.features` 或另配模型。先在 manifest 中声明 `ai:<能力名>` 权限,再申请对应客户端:
|
|
10
|
-
|
|
11
|
-
```json
|
|
12
|
-
{ "permissions": ["ai:titleSummary"] }
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
```ts
|
|
16
|
-
const model = await context.ai.requestCapability("titleSummary");
|
|
17
|
-
const result = await model.chat({
|
|
18
|
-
messages: [{ role: "user", content: "为这段文字拟一个简短标题:……" }],
|
|
19
|
-
});
|
|
20
|
-
console.log(result.text);
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
申请时由用户选择允许或拒绝;能力分别授权,未声明的申请会被拒绝。返回客户端提供 `chat(request)` 和 `stream(request)`,参数与下文自定义 AI 相同,但不传 `feature`。每次调用复核权限,撤权、停用或切库取消在途生成;额度、并发和用量审计按插件统计。缺少应用模型分配时明确失败,不自动选择其他模型。
|
|
24
|
-
|
|
25
|
-
当前全部 12 项大模型功能分配均可申请,能力清单也可从 `PLUGIN_AI_CAPABILITIES` 导入:
|
|
26
|
-
|
|
27
|
-
| 能力名 | 沿用的应用分配 |
|
|
28
|
-
| ------------------------------ | -------------- |
|
|
29
|
-
| `chat` | 对话功能 |
|
|
30
|
-
| `titleSummary` | 标题总结 |
|
|
31
|
-
| `webClip` | 网页剪藏 |
|
|
32
|
-
| `podcastGeneration` | 播客生成 |
|
|
33
|
-
| `flashcardGeneration` | 闪卡生成 |
|
|
34
|
-
| `aiJudgement` | 答案评判 |
|
|
35
|
-
| `transcriptionOptimization` | 转录断句优化 |
|
|
36
|
-
| `videoSummary` | 视频总结 |
|
|
37
|
-
| `videoEbookRewrite` | 视频电子书重写 |
|
|
38
|
-
| `vibeLearningImageDescription` | 图片理解 |
|
|
39
|
-
| `contentMetadata` | 笔记元信息 |
|
|
40
|
-
| `contentInsights` | AI 洞见 |
|
|
41
|
-
|
|
42
|
-
这里复用模型分配,不自动执行宿主的业务流程或读取业务数据;插件传入自己的消息。已有闪卡业务流程由 `context.flashcards` 提供,它内部调用同一通用机制,需声明 `ai:flashcardGeneration`,详见 [FLASHCARDS.md](FLASHCARDS.md)。
|
|
43
|
-
|
|
44
|
-
图片理解可在 user 消息中传入 `images: [{ data: imageBase64, mimeType: "image/png" }]`。`data` 不带 data: 前缀;支持 PNG、JPEG、WebP、GIF,每条消息最多 10 张,整次请求的 Base64 总长最多 20 MiB,模型须支持图片。图片与消息正文不会写入用量审计。
|
|
45
|
-
|
|
46
|
-
## 声明自定义 AI 功能
|
|
47
|
-
|
|
48
|
-
```ts
|
|
49
|
-
import { definePlugin } from "@tau/plugins";
|
|
50
|
-
|
|
51
|
-
declare const __PLUGIN_META__: { id: string; name: string; version: string };
|
|
52
|
-
|
|
53
|
-
export default definePlugin({
|
|
54
|
-
...__PLUGIN_META__,
|
|
55
|
-
ai: {
|
|
56
|
-
features: [{ id: "summary", name: "文章摘要", description: "概括用户选择的文章" }],
|
|
57
|
-
},
|
|
58
|
-
create: () => ({
|
|
59
|
-
activate(ctx) {
|
|
60
|
-
ctx.commands.register({
|
|
61
|
-
id: "summary",
|
|
62
|
-
title: "生成摘要",
|
|
63
|
-
async run(input) {
|
|
64
|
-
const status = await ctx.ai.getStatus("summary");
|
|
65
|
-
if (!status.configured || !status.enabled) {
|
|
66
|
-
ctx.ai.openSettings("summary");
|
|
67
|
-
return null;
|
|
68
|
-
}
|
|
69
|
-
const result = await ctx.ai.chat({
|
|
70
|
-
feature: "summary",
|
|
71
|
-
messages: [
|
|
72
|
-
{ role: "system", content: "概括主要内容,不添加原文以外的信息。" },
|
|
73
|
-
{ role: "user", content: typeof input === "string" ? input : "请先选择正文。" },
|
|
74
|
-
],
|
|
75
|
-
maxOutputTokens: 1024,
|
|
76
|
-
});
|
|
77
|
-
return result.text;
|
|
78
|
-
},
|
|
79
|
-
});
|
|
80
|
-
},
|
|
81
|
-
}),
|
|
82
|
-
});
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
## 接口
|
|
86
|
-
|
|
87
|
-
| 接口 | 返回与用途 |
|
|
88
|
-
| ------------------------ | ----------------------------------------------------------------------------------- |
|
|
89
|
-
| `getStatus(feature)` | `{ configured, enabled }`;模型被删除也视为未配置 |
|
|
90
|
-
| `openSettings(feature?)` | 打开当前插件设置,由用户分配模型、管理授权 |
|
|
91
|
-
| `chat(request)` | `{ text, usage }`;usage 未知时为 null |
|
|
92
|
-
| `stream(request)` | 异步迭代器,依次产生 `{ type: "text", delta }`,最后产生 `{ type: "done", result }` |
|
|
93
|
-
|
|
94
|
-
请求字段:`feature` 必须是插件声明的功能 ID;`messages` 为 system/user/assistant 文本消息数组;`maxOutputTokens` 是可选的最大输出 Token;`signal` 为可选的取消信号。多轮历史由插件传入。多个 system 消息合并为系统提示,不提供工具调用或自动代理执行。
|
|
95
|
-
|
|
96
|
-
```ts
|
|
97
|
-
const controller = new AbortController();
|
|
98
|
-
for await (const event of ctx.ai.stream({
|
|
99
|
-
feature: "summary",
|
|
100
|
-
messages: [{ role: "user", content: article }],
|
|
101
|
-
signal: controller.signal,
|
|
102
|
-
})) {
|
|
103
|
-
if (event.type === "text") appendText(event.delta);
|
|
104
|
-
else showUsage(event.result.usage);
|
|
105
|
-
}
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
退出迭代、取消 signal、停用插件或用户撤销 AI 授权都会请求取消。不要在模块顶层调用 AI,也不要在遇到额度不足或拒绝授权后自动循环重试。
|
|
109
|
-
|
|
110
|
-
## 审计与额度
|
|
111
|
-
|
|
112
|
-
所有模型调用由宿主归属到插件及功能,进入「大语言模型 → 用量统计」,插件设置的「查看用量」会跳转并筛选本插件。记录包含时间、模型、状态、Token、估算费用和耗时,不保存提示词或回复正文。运行中的请求可取消,也可一次关闭插件的 AI 授权。
|
|
113
|
-
|
|
114
|
-
额度按本机自然日统计,所有窗口共用,并在重启后保留。每日请求次数、每日 Token 和并发限制由用户设置;并发达到上限直接拒绝,不排队。宿主按模型上下文容量加输出上限保守预占 Token,结束后按实际已知用量结算;未知用量保留预占。供应商未报告用量时不能当作零消费;费用为估算,不替代账单。取消无法撤销已经产生的消费。
|
|
115
|
-
|
|
116
|
-
错误消息以稳定代码开头:`AI_NOT_CONFIGURED`(未配置)、`AI_DISABLED`(未授权或插件已停用)、`AI_UNDECLARED_FEATURE`(未声明)、`AI_QUOTA_EXCEEDED`(每日额度不足)、`AI_CONCURRENCY_LIMIT`(并发已满)、`AI_CONFIG_CHANGED`(模型分配变化)、`AI_ABORTED`(取消)、`AI_REQUEST_FAILED`(模型或审计失败)。本地 AbortSignal 取消也可能抛出标准 AbortError。
|
|
1
|
+
# AI 服务
|
|
2
|
+
|
|
3
|
+
自定义 AI 功能需要 SDK 0.7.0;申请应用已有的模型分配需要 SDK 0.27.0。两者都需要包含对应实现的 Tau 客户端。
|
|
4
|
+
|
|
5
|
+
自定义 AI 功能由插件声明,用户在插件详情的「设置 → AI 配置」分配已有模型并开启授权。全局「大语言模型」设置管理服务商和密钥;这类功能通过 `ctx.ai` 请求模型,接口不返回密钥、连接地址或用户的聊天历史。
|
|
6
|
+
|
|
7
|
+
## 使用应用已有模型分配
|
|
8
|
+
|
|
9
|
+
无需声明 `ai.features` 或另配模型。先在 manifest 中声明 `ai:<能力名>` 权限,再申请对应客户端:
|
|
10
|
+
|
|
11
|
+
```json
|
|
12
|
+
{ "permissions": ["ai:titleSummary"] }
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
const model = await context.ai.requestCapability("titleSummary");
|
|
17
|
+
const result = await model.chat({
|
|
18
|
+
messages: [{ role: "user", content: "为这段文字拟一个简短标题:……" }],
|
|
19
|
+
});
|
|
20
|
+
console.log(result.text);
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
申请时由用户选择允许或拒绝;能力分别授权,未声明的申请会被拒绝。返回客户端提供 `chat(request)` 和 `stream(request)`,参数与下文自定义 AI 相同,但不传 `feature`。每次调用复核权限,撤权、停用或切库取消在途生成;额度、并发和用量审计按插件统计。缺少应用模型分配时明确失败,不自动选择其他模型。
|
|
24
|
+
|
|
25
|
+
当前全部 12 项大模型功能分配均可申请,能力清单也可从 `PLUGIN_AI_CAPABILITIES` 导入:
|
|
26
|
+
|
|
27
|
+
| 能力名 | 沿用的应用分配 |
|
|
28
|
+
| ------------------------------ | -------------- |
|
|
29
|
+
| `chat` | 对话功能 |
|
|
30
|
+
| `titleSummary` | 标题总结 |
|
|
31
|
+
| `webClip` | 网页剪藏 |
|
|
32
|
+
| `podcastGeneration` | 播客生成 |
|
|
33
|
+
| `flashcardGeneration` | 闪卡生成 |
|
|
34
|
+
| `aiJudgement` | 答案评判 |
|
|
35
|
+
| `transcriptionOptimization` | 转录断句优化 |
|
|
36
|
+
| `videoSummary` | 视频总结 |
|
|
37
|
+
| `videoEbookRewrite` | 视频电子书重写 |
|
|
38
|
+
| `vibeLearningImageDescription` | 图片理解 |
|
|
39
|
+
| `contentMetadata` | 笔记元信息 |
|
|
40
|
+
| `contentInsights` | AI 洞见 |
|
|
41
|
+
|
|
42
|
+
这里复用模型分配,不自动执行宿主的业务流程或读取业务数据;插件传入自己的消息。已有闪卡业务流程由 `context.flashcards` 提供,它内部调用同一通用机制,需声明 `ai:flashcardGeneration`,详见 [FLASHCARDS.md](FLASHCARDS.md)。
|
|
43
|
+
|
|
44
|
+
图片理解可在 user 消息中传入 `images: [{ data: imageBase64, mimeType: "image/png" }]`。`data` 不带 data: 前缀;支持 PNG、JPEG、WebP、GIF,每条消息最多 10 张,整次请求的 Base64 总长最多 20 MiB,模型须支持图片。图片与消息正文不会写入用量审计。
|
|
45
|
+
|
|
46
|
+
## 声明自定义 AI 功能
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
import { definePlugin } from "@tau/plugins";
|
|
50
|
+
|
|
51
|
+
declare const __PLUGIN_META__: { id: string; name: string; version: string };
|
|
52
|
+
|
|
53
|
+
export default definePlugin({
|
|
54
|
+
...__PLUGIN_META__,
|
|
55
|
+
ai: {
|
|
56
|
+
features: [{ id: "summary", name: "文章摘要", description: "概括用户选择的文章" }],
|
|
57
|
+
},
|
|
58
|
+
create: () => ({
|
|
59
|
+
activate(ctx) {
|
|
60
|
+
ctx.commands.register({
|
|
61
|
+
id: "summary",
|
|
62
|
+
title: "生成摘要",
|
|
63
|
+
async run(input) {
|
|
64
|
+
const status = await ctx.ai.getStatus("summary");
|
|
65
|
+
if (!status.configured || !status.enabled) {
|
|
66
|
+
ctx.ai.openSettings("summary");
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
const result = await ctx.ai.chat({
|
|
70
|
+
feature: "summary",
|
|
71
|
+
messages: [
|
|
72
|
+
{ role: "system", content: "概括主要内容,不添加原文以外的信息。" },
|
|
73
|
+
{ role: "user", content: typeof input === "string" ? input : "请先选择正文。" },
|
|
74
|
+
],
|
|
75
|
+
maxOutputTokens: 1024,
|
|
76
|
+
});
|
|
77
|
+
return result.text;
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
},
|
|
81
|
+
}),
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## 接口
|
|
86
|
+
|
|
87
|
+
| 接口 | 返回与用途 |
|
|
88
|
+
| ------------------------ | ----------------------------------------------------------------------------------- |
|
|
89
|
+
| `getStatus(feature)` | `{ configured, enabled }`;模型被删除也视为未配置 |
|
|
90
|
+
| `openSettings(feature?)` | 打开当前插件设置,由用户分配模型、管理授权 |
|
|
91
|
+
| `chat(request)` | `{ text, usage }`;usage 未知时为 null |
|
|
92
|
+
| `stream(request)` | 异步迭代器,依次产生 `{ type: "text", delta }`,最后产生 `{ type: "done", result }` |
|
|
93
|
+
|
|
94
|
+
请求字段:`feature` 必须是插件声明的功能 ID;`messages` 为 system/user/assistant 文本消息数组;`maxOutputTokens` 是可选的最大输出 Token;`signal` 为可选的取消信号。多轮历史由插件传入。多个 system 消息合并为系统提示,不提供工具调用或自动代理执行。
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
const controller = new AbortController();
|
|
98
|
+
for await (const event of ctx.ai.stream({
|
|
99
|
+
feature: "summary",
|
|
100
|
+
messages: [{ role: "user", content: article }],
|
|
101
|
+
signal: controller.signal,
|
|
102
|
+
})) {
|
|
103
|
+
if (event.type === "text") appendText(event.delta);
|
|
104
|
+
else showUsage(event.result.usage);
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
退出迭代、取消 signal、停用插件或用户撤销 AI 授权都会请求取消。不要在模块顶层调用 AI,也不要在遇到额度不足或拒绝授权后自动循环重试。
|
|
109
|
+
|
|
110
|
+
## 审计与额度
|
|
111
|
+
|
|
112
|
+
所有模型调用由宿主归属到插件及功能,进入「大语言模型 → 用量统计」,插件设置的「查看用量」会跳转并筛选本插件。记录包含时间、模型、状态、Token、估算费用和耗时,不保存提示词或回复正文。运行中的请求可取消,也可一次关闭插件的 AI 授权。
|
|
113
|
+
|
|
114
|
+
额度按本机自然日统计,所有窗口共用,并在重启后保留。每日请求次数、每日 Token 和并发限制由用户设置;并发达到上限直接拒绝,不排队。宿主按模型上下文容量加输出上限保守预占 Token,结束后按实际已知用量结算;未知用量保留预占。供应商未报告用量时不能当作零消费;费用为估算,不替代账单。取消无法撤销已经产生的消费。
|
|
115
|
+
|
|
116
|
+
错误消息以稳定代码开头:`AI_NOT_CONFIGURED`(未配置)、`AI_DISABLED`(未授权或插件已停用)、`AI_UNDECLARED_FEATURE`(未声明)、`AI_QUOTA_EXCEEDED`(每日额度不足)、`AI_CONCURRENCY_LIMIT`(并发已满)、`AI_CONFIG_CHANGED`(模型分配变化)、`AI_ABORTED`(取消)、`AI_REQUEST_FAILED`(模型或审计失败)。本地 AbortSignal 取消也可能抛出标准 AbortError。
|
package/BACKEND.md
CHANGED
|
@@ -1,68 +1,68 @@
|
|
|
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 不写宿主日志,管理页展示有界错误、启动耗时、失败/超时次数及进程资源采样。
|
|
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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# 更新记录
|
|
2
2
|
|
|
3
|
+
## 0.31.1
|
|
4
|
+
|
|
5
|
+
- 修复:数据客户端读取 0.31.0 生成的站点清单时报「站点数据缺失」。客户端改为校验 `site.fields`,不再要求已移除的 `site.description`。
|
|
6
|
+
|
|
7
|
+
## 0.31.0
|
|
8
|
+
|
|
9
|
+
- 模板 manifest 新增 `template.siteFields`:声明模板需要的站点字段(文本、多行、链接、下拉、开关),用户在发布页「站点设置」中填写,宿主校验后按声明渲染。
|
|
10
|
+
- 发布数据的 `site.fields` 提供这些字段的取值;`site.description` 与首页的 `hero` 已移除,需要站点描述的模板请声明同名字段并自行渲染介绍区。
|
|
11
|
+
- 字段声明格式与取值规则见 PUBLISH-DATA.md「数据分布」:只输出已声明的键,未填写或类型不符时取 `default`。
|
|
12
|
+
|
|
3
13
|
## 0.29.0
|
|
4
14
|
|
|
5
15
|
- 页面组件新增 `pageContext.register(provider)`:通过现有 `get_current_context` 向 AI 提供当前页面状态,返回任意有限 JSON,业务内容与形状完全由作者决定。
|