dsh-deeppilot 0.9.1 → 0.9.2

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/lib/index.d.ts CHANGED
@@ -1,39 +1,212 @@
1
- import { Context } from "@deepseek-ai/cordis";
2
1
  import z from "@deepseek-ai/schemastery";
3
- //#region src/prompt-delivery.d.ts
4
- type DeliveryStatus = 'accepted' | 'rejected' | 'unknown' | 'notFound' | 'expired';
5
- interface DeliveryReceipt {
6
- clientSendId: string;
7
- status: DeliveryStatus;
8
- userSeq?: number;
9
- code?: string;
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
+ {
86
+ kind: 'reserve-failed';
87
+ } |
88
+ /** id 形状不合法(仅 mutation 变体开启这道守卫)。 */
89
+ {
90
+ kind: 'invalid-id';
91
+ };
92
+ interface DispatchCodec<TRequest = unknown, TResult = unknown> {
93
+ /** 实例身份:opener 单例键的一部分(含 persistValues 等变体差异)。 */
94
+ readonly identity: string;
95
+ /** 请求指纹。prompt 覆盖 [sessionId, content];mutation 只覆盖 content。 */
96
+ fingerprint(request: TRequest): string;
97
+ /** 预留条目时写入的 codec 字段(fingerprint/createdAt 由核心补)。 */
98
+ reserve(request: TRequest, id: string): Record<string, unknown>;
99
+ /** operation 成功后就地更新条目。 */
100
+ accepted(entry: JournalEntry, id: string, value: unknown): void;
101
+ /** operation 失败后就地更新条目。 */
102
+ rejected(entry: JournalEntry, id: string, code: WireErrorCode): void;
103
+ /** 把结果类别翻译成调用方言。 */
104
+ resultOf(outcome: DispatchOutcome, id: string): TResult;
105
+ /** id 非法时是否先拒掉(mutation 是;prompt 由 wire 层保证,故否)。 */
106
+ readonly requiresValidId?: boolean;
107
+ /** lookup 的匹配规则;缺省表示该实例不提供 lookup。 */
108
+ matches?(entry: JournalEntry, request: unknown): boolean;
109
+ /** lookup 未命中时回什么(prompt 要区分 notFound / expired)。 */
110
+ miss?(id: string, expired: boolean): TResult;
111
+ /** 落盘容器 → 内存条目表;任何不合法都抛错(核心转成 healthy=false)。 */
112
+ parse(raw: unknown): Record<string, JournalEntry>;
113
+ /** 内存条目表 → 落盘容器。 */
114
+ serialize(entries: Record<string, JournalEntry>): unknown;
115
+ }
116
+ interface DispatchJournalOptions<TRequest = unknown, TResult = unknown> {
117
+ codec: DispatchCodec<TRequest, TResult>;
118
+ path?: string;
119
+ /** 落盘体积上限:prompt 8MB、mutation 4MB(由条目实际大小决定,不统一)。 */
120
+ maxFileBytes?: number;
121
+ capacity?: number;
122
+ retentionMs?: number;
123
+ /**
124
+ * 并发重复是否搭同在途那次。prompt 是(重复方拿到同一个最终回执);
125
+ * mutation 否(重复方立刻拿到 unknown → E_INTERNAL)。两者都由对等快照钉住。
126
+ */
127
+ joinInFlight?: boolean;
10
128
  }
11
129
  /** Durable at-most-once dispatch. Unknown outcomes are never automatically retried. */
12
- declare class PromptDeliveryJournal {
13
- private readonly path?;
14
- private readonly capacity;
130
+ declare class DispatchJournal<TRequest = unknown, TResult = unknown> {
131
+ private readonly options;
15
132
  private entries;
16
133
  private inFlight;
17
134
  private healthy;
18
- constructor(path?: string | undefined, capacity?: number);
135
+ private readonly maxFileBytes;
136
+ private readonly capacity;
137
+ private readonly retentionMs;
138
+ private readonly joinInFlight;
139
+ constructor(options: DispatchJournalOptions<TRequest, TResult>);
19
140
  private key;
141
+ /** id 的纪元前缀是否还在保留窗口内(未来 5 分钟以上同样算非法)。 */
20
142
  private expired;
21
143
  private save;
22
- lookup(deviceId: string, sessionId: string, id: string): DeliveryReceipt;
23
- dispatch(deviceId: string, sessionId: string, id: string, content: unknown, operation: () => Promise<{
24
- ok: true;
25
- value: number;
26
- } | {
27
- ok: false;
28
- kind: string;
29
- }>): Promise<DeliveryReceipt>;
144
+ /** 查询既有回执;`request` 交给 codec 的 matches 判定(缺省即不提供 lookup)。 */
145
+ lookup(deviceId: string, id: string, request?: unknown): TResult | undefined;
146
+ /**
147
+ * 幂等投递。未知结果绝不自动重试:条目保持 unknown,重放时由 codec 决定
148
+ * 调用方看到什么。
149
+ */
150
+ dispatch(deviceId: string, id: string, request: TRequest, operation: () => Promise<OperationResult>): Promise<TResult>;
151
+ /** 等所有在途投递结束;供进程收尾。 */
152
+ settled(): Promise<void>;
153
+ }
154
+ /** prompt 投递的回执:手机侧按 clientSendId 对账。 */
155
+ type DeliveryStatus = 'accepted' | 'rejected' | 'unknown' | 'notFound' | 'expired';
156
+ interface DeliveryReceipt {
157
+ clientSendId: string;
158
+ status: DeliveryStatus;
159
+ userSeq?: number;
160
+ code?: string;
30
161
  }
162
+ /** mutation 的结果:replayed 让调用方知道这是重放而非新执行。 */
163
+ type MutationErrorCode = WireErrorCode;
164
+ type MutationDispatchResult<T> = {
165
+ ok: true;
166
+ value?: T;
167
+ replayed?: boolean;
168
+ } | {
169
+ ok: false;
170
+ code: MutationErrorCode;
171
+ message?: string;
172
+ replayed?: boolean;
173
+ };
31
174
  //#endregion
32
175
  //#region src/device-auth.d.ts
33
176
  declare const DEVICE_SCOPES: readonly ['sessions.read', 'prompt.send', 'sessions.manage', 'interactions.respond', 'notifications.register', 'schedule.manage'];
34
177
  type DeviceScope = (typeof DEVICE_SCOPES)[number];
35
178
  //#endregion
36
179
  //#region src/protocol.d.ts
180
+ interface WelcomeCapabilities {
181
+ historyPaging: boolean;
182
+ replay: boolean;
183
+ approvals: boolean;
184
+ questions: boolean;
185
+ /** Client can request the complete currently-pending approval/question set. */
186
+ pendingSnapshot?: boolean;
187
+ promptDelivery?: boolean;
188
+ /** Bridge emits s2c.notify for all four notification categories. */
189
+ notifyAllCategories?: boolean;
190
+ models: boolean;
191
+ sessionManagement: boolean;
192
+ /** Bridge can fork a session at an exact event boundary. */
193
+ sessionFork?: boolean;
194
+ /** Bridge can list archived sessions and restore them
195
+ * (c2s.sessions.archived / c2s.session.unarchive). Absent on hosts whose
196
+ * workspace controller predates unarchiveSession. */
197
+ sessionRestore?: boolean;
198
+ projectSelection: boolean;
199
+ /** Host exposes the optional DSH Schedule service. */
200
+ schedules?: boolean;
201
+ /** Bridge has APNs configured; clients may send c2s.push.register. */
202
+ push?: boolean;
203
+ widgetPush?: boolean;
204
+ liveActivityPush?: boolean;
205
+ /** Bridge accepts c2s.device.revoke, letting a client unbind itself before
206
+ * deleting its local credentials. Absent on older bridges; older clients
207
+ * ignore the extra field. */
208
+ deviceRevoke?: boolean;
209
+ }
37
210
  type SessionStatus = "running" | "idle" | "error" | "unknown";
38
211
  /**
39
212
  * Cumulative model/token statistics for one session, mirrored from the
@@ -435,12 +608,17 @@ interface HostSessionModels {
435
608
  message: string;
436
609
  }>;
437
610
  }
611
+ /**
612
+ * Bridge 方法的结果。失败直接携带 wire 错误码(error vocabulary 见
613
+ * wire-errors.ts):调用方(wire-registry 的行)原样透给手机,不再经过
614
+ * kind 中间层翻译。
615
+ */
438
616
  type ModelBridgeResult<T> = {
439
617
  ok: true;
440
618
  value: T;
441
619
  } | {
442
620
  ok: false;
443
- kind: 'unsupported' | 'not-found' | 'busy' | 'unavailable' | 'internal';
621
+ code: WireErrorCode;
444
622
  message: string;
445
623
  };
446
624
  type SessionManagementResult<T> = {
@@ -448,7 +626,7 @@ type SessionManagementResult<T> = {
448
626
  value: T;
449
627
  } | {
450
628
  ok: false;
451
- kind: 'unsupported' | 'not-found' | 'busy' | 'invalid' | 'internal';
629
+ code: WireErrorCode;
452
630
  message: string;
453
631
  };
454
632
  interface PromptArgs {
@@ -597,56 +775,22 @@ interface PromptDocument {
597
775
  truncated?: boolean;
598
776
  }
599
777
  //#endregion
600
- //#region src/mutation-journal.d.ts
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
- };
778
+ //#region src/host-bridge.d.ts
620
779
  /**
621
- * Small durable at-most-once journal for non-prompt mutations.
780
+ * 失败结果直接携带 wire 错误码(error vocabulary 见 wire-errors.ts)。
622
781
  *
623
- * Only a hash of the request content is persisted. The successful value is
624
- * kept in memory for the current process so a concurrent retry can receive the
625
- * same response; after a restart a replay is acknowledged and the client
626
- * refetches the authoritative resource. This avoids duplicating reminder
627
- * prompts or conversation data in a second journal.
782
+ * 迁移前这里有 kind 中间层('not-found' | 'busy' | 'conflict' | 'invalid'…),
783
+ * 由 5 个映射函数在「Host code ↔ kind ↔ E_*」之间来回翻译,其中
784
+ * E_BUSY→conflict→E_BUSY 的往返已证明有损。现在每个域查一次表,调用方拿到的
785
+ * 就是手机上会看到的错误码。
628
786
  */
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
787
  type ScheduleBridgeResult<T> = {
644
788
  ok: true;
645
789
  value: T;
646
790
  replayed?: boolean;
647
791
  } | {
648
792
  ok: false;
649
- kind: 'unsupported' | 'not-found' | 'invalid' | 'conflict' | 'busy' | 'internal';
793
+ code: WireErrorCode;
650
794
  message: string;
651
795
  replayed?: boolean;
652
796
  };
@@ -670,9 +814,12 @@ declare class HostBridge {
670
814
  private abort;
671
815
  private started;
672
816
  private disposed;
673
- readonly promptDeliveries: PromptDeliveryJournal;
674
- readonly scheduleMutations: MutationJournal;
675
- readonly forkMutations: MutationJournal;
817
+ readonly promptDeliveries: DispatchJournal<{
818
+ sessionId: string;
819
+ content: unknown;
820
+ }, DeliveryReceipt>;
821
+ readonly scheduleMutations: DispatchJournal<unknown, MutationDispatchResult<unknown>>;
822
+ readonly forkMutations: DispatchJournal<unknown, MutationDispatchResult<unknown>>;
676
823
  constructor(apiProxy: ApiProxyLike, historyBufferMax?: number, deliveryJournalPath?: string, scheduleJournalPath?: string, forkJournalPath?: string);
677
824
  private pushOutlet;
678
825
  private widgetFingerprint;
@@ -681,25 +828,12 @@ declare class HostBridge {
681
828
  * capability and notify-worthy events are mirrored to APNs.
682
829
  */
683
830
  setPushOutlet(outlet: PushOutlet | undefined): void;
684
- get capabilities(): {
685
- historyPaging: boolean;
686
- replay: boolean;
687
- approvals: boolean;
688
- questions: boolean;
689
- pendingSnapshot: boolean;
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
- };
831
+ /**
832
+ * welcome 能力位。委托 host-capabilities.ts 的探测表:此前同一条事实在这里
833
+ * 和各方法体内各存一份,已经漂移过两次(models 位过严、schedules 位与
834
+ * schedule 方法的探测不同源)。
835
+ */
836
+ get capabilities(): WelcomeCapabilities;
703
837
  diagnostic(message: string): void;
704
838
  currentCursor(): number;
705
839
  addSink(sink: BridgeSink): void;