@syllm/brickly-sdk 0.1.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/dist/api.d.ts ADDED
@@ -0,0 +1,412 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import { BppTransport, type BppTransportOptions } from './runtime';
3
+ import { type BrickUiWindowOptions, type BrickWindowNetworkEvent, type BrickWindowMethod, type CommandInvocationContext, type PlatformClipboardReadResult, type PlatformClipboardContent, type PlatformClipboardSetResult, type PlatformInputKeyboardTapPayload, type PlatformInputMousePointPayload, type PlatformScreenCaptureOptions, type PlatformScreenCaptureResult, type PlatformScreenColorPickOptions, type PlatformScreenColorPickResult, type PlatformScreenDesktopCaptureOptions, type PlatformScreenDesktopCaptureSource, type PlatformScreenDisplay, type PlatformScreenPoint, type PlatformScreenRect, type PlatformSystemPathName, type PlatformScreenshotRegionOptions, type PlatformScreenshotResult } from './protocol';
4
+ /**
5
+ * 跨 Brick 命令类型映射,由 typegen 生成的声明文件扩展。
6
+ *
7
+ * 形态:
8
+ * interface CommandMap {
9
+ * 'com.example.foo': {
10
+ * run: { input: { text: string }; output: string }
11
+ * }
12
+ * }
13
+ */
14
+ export interface CommandMap {
15
+ }
16
+ type KnownBrickId = keyof CommandMap & string;
17
+ type KnownCommandId<TBrickId extends KnownBrickId> = keyof CommandMap[TBrickId] & string;
18
+ type CommandShape<TBrickId extends KnownBrickId, TCommandId extends KnownCommandId<TBrickId>> = CommandMap[TBrickId][TCommandId] extends {
19
+ input: infer TInput;
20
+ output: infer TOutput;
21
+ } ? {
22
+ input: TInput;
23
+ output: TOutput;
24
+ } : {
25
+ input: unknown;
26
+ output: unknown;
27
+ };
28
+ type CommandInput<TBrickId extends KnownBrickId, TCommandId extends KnownCommandId<TBrickId>> = CommandShape<TBrickId, TCommandId>['input'];
29
+ type CommandOutput<TBrickId extends KnownBrickId, TCommandId extends KnownCommandId<TBrickId>> = CommandShape<TBrickId, TCommandId>['output'];
30
+ type InvokeReturn<TBrickId extends string, TCommandId extends string, TFallback> = TBrickId extends KnownBrickId ? TCommandId extends KnownCommandId<TBrickId> ? CommandOutput<TBrickId, TCommandId> : TFallback : TFallback;
31
+ type InvokeInput<TBrickId extends string, TCommandId extends string> = TBrickId extends KnownBrickId ? TCommandId extends KnownCommandId<TBrickId> ? CommandInput<TBrickId, TCommandId> : unknown : unknown;
32
+ /** 在 onCommand handler 中可用的上下文对象。 */
33
+ export interface CommandContext {
34
+ /** 当前请求 id(用于 progress / chunk / output 与 cancel 关联)。 */
35
+ readonly requestId: string;
36
+ /** 当前 commandId。 */
37
+ readonly commandId: string;
38
+ /** 本次 command 的可信调用来源。 */
39
+ readonly invocation: CommandInvocationContext;
40
+ /** 注册取消回调;宿主下发 command.cancel 时触发。 */
41
+ onCancel(handler: () => void): void;
42
+ /** 用户协作式取消判断:handler 自行轮询。 */
43
+ isCancelled(): boolean;
44
+ /** 进度(0~1)。 */
45
+ progress(value: number, message?: string): void;
46
+ /** 追加流片段到指定具名输出(省略 name 表示匿名输出)。 */
47
+ chunk(chunk: unknown, name?: string): void;
48
+ /** 一次性覆盖某个具名输出。 */
49
+ output(name: string, value: unknown): void;
50
+ /** 跨 Brick 调用命令。未指定 profileId 时使用目标 Brick 默认 Profile。 */
51
+ invoke<T = unknown, TBrickId extends string = string, TCommandId extends string = string>(brickId: TBrickId, commandId: TCommandId, input?: InvokeInput<TBrickId, TCommandId>, options?: InvokeOptions): Promise<InvokeReturn<TBrickId, TCommandId, T>>;
52
+ /** 跨 Brick 流式调用命令,实时返回目标命令的 progress/chunk/output/result。 */
53
+ invokeStream<TBrickId extends string = string, TCommandId extends string = string>(brickId: TBrickId, commandId: TCommandId, input?: InvokeInput<TBrickId, TCommandId>, options?: InvokeOptions): AsyncIterable<HostInvokeStreamEvent>;
54
+ /** 打开跨 Brick 会话。会话关闭前,宿主保持目标 Brick 实例不被回收。 */
55
+ openSession<TBrickId extends string = string>(brickId: TBrickId, options?: SessionOptions): Promise<BrickSession<TBrickId>>;
56
+ /** 子窗口与事件 API(与 brick.ui / brick.events 同源,便于在 handler 内调用)。 */
57
+ readonly ui: UiApi;
58
+ readonly events: EventsApi;
59
+ readonly platform: PlatformApi;
60
+ /** 由 host.hello.config 注入的当前 Profile 配置快照。 */
61
+ readonly config: Record<string, unknown>;
62
+ }
63
+ export type CommandHandler = (ctx: CommandContext, input: unknown) => unknown | Promise<unknown>;
64
+ export interface InvokeOptions {
65
+ /** 目标 Brick Profile ID;不传则由宿主选择目标 Brick 默认 Profile。 */
66
+ profileId?: string;
67
+ }
68
+ export type HostInvokeStreamEvent = {
69
+ type: 'progress';
70
+ progress: number;
71
+ message?: string;
72
+ } | {
73
+ type: 'chunk';
74
+ name?: string;
75
+ chunk: unknown;
76
+ } | {
77
+ type: 'output';
78
+ name: string;
79
+ value: unknown;
80
+ } | {
81
+ type: 'result';
82
+ result?: unknown;
83
+ } | {
84
+ type: 'error';
85
+ error: unknown;
86
+ };
87
+ export interface SessionOptions {
88
+ /** 目标 Brick Profile ID;不传则由宿主选择目标 Brick 默认 Profile。 */
89
+ profileId?: string;
90
+ }
91
+ export declare class BrickSession<TBrickId extends string = string> {
92
+ private readonly transport;
93
+ readonly id: string;
94
+ readonly brickId: TBrickId;
95
+ readonly profileId?: string | undefined;
96
+ constructor(transport: BppTransport, id: string, brickId: TBrickId, profileId?: string | undefined);
97
+ invoke<T = unknown, TCommandId extends string = string>(commandId: TCommandId, input?: InvokeInput<TBrickId, TCommandId>): Promise<InvokeReturn<TBrickId, TCommandId, T>>;
98
+ close(): Promise<void>;
99
+ }
100
+ /** BrickWindowMethod 中可发送的方法签名。 */
101
+ export interface UiApi {
102
+ /**
103
+ * 创建一个 Brick 子窗口。url 可为 https:// / file:// / 相对 Brick rootDir 的路径。
104
+ * 返回 WindowHandle,可继续调用窗口方法或订阅事件。
105
+ */
106
+ createBrowserWindow(url: string, options?: BrickUiWindowOptions): Promise<WindowHandle>;
107
+ /** 列出本 Brick 持有的子窗口(来自宿主权威视图)。 */
108
+ listWindows(): Promise<unknown[]>;
109
+ }
110
+ /** event.notify 事件订阅 API。 */
111
+ export interface EventsApi {
112
+ /**
113
+ * 订阅事件总线上的事件。返回取消函数。
114
+ * 仅本地路由:宿主侧的实际订阅声明在 manifest.subscriptions 中。
115
+ */
116
+ on(event: string, handler: (payload: unknown, envelope: EventEnvelope) => void): () => void;
117
+ /** 主动发布事件到总线。 */
118
+ publish(event: string, payload?: unknown): Promise<void>;
119
+ }
120
+ export interface PlatformApi {
121
+ screenshot: {
122
+ selectRegion(options?: PlatformScreenshotRegionOptions): Promise<PlatformScreenshotResult>;
123
+ };
124
+ screen: {
125
+ captureRegion(options?: PlatformScreenCaptureOptions): Promise<PlatformScreenCaptureResult>;
126
+ pickColor(options?: PlatformScreenColorPickOptions): Promise<PlatformScreenColorPickResult>;
127
+ getPrimaryDisplay(): Promise<PlatformScreenDisplay>;
128
+ getAllDisplays(): Promise<PlatformScreenDisplay[]>;
129
+ getCursorScreenPoint(): Promise<PlatformScreenPoint>;
130
+ getDisplayNearestPoint(point: PlatformScreenPoint): Promise<PlatformScreenDisplay>;
131
+ getDisplayMatching(rect: PlatformScreenRect): Promise<PlatformScreenDisplay>;
132
+ screenToDipPoint(point: PlatformScreenPoint): Promise<PlatformScreenPoint>;
133
+ dipToScreenPoint(point: PlatformScreenPoint): Promise<PlatformScreenPoint>;
134
+ screenToDipRect(rect: PlatformScreenRect): Promise<PlatformScreenRect>;
135
+ dipToScreenRect(rect: PlatformScreenRect): Promise<PlatformScreenRect>;
136
+ desktopCaptureSources(options: PlatformScreenDesktopCaptureOptions): Promise<PlatformScreenDesktopCaptureSource[]>;
137
+ };
138
+ input: {
139
+ keyboardTap(key: string, ...modifiers: string[]): Promise<void>;
140
+ keyboardTap(payload: PlatformInputKeyboardTapPayload): Promise<void>;
141
+ mouseMove(x: number, y: number): Promise<void>;
142
+ mouseMove(payload: PlatformInputMousePointPayload): Promise<void>;
143
+ mouseClick(x: number, y: number): Promise<void>;
144
+ mouseClick(payload: PlatformInputMousePointPayload): Promise<void>;
145
+ mouseDoubleClick(x: number, y: number): Promise<void>;
146
+ mouseDoubleClick(payload: PlatformInputMousePointPayload): Promise<void>;
147
+ mouseRightClick(x: number, y: number): Promise<void>;
148
+ mouseRightClick(payload: PlatformInputMousePointPayload): Promise<void>;
149
+ };
150
+ clipboard: {
151
+ readContent(): Promise<PlatformClipboardReadResult>;
152
+ setContent(content: PlatformClipboardContent): Promise<PlatformClipboardSetResult>;
153
+ };
154
+ system: {
155
+ showNotification(body: string, clickFeatureCode?: string): Promise<void>;
156
+ shellOpenPath(fullPath: string): Promise<void>;
157
+ shellTrashItem(fullPath: string): Promise<void>;
158
+ shellShowItemInFolder(fullPath: string): Promise<void>;
159
+ shellOpenExternal(url: string): Promise<void>;
160
+ shellBeep(): Promise<void>;
161
+ getNativeId(): Promise<string>;
162
+ getAppName(): Promise<string>;
163
+ getAppVersion(): Promise<string>;
164
+ getPath(name: PlatformSystemPathName): Promise<string>;
165
+ getFileIcon(filePath: string): Promise<string>;
166
+ readCurrentFolderPath(): Promise<string>;
167
+ readCurrentBrowserUrl(): Promise<string>;
168
+ isDev(): Promise<boolean>;
169
+ isMacOS(): Promise<boolean>;
170
+ isWindows(): Promise<boolean>;
171
+ isLinux(): Promise<boolean>;
172
+ };
173
+ }
174
+ export interface EventEnvelope {
175
+ event: string;
176
+ payload: unknown;
177
+ sourceBrickId: string;
178
+ publishedAt: number;
179
+ }
180
+ /** 子窗口句柄。close() 调 host.ui.closeWindow,其余方法走 host.ui.callWindow。 */
181
+ export declare class WindowHandle extends EventEmitter {
182
+ readonly id: number;
183
+ private readonly transport;
184
+ private closed;
185
+ constructor(transport: BppTransport, windowId: number);
186
+ /** 通用:调用窗口白名单方法。 */
187
+ call<T = unknown>(method: BrickWindowMethod, args?: unknown[]): Promise<T>;
188
+ private sendToWebContents;
189
+ /** 订阅该窗口的网络检查事件。需在 createBrowserWindow options.network 中开启。 */
190
+ onNetwork(handler: (event: BrickWindowNetworkEvent) => void): this;
191
+ setBounds(bounds: {
192
+ x?: number;
193
+ y?: number;
194
+ width?: number;
195
+ height?: number;
196
+ }): Promise<void>;
197
+ getBounds(): Promise<{
198
+ x: number;
199
+ y: number;
200
+ width: number;
201
+ height: number;
202
+ }>;
203
+ setPosition(x: number, y: number): Promise<void>;
204
+ getPosition(): Promise<[number, number]>;
205
+ setSize(width: number, height: number): Promise<void>;
206
+ getSize(): Promise<[number, number]>;
207
+ setOpacity(opacity: number): Promise<void>;
208
+ getOpacity(): Promise<number>;
209
+ setBackgroundColor(color: string): Promise<void>;
210
+ setHasShadow(hasShadow: boolean): Promise<void>;
211
+ setTitle(title: string): Promise<void>;
212
+ getTitle(): Promise<string>;
213
+ setAlwaysOnTop(flag: boolean, level?: string): Promise<void>;
214
+ isAlwaysOnTop(): Promise<boolean>;
215
+ setIgnoreMouseEvents(ignore: boolean, opts?: {
216
+ forward?: boolean;
217
+ }): Promise<void>;
218
+ setSkipTaskbar(skip: boolean): Promise<void>;
219
+ setVisibleOnAllWorkspaces(visible: boolean, opts?: {
220
+ visibleOnFullScreen?: boolean;
221
+ }): Promise<void>;
222
+ setResizable(resizable: boolean): Promise<void>;
223
+ setMovable(movable: boolean): Promise<void>;
224
+ setFocusable(focusable: boolean): Promise<void>;
225
+ minimize(): Promise<void>;
226
+ maximize(): Promise<void>;
227
+ unmaximize(): Promise<void>;
228
+ restore(): Promise<void>;
229
+ hide(): Promise<void>;
230
+ show(): Promise<void>;
231
+ showInactive(): Promise<void>;
232
+ focus(): Promise<void>;
233
+ blur(): Promise<void>;
234
+ isDestroyed(): Promise<boolean>;
235
+ isVisible(): Promise<boolean>;
236
+ isFocused(): Promise<boolean>;
237
+ isMinimized(): Promise<boolean>;
238
+ isMaximized(): Promise<boolean>;
239
+ loadURL(url: string, options?: Record<string, unknown>): Promise<void>;
240
+ loadFile(filePath: string, options?: Record<string, unknown>): Promise<void>;
241
+ reload(): Promise<void>;
242
+ setContentBounds(bounds: {
243
+ x?: number;
244
+ y?: number;
245
+ width?: number;
246
+ height?: number;
247
+ }): Promise<void>;
248
+ getContentBounds(): Promise<{
249
+ x: number;
250
+ y: number;
251
+ width: number;
252
+ height: number;
253
+ }>;
254
+ setContentSize(width: number, height: number): Promise<void>;
255
+ getContentSize(): Promise<[number, number]>;
256
+ setMinimumSize(width: number, height: number): Promise<void>;
257
+ getMinimumSize(): Promise<[number, number]>;
258
+ setMaximumSize(width: number, height: number): Promise<void>;
259
+ getMaximumSize(): Promise<[number, number]>;
260
+ setAspectRatio(aspectRatio: number, extraSize?: {
261
+ width: number;
262
+ height: number;
263
+ }): Promise<void>;
264
+ /** 获取窗口在非最大化/全屏/最小化时的"普通"位置和尺寸。 */
265
+ getNormalBounds(): Promise<{
266
+ x: number;
267
+ y: number;
268
+ width: number;
269
+ height: number;
270
+ }>;
271
+ center(): Promise<void>;
272
+ moveTop(): Promise<void>;
273
+ /** mediaSourceId 由 Electron getMediaSourceId 提供;通常在同 Brick 多窗口间使用。 */
274
+ moveAbove(mediaSourceId: string): Promise<void>;
275
+ setFullScreen(flag: boolean): Promise<void>;
276
+ isFullScreen(): Promise<boolean>;
277
+ isNormal(): Promise<boolean>;
278
+ isModal(): Promise<boolean>;
279
+ /** 强制销毁窗口(不触发 close 事件),等价于 BrowserWindow.destroy()。慎用。 */
280
+ destroy(): Promise<void>;
281
+ isResizable(): Promise<boolean>;
282
+ isMovable(): Promise<boolean>;
283
+ isFocusable(): Promise<boolean>;
284
+ setMinimizable(flag: boolean): Promise<void>;
285
+ isMinimizable(): Promise<boolean>;
286
+ setMaximizable(flag: boolean): Promise<void>;
287
+ isMaximizable(): Promise<boolean>;
288
+ setClosable(flag: boolean): Promise<void>;
289
+ isClosable(): Promise<boolean>;
290
+ setFullScreenable(flag: boolean): Promise<void>;
291
+ isFullScreenable(): Promise<boolean>;
292
+ setEnabled(enabled: boolean): Promise<void>;
293
+ isEnabled(): Promise<boolean>;
294
+ hasShadow(): Promise<boolean>;
295
+ isVisibleOnAllWorkspaces(): Promise<boolean>;
296
+ setKiosk(flag: boolean): Promise<void>;
297
+ isKiosk(): Promise<boolean>;
298
+ flashFrame(flag: boolean): Promise<void>;
299
+ /**
300
+ * 任务栏进度条。progress:[0,1] 显示进度;-1 关闭;>1 不确定。
301
+ * options.mode: 'none' | 'normal' | 'indeterminate' | 'error' | 'paused'。
302
+ */
303
+ setProgressBar(progress: number, options?: {
304
+ mode?: 'none' | 'normal' | 'indeterminate' | 'error' | 'paused';
305
+ }): Promise<void>;
306
+ setMenuBarVisibility(visible: boolean): Promise<void>;
307
+ isMenuBarVisible(): Promise<boolean>;
308
+ setAutoHideMenuBar(hide: boolean): Promise<void>;
309
+ isMenuBarAutoHide(): Promise<boolean>;
310
+ removeMenu(): Promise<void>;
311
+ /** macOS 透明窗口在内容大小变化后需手动失效阴影。 */
312
+ invalidateShadow(): Promise<void>;
313
+ setRepresentedFilename(path: string): Promise<void>;
314
+ getRepresentedFilename(): Promise<string>;
315
+ setDocumentEdited(edited: boolean): Promise<void>;
316
+ isDocumentEdited(): Promise<boolean>;
317
+ /**
318
+ * 类 Electron 风格的 webContents 子对象。等价于直接调用 `webContentsSend` 等方法,
319
+ * 但写法更接近 uTools / Electron 原生:`win.webContents.send('ch', payload)`。
320
+ */
321
+ readonly webContents: {
322
+ send: (channel: string, ...args: unknown[]) => Promise<void>;
323
+ executeJavaScript: (code: string, userGesture?: boolean) => Promise<unknown>;
324
+ openDevTools: (options?: {
325
+ mode?: "left" | "right" | "bottom" | "undocked" | "detach";
326
+ }) => Promise<void>;
327
+ closeDevTools: () => Promise<void>;
328
+ toggleDevTools: () => Promise<void>;
329
+ isDevToolsOpened: () => Promise<boolean>;
330
+ goBack: () => Promise<void>;
331
+ goForward: () => Promise<void>;
332
+ canGoBack: () => Promise<boolean>;
333
+ canGoForward: () => Promise<boolean>;
334
+ getURL: () => Promise<string>;
335
+ getTitle: () => Promise<string>;
336
+ setZoomFactor: (factor: number) => Promise<void>;
337
+ getZoomFactor: () => Promise<number>;
338
+ setZoomLevel: (level: number) => Promise<void>;
339
+ getZoomLevel: () => Promise<number>;
340
+ copy: () => Promise<void>;
341
+ paste: () => Promise<void>;
342
+ cut: () => Promise<void>;
343
+ selectAll: () => Promise<void>;
344
+ undo: () => Promise<void>;
345
+ redo: () => Promise<void>;
346
+ };
347
+ /** webContents.send 旧别名,保留向后兼容。新代码请用 `win.webContents.send(...)`。 */
348
+ webContentsSend(channel: string, ...args: unknown[]): Promise<void>;
349
+ /** 关闭窗口(不可逆)。走 host.ui.closeWindow,而非白名单 close 方法。 */
350
+ close(): Promise<void>;
351
+ /** 内部:由 BricklyRuntime 在收到对应 window.* 事件时调用。 */
352
+ _emit(eventName: string, payload: unknown): void;
353
+ }
354
+ export interface BricklyRuntimeOptions extends BppTransportOptions {
355
+ /** 协议版本;默认 SDK 内置 PROTOCOL_VERSION。 */
356
+ protocolVersion?: string;
357
+ }
358
+ /**
359
+ * Brick SDK 主入口。典型用法:
360
+ *
361
+ * const brick = new BricklyRuntime({ brickId: 'com.example.foo' })
362
+ * brick.onCommand('do-it', async (ctx, input) => { ... })
363
+ * brick.onReady(async () => { ... })
364
+ * brick.start()
365
+ */
366
+ export declare class BricklyRuntime {
367
+ readonly brickId: string;
368
+ readonly transport: BppTransport;
369
+ private readonly protocolVersion;
370
+ private readonly commandHandlers;
371
+ private readonly cancelHandlers;
372
+ private readonly cancelled;
373
+ private readonly eventListeners;
374
+ private readonly windows;
375
+ private readyHandler?;
376
+ private shutdownHandler?;
377
+ private config;
378
+ private started;
379
+ private exiting;
380
+ private hostPidWatchdog?;
381
+ constructor(opts: BricklyRuntimeOptions);
382
+ /** 注册 command 处理器。 */
383
+ onCommand(commandId: string, handler: CommandHandler): this;
384
+ /** 注册 runtime.ready 之后立即执行的钩子(适合 host-start service 或实例初始化逻辑)。 */
385
+ onReady(handler: () => unknown | Promise<unknown>): this;
386
+ /** 注册 runtime.shutdown 处理逻辑;返回后 SDK 自动发送 runtime.bye 并退出。 */
387
+ onShutdown(handler: () => unknown | Promise<unknown>): this;
388
+ /** 子窗口 / UI API。 */
389
+ readonly ui: UiApi;
390
+ /** 事件订阅 API。 */
391
+ readonly events: EventsApi;
392
+ /** 宿主平台能力 API。 */
393
+ readonly platform: PlatformApi;
394
+ /** 启动 stdin 循环。 */
395
+ start(): this;
396
+ /** 停止 stdin 循环(一般不需要主动调,runtime.shutdown 会自动处理)。 */
397
+ stop(): void;
398
+ /** 跨 Brick 调用命令。宿主会自动管理目标 Brick 实例生命周期。 */
399
+ invoke<T = unknown, TBrickId extends string = string, TCommandId extends string = string>(brickId: TBrickId, commandId: TCommandId, input?: InvokeInput<TBrickId, TCommandId>, options?: InvokeOptions): Promise<InvokeReturn<TBrickId, TCommandId, T>>;
400
+ invokeRoot<T = unknown, TBrickId extends string = string, TCommandId extends string = string>(brickId: TBrickId, commandId: TCommandId, input?: InvokeInput<TBrickId, TCommandId>, options?: InvokeOptions): Promise<InvokeReturn<TBrickId, TCommandId, T>>;
401
+ invokeStream<TBrickId extends string = string, TCommandId extends string = string>(brickId: TBrickId, commandId: TCommandId, input?: InvokeInput<TBrickId, TCommandId>, options?: InvokeOptions): AsyncIterable<HostInvokeStreamEvent>;
402
+ private hostInvokeStream;
403
+ openSession<TBrickId extends string = string>(brickId: TBrickId, options?: SessionOptions): Promise<BrickSession<TBrickId>>;
404
+ private handleHello;
405
+ private handleCommand;
406
+ private handleEvent;
407
+ private handleShutdown;
408
+ private handleHostDisconnect;
409
+ private startHostPidWatchdog;
410
+ private buildContext;
411
+ }
412
+ export {};