dsh-deeppilot 0.9.1 → 0.9.3
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/docs/DSH_RELEASE_MEMORY.md +217 -0
- package/lib/client.js +488 -209
- package/lib/client.js.map +1 -1
- package/lib/index.d.ts +250 -86
- package/lib/index.js +7007 -5971
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
package/lib/index.d.ts
CHANGED
|
@@ -1,39 +1,238 @@
|
|
|
1
|
-
import { Context } from "@deepseek-ai/cordis";
|
|
2
1
|
import z from "@deepseek-ai/schemastery";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
import { Context } from "@deepseek-ai/cordis";
|
|
3
|
+
//#region src/wire-errors.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* 错误词表(error vocabulary)的唯一属主。
|
|
6
|
+
*
|
|
7
|
+
* 一条失败信息在系统里要过三种词汇:Host 控制器返回的错误码(`session-not-found`、
|
|
8
|
+
* `schedule_conflict`……)、Bridge 结果里的状态、以及 wire 上的 `E_*` 码。
|
|
9
|
+
* 此前这三层各有映射函数(host-bridge 里 5 个、connection-policy 里 2 个、
|
|
10
|
+
* connection.ts 的 switch 里 5 处内联三元链),一处漂移就会让客户端对
|
|
11
|
+
* 「该不该重试」的判断失真。
|
|
12
|
+
*
|
|
13
|
+
* 本 module 只做一次翻译:每个域一张「Host code -> wire code」表,
|
|
14
|
+
* Bridge 的结果直接携带 wire 码。`E_BUSY` 与 `E_PROTOCOL` 决定客户端是否
|
|
15
|
+
* 重试,因此这张表是 wire 行为的一部分,逐码都有测试把守。
|
|
16
|
+
*
|
|
17
|
+
* 规范见 PROTOCOL.md 错误码表(`E_PROTOCOL` = 未知类型或非法 payload,
|
|
18
|
+
* `E_FORBIDDEN` = 权限不足,`E_UNSUPPORTED` = 能力缺失)。
|
|
19
|
+
*/
|
|
20
|
+
/** wire 错误码及其规范描述;PROTOCOL.md 错误码表的 TS 镜像。 */
|
|
21
|
+
declare const ERROR_CODES: {
|
|
22
|
+
readonly E_AUTH: 'device proof missing or invalid';
|
|
23
|
+
readonly E_FORBIDDEN: 'device scope does not allow this operation';
|
|
24
|
+
readonly E_PROTOCOL: 'unknown type or malformed payload';
|
|
25
|
+
readonly E_NOT_FOUND: 'session or request not found';
|
|
26
|
+
readonly E_BUSY: 'session is busy';
|
|
27
|
+
readonly E_UNSUPPORTED: 'protocol version or capability unsupported';
|
|
28
|
+
readonly E_INTERNAL: 'internal error';
|
|
29
|
+
};
|
|
30
|
+
type WireErrorCode = keyof typeof ERROR_CODES;
|
|
31
|
+
//#endregion
|
|
32
|
+
//#region src/dispatch-journal.d.ts
|
|
33
|
+
/** 落盘条目:两个通用字段 + codec 私有字段。 */
|
|
34
|
+
interface JournalEntry {
|
|
35
|
+
fingerprint: string;
|
|
36
|
+
createdAt: number;
|
|
37
|
+
[field: string]: unknown;
|
|
38
|
+
}
|
|
39
|
+
/** operation 的结果:成功带值,失败带 wire 错误码。 */
|
|
40
|
+
type OperationResult<T = unknown> = {
|
|
41
|
+
ok: true;
|
|
42
|
+
value: T;
|
|
43
|
+
} | {
|
|
44
|
+
ok: false;
|
|
45
|
+
code: WireErrorCode;
|
|
46
|
+
message?: string;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* 一切「不看条目就能定」的结果类别。codec 用一个方法把它们翻译成自己的方言,
|
|
50
|
+
* 而不是让核心知道任何一方的形状。
|
|
51
|
+
*/
|
|
52
|
+
type DispatchOutcome =
|
|
53
|
+
/** 命中既有条目(重放)。 */
|
|
54
|
+
{
|
|
55
|
+
kind: 'replay';
|
|
56
|
+
entry: JournalEntry;
|
|
57
|
+
} |
|
|
58
|
+
/** 同一 id 搭不同内容。 */
|
|
59
|
+
{
|
|
60
|
+
kind: 'mismatch';
|
|
61
|
+
} |
|
|
62
|
+
/** 构造期解析失败:journal 已永久降级,本次进程不再投递。 */
|
|
63
|
+
{
|
|
64
|
+
kind: 'unavailable';
|
|
65
|
+
} |
|
|
66
|
+
/** id 的纪元前缀超出保留窗口。 */
|
|
67
|
+
{
|
|
68
|
+
kind: 'expired';
|
|
69
|
+
} |
|
|
70
|
+
/** 条目数已达容量上限。 */
|
|
71
|
+
{
|
|
72
|
+
kind: 'full';
|
|
73
|
+
} |
|
|
74
|
+
/** 刚跑完的那一次:operation 的结果原样带出(不标 replayed)。 */
|
|
75
|
+
{
|
|
76
|
+
kind: 'ran';
|
|
77
|
+
entry: JournalEntry;
|
|
78
|
+
result: OperationResult;
|
|
79
|
+
} |
|
|
80
|
+
/** operation 抛错:条目保持 unknown,且不得自动重试。 */
|
|
81
|
+
{
|
|
82
|
+
kind: 'crashed';
|
|
83
|
+
} |
|
|
84
|
+
/**
|
|
85
|
+
* 预留条目时落盘失败——上游**没有**被调用,但无从判断 rename 是否已经
|
|
86
|
+
* 生效(save() 可能在 rename 之后才抛),因此条目留在内存里按 unknown 处理。
|
|
87
|
+
*/
|
|
88
|
+
{
|
|
89
|
+
kind: 'reserve-failed';
|
|
90
|
+
} |
|
|
91
|
+
/** id 形状不合法(仅 mutation 变体开启这道守卫)。 */
|
|
92
|
+
{
|
|
93
|
+
kind: 'invalid-id';
|
|
94
|
+
};
|
|
95
|
+
interface DispatchCodec<TRequest = unknown, TResult = unknown> {
|
|
96
|
+
/** 实例身份:opener 单例键的一部分(含 persistValues 等变体差异)。 */
|
|
97
|
+
readonly identity: string;
|
|
98
|
+
/** 请求指纹。prompt 覆盖 [sessionId, content];mutation 只覆盖 content。 */
|
|
99
|
+
fingerprint(request: TRequest): string;
|
|
100
|
+
/** 预留条目时写入的 codec 字段(fingerprint/createdAt 由核心补)。 */
|
|
101
|
+
reserve(request: TRequest, id: string): Record<string, unknown>;
|
|
102
|
+
/** operation 成功后就地更新条目。 */
|
|
103
|
+
accepted(entry: JournalEntry, id: string, value: unknown): void;
|
|
104
|
+
/** operation 失败后就地更新条目。 */
|
|
105
|
+
rejected(entry: JournalEntry, id: string, code: WireErrorCode): void;
|
|
106
|
+
/** 把结果类别翻译成调用方言。 */
|
|
107
|
+
resultOf(outcome: DispatchOutcome, id: string): TResult;
|
|
108
|
+
/** id 非法时是否先拒掉(mutation 是;prompt 由 wire 层保证,故否)。 */
|
|
109
|
+
readonly requiresValidId?: boolean;
|
|
110
|
+
/** lookup 的匹配规则;缺省表示该实例不提供 lookup。 */
|
|
111
|
+
matches?(entry: JournalEntry, request: unknown): boolean;
|
|
112
|
+
/** lookup 未命中时回什么(prompt 要区分 notFound / expired)。 */
|
|
113
|
+
miss?(id: string, expired: boolean): TResult;
|
|
114
|
+
/** 落盘容器 → 内存条目表;任何不合法都抛错(核心转成 healthy=false)。 */
|
|
115
|
+
parse(raw: unknown): Record<string, JournalEntry>;
|
|
116
|
+
/** 内存条目表 → 落盘容器。 */
|
|
117
|
+
serialize(entries: Record<string, JournalEntry>): unknown;
|
|
118
|
+
}
|
|
119
|
+
interface DispatchJournalOptions<TRequest = unknown, TResult = unknown> {
|
|
120
|
+
codec: DispatchCodec<TRequest, TResult>;
|
|
121
|
+
path?: string;
|
|
122
|
+
/** 落盘体积上限:prompt 8MB、mutation 4MB(由条目实际大小决定,不统一)。 */
|
|
123
|
+
maxFileBytes?: number;
|
|
124
|
+
capacity?: number;
|
|
125
|
+
retentionMs?: number;
|
|
126
|
+
/**
|
|
127
|
+
* 并发重复是否搭同在途那次。prompt 是(重复方拿到同一个最终回执);
|
|
128
|
+
* mutation 否(重复方立刻拿到 unknown → E_INTERNAL)。两者都由对等快照钉住。
|
|
129
|
+
*/
|
|
130
|
+
joinInFlight?: boolean;
|
|
131
|
+
/**
|
|
132
|
+
* 落盘失败的诊断输出。由调用方注入它已有的 logger;缺省即静默。
|
|
133
|
+
* 只打阶段与 errno,绝不打条目内容或消息体(plugin 的日志禁令)。
|
|
134
|
+
*/
|
|
135
|
+
log?: (message: string) => void;
|
|
136
|
+
/**
|
|
137
|
+
* 目录 fsync 里「对 fd 调用 fsync」这一步的覆盖点,缺省即 `fsyncSync`。
|
|
138
|
+
*
|
|
139
|
+
* 存在的唯一理由是可测:Linux CI 上复现不出 Windows 的 EPERM。注入点刻意
|
|
140
|
+
* 停在 fd 这一层而不是替换整个目录 fsync——容忍 EPERM 的判断必须留在真实
|
|
141
|
+
* 路径里被测到,换掉整函数就等于把待测逻辑一起换掉了。
|
|
142
|
+
*/
|
|
143
|
+
fsyncFileDescriptor?: (fd: number) => void;
|
|
10
144
|
}
|
|
11
145
|
/** Durable at-most-once dispatch. Unknown outcomes are never automatically retried. */
|
|
12
|
-
declare class
|
|
13
|
-
private readonly
|
|
14
|
-
private readonly capacity;
|
|
146
|
+
declare class DispatchJournal<TRequest = unknown, TResult = unknown> {
|
|
147
|
+
private readonly options;
|
|
15
148
|
private entries;
|
|
16
149
|
private inFlight;
|
|
150
|
+
/** 只由构造期的解析失败置位,见下方 catch;运行期落盘失败不碰它。 */
|
|
17
151
|
private healthy;
|
|
18
|
-
|
|
152
|
+
private readonly maxFileBytes;
|
|
153
|
+
private readonly capacity;
|
|
154
|
+
private readonly retentionMs;
|
|
155
|
+
private readonly joinInFlight;
|
|
156
|
+
constructor(options: DispatchJournalOptions<TRequest, TResult>);
|
|
19
157
|
private key;
|
|
158
|
+
/** id 的纪元前缀是否还在保留窗口内(未来 5 分钟以上同样算非法)。 */
|
|
20
159
|
private expired;
|
|
21
160
|
private save;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
161
|
+
/**
|
|
162
|
+
* 落盘一次,失败只报不降级。
|
|
163
|
+
*
|
|
164
|
+
* 与 `healthy` 的分工:`healthy` 只由构造期的解析失败置位,运行期的磁盘错误
|
|
165
|
+
* 不再拉黑整个进程——此前一次 save() 失败就让本进程余下的所有投递永久返回
|
|
166
|
+
* unknown,直到 DSH 重启(issue #20 / #26)。现在只影响当次投递,下一次
|
|
167
|
+
* dispatch 会重新尝试。
|
|
168
|
+
*/
|
|
169
|
+
private persist;
|
|
170
|
+
/** 查询既有回执;`request` 交给 codec 的 matches 判定(缺省即不提供 lookup)。 */
|
|
171
|
+
lookup(deviceId: string, id: string, request?: unknown): TResult | undefined;
|
|
172
|
+
/**
|
|
173
|
+
* 幂等投递。未知结果绝不自动重试:条目保持 unknown,重放时由 codec 决定
|
|
174
|
+
* 调用方看到什么。
|
|
175
|
+
*/
|
|
176
|
+
dispatch(deviceId: string, id: string, request: TRequest, operation: () => Promise<OperationResult>): Promise<TResult>;
|
|
177
|
+
/** 等所有在途投递结束;供进程收尾。 */
|
|
178
|
+
settled(): Promise<void>;
|
|
179
|
+
}
|
|
180
|
+
/** prompt 投递的回执:手机侧按 clientSendId 对账。 */
|
|
181
|
+
type DeliveryStatus = 'accepted' | 'rejected' | 'unknown' | 'notFound' | 'expired';
|
|
182
|
+
interface DeliveryReceipt {
|
|
183
|
+
clientSendId: string;
|
|
184
|
+
status: DeliveryStatus;
|
|
185
|
+
userSeq?: number;
|
|
186
|
+
code?: string;
|
|
30
187
|
}
|
|
188
|
+
/** mutation 的结果:replayed 让调用方知道这是重放而非新执行。 */
|
|
189
|
+
type MutationErrorCode = WireErrorCode;
|
|
190
|
+
type MutationDispatchResult<T> = {
|
|
191
|
+
ok: true;
|
|
192
|
+
value?: T;
|
|
193
|
+
replayed?: boolean;
|
|
194
|
+
} | {
|
|
195
|
+
ok: false;
|
|
196
|
+
code: MutationErrorCode;
|
|
197
|
+
message?: string;
|
|
198
|
+
replayed?: boolean;
|
|
199
|
+
};
|
|
31
200
|
//#endregion
|
|
32
201
|
//#region src/device-auth.d.ts
|
|
33
202
|
declare const DEVICE_SCOPES: readonly ['sessions.read', 'prompt.send', 'sessions.manage', 'interactions.respond', 'notifications.register', 'schedule.manage'];
|
|
34
203
|
type DeviceScope = (typeof DEVICE_SCOPES)[number];
|
|
35
204
|
//#endregion
|
|
36
205
|
//#region src/protocol.d.ts
|
|
206
|
+
interface WelcomeCapabilities {
|
|
207
|
+
historyPaging: boolean;
|
|
208
|
+
replay: boolean;
|
|
209
|
+
approvals: boolean;
|
|
210
|
+
questions: boolean;
|
|
211
|
+
/** Client can request the complete currently-pending approval/question set. */
|
|
212
|
+
pendingSnapshot?: boolean;
|
|
213
|
+
promptDelivery?: boolean;
|
|
214
|
+
/** Bridge emits s2c.notify for all four notification categories. */
|
|
215
|
+
notifyAllCategories?: boolean;
|
|
216
|
+
models: boolean;
|
|
217
|
+
sessionManagement: boolean;
|
|
218
|
+
/** Bridge can fork a session at an exact event boundary. */
|
|
219
|
+
sessionFork?: boolean;
|
|
220
|
+
/** Bridge can list archived sessions and restore them
|
|
221
|
+
* (c2s.sessions.archived / c2s.session.unarchive). Absent on hosts whose
|
|
222
|
+
* workspace controller predates unarchiveSession. */
|
|
223
|
+
sessionRestore?: boolean;
|
|
224
|
+
projectSelection: boolean;
|
|
225
|
+
/** Host exposes the optional DSH Schedule service. */
|
|
226
|
+
schedules?: boolean;
|
|
227
|
+
/** Bridge has APNs configured; clients may send c2s.push.register. */
|
|
228
|
+
push?: boolean;
|
|
229
|
+
widgetPush?: boolean;
|
|
230
|
+
liveActivityPush?: boolean;
|
|
231
|
+
/** Bridge accepts c2s.device.revoke, letting a client unbind itself before
|
|
232
|
+
* deleting its local credentials. Absent on older bridges; older clients
|
|
233
|
+
* ignore the extra field. */
|
|
234
|
+
deviceRevoke?: boolean;
|
|
235
|
+
}
|
|
37
236
|
type SessionStatus = "running" | "idle" | "error" | "unknown";
|
|
38
237
|
/**
|
|
39
238
|
* Cumulative model/token statistics for one session, mirrored from the
|
|
@@ -435,12 +634,17 @@ interface HostSessionModels {
|
|
|
435
634
|
message: string;
|
|
436
635
|
}>;
|
|
437
636
|
}
|
|
637
|
+
/**
|
|
638
|
+
* Bridge 方法的结果。失败直接携带 wire 错误码(error vocabulary 见
|
|
639
|
+
* wire-errors.ts):调用方(wire-registry 的行)原样透给手机,不再经过
|
|
640
|
+
* kind 中间层翻译。
|
|
641
|
+
*/
|
|
438
642
|
type ModelBridgeResult<T> = {
|
|
439
643
|
ok: true;
|
|
440
644
|
value: T;
|
|
441
645
|
} | {
|
|
442
646
|
ok: false;
|
|
443
|
-
|
|
647
|
+
code: WireErrorCode;
|
|
444
648
|
message: string;
|
|
445
649
|
};
|
|
446
650
|
type SessionManagementResult<T> = {
|
|
@@ -448,7 +652,7 @@ type SessionManagementResult<T> = {
|
|
|
448
652
|
value: T;
|
|
449
653
|
} | {
|
|
450
654
|
ok: false;
|
|
451
|
-
|
|
655
|
+
code: WireErrorCode;
|
|
452
656
|
message: string;
|
|
453
657
|
};
|
|
454
658
|
interface PromptArgs {
|
|
@@ -597,62 +801,30 @@ interface PromptDocument {
|
|
|
597
801
|
truncated?: boolean;
|
|
598
802
|
}
|
|
599
803
|
//#endregion
|
|
600
|
-
//#region src/
|
|
601
|
-
type MutationErrorCode = 'E_PROTOCOL' | 'E_NOT_FOUND' | 'E_BUSY' | 'E_UNSUPPORTED' | 'E_INTERNAL';
|
|
602
|
-
type MutationOperationResult<T> = {
|
|
603
|
-
ok: true;
|
|
604
|
-
value: T;
|
|
605
|
-
} | {
|
|
606
|
-
ok: false;
|
|
607
|
-
code: MutationErrorCode;
|
|
608
|
-
message?: string;
|
|
609
|
-
};
|
|
610
|
-
type MutationDispatchResult<T> = {
|
|
611
|
-
ok: true;
|
|
612
|
-
value?: T;
|
|
613
|
-
replayed?: boolean;
|
|
614
|
-
} | {
|
|
615
|
-
ok: false;
|
|
616
|
-
code: MutationErrorCode;
|
|
617
|
-
message?: string;
|
|
618
|
-
replayed?: boolean;
|
|
619
|
-
};
|
|
804
|
+
//#region src/host-bridge.d.ts
|
|
620
805
|
/**
|
|
621
|
-
*
|
|
806
|
+
* 失败结果直接携带 wire 错误码(error vocabulary 见 wire-errors.ts)。
|
|
622
807
|
*
|
|
623
|
-
*
|
|
624
|
-
*
|
|
625
|
-
*
|
|
626
|
-
*
|
|
627
|
-
* prompts or conversation data in a second journal.
|
|
808
|
+
* 迁移前这里有 kind 中间层('not-found' | 'busy' | 'conflict' | 'invalid'…),
|
|
809
|
+
* 由 5 个映射函数在「Host code ↔ kind ↔ E_*」之间来回翻译,其中
|
|
810
|
+
* E_BUSY→conflict→E_BUSY 的往返已证明有损。现在每个域查一次表,调用方拿到的
|
|
811
|
+
* 就是手机上会看到的错误码。
|
|
628
812
|
*/
|
|
629
|
-
declare class MutationJournal {
|
|
630
|
-
private readonly path?;
|
|
631
|
-
private readonly persistValues;
|
|
632
|
-
private readonly entries;
|
|
633
|
-
private readonly inFlight;
|
|
634
|
-
private healthy;
|
|
635
|
-
constructor(path?: string | undefined, persistValues?: boolean);
|
|
636
|
-
private key;
|
|
637
|
-
private expired;
|
|
638
|
-
private save;
|
|
639
|
-
dispatch<T>(deviceId: string, id: string, content: unknown, operation: () => Promise<MutationOperationResult<T>>): Promise<MutationDispatchResult<T>>;
|
|
640
|
-
}
|
|
641
|
-
//#endregion
|
|
642
|
-
//#region src/host-bridge.d.ts
|
|
643
813
|
type ScheduleBridgeResult<T> = {
|
|
644
814
|
ok: true;
|
|
645
815
|
value: T;
|
|
646
816
|
replayed?: boolean;
|
|
647
817
|
} | {
|
|
648
818
|
ok: false;
|
|
649
|
-
|
|
819
|
+
code: WireErrorCode;
|
|
650
820
|
message: string;
|
|
651
821
|
replayed?: boolean;
|
|
652
822
|
};
|
|
653
823
|
declare class HostBridge {
|
|
654
824
|
private readonly apiProxy;
|
|
655
825
|
private readonly historyBufferMax;
|
|
826
|
+
/** 三个 journal 的落盘失败诊断输出;缺省即静默。不打任何消息体。 */
|
|
827
|
+
private readonly log?;
|
|
656
828
|
readonly id: number;
|
|
657
829
|
private summaries;
|
|
658
830
|
private activeTools;
|
|
@@ -670,10 +842,15 @@ declare class HostBridge {
|
|
|
670
842
|
private abort;
|
|
671
843
|
private started;
|
|
672
844
|
private disposed;
|
|
673
|
-
readonly promptDeliveries:
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
845
|
+
readonly promptDeliveries: DispatchJournal<{
|
|
846
|
+
sessionId: string;
|
|
847
|
+
content: unknown;
|
|
848
|
+
}, DeliveryReceipt>;
|
|
849
|
+
readonly scheduleMutations: DispatchJournal<unknown, MutationDispatchResult<unknown>>;
|
|
850
|
+
readonly forkMutations: DispatchJournal<unknown, MutationDispatchResult<unknown>>;
|
|
851
|
+
constructor(apiProxy: ApiProxyLike, historyBufferMax?: number, deliveryJournalPath?: string, scheduleJournalPath?: string, forkJournalPath?: string,
|
|
852
|
+
/** 三个 journal 的落盘失败诊断输出;缺省即静默。不打任何消息体。 */
|
|
853
|
+
log?: ((message: string) => void) | undefined);
|
|
677
854
|
private pushOutlet;
|
|
678
855
|
private widgetFingerprint;
|
|
679
856
|
/**
|
|
@@ -681,25 +858,12 @@ declare class HostBridge {
|
|
|
681
858
|
* capability and notify-worthy events are mirrored to APNs.
|
|
682
859
|
*/
|
|
683
860
|
setPushOutlet(outlet: PushOutlet | undefined): void;
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
promptDelivery: boolean;
|
|
691
|
-
notifyAllCategories: boolean;
|
|
692
|
-
models: boolean;
|
|
693
|
-
sessionManagement: boolean;
|
|
694
|
-
sessionFork: boolean;
|
|
695
|
-
sessionRestore: boolean;
|
|
696
|
-
projectSelection: boolean;
|
|
697
|
-
schedules: boolean;
|
|
698
|
-
push: boolean;
|
|
699
|
-
widgetPush: boolean;
|
|
700
|
-
liveActivityPush: boolean;
|
|
701
|
-
deviceRevoke: boolean;
|
|
702
|
-
};
|
|
861
|
+
/**
|
|
862
|
+
* welcome 能力位。委托 host-capabilities.ts 的探测表:此前同一条事实在这里
|
|
863
|
+
* 和各方法体内各存一份,已经漂移过两次(models 位过严、schedules 位与
|
|
864
|
+
* schedule 方法的探测不同源)。
|
|
865
|
+
*/
|
|
866
|
+
get capabilities(): WelcomeCapabilities;
|
|
703
867
|
diagnostic(message: string): void;
|
|
704
868
|
currentCursor(): number;
|
|
705
869
|
addSink(sink: BridgeSink): void;
|