dsh-deeppilot 0.6.0 → 0.6.1

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,7 +1,76 @@
1
1
  import { Context } from "@deepseek-ai/cordis";
2
2
  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;
10
+ }
11
+ /** Durable at-most-once dispatch. Unknown outcomes are never automatically retried. */
12
+ declare class PromptDeliveryJournal {
13
+ private readonly path?;
14
+ private readonly capacity;
15
+ private entries;
16
+ private inFlight;
17
+ private healthy;
18
+ constructor(path?: string | undefined, capacity?: number);
19
+ private key;
20
+ private expired;
21
+ 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>;
30
+ }
31
+ //#endregion
32
+ //#region src/device-auth.d.ts
33
+ declare const DEVICE_SCOPES: readonly ['sessions.read', 'prompt.send', 'sessions.manage', 'interactions.respond', 'notifications.register'];
34
+ type DeviceScope = (typeof DEVICE_SCOPES)[number];
35
+ //#endregion
3
36
  //#region src/protocol.d.ts
4
37
  type SessionStatus = "running" | "idle" | "error" | "unknown";
38
+ /**
39
+ * Cumulative model/token statistics for one session, mirrored from the
40
+ * host's `sessionStats` (dsh-session-stats) + `tokenUsage` (dsh-token-meter)
41
+ * projections. Every counter is a non-negative integer; 0 means nothing
42
+ * recorded yet. Clients derive their display figures from the raw sums:
43
+ * average TTFT = ttftMs / ttftSteps; decode speed = decodeTokens /
44
+ * (decodeMs / 1000); cache hit ratio = cacheReadTokens / (inputTokens +
45
+ * cacheReadTokens + cacheWriteTokens); total prompt tokens = inputTokens +
46
+ * cacheReadTokens + cacheWriteTokens. Absent/null when the host exposes no
47
+ * stats projections (older DSH versions) or nothing has been measured —
48
+ * clients must tolerate missing stats and fall back.
49
+ */
50
+ interface SessionUsageStats {
51
+ turns: number;
52
+ steps: number;
53
+ /** Summed model wall time in ms. */
54
+ llmMs: number;
55
+ /** Summed tool wall time in ms. */
56
+ toolMs: number;
57
+ /** Summed first-token latency in ms over ttftSteps. */
58
+ ttftMs: number;
59
+ /** Steps that recorded a first token. */
60
+ ttftSteps: number;
61
+ /** Summed decode wall time in ms over the decode-timed steps. */
62
+ decodeMs: number;
63
+ /** Provider output tokens over the same decode-timed steps. */
64
+ decodeTokens: number;
65
+ /** Provider-reported uncached prompt tokens. */
66
+ inputTokens: number;
67
+ /** Provider-reported output tokens (reasoning included). */
68
+ outputTokens: number;
69
+ /** Prompt tokens served from the provider cache. */
70
+ cacheReadTokens: number;
71
+ /** Prompt tokens written to the provider cache. */
72
+ cacheWriteTokens: number;
73
+ }
5
74
  type SessionTodoStatus = "pending" | "in_progress" | "completed";
6
75
  /** One checklist entry of the session todo projection. */
7
76
  interface SessionTodoItem {
@@ -21,6 +90,9 @@ interface SessionSummary {
21
90
  todoItems?: SessionTodoItem[] | null;
22
91
  pendingApproval: boolean;
23
92
  pendingQuestion: boolean;
93
+ /** Optional cumulative usage stats (see SessionUsageStats); hosts without
94
+ * the stats projections omit it, and clients must tolerate its absence. */
95
+ stats?: SessionUsageStats | null;
24
96
  workspaceLabel: string | null;
25
97
  workspaceId?: string | null;
26
98
  workspacePath?: string | null;
@@ -78,6 +150,7 @@ type NotifyCategory = 'turn.completed' | 'approval.required' | 'question.asked'
78
150
  * an APNs token and no live WebSocket.
79
151
  */
80
152
  interface PushNotification {
153
+ hostAudience?: string;
81
154
  notificationId: string;
82
155
  category: NotifyCategory;
83
156
  sessionId: string;
@@ -386,6 +459,12 @@ interface BridgeSink {
386
459
  }>): void;
387
460
  replayDone(): void;
388
461
  resync(): void;
462
+ /**
463
+ * S→C permission gate (R1/P2): whether this sink may receive broadcast or
464
+ * replayed frames that require `scope`. The bridge consults this before
465
+ * every push/replay delivery; unknown broadcast types are denied.
466
+ */
467
+ canReceive(scope: DeviceScope): boolean;
389
468
  }
390
469
  /**
391
470
  * Offline push fan-out (F-9 离线推送). The bridge forwards every
@@ -394,6 +473,7 @@ interface BridgeSink {
394
473
  */
395
474
  interface PushOutlet {
396
475
  fanOut(notification: PushNotification): void;
476
+ widgetChanged?(): void;
397
477
  /**
398
478
  * Whether offline push is currently configured and usable. Drives the
399
479
  * welcome capability bit: advertising push while no APNs credentials are
@@ -428,8 +508,10 @@ declare class HostBridge {
428
508
  private abort;
429
509
  private started;
430
510
  private disposed;
431
- constructor(apiProxy: ApiProxyLike, historyBufferMax?: number);
511
+ readonly promptDeliveries: PromptDeliveryJournal;
512
+ constructor(apiProxy: ApiProxyLike, historyBufferMax?: number, deliveryJournalPath?: string);
432
513
  private pushOutlet;
514
+ private widgetFingerprint;
433
515
  /**
434
516
  * Wire the offline-push fan-out. Present ⇒ welcome advertises the `push`
435
517
  * capability and notify-worthy events are mirrored to APNs.
@@ -441,11 +523,13 @@ declare class HostBridge {
441
523
  approvals: boolean;
442
524
  questions: boolean;
443
525
  pendingSnapshot: boolean;
526
+ promptDelivery: boolean;
444
527
  notifyAllCategories: boolean;
445
528
  models: boolean;
446
529
  sessionManagement: boolean;
447
530
  projectSelection: boolean;
448
531
  push: boolean;
532
+ widgetPush: boolean;
449
533
  };
450
534
  diagnostic(message: string): void;
451
535
  currentCursor(): number;
@@ -479,6 +563,9 @@ declare class HostBridge {
479
563
  * Replay buffered pushes after the given cursor; false when the gap is
480
564
  * unrecoverable. Frames go to `target` only — replaying into every sink
481
565
  * duplicated the whole window onto devices that never asked for it.
566
+ * Each frame is filtered by the S→C permission policy per sink, so a
567
+ * reader without interactions.respond never gets the missed approval
568
+ * frames back (R1/P2).
482
569
  */
483
570
  resumeFrom(cursor: number, target?: BridgeSink): boolean;
484
571
  private record;
@@ -586,6 +673,8 @@ interface Config {
586
673
  push?: {
587
674
  /** `none` (default), `apns`, or `relay`. */
588
675
  provider?: 'none' | 'apns' | 'relay';
676
+ /** Generic mode removes conversation-derived titles and bodies before outbound push. */
677
+ contentMode?: 'preview' | 'generic';
589
678
  /** Apple Developer team id (JWT iss claim). */
590
679
  teamId?: string;
591
680
  /** APNs auth key id (JWT kid header). */
@@ -631,6 +720,7 @@ declare const Config: z<Schemastery.ObjectS<{
631
720
  }>>;
632
721
  push: z<Schemastery.ObjectS<{
633
722
  provider: z<"apns" | "none" | "relay", "apns" | "none" | "relay">;
723
+ contentMode: z<"generic" | "preview", "generic" | "preview">;
634
724
  teamId: z<string, string>;
635
725
  keyId: z<string, string>;
636
726
  keyPath: z<string, string>;
@@ -639,6 +729,7 @@ declare const Config: z<Schemastery.ObjectS<{
639
729
  relayToken: z<string, string>;
640
730
  }>, Schemastery.ObjectT<{
641
731
  provider: z<"apns" | "none" | "relay", "apns" | "none" | "relay">;
732
+ contentMode: z<"generic" | "preview", "generic" | "preview">;
642
733
  teamId: z<string, string>;
643
734
  keyId: z<string, string>;
644
735
  keyPath: z<string, string>;
@@ -677,6 +768,7 @@ declare const Config: z<Schemastery.ObjectS<{
677
768
  }>>;
678
769
  push: z<Schemastery.ObjectS<{
679
770
  provider: z<"apns" | "none" | "relay", "apns" | "none" | "relay">;
771
+ contentMode: z<"generic" | "preview", "generic" | "preview">;
680
772
  teamId: z<string, string>;
681
773
  keyId: z<string, string>;
682
774
  keyPath: z<string, string>;
@@ -685,6 +777,7 @@ declare const Config: z<Schemastery.ObjectS<{
685
777
  relayToken: z<string, string>;
686
778
  }>, Schemastery.ObjectT<{
687
779
  provider: z<"apns" | "none" | "relay", "apns" | "none" | "relay">;
780
+ contentMode: z<"generic" | "preview", "generic" | "preview">;
688
781
  teamId: z<string, string>;
689
782
  keyId: z<string, string>;
690
783
  keyPath: z<string, string>;
@@ -697,6 +790,10 @@ declare const Config: z<Schemastery.ObjectS<{
697
790
  //#region src/push-policy.d.ts
698
791
  /** Prune only when the provider supplies an authoritative token-lifecycle verdict. */
699
792
  declare function shouldPrunePushToken(outcome: 'sent' | 'invalid-token' | 'failed', reason?: string): boolean;
793
+ /** APNs requires both registration and the same content permission as WS. */
794
+ declare function mayReceivePush(device: {
795
+ scopes?: readonly string[];
796
+ }, notification: unknown): boolean;
700
797
  /**
701
798
  * Zero-touch relay self-heal: HTTP 401 means the relay no longer honors the
702
799
  * cached credential. Only auto-enrolled cells with a still-current token may
@@ -729,5 +826,5 @@ declare const name = "deeppilot";
729
826
  declare const inject: string[];
730
827
  declare function apply(ctx: Context, options: unknown): void;
731
828
  //#endregion
732
- export { Config, HostBridge, apply, inject, name, shouldPrunePushToken, shouldReEnrollRelayToken };
829
+ export { Config, HostBridge, apply, inject, mayReceivePush, name, shouldPrunePushToken, shouldReEnrollRelayToken };
733
830
  //# sourceMappingURL=index.d.ts.map