@xiongtao.xt/tau-plugins 0.20.0 → 0.21.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 CHANGED
@@ -1,5 +1,11 @@
1
1
  # 更新记录
2
2
 
3
+ ## 0.21.0
4
+
5
+ - 新增 context.publish 发布提供方、publishConfig 配置表单和文件式/快照式提交协议,本地导出仍由宿主提供。
6
+ - 新增受控 Git 快照发布与缓存目录选择服务,插件不获得任意命令或宿主文件访问。
7
+ - 插件分类新增博客发布。
8
+
3
9
  ## 0.20.0
4
10
 
5
11
  - manifest 支持 `categories`(插件中心分类)与 `keywords`(目录搜索),门户上传严格校验,客户端忽略未知值。
package/PUBLISH.md ADDED
@@ -0,0 +1,17 @@
1
+ # 博客发布提供方
2
+
3
+ 需要 SDK 0.21.0 及包含博客发布能力的客户端。提供方只在渲染进程注册和执行,网络使用 `context.fetch`。本地导出由宿主提供,不注册本地发布插件。
4
+
5
+ 在 activate 中调用 `context.publish.register({ id: context.pluginId, name, create(config) })`。create 返回文件式或快照式实例,配置是本轮固定的 JSON 副本。提供方 ID 必须等于所属插件 ID。
6
+
7
+ 两种实例都实现 `describe(signal)` 与 `checkConnection(signal)`;describe 返回 `identity`、`basePath`、可选 `publicUrl`。identity 是不含密钥的物理目标稳定身份,不随插件版本、模板、Token 或提交方式变化。basePath 以斜杠开头和结尾,根路径为 `/`。
8
+
9
+ 文件式实例声明 `mode: "files"`,实现 `uploadFile(path, Uint8Array, signal)` 与 `deleteFile(path, signal)`,可用 `concurrency` 声明 1–32 的上限。方法成功返回 void,失败抛出异常。宿主负责增量、重试、依赖先行和入口后置、旧资源清理,不把远端目录当成可任意删除的文件清单。
10
+
11
+ 快照式实例声明 `mode: "snapshot"`,实现 `publish(snapshot, signal)`。snapshot 包含本轮临时 id、待上传文件的路径和摘要及删除路径。只有远端确认整轮提交后才返回;失败抛异常,不返回部分成功。可选 dispose 在会话关闭时回收连接。
12
+
13
+ Git 快照使用 `context.services.git.publishSnapshot({ publicationId: snapshot.id, remote, branch, author: { name, email }, authentication: { username, password }, cacheId? }, { signal })`。remote 只接受不含凭据的 HTTPS 地址;认证通过任务通道使用,不写入 remote URL。publicationId 仅在所属窗口本轮发布中有效,不能用于读取任意本地文件。需要缓存目录时调用 `context.services.git.selectCacheDirectory({})`,由宿主选择并返回 `{ id, label }`;只保存 id 和展示用 label,不传入任意 cwd 或 shell 命令。
14
+
15
+ 配置视图使用 `context.settings.register({ id, title, target: "publish", component })`。组件接收 `PluginSettingsProps.publishConfig` 的 value 与 save,保存成功后再提交表单值,不用按工作区隔离的 context.storage 保存账号。普通插件详情页提供前往博客发布页的入口。
16
+
17
+ 离开发布页继续运行;停用、切库和发起窗口关闭使旧会话失效。每次请求都传递 signal,错误信息不得包含凭据。新安装默认停用,插件缺失或未启用时宿主保留用户配置及选择,不自动切换其他目标。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xiongtao.xt/tau-plugins",
3
- "version": "0.20.0",
3
+ "version": "0.21.0",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -43,6 +43,7 @@ var PLUGIN_CATEGORIES = [
43
43
  { id: "editor", label: "\u7F16\u8F91\u5668" },
44
44
  { id: "whiteboard", label: "\u767D\u677F" },
45
45
  { id: "blog-template", label: "\u535A\u5BA2\u6A21\u677F" },
46
+ { id: "blog-publish", label: "\u535A\u5BA2\u53D1\u5E03" },
46
47
  { id: "ai", label: "AI" },
47
48
  { id: "voice", label: "\u8BED\u97F3" },
48
49
  { id: "page", label: "\u9875\u9762" }
@@ -14,6 +14,9 @@ export declare const PLUGIN_CATEGORIES: readonly [{
14
14
  }, {
15
15
  readonly id: "blog-template";
16
16
  readonly label: "博客模板";
17
+ }, {
18
+ readonly id: "blog-publish";
19
+ readonly label: "博客发布";
17
20
  }, {
18
21
  readonly id: "ai";
19
22
  readonly label: "AI";
@@ -11,6 +11,7 @@ import type { PluginSync } from "./sync";
11
11
  import type { PluginUpload } from "./upload";
12
12
  import type { PluginTTS } from "./tts";
13
13
  import type { PluginImages } from "./images";
14
+ import type { PluginPublish } from "./publish";
14
15
  import type { PluginSidebar } from "./sidebar";
15
16
  import type { PluginExcerpts, PluginMaterials } from "./excerpts";
16
17
  import type { PluginMCP } from "./mcp";
@@ -46,6 +47,7 @@ export interface PluginContext {
46
47
  readonly upload: PluginUpload;
47
48
  readonly tts: PluginTTS;
48
49
  readonly images: PluginImages;
50
+ readonly publish: PluginPublish;
49
51
  readonly sidebar: PluginSidebar;
50
52
  readonly excerpts: PluginExcerpts;
51
53
  readonly materials: PluginMaterials;
@@ -2,6 +2,7 @@ import type { PluginDefinition } from "./contract";
2
2
  export type * from "./upload";
3
3
  export type * from "./tts";
4
4
  export type * from "./images";
5
+ export type * from "./publish";
5
6
  export type { JsonValue, Disposable, PluginStorage, PluginCommand, PluginContext, PluginInstance, PluginDefinition, } from "./contract";
6
7
  export type { PluginSettings, PluginSettingsDefinition, PluginSettingsProps, PluginSettingsHandle, } from "./settings";
7
8
  export * from "./editor";
@@ -0,0 +1,59 @@
1
+ import type { Disposable, JsonValue } from "./contract";
2
+ export interface PublishTarget {
3
+ /** 物理目标的稳定身份,不包含凭据、插件或模板版本。 */
4
+ identity: string;
5
+ basePath: string;
6
+ publicUrl?: string;
7
+ }
8
+ export interface PublicationSnapshot {
9
+ /** 宿主为本轮文件计划颁发的临时句柄,不能读取任意本地文件。 */
10
+ id: string;
11
+ files: readonly {
12
+ path: string;
13
+ hash: string;
14
+ }[];
15
+ deletions: readonly string[];
16
+ }
17
+ interface PublishInstanceBase {
18
+ describe(signal: AbortSignal): Promise<PublishTarget>;
19
+ checkConnection(signal: AbortSignal): Promise<boolean>;
20
+ dispose?(): void | Promise<void>;
21
+ }
22
+ export interface FilePublishInstance extends PublishInstanceBase {
23
+ mode: "files";
24
+ concurrency?: number;
25
+ uploadFile(path: string, content: Uint8Array, signal: AbortSignal): Promise<void>;
26
+ deleteFile(path: string, signal: AbortSignal): Promise<void>;
27
+ }
28
+ export interface SnapshotPublishInstance extends PublishInstanceBase {
29
+ mode: "snapshot";
30
+ publish(snapshot: PublicationSnapshot, signal: AbortSignal): Promise<void>;
31
+ }
32
+ export type PublishInstance = FilePublishInstance | SnapshotPublishInstance;
33
+ export interface PublishProviderDefinition {
34
+ id: string;
35
+ name: string;
36
+ create(config: JsonValue): PublishInstance;
37
+ }
38
+ export interface PluginPublish {
39
+ register(definition: PublishProviderDefinition): Disposable;
40
+ }
41
+ export interface GitSnapshotRequest {
42
+ publicationId: string;
43
+ remote: string;
44
+ branch: string;
45
+ author: {
46
+ name: string;
47
+ email: string;
48
+ };
49
+ authentication: {
50
+ username: string;
51
+ password: string;
52
+ };
53
+ cacheId?: string;
54
+ }
55
+ export interface GitCacheDirectory {
56
+ id: string;
57
+ label: string;
58
+ }
59
+ export {};
@@ -1,5 +1,6 @@
1
1
  import type { Descendant } from "slate";
2
2
  import type { MarkdownCodec } from "../../markdown/src/index";
3
+ import type { GitSnapshotRequest, GitCacheDirectory } from "./publish";
3
4
  export type { Descendant } from "slate";
4
5
  export interface ServiceOptions {
5
6
  signal?: AbortSignal;
@@ -39,6 +40,10 @@ export interface MediaInfo {
39
40
  }[];
40
41
  }
41
42
  export interface PluginServices {
43
+ git: {
44
+ publishSnapshot(input: GitSnapshotRequest, options?: ServiceOptions): Promise<void>;
45
+ selectCacheDirectory(input: Record<string, never>, options?: ServiceOptions): Promise<GitCacheDirectory | null>;
46
+ };
42
47
  tailwind: {
43
48
  compile(input: {
44
49
  source: string;
@@ -3,6 +3,10 @@ import type { Disposable, PluginContext } from "./index";
3
3
  import type { JsonValue } from "./json";
4
4
  export interface PluginSettingsProps {
5
5
  readonly context: PluginContext;
6
+ readonly publishConfig?: {
7
+ readonly value: JsonValue;
8
+ save(value: JsonValue): Promise<void>;
9
+ };
6
10
  readonly imageConfig?: {
7
11
  readonly instanceId: string;
8
12
  readonly value: JsonValue;
@@ -35,7 +39,7 @@ export interface PluginSettingsDefinition {
35
39
  title: string;
36
40
  description?: string;
37
41
  /** 提供方配置表单挂载到对应宿主设置;普通插件设置省略。 */
38
- target?: "sync" | "upload" | "tts" | "images";
42
+ target?: "sync" | "upload" | "tts" | "images" | "publish";
39
43
  component: ComponentType<PluginSettingsProps>;
40
44
  }
41
45
  export interface PluginSettingsHandle extends Disposable {