@tbox-claw/bridge-sdk 1.0.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/README.md ADDED
@@ -0,0 +1,201 @@
1
+ # @tbox-claw/bridge-sdk
2
+
3
+ > TboxClaw 桌面端嵌入页面开发 SDK
4
+
5
+ 本包为嵌入在 TboxClaw 桌面应用中的三方页面提供 **TypeScript 类型定义** 和 **运行时工具函数**。三方页面通过 `window.tboxClawBridge` 与客户端进行安全通信。
6
+
7
+ ---
8
+
9
+ ## 安装
10
+
11
+ ```bash
12
+ npm install @tbox-claw/bridge-sdk
13
+ # 或
14
+ pnpm add @tbox-claw/bridge-sdk
15
+ # 或
16
+ yarn add @tbox-claw/bridge-sdk
17
+ ```
18
+
19
+ ---
20
+
21
+ ## 快速开始
22
+
23
+ ```typescript
24
+ import { getBridge, isTboxClawEnv } from '@tbox-claw/bridge-sdk';
25
+
26
+ if (isTboxClawEnv()) {
27
+ const bridge = getBridge();
28
+
29
+ // 获取当前用户信息
30
+ const userResult = await bridge.getUserInfo();
31
+ if (userResult.ok) {
32
+ console.log('你好,', userResult.data.name);
33
+ }
34
+
35
+ // 获取客户端信息
36
+ const clientResult = await bridge.getClientInfo();
37
+ if (clientResult.ok) {
38
+ console.log('操作系统:', clientResult.data.platform);
39
+ console.log('客户端版本:', clientResult.data.clientVersion);
40
+ }
41
+ }
42
+ ```
43
+
44
+ ---
45
+
46
+ ## Bridge API
47
+
48
+ 所有 Bridge API 返回统一的 `BridgeResponse<T>` 格式:
49
+
50
+ ```typescript
51
+ interface BridgeResponse<T = unknown> {
52
+ ok: boolean; // 调用是否成功
53
+ data?: T; // 响应数据(ok=true 时存在)
54
+ error?: string; // 错误信息(ok=false 时存在)
55
+ }
56
+ ```
57
+
58
+ > **权限模型**:每个嵌入页面在服务端配置了允许调用的 API 白名单(`bridge.allowedApis`)。调用白名单之外的 API 会返回 `{ ok: false, error: 'API "xxx" not allowed for page "yyy"' }`。
59
+
60
+ ### 用户信息
61
+
62
+ | API | 说明 | 最小客户端版本 |
63
+ |-----|------|:--------------:|
64
+ | [`getUserInfo()`](./docs/api/getUserInfo.md) | 获取当前登录用户信息(已脱敏) | `1.2.1` |
65
+
66
+ ### 应用设置
67
+
68
+ | API | 说明 | 最小客户端版本 |
69
+ |-----|------|:--------------:|
70
+ | [`getSettings(keys)`](./docs/api/getSettings.md) | 读取应用设置(支持 `theme`、`language`) | `1.2.1` |
71
+
72
+ ### 客户端环境
73
+
74
+ | API | 说明 | 最小客户端版本 |
75
+ |-----|------|:--------------:|
76
+ | [`getClientInfo()`](./docs/api/getClientInfo.md) | 获取操作系统、系统版本、客户端版本等环境信息 | `1.2.1` |
77
+
78
+ ### 系统通知
79
+
80
+ | API | 说明 | 最小客户端版本 |
81
+ |-----|------|:--------------:|
82
+ | [`sendNotification(options)`](./docs/api/sendNotification.md) | 通过主应用发送系统通知 | `1.2.1` |
83
+
84
+
85
+ ### 对话消息
86
+
87
+ | API | 说明 | 最小客户端版本 |
88
+ |-----|------|:--------------:|
89
+ | [`sendChatMessage(options)`](./docs/api/sendChatMessage.md) | 发送对话消息,等同于在 Chat 页面发送 | `1.2.1` |
90
+ | [`getChatHistory(options?)`](./docs/api/getChatHistory.md) | 查询对话历史记录 | `1.2.1` |
91
+
92
+ ### 网关状态
93
+
94
+ | API | 说明 | 最小客户端版本 |
95
+ |-----|------|:--------------:|
96
+ | [`getGatewayStatus()`](./docs/api/getGatewayStatus.md) | 查询 Gateway 运行状态,判断对话类 API 是否可用 | `1.2.1` |
97
+
98
+ ---
99
+
100
+ ## 工具函数
101
+
102
+ SDK 提供以下工具函数,用于环境检测和安全调用,**不依赖客户端版本**。
103
+
104
+ ### `isTboxClawEnv(): boolean`
105
+
106
+ 判断当前页面是否运行在 TboxClaw 桌面端中(即 `window.tboxClawBridge` 是否可用)。
107
+
108
+ ```typescript
109
+ import { isTboxClawEnv } from '@tbox-claw/bridge-sdk';
110
+
111
+ if (isTboxClawEnv()) {
112
+ // 在 TboxClaw 中运行,Bridge API 可用
113
+ } else {
114
+ // 独立运行,使用降级逻辑
115
+ }
116
+ ```
117
+
118
+ ### `getBridge(): TboxClawBridge`
119
+
120
+ 获取 `window.tboxClawBridge` 实例。**如果不在 TboxClaw 环境中会抛出异常**。
121
+
122
+ ```typescript
123
+ import { getBridge } from '@tbox-claw/bridge-sdk';
124
+
125
+ const bridge = getBridge();
126
+ const user = await bridge.getUserInfo();
127
+ ```
128
+
129
+ ### `safeBridgeCall<T>(apiFn, fallback): Promise<T>`
130
+
131
+ 安全调用 Bridge API。如果不在 TboxClaw 环境中或调用出错,返回 `fallback` 值。适用于需要同时支持独立运行和嵌入运行的页面。
132
+
133
+ ```typescript
134
+ import { safeBridgeCall } from '@tbox-claw/bridge-sdk';
135
+
136
+ const user = await safeBridgeCall(
137
+ (bridge) => bridge.getUserInfo(),
138
+ { ok: false, error: '不在 TboxClaw 环境中' },
139
+ );
140
+ ```
141
+
142
+ ---
143
+
144
+ ## 双模式页面(独立运行 + 嵌入运行)
145
+
146
+ 如果你的页面需要同时支持作为独立 Web 应用和嵌入页面运行,推荐使用 `safeBridgeCall` 模式:
147
+
148
+ ```typescript
149
+ import { safeBridgeCall, isTboxClawEnv } from '@tbox-claw/bridge-sdk';
150
+
151
+ // 获取用户信息 — 在 TboxClaw 外自动降级
152
+ const userResult = await safeBridgeCall(
153
+ (bridge) => bridge.getUserInfo(),
154
+ { ok: false, error: '非嵌入环境' },
155
+ );
156
+
157
+ if (userResult.ok) {
158
+ renderUserProfile(userResult.data);
159
+ } else {
160
+ renderLoginForm();
161
+ }
162
+
163
+ // 按需渲染 TboxClaw 专属功能
164
+ if (isTboxClawEnv()) {
165
+ showClientInfoPanel();
166
+ }
167
+ ```
168
+
169
+ ---
170
+
171
+ ## TypeScript 支持
172
+
173
+ SDK 内置完整的 TypeScript 类型声明。安装后 `window.tboxClawBridge` 会自动获得类型提示:
174
+
175
+ ```typescript
176
+ // 无需额外配置 — window.tboxClawBridge 已自动声明类型
177
+ const bridge = window.tboxClawBridge;
178
+ const user = await bridge.getUserInfo(); // 完整类型推导
179
+ ```
180
+
181
+ ### 导出的类型
182
+
183
+ ```typescript
184
+ import type {
185
+ TboxClawBridge, // Bridge 接口定义
186
+ BridgeResponse, // { ok, data?, error? }
187
+ UserInfo, // { userId, name, avatar }
188
+ ClientInfo, // { platform, osVersion, clientVersion }
189
+ SendNotificationOptions, // { title, body, silent? }
190
+ SendChatMessageOptions, // { message, sessionKey? }
191
+ GetChatHistoryOptions, // { sessionKey?, limit? }
192
+ ChatMessage, // { role, content, timestamp?, id? }
193
+ GatewayStatusInfo, // { state, ready }
194
+ } from '@tbox-claw/bridge-sdk';
195
+ ```
196
+
197
+ ---
198
+
199
+ ## License
200
+
201
+ MIT
@@ -0,0 +1,102 @@
1
+ /** Bridge API unified response format */
2
+ interface BridgeResponse<T = unknown> {
3
+ ok: boolean;
4
+ data?: T;
5
+ error?: string;
6
+ }
7
+ /** User info (sanitized, no sensitive data) */
8
+ interface UserInfo {
9
+ userId: string;
10
+ name: string;
11
+ avatar: string;
12
+ /** Login channel type (e.g. 'dingtalk', 'alipay') */
13
+ loginType?: string;
14
+ /** Extra user context from server */
15
+ extra?: Record<string, unknown>;
16
+ }
17
+ /** Client environment info */
18
+ interface ClientInfo {
19
+ /** Operating system: 'darwin' | 'win32' | 'linux' */
20
+ platform: string;
21
+ /** OS version string (e.g. '24.3.0') */
22
+ osVersion: string;
23
+ /** Client application version (e.g. '1.2.0') */
24
+ clientVersion: string;
25
+ }
26
+ /** Options for sending a system notification */
27
+ interface SendNotificationOptions {
28
+ /** Notification title */
29
+ title: string;
30
+ /** Notification body text */
31
+ body: string;
32
+ /** Whether to suppress the notification sound (default: false) */
33
+ silent?: boolean;
34
+ }
35
+ /** Options for sending a chat message */
36
+ interface SendChatMessageOptions {
37
+ /** Message text content */
38
+ message: string;
39
+ /**
40
+ * Session identifier within this page, used to maintain separate conversations.
41
+ * Defaults to 'default'. The host app automatically prefixes it with the page ID
42
+ * to ensure full session isolation between pages (format: `embedded:{pageId}:{sessionKey}`).
43
+ */
44
+ sessionKey?: string;
45
+ }
46
+ /** Options for querying chat history */
47
+ interface GetChatHistoryOptions {
48
+ /**
49
+ * Session identifier within this page. Defaults to 'default'.
50
+ * Must match the sessionKey used when sending messages.
51
+ */
52
+ sessionKey?: string;
53
+ /** Maximum number of messages to return (default: 50) */
54
+ limit?: number;
55
+ }
56
+ /** A single chat message returned from history */
57
+ interface ChatMessage {
58
+ /** Message role */
59
+ role: 'user' | 'assistant' | 'system';
60
+ /** Message text content */
61
+ content: string;
62
+ /** Unix timestamp (seconds) */
63
+ timestamp?: number;
64
+ /** Message unique identifier */
65
+ id?: string;
66
+ }
67
+ /** Gateway runtime status */
68
+ interface GatewayStatusInfo {
69
+ /** Current lifecycle state */
70
+ state: 'stopped' | 'starting' | 'running' | 'error' | 'reconnecting';
71
+ /** Whether the gateway is ready to accept requests */
72
+ ready: boolean;
73
+ }
74
+
75
+ /** TboxClaw Bridge interface definition */
76
+ interface TboxClawBridge {
77
+ getUserInfo(): Promise<BridgeResponse<UserInfo>>;
78
+ getSettings(keys: string[]): Promise<BridgeResponse<Record<string, unknown>>>;
79
+ getClientInfo(): Promise<BridgeResponse<ClientInfo>>;
80
+ /** Send a system notification via the host application */
81
+ sendNotification(options: SendNotificationOptions): Promise<BridgeResponse<void>>;
82
+ /** Send a chat message, equivalent to typing in the Chat page */
83
+ sendChatMessage(options: SendChatMessageOptions): Promise<BridgeResponse<{
84
+ runId?: string;
85
+ }>>;
86
+ /** Query chat history for a given session */
87
+ getChatHistory(options?: GetChatHistoryOptions): Promise<BridgeResponse<ChatMessage[]>>;
88
+ /** Check whether the Gateway is running and ready */
89
+ getGatewayStatus(): Promise<BridgeResponse<GatewayStatusInfo>>;
90
+ }
91
+
92
+ /** Check if currently running inside TboxClaw embedded environment */
93
+ declare function isTboxClawEnv(): boolean;
94
+ /** Get the Bridge instance. Throws if not in embedded environment. */
95
+ declare function getBridge(): TboxClawBridge;
96
+ /**
97
+ * Safely call a Bridge API. Returns fallback value if not in embedded environment.
98
+ * Useful for pages that need to work both standalone and embedded.
99
+ */
100
+ declare function safeBridgeCall<T>(apiFn: (bridge: TboxClawBridge) => Promise<T>, fallback: T): Promise<T>;
101
+
102
+ export { type BridgeResponse, type ChatMessage, type ClientInfo, type GatewayStatusInfo, type GetChatHistoryOptions, type SendChatMessageOptions, type SendNotificationOptions, type TboxClawBridge, type UserInfo, getBridge, isTboxClawEnv, safeBridgeCall };
@@ -0,0 +1,102 @@
1
+ /** Bridge API unified response format */
2
+ interface BridgeResponse<T = unknown> {
3
+ ok: boolean;
4
+ data?: T;
5
+ error?: string;
6
+ }
7
+ /** User info (sanitized, no sensitive data) */
8
+ interface UserInfo {
9
+ userId: string;
10
+ name: string;
11
+ avatar: string;
12
+ /** Login channel type (e.g. 'dingtalk', 'alipay') */
13
+ loginType?: string;
14
+ /** Extra user context from server */
15
+ extra?: Record<string, unknown>;
16
+ }
17
+ /** Client environment info */
18
+ interface ClientInfo {
19
+ /** Operating system: 'darwin' | 'win32' | 'linux' */
20
+ platform: string;
21
+ /** OS version string (e.g. '24.3.0') */
22
+ osVersion: string;
23
+ /** Client application version (e.g. '1.2.0') */
24
+ clientVersion: string;
25
+ }
26
+ /** Options for sending a system notification */
27
+ interface SendNotificationOptions {
28
+ /** Notification title */
29
+ title: string;
30
+ /** Notification body text */
31
+ body: string;
32
+ /** Whether to suppress the notification sound (default: false) */
33
+ silent?: boolean;
34
+ }
35
+ /** Options for sending a chat message */
36
+ interface SendChatMessageOptions {
37
+ /** Message text content */
38
+ message: string;
39
+ /**
40
+ * Session identifier within this page, used to maintain separate conversations.
41
+ * Defaults to 'default'. The host app automatically prefixes it with the page ID
42
+ * to ensure full session isolation between pages (format: `embedded:{pageId}:{sessionKey}`).
43
+ */
44
+ sessionKey?: string;
45
+ }
46
+ /** Options for querying chat history */
47
+ interface GetChatHistoryOptions {
48
+ /**
49
+ * Session identifier within this page. Defaults to 'default'.
50
+ * Must match the sessionKey used when sending messages.
51
+ */
52
+ sessionKey?: string;
53
+ /** Maximum number of messages to return (default: 50) */
54
+ limit?: number;
55
+ }
56
+ /** A single chat message returned from history */
57
+ interface ChatMessage {
58
+ /** Message role */
59
+ role: 'user' | 'assistant' | 'system';
60
+ /** Message text content */
61
+ content: string;
62
+ /** Unix timestamp (seconds) */
63
+ timestamp?: number;
64
+ /** Message unique identifier */
65
+ id?: string;
66
+ }
67
+ /** Gateway runtime status */
68
+ interface GatewayStatusInfo {
69
+ /** Current lifecycle state */
70
+ state: 'stopped' | 'starting' | 'running' | 'error' | 'reconnecting';
71
+ /** Whether the gateway is ready to accept requests */
72
+ ready: boolean;
73
+ }
74
+
75
+ /** TboxClaw Bridge interface definition */
76
+ interface TboxClawBridge {
77
+ getUserInfo(): Promise<BridgeResponse<UserInfo>>;
78
+ getSettings(keys: string[]): Promise<BridgeResponse<Record<string, unknown>>>;
79
+ getClientInfo(): Promise<BridgeResponse<ClientInfo>>;
80
+ /** Send a system notification via the host application */
81
+ sendNotification(options: SendNotificationOptions): Promise<BridgeResponse<void>>;
82
+ /** Send a chat message, equivalent to typing in the Chat page */
83
+ sendChatMessage(options: SendChatMessageOptions): Promise<BridgeResponse<{
84
+ runId?: string;
85
+ }>>;
86
+ /** Query chat history for a given session */
87
+ getChatHistory(options?: GetChatHistoryOptions): Promise<BridgeResponse<ChatMessage[]>>;
88
+ /** Check whether the Gateway is running and ready */
89
+ getGatewayStatus(): Promise<BridgeResponse<GatewayStatusInfo>>;
90
+ }
91
+
92
+ /** Check if currently running inside TboxClaw embedded environment */
93
+ declare function isTboxClawEnv(): boolean;
94
+ /** Get the Bridge instance. Throws if not in embedded environment. */
95
+ declare function getBridge(): TboxClawBridge;
96
+ /**
97
+ * Safely call a Bridge API. Returns fallback value if not in embedded environment.
98
+ * Useful for pages that need to work both standalone and embedded.
99
+ */
100
+ declare function safeBridgeCall<T>(apiFn: (bridge: TboxClawBridge) => Promise<T>, fallback: T): Promise<T>;
101
+
102
+ export { type BridgeResponse, type ChatMessage, type ClientInfo, type GatewayStatusInfo, type GetChatHistoryOptions, type SendChatMessageOptions, type SendNotificationOptions, type TboxClawBridge, type UserInfo, getBridge, isTboxClawEnv, safeBridgeCall };
package/dist/index.js ADDED
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ getBridge: () => getBridge,
24
+ isTboxClawEnv: () => isTboxClawEnv,
25
+ safeBridgeCall: () => safeBridgeCall
26
+ });
27
+ module.exports = __toCommonJS(index_exports);
28
+
29
+ // src/utils.ts
30
+ function isTboxClawEnv() {
31
+ return typeof window !== "undefined" && typeof window.tboxClawBridge !== "undefined";
32
+ }
33
+ function getBridge() {
34
+ if (!isTboxClawEnv()) {
35
+ throw new Error(
36
+ "tboxClawBridge is not available. This page must be embedded in the TboxClaw desktop app."
37
+ );
38
+ }
39
+ return window.tboxClawBridge;
40
+ }
41
+ async function safeBridgeCall(apiFn, fallback) {
42
+ if (!isTboxClawEnv()) return fallback;
43
+ try {
44
+ return await apiFn(window.tboxClawBridge);
45
+ } catch {
46
+ return fallback;
47
+ }
48
+ }
49
+ // Annotate the CommonJS export names for ESM import in node:
50
+ 0 && (module.exports = {
51
+ getBridge,
52
+ isTboxClawEnv,
53
+ safeBridgeCall
54
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,25 @@
1
+ // src/utils.ts
2
+ function isTboxClawEnv() {
3
+ return typeof window !== "undefined" && typeof window.tboxClawBridge !== "undefined";
4
+ }
5
+ function getBridge() {
6
+ if (!isTboxClawEnv()) {
7
+ throw new Error(
8
+ "tboxClawBridge is not available. This page must be embedded in the TboxClaw desktop app."
9
+ );
10
+ }
11
+ return window.tboxClawBridge;
12
+ }
13
+ async function safeBridgeCall(apiFn, fallback) {
14
+ if (!isTboxClawEnv()) return fallback;
15
+ try {
16
+ return await apiFn(window.tboxClawBridge);
17
+ } catch {
18
+ return fallback;
19
+ }
20
+ }
21
+ export {
22
+ getBridge,
23
+ isTboxClawEnv,
24
+ safeBridgeCall
25
+ };
@@ -0,0 +1,123 @@
1
+ ## getChatHistory(options?)
2
+
3
+ 查询当前页面的对话历史记录。返回指定会话中的消息列表。
4
+
5
+ | 属性 | 值 |
6
+ |------|-----|
7
+ | **最小客户端版本** | `1.2.1` |
8
+ | **分类** | 对话消息 |
9
+ | **需要权限** | `getChatHistory` 需在页面 `bridge.allowedApis` 白名单中 |
10
+ | **依赖** | 需要 Gateway 处于 `running` 状态 |
11
+
12
+ ---
13
+
14
+ ### 签名
15
+
16
+ ```typescript
17
+ getChatHistory(options?: GetChatHistoryOptions): Promise<BridgeResponse<ChatMessage[]>>
18
+ ```
19
+
20
+ ### 参数
21
+
22
+ **`GetChatHistoryOptions` 类型定义**:
23
+
24
+ ```typescript
25
+ interface GetChatHistoryOptions {
26
+ /** 页面内的会话标识,默认 'default'。需与 sendChatMessage 使用的 sessionKey 一致。 */
27
+ sessionKey?: string;
28
+ /** 返回的最大消息数量,默认 50,上限 200 */
29
+ limit?: number;
30
+ }
31
+ ```
32
+
33
+ | 参数 | 类型 | 必填 | 说明 |
34
+ |------|------|:----:|------|
35
+ | `sessionKey` | `string` | ❌ | 页面内的会话标识,默认 `'default'` |
36
+ | `limit` | `number` | ❌ | 最大返回消息数,默认 `50`,上限 `200` |
37
+
38
+ ### 返回值
39
+
40
+ `Promise<BridgeResponse<ChatMessage[]>>`
41
+
42
+ **`ChatMessage` 类型定义**:
43
+
44
+ ```typescript
45
+ interface ChatMessage {
46
+ /** 消息角色:'user' | 'assistant' | 'system' */
47
+ role: 'user' | 'assistant' | 'system';
48
+ /** 消息文本内容 */
49
+ content: string;
50
+ /** Unix 时间戳(秒) */
51
+ timestamp?: number;
52
+ /** 消息唯一标识 */
53
+ id?: string;
54
+ }
55
+ ```
56
+
57
+ ### 示例
58
+
59
+ ```typescript
60
+ import { getBridge } from '@tbox-claw/bridge-sdk';
61
+
62
+ const bridge = getBridge();
63
+
64
+ // 查询默认会话的历史记录
65
+ const result = await bridge.getChatHistory();
66
+ if (result.ok) {
67
+ for (const msg of result.data) {
68
+ console.log(`[${msg.role}] ${msg.content}`);
69
+ }
70
+ }
71
+
72
+ // 查询指定会话,限制返回 20 条
73
+ const result2 = await bridge.getChatHistory({
74
+ sessionKey: 'analysis-task',
75
+ limit: 20,
76
+ });
77
+ ```
78
+
79
+ ### 错误场景
80
+
81
+ | error | 说明 |
82
+ |-------|------|
83
+ | `API "getChatHistory" not allowed for page "xxx"` | 页面未配置该 API 的调用权限 |
84
+ | `Gateway is not available` | Gateway 服务未启动或不可用 |
85
+
86
+ ### 返回示例
87
+
88
+ **成功**:
89
+
90
+ ```json
91
+ {
92
+ "ok": true,
93
+ "data": [
94
+ {
95
+ "role": "user",
96
+ "content": "帮我分析一下这个数据",
97
+ "timestamp": 1713700000,
98
+ "id": "msg-001"
99
+ },
100
+ {
101
+ "role": "assistant",
102
+ "content": "好的,我来帮你分析...",
103
+ "timestamp": 1713700005,
104
+ "id": "msg-002"
105
+ }
106
+ ]
107
+ }
108
+ ```
109
+
110
+ **成功(空历史)**:
111
+
112
+ ```json
113
+ {
114
+ "ok": true,
115
+ "data": []
116
+ }
117
+ ```
118
+
119
+ ### 注意事项
120
+
121
+ - `sessionKey` 需与 `sendChatMessage` 中使用的一致,才能查到对应的历史记录。
122
+ - 会话隔离机制同样适用:主应用会自动拼接 `pageId` 前缀,不同页面无法查看彼此的历史。
123
+ - 如果 Gateway 尚未启动完成,调用会返回错误。建议先通过 `getGatewayStatus()` 确认 Gateway 状态。
@@ -0,0 +1,74 @@
1
+ ## getClientInfo()
2
+
3
+ 获取当前客户端的环境信息,包括操作系统、系统版本和客户端版本号。
4
+
5
+ | 属性 | 值 |
6
+ |------|-----|
7
+ | **最小客户端版本** | `1.2.1` |
8
+ | **分类** | 客户端环境 |
9
+ | **需要权限** | `getClientInfo` 需在页面 `bridge.allowedApis` 白名单中 |
10
+
11
+ ---
12
+
13
+ ### 签名
14
+
15
+ ```typescript
16
+ getClientInfo(): Promise<BridgeResponse<ClientInfo>>
17
+ ```
18
+
19
+ ### 参数
20
+
21
+ 无。
22
+
23
+ ### 返回值
24
+
25
+ `Promise<BridgeResponse<ClientInfo>>`
26
+
27
+ **`ClientInfo` 类型定义**:
28
+
29
+ ```typescript
30
+ interface ClientInfo {
31
+ /** 操作系统:'darwin' | 'win32' | 'linux' */
32
+ platform: string;
33
+ /** 操作系统版本号,如 '24.3.0' */
34
+ osVersion: string;
35
+ /** 客户端应用版本号,如 '1.2.0' */
36
+ clientVersion: string;
37
+ }
38
+ ```
39
+
40
+ ### 示例
41
+
42
+ ```typescript
43
+ import { getBridge } from '@tbox-claw/bridge-sdk';
44
+
45
+ const bridge = getBridge();
46
+ const result = await bridge.getClientInfo();
47
+
48
+ if (result.ok) {
49
+ console.log(result.data.platform); // 'darwin' | 'win32' | 'linux'
50
+ console.log(result.data.osVersion); // 如 '24.3.0'
51
+ console.log(result.data.clientVersion); // 如 '1.2.0'
52
+ }
53
+ ```
54
+
55
+ ### 错误场景
56
+
57
+ | error | 说明 |
58
+ |-------|------|
59
+ | `API "getClientInfo" not allowed for page "xxx"` | 页面未配置该 API 的调用权限 |
60
+
61
+ ### 返回示例
62
+
63
+ **成功**:
64
+
65
+ ```json
66
+ {
67
+ "ok": true,
68
+ "data": {
69
+ "platform": "darwin",
70
+ "osVersion": "24.3.0",
71
+ "clientVersion": "1.2.0"
72
+ }
73
+ }
74
+ ```
@@ -0,0 +1,118 @@
1
+ ## getGatewayStatus()
2
+
3
+ 查询 Gateway 服务的运行状态。可用于在调用 `sendChatMessage` 或 `getChatHistory` 之前判断 Gateway 是否就绪,避免调用失败。
4
+
5
+ | 属性 | 值 |
6
+ |------|-----|
7
+ | **最小客户端版本** | `1.2.1` |
8
+ | **分类** | 网关状态 |
9
+ | **需要权限** | `getGatewayStatus` 需在页面 `bridge.allowedApis` 白名单中 |
10
+
11
+ ---
12
+
13
+ ### 签名
14
+
15
+ ```typescript
16
+ getGatewayStatus(): Promise<BridgeResponse<GatewayStatusInfo>>
17
+ ```
18
+
19
+ ### 参数
20
+
21
+ 无。
22
+
23
+ ### 返回值
24
+
25
+ `Promise<BridgeResponse<GatewayStatusInfo>>`
26
+
27
+ **`GatewayStatusInfo` 类型定义**:
28
+
29
+ ```typescript
30
+ interface GatewayStatusInfo {
31
+ /** 当前生命周期状态 */
32
+ state: 'stopped' | 'starting' | 'running' | 'error' | 'reconnecting';
33
+ /** Gateway 是否已就绪,可以接受请求 */
34
+ ready: boolean;
35
+ }
36
+ ```
37
+
38
+ | 字段 | 类型 | 说明 |
39
+ |------|------|------|
40
+ | `state` | `string` | 生命周期状态,见下方状态说明 |
41
+ | `ready` | `boolean` | 是否就绪(仅 `state === 'running'` 时为 `true`) |
42
+
43
+ **状态说明**:
44
+
45
+ | state | 说明 |
46
+ |-------|------|
47
+ | `stopped` | Gateway 未启动 |
48
+ | `starting` | Gateway 正在启动中(通常需要 10-30 秒) |
49
+ | `running` | Gateway 正常运行,可以接受请求 |
50
+ | `error` | Gateway 启动失败或运行时出错 |
51
+ | `reconnecting` | Gateway 正在尝试重新连接 |
52
+
53
+ ### 示例
54
+
55
+ ```typescript
56
+ import { getBridge } from '@tbox-claw/bridge-sdk';
57
+
58
+ const bridge = getBridge();
59
+
60
+ // 检查 Gateway 是否就绪
61
+ const status = await bridge.getGatewayStatus();
62
+ if (status.ok && status.data.ready) {
63
+ // Gateway 已就绪,可以安全调用对话相关 API
64
+ await bridge.sendChatMessage({ message: '你好' });
65
+ } else {
66
+ console.log('Gateway 状态:', status.data?.state);
67
+ // 可以提示用户等待或重试
68
+ }
69
+ ```
70
+
71
+ ```typescript
72
+ // 等待 Gateway 就绪的轮询示例
73
+ async function waitForGateway(bridge, maxRetries = 10) {
74
+ for (let i = 0; i < maxRetries; i++) {
75
+ const status = await bridge.getGatewayStatus();
76
+ if (status.ok && status.data.ready) return true;
77
+ await new Promise((r) => setTimeout(r, 3000));
78
+ }
79
+ return false;
80
+ }
81
+ ```
82
+
83
+ ### 错误场景
84
+
85
+ | error | 说明 |
86
+ |-------|------|
87
+ | `API "getGatewayStatus" not allowed for page "xxx"` | 页面未配置该 API 的调用权限 |
88
+
89
+ ### 返回示例
90
+
91
+ **成功(Gateway 运行中)**:
92
+
93
+ ```json
94
+ {
95
+ "ok": true,
96
+ "data": {
97
+ "state": "running",
98
+ "ready": true
99
+ }
100
+ }
101
+ ```
102
+
103
+ **成功(Gateway 启动中)**:
104
+
105
+ ```json
106
+ {
107
+ "ok": true,
108
+ "data": {
109
+ "state": "starting",
110
+ "ready": false
111
+ }
112
+ }
113
+ ```
114
+
115
+ ### 注意事项
116
+
117
+ - 此 API 始终返回成功(`ok: true`),即使 Gateway 未启动也会返回 `{ state: 'stopped', ready: false }`。
118
+ - 建议在调用 `sendChatMessage` 或 `getChatHistory` 之前先调用此 API 确认 `ready === true`。
@@ -0,0 +1,70 @@
1
+ ## getSettings(keys)
2
+
3
+ 读取应用设置。仅返回白名单内的 key(当前支持:`theme`、`language`)。
4
+
5
+ | 属性 | 值 |
6
+ |------|-----|
7
+ | **最小客户端版本** | `1.2.1` |
8
+ | **分类** | 应用设置 |
9
+ | **需要权限** | `getSettings` 需在页面 `bridge.allowedApis` 白名单中 |
10
+
11
+ ---
12
+
13
+ ### 签名
14
+
15
+ ```typescript
16
+ getSettings(keys: string[]): Promise<BridgeResponse<Record<string, unknown>>>
17
+ ```
18
+
19
+ ### 参数
20
+
21
+ | 参数 | 类型 | 必填 | 说明 |
22
+ |------|------|------|------|
23
+ | `keys` | `string[]` | 是 | 要读取的设置项名称数组 |
24
+
25
+ **当前支持的 key**:
26
+
27
+ | key | 类型 | 可选值 | 说明 |
28
+ |-----|------|--------|------|
29
+ | `theme` | `string` | `"light"` \| `"dark"` | 当前主题 |
30
+ | `language` | `string` | `"zh"` \| `"en"` | 当前语言 |
31
+
32
+ > 请求不在白名单内的 key 时,该 key 会被静默忽略,不会报错。
33
+
34
+ ### 返回值
35
+
36
+ `Promise<BridgeResponse<Record<string, unknown>>>`
37
+
38
+ ### 示例
39
+
40
+ ```typescript
41
+ import { getBridge } from '@tbox-claw/bridge-sdk';
42
+
43
+ const bridge = getBridge();
44
+ const result = await bridge.getSettings(['theme', 'language']);
45
+
46
+ if (result.ok) {
47
+ console.log(result.data.theme); // "light" | "dark"
48
+ console.log(result.data.language); // "zh" | "en"
49
+ }
50
+ ```
51
+
52
+ ### 错误场景
53
+
54
+ | error | 说明 |
55
+ |-------|------|
56
+ | `API "getSettings" not allowed for page "xxx"` | 页面未配置该 API 的调用权限 |
57
+
58
+ ### 返回示例
59
+
60
+ **成功**:
61
+
62
+ ```json
63
+ {
64
+ "ok": true,
65
+ "data": {
66
+ "theme": "dark",
67
+ "language": "zh"
68
+ }
69
+ }
70
+ ```
@@ -0,0 +1,92 @@
1
+ ## getUserInfo()
2
+
3
+ 获取当前登录用户的信息(已脱敏,不包含 token 等敏感数据)。
4
+
5
+ | 属性 | 值 |
6
+ |------|-----|
7
+ | **最小客户端版本** | `1.2.1` |
8
+ | **分类** | 用户信息 |
9
+ | **需要权限** | `getUserInfo` 需在页面 `bridge.allowedApis` 白名单中 |
10
+
11
+ ---
12
+
13
+ ### 签名
14
+
15
+ ```typescript
16
+ getUserInfo(): Promise<BridgeResponse<UserInfo>>
17
+ ```
18
+
19
+ ### 参数
20
+
21
+ 无。
22
+
23
+ ### 返回值
24
+
25
+ `Promise<BridgeResponse<UserInfo>>`
26
+
27
+ **`UserInfo` 类型定义**:
28
+
29
+ ```typescript
30
+ interface UserInfo {
31
+ /** 用户 ID */
32
+ userId: string;
33
+ /** 用户昵称 */
34
+ name: string;
35
+ /** 头像 URL */
36
+ avatar: string;
37
+ /** 登录渠道,>= 1.2.5 */
38
+ loginType?: string;
39
+ /** 服务端扩展信息,>= 1.2.5 */
40
+ extra?: Record<string, unknown>;
41
+ }
42
+ ```
43
+
44
+ ### 示例
45
+
46
+ ```typescript
47
+ import { getBridge } from '@tbox-claw/bridge-sdk';
48
+
49
+ const bridge = getBridge();
50
+ const result = await bridge.getUserInfo();
51
+
52
+ if (result.ok) {
53
+ console.log(result.data.userId); // 如 "12345"
54
+ console.log(result.data.name); // 如 "张三"
55
+ console.log(result.data.avatar); // 头像 URL
56
+ console.log(result.data.loginType); // 如 "dingtalk"(>= 1.2.5)
57
+ console.log(result.data.extra); // 服务端扩展信息(>= 1.2.5)
58
+ }
59
+ ```
60
+
61
+ ### 错误场景
62
+
63
+ | error | 说明 |
64
+ |-------|------|
65
+ | `NOT_AUTHENTICATED` | 用户未登录 |
66
+ | `API "getUserInfo" not allowed for page "xxx"` | 页面未配置该 API 的调用权限 |
67
+
68
+ ### 返回示例
69
+
70
+ **成功**:
71
+
72
+ ```json
73
+ {
74
+ "ok": true,
75
+ "data": {
76
+ "userId": "12345",
77
+ "name": "张三",
78
+ "avatar": "https://example.com/avatar.png",
79
+ "loginType": "dingtalk",
80
+ "extra": {}
81
+ }
82
+ }
83
+ ```
84
+
85
+ **失败(未登录)**:
86
+
87
+ ```json
88
+ {
89
+ "ok": false,
90
+ "error": "NOT_AUTHENTICATED"
91
+ }
92
+ ```
@@ -0,0 +1,104 @@
1
+ ## sendChatMessage(options)
2
+
3
+ 发送对话消息,功能等同于在 Chat 页面输入并发送。嵌入页面可通过此 API 与 AI Agent 进行对话交互。
4
+
5
+ | 属性 | 值 |
6
+ |------|-----|
7
+ | **最小客户端版本** | `1.2.1` |
8
+ | **分类** | 对话消息 |
9
+ | **需要权限** | `sendChatMessage` 需在页面 `bridge.allowedApis` 白名单中 |
10
+
11
+ ---
12
+
13
+ ### 签名
14
+
15
+ ```typescript
16
+ sendChatMessage(options: SendChatMessageOptions): Promise<BridgeResponse<{ runId?: string }>>
17
+ ```
18
+
19
+ ### 参数
20
+
21
+ **`SendChatMessageOptions` 类型定义**:
22
+
23
+ ```typescript
24
+ interface SendChatMessageOptions {
25
+ /** 消息文本内容 */
26
+ message: string;
27
+ /**
28
+ * 页面内的会话标识,用于区分同一页面内的多个独立对话。
29
+ * 省略时默认为 'default'。
30
+ */
31
+ sessionKey?: string;
32
+ }
33
+ ```
34
+
35
+ | 参数 | 类型 | 必填 | 说明 |
36
+ |------|------|:----:|------|
37
+ | `message` | `string` | ✅ | 消息文本内容,不能为空 |
38
+ | `sessionKey` | `string` | ❌ | 页面内的会话标识,默认 `'default'` |
39
+
40
+ ### 返回值
41
+
42
+ `Promise<BridgeResponse<{ runId?: string }>>`
43
+
44
+ 成功时 `data` 中包含本次对话运行的 `runId`,可用于后续追踪对话状态。
45
+
46
+ ### 示例
47
+
48
+ ```typescript
49
+ import { getBridge } from '@tbox-claw/bridge-sdk';
50
+
51
+ const bridge = getBridge();
52
+
53
+ // 使用默认会话发送消息
54
+ const result = await bridge.sendChatMessage({
55
+ message: '帮我分析一下这个数据',
56
+ });
57
+
58
+ if (result.ok) {
59
+ console.log('消息已发送,runId:', result.data?.runId);
60
+ } else {
61
+ console.error('发送失败:', result.error);
62
+ }
63
+
64
+ // 同一页面内使用不同的会话(用于多轮独立对话场景)
65
+ const result2 = await bridge.sendChatMessage({
66
+ message: '这是另一个独立对话',
67
+ sessionKey: 'analysis-task',
68
+ });
69
+ ```
70
+
71
+ ### 错误场景
72
+
73
+ | error | 说明 |
74
+ |-------|------|
75
+ | `API "sendChatMessage" not allowed for page "xxx"` | 页面未配置该 API 的调用权限 |
76
+ | `options must include a non-empty "message" (string)` | 消息内容为空或类型错误 |
77
+ | `Gateway is not available` | Gateway 服务未启动或不可用 |
78
+ | `Gateway RPC failed: chat.send` | Gateway 处理消息时发生错误 |
79
+
80
+ ### 返回示例
81
+
82
+ **成功**:
83
+
84
+ ```json
85
+ {
86
+ "ok": true,
87
+ "data": {
88
+ "runId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
89
+ }
90
+ }
91
+ ```
92
+
93
+ **失败(Gateway 不可用)**:
94
+
95
+ ```json
96
+ {
97
+ "ok": false,
98
+ "error": "Gateway is not available"
99
+ }
100
+ ```
101
+
102
+ ### 注意事项
103
+
104
+ - 如果 Gateway 尚未启动完成(通常需要 10-30 秒),调用会返回错误。
@@ -0,0 +1,94 @@
1
+ ## sendNotification(options)
2
+
3
+ 通过主应用发送系统级桌面通知。嵌入页面可借助此 API 向用户推送操作系统原生通知。
4
+
5
+ | 属性 | 值 |
6
+ |------|-----|
7
+ | **最小客户端版本** | `1.2.1` |
8
+ | **分类** | 系统通知 |
9
+ | **需要权限** | `sendNotification` 需在页面 `bridge.allowedApis` 白名单中 |
10
+
11
+ ---
12
+
13
+ ### 签名
14
+
15
+ ```typescript
16
+ sendNotification(options: SendNotificationOptions): Promise<BridgeResponse<void>>
17
+ ```
18
+
19
+ ### 参数
20
+
21
+ **`SendNotificationOptions` 类型定义**:
22
+
23
+ ```typescript
24
+ interface SendNotificationOptions {
25
+ /** 通知标题 */
26
+ title: string;
27
+ /** 通知正文内容 */
28
+ body: string;
29
+ /** 是否静音(不播放提示音),默认 false */
30
+ silent?: boolean;
31
+ }
32
+ ```
33
+
34
+ | 参数 | 类型 | 必填 | 说明 |
35
+ |------|------|:----:|------|
36
+ | `title` | `string` | ✅ | 通知标题 |
37
+ | `body` | `string` | ✅ | 通知正文内容 |
38
+ | `silent` | `boolean` | ❌ | 是否静音,默认 `false` |
39
+
40
+ ### 返回值
41
+
42
+ `Promise<BridgeResponse<void>>`
43
+
44
+ 成功时返回 `{ ok: true }`,不包含 `data` 字段。
45
+
46
+ ### 示例
47
+
48
+ ```typescript
49
+ import { getBridge } from '@tbox-claw/bridge-sdk';
50
+
51
+ const bridge = getBridge();
52
+ const result = await bridge.sendNotification({
53
+ title: '任务完成',
54
+ body: '你的数据已处理完毕',
55
+ silent: false,
56
+ });
57
+
58
+ if (result.ok) {
59
+ console.log('通知已发送');
60
+ } else {
61
+ console.error('发送失败:', result.error);
62
+ }
63
+ ```
64
+
65
+ ### 错误场景
66
+
67
+ | error | 说明 |
68
+ |-------|------|
69
+ | `API "sendNotification" not allowed for page "xxx"` | 页面未配置该 API 的调用权限 |
70
+ | `options must include "title" (string) and "body" (string)` | 参数缺失或类型错误 |
71
+
72
+ ### 返回示例
73
+
74
+ **成功**:
75
+
76
+ ```json
77
+ {
78
+ "ok": true
79
+ }
80
+ ```
81
+
82
+ **失败(参数错误)**:
83
+
84
+ ```json
85
+ {
86
+ "ok": false,
87
+ "error": "options must include \"title\" (string) and \"body\" (string)"
88
+ }
89
+ ```
90
+
91
+ ### 注意事项
92
+
93
+ - 通知是否实际显示取决于操作系统的通知权限设置。如果用户关闭了应用的通知权限,调用仍会返回成功,但通知不会显示。
94
+ - macOS 和 Windows 的通知样式由操作系统决定,应用无法自定义外观。
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@tbox-claw/bridge-sdk",
3
+ "version": "1.0.0",
4
+ "description": "Bridge SDK for developing embedded pages in TboxClaw desktop app",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "docs",
18
+ "README.md"
19
+ ],
20
+ "scripts": {
21
+ "build": "tsup src/index.ts --format cjs,esm --dts --clean",
22
+ "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
23
+ "prepublishOnly": "pnpm run build"
24
+ },
25
+ "devDependencies": {
26
+ "tsup": "^8.0.0",
27
+ "typescript": "^5.4.0"
28
+ },
29
+ "keywords": [
30
+ "tbox",
31
+ "claw",
32
+ "bridge",
33
+ "sdk",
34
+ "electron",
35
+ "embedded-page"
36
+ ],
37
+ "license": "MIT"
38
+ }