dsh-deeppilot 0.3.0 → 0.5.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/COMPATIBILITY.md +20 -17
- package/PRIVACY.md +15 -43
- package/README.md +18 -8
- package/README.zh-CN.md +13 -7
- package/SECURITY.md +27 -29
- package/bin/SHA256SUMS +6 -6
- package/bin/darwin-amd64/dsh-deeppilot-tunnel +0 -0
- package/bin/darwin-arm64/dsh-deeppilot-tunnel +0 -0
- package/bin/linux-amd64/dsh-deeppilot-tunnel +0 -0
- package/bin/linux-arm64/dsh-deeppilot-tunnel +0 -0
- package/bin/windows-amd64/dsh-deeppilot-tunnel.exe +0 -0
- package/bin/windows-arm64/dsh-deeppilot-tunnel.exe +0 -0
- package/docs/SECURITY_ROADMAP.md +24 -0
- package/docs/SECURITY_ROADMAP.zh-CN.md +24 -0
- package/lib/client.js +2043 -1419
- package/lib/client.js.map +1 -1
- package/lib/index.d.ts +131 -56
- package/lib/index.js +2165 -1009
- package/lib/index.js.map +1 -1
- package/package.json +38 -9
package/lib/index.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { IncomingMessage } from "node:http";
|
|
2
1
|
import z from "@deepseek-ai/schemastery";
|
|
3
2
|
import { Context } from "@deepseek-ai/cordis";
|
|
4
3
|
//#region src/protocol.d.ts
|
|
@@ -26,6 +25,51 @@ interface SessionSummary {
|
|
|
26
25
|
workspaceId?: string | null;
|
|
27
26
|
workspacePath?: string | null;
|
|
28
27
|
}
|
|
28
|
+
type MessageRole = 'user' | 'assistant' | 'tool' | 'system' | 'error';
|
|
29
|
+
type ToolState = 'running' | 'ok' | 'error';
|
|
30
|
+
/** Provenance of host-injected context; present only on `role: "system"` rows.
|
|
31
|
+
* Mirrors the durable DSH message source (`dsh-llm` MessageSource): `label`
|
|
32
|
+
* names the producer (plugin name, skill name, instruction paths…), `form` is
|
|
33
|
+
* the semantic ContextForm vocabulary ('instructions' | 'catalog' | 'snapshot'
|
|
34
|
+
* | 'notice' | 'relay' | 'recall'). Both degrade gracefully — clients must
|
|
35
|
+
* tolerate absent fields and unknown values. */
|
|
36
|
+
interface MessageContextInfo {
|
|
37
|
+
label?: string;
|
|
38
|
+
form?: string;
|
|
39
|
+
}
|
|
40
|
+
/** One image carried by a user message. `attachmentId` keys the read-back RPC
|
|
41
|
+
* (c2s.session.attachment); width/height let clients reserve layout space. */
|
|
42
|
+
interface MessageAttachment {
|
|
43
|
+
kind: 'image';
|
|
44
|
+
name?: string;
|
|
45
|
+
mediaType?: string;
|
|
46
|
+
attachmentId?: string;
|
|
47
|
+
width?: number;
|
|
48
|
+
height?: number;
|
|
49
|
+
}
|
|
50
|
+
interface MessageProjection {
|
|
51
|
+
/** Durable row identity; unique within one session/page. */
|
|
52
|
+
seq: number;
|
|
53
|
+
role: MessageRole;
|
|
54
|
+
text?: string;
|
|
55
|
+
/** Reasoning ("thinking") text accompanying the answer, when present. */
|
|
56
|
+
thinking?: string;
|
|
57
|
+
streaming?: boolean;
|
|
58
|
+
tool?: {
|
|
59
|
+
name: string;
|
|
60
|
+
state: ToolState;
|
|
61
|
+
summary: string;
|
|
62
|
+
};
|
|
63
|
+
attachments?: MessageAttachment[];
|
|
64
|
+
/** Present only on system rows: provenance of the injected context.
|
|
65
|
+
* The DSH host logs synthetic agent.inject() content (runtime-context
|
|
66
|
+
* snapshots, background-job notices, workspace instructions…) as user-role
|
|
67
|
+
* messages whose `source.kind` is not 'user'; those project here as
|
|
68
|
+
* `role: "system"` so clients never show them as human prompts. */
|
|
69
|
+
context?: MessageContextInfo;
|
|
70
|
+
ts: number;
|
|
71
|
+
truncated?: boolean;
|
|
72
|
+
}
|
|
29
73
|
type NotifyCategory = 'turn.completed' | 'approval.required' | 'question.asked' | 'session.error';
|
|
30
74
|
/**
|
|
31
75
|
* One offline-push-worthy event (same facts as s2c.notify / pending frames,
|
|
@@ -66,7 +110,7 @@ interface PendingSnapshotPayload {
|
|
|
66
110
|
questions: PendingQuestionPayload[];
|
|
67
111
|
}
|
|
68
112
|
//#endregion
|
|
69
|
-
//#region src/host-
|
|
113
|
+
//#region src/host-api.d.ts
|
|
70
114
|
interface RpcOk<T> {
|
|
71
115
|
ok: true;
|
|
72
116
|
value: T;
|
|
@@ -250,7 +294,9 @@ interface PhoneSessionRow {
|
|
|
250
294
|
sessionId: string;
|
|
251
295
|
updatedAt: number;
|
|
252
296
|
running: boolean;
|
|
253
|
-
blank
|
|
297
|
+
/** Host marks never-prompted sessions as blank; informational only — the
|
|
298
|
+
* summary projects them as idle (see toSummary) so phones can send. */
|
|
299
|
+
blank?: boolean;
|
|
254
300
|
cwd?: string;
|
|
255
301
|
origin?: string;
|
|
256
302
|
parentSessionId?: string;
|
|
@@ -355,6 +401,8 @@ interface PushOutlet {
|
|
|
355
401
|
*/
|
|
356
402
|
isAvailable(): boolean;
|
|
357
403
|
}
|
|
404
|
+
//#endregion
|
|
405
|
+
//#region src/host-bridge.d.ts
|
|
358
406
|
declare class HostBridge {
|
|
359
407
|
private readonly apiProxy;
|
|
360
408
|
private readonly historyBufferMax;
|
|
@@ -367,7 +415,10 @@ declare class HostBridge {
|
|
|
367
415
|
private sinks;
|
|
368
416
|
private ring;
|
|
369
417
|
private cursor;
|
|
418
|
+
private userReceiptSeq;
|
|
370
419
|
private abort;
|
|
420
|
+
private started;
|
|
421
|
+
private disposed;
|
|
371
422
|
constructor(apiProxy: ApiProxyLike, historyBufferMax?: number);
|
|
372
423
|
private pushOutlet;
|
|
373
424
|
/**
|
|
@@ -381,6 +432,7 @@ declare class HostBridge {
|
|
|
381
432
|
approvals: boolean;
|
|
382
433
|
questions: boolean;
|
|
383
434
|
pendingSnapshot: boolean;
|
|
435
|
+
notifyAllCategories: boolean;
|
|
384
436
|
models: boolean;
|
|
385
437
|
sessionManagement: boolean;
|
|
386
438
|
projectSelection: boolean;
|
|
@@ -399,6 +451,12 @@ declare class HostBridge {
|
|
|
399
451
|
markSinkClosed(sink: BridgeSink, sessionId: string): void;
|
|
400
452
|
dropSinkSessions(sink: BridgeSink): void;
|
|
401
453
|
private isViewedBy;
|
|
454
|
+
/** F-9: when a notification-worthy event fires, mirror it to every
|
|
455
|
+
* online device that is not currently viewing the session (the s2c.notify
|
|
456
|
+
* frame counts toward the seq cursor and joins the replay ring per
|
|
457
|
+
* PROTOCOL §6 + §7), then fan the same payload out to offline devices
|
|
458
|
+
* holding an APNs token. */
|
|
459
|
+
private emitNotify;
|
|
402
460
|
/** F-9: when a turn completes, notify every device not viewing the session. */
|
|
403
461
|
private emitTurnCompletedNotify;
|
|
404
462
|
/**
|
|
@@ -438,7 +496,11 @@ declare class HostBridge {
|
|
|
438
496
|
pendingSnapshot(): PendingSnapshotPayload;
|
|
439
497
|
/** Tail history for an opened session; pushes s2c.session.tail to the sink. */
|
|
440
498
|
openSession(sink: BridgeSink, sessionId: string, tailCount: number): Promise<boolean>;
|
|
441
|
-
historyPage(
|
|
499
|
+
historyPage(sessionId: string, beforeSeq: number, limit: number): Promise<{
|
|
500
|
+
sessionId: string;
|
|
501
|
+
messages: MessageProjection[];
|
|
502
|
+
hasMore: boolean;
|
|
503
|
+
} | null>;
|
|
442
504
|
/** Result of one attachment read-back for the phone. */
|
|
443
505
|
attachmentData(sessionId: string, attachmentId: string): Promise<{
|
|
444
506
|
mediaType?: string;
|
|
@@ -480,29 +542,11 @@ declare class HostBridge {
|
|
|
480
542
|
respondQuestion(requestId: string, answers: unknown): Promise<PendingResponseOutcome>;
|
|
481
543
|
}
|
|
482
544
|
//#endregion
|
|
483
|
-
//#region src/
|
|
484
|
-
/**
|
|
485
|
-
* dsh-deeppilot — data bridge between the DSH host and DeepPilot
|
|
486
|
-
* clients. Registers exactly one WebSocket upgrade route (/phone) plus an
|
|
487
|
-
* optional health probe (/phone/health) on the existing web server. The web
|
|
488
|
-
* UI is never touched.
|
|
489
|
-
*
|
|
490
|
-
* Data plane: an in-process HostBridge consumes apiProxy.events.mux()/host()
|
|
491
|
-
* streams, mirrors session summaries, tracks pending approvals/questions,
|
|
492
|
-
* and fans projected protocol-v1 pushes out to every connected device.
|
|
493
|
-
*
|
|
494
|
-
* Protocol: src/protocol.ts, v1. The private app repository carries the
|
|
495
|
-
* matching normative document and Swift models.
|
|
496
|
-
*/
|
|
497
|
-
declare const name = "deeppilot";
|
|
498
|
-
/** No eager service requirement: profiles without a web stack simply skip. */
|
|
499
|
-
declare const inject: string[];
|
|
545
|
+
//#region src/config.d.ts
|
|
500
546
|
interface Config {
|
|
501
547
|
/** Master switch; when false the plugin activates and does nothing. */
|
|
502
548
|
enabled?: boolean;
|
|
503
|
-
/**
|
|
504
|
-
authTokenPath?: string;
|
|
505
|
-
/** Paired-device registry JSON path. */
|
|
549
|
+
/** Protocol-v2 device registry JSON path. */
|
|
506
550
|
devicesPath?: string;
|
|
507
551
|
/** Replay ring buffer bound (frames) per deployment. */
|
|
508
552
|
historyBufferMax?: number;
|
|
@@ -511,35 +555,32 @@ interface Config {
|
|
|
511
555
|
/** Optional embedded remote transport. Reconciled when settings change. */
|
|
512
556
|
remote?: {
|
|
513
557
|
enabled?: boolean;
|
|
514
|
-
provider?:
|
|
558
|
+
provider?: 'tailscale-funnel';
|
|
515
559
|
hostname?: string;
|
|
516
560
|
statePath?: string;
|
|
517
561
|
helperPath?: string;
|
|
518
|
-
funnelPort?:
|
|
562
|
+
funnelPort?: 443 | 8443 | 10000;
|
|
563
|
+
/** Concurrent Funnel WebSockets allowed from one public source address. */
|
|
564
|
+
maxConnectionsPerSource?: number;
|
|
519
565
|
};
|
|
520
566
|
/**
|
|
521
|
-
* Offline push (F-9).
|
|
522
|
-
*
|
|
523
|
-
*
|
|
524
|
-
*
|
|
525
|
-
* distributor's key — used when the App ships via TestFlight/App Store.
|
|
526
|
-
*
|
|
527
|
-
* Deliberately NO environment knob here: each device reports its own
|
|
528
|
-
* environment when registering (derived from its build kind), and
|
|
529
|
-
* deliveries route per device — mixed dev/TestFlight phones coexist.
|
|
567
|
+
* Offline push (F-9). `apns` sends directly from the Mac with the user's
|
|
568
|
+
* Apple credentials. `relay` sends notify projections to an operator-run
|
|
569
|
+
* relay for distributed builds. The device reports its own APNs environment,
|
|
570
|
+
* so development and TestFlight/App Store devices may coexist.
|
|
530
571
|
*/
|
|
531
572
|
push?: {
|
|
532
|
-
/**
|
|
533
|
-
provider?:
|
|
573
|
+
/** `none` (default), `apns`, or `relay`. */
|
|
574
|
+
provider?: 'none' | 'apns' | 'relay';
|
|
534
575
|
/** Apple Developer team id (JWT iss claim). */
|
|
535
576
|
teamId?: string;
|
|
536
577
|
/** APNs auth key id (JWT kid header). */
|
|
537
578
|
keyId?: string;
|
|
538
|
-
/**
|
|
579
|
+
/** `.p8` private key path. */
|
|
539
580
|
keyPath?: string;
|
|
540
581
|
/** App bundle id — the apns-topic header. */
|
|
541
582
|
bundleId?: string;
|
|
542
|
-
/** Relay base URL
|
|
583
|
+
/** Relay base URL. */
|
|
543
584
|
relayUrl?: string;
|
|
544
585
|
/** Per-user bearer token issued by the relay operator. */
|
|
545
586
|
relayToken?: string;
|
|
@@ -547,27 +588,28 @@ interface Config {
|
|
|
547
588
|
}
|
|
548
589
|
declare const Config: z<Schemastery.ObjectS<{
|
|
549
590
|
enabled: z<boolean, boolean>;
|
|
550
|
-
authTokenPath: z<string, string>;
|
|
551
591
|
devicesPath: z<string, string>;
|
|
552
592
|
historyBufferMax: z<number, number>;
|
|
553
593
|
debug: z<boolean, boolean>;
|
|
554
594
|
remote: z<Schemastery.ObjectS<{
|
|
555
595
|
enabled: z<boolean, boolean>;
|
|
556
|
-
provider: z<
|
|
596
|
+
provider: z<"tailscale-funnel", "tailscale-funnel">;
|
|
557
597
|
hostname: z<string, string>;
|
|
558
598
|
statePath: z<string, string>;
|
|
559
599
|
helperPath: z<string, string>;
|
|
560
|
-
funnelPort: z<
|
|
600
|
+
funnelPort: z<443 | 8443 | 10000, 443 | 8443 | 10000>;
|
|
601
|
+
maxConnectionsPerSource: z<number, number>;
|
|
561
602
|
}>, Schemastery.ObjectT<{
|
|
562
603
|
enabled: z<boolean, boolean>;
|
|
563
|
-
provider: z<
|
|
604
|
+
provider: z<"tailscale-funnel", "tailscale-funnel">;
|
|
564
605
|
hostname: z<string, string>;
|
|
565
606
|
statePath: z<string, string>;
|
|
566
607
|
helperPath: z<string, string>;
|
|
567
|
-
funnelPort: z<
|
|
608
|
+
funnelPort: z<443 | 8443 | 10000, 443 | 8443 | 10000>;
|
|
609
|
+
maxConnectionsPerSource: z<number, number>;
|
|
568
610
|
}>>;
|
|
569
611
|
push: z<Schemastery.ObjectS<{
|
|
570
|
-
provider: z<
|
|
612
|
+
provider: z<"none" | "apns" | "relay", "none" | "apns" | "relay">;
|
|
571
613
|
teamId: z<string, string>;
|
|
572
614
|
keyId: z<string, string>;
|
|
573
615
|
keyPath: z<string, string>;
|
|
@@ -575,7 +617,7 @@ declare const Config: z<Schemastery.ObjectS<{
|
|
|
575
617
|
relayUrl: z<string, string>;
|
|
576
618
|
relayToken: z<string, string>;
|
|
577
619
|
}>, Schemastery.ObjectT<{
|
|
578
|
-
provider: z<
|
|
620
|
+
provider: z<"none" | "apns" | "relay", "none" | "apns" | "relay">;
|
|
579
621
|
teamId: z<string, string>;
|
|
580
622
|
keyId: z<string, string>;
|
|
581
623
|
keyPath: z<string, string>;
|
|
@@ -585,27 +627,28 @@ declare const Config: z<Schemastery.ObjectS<{
|
|
|
585
627
|
}>>;
|
|
586
628
|
}>, Schemastery.ObjectT<{
|
|
587
629
|
enabled: z<boolean, boolean>;
|
|
588
|
-
authTokenPath: z<string, string>;
|
|
589
630
|
devicesPath: z<string, string>;
|
|
590
631
|
historyBufferMax: z<number, number>;
|
|
591
632
|
debug: z<boolean, boolean>;
|
|
592
633
|
remote: z<Schemastery.ObjectS<{
|
|
593
634
|
enabled: z<boolean, boolean>;
|
|
594
|
-
provider: z<
|
|
635
|
+
provider: z<"tailscale-funnel", "tailscale-funnel">;
|
|
595
636
|
hostname: z<string, string>;
|
|
596
637
|
statePath: z<string, string>;
|
|
597
638
|
helperPath: z<string, string>;
|
|
598
|
-
funnelPort: z<
|
|
639
|
+
funnelPort: z<443 | 8443 | 10000, 443 | 8443 | 10000>;
|
|
640
|
+
maxConnectionsPerSource: z<number, number>;
|
|
599
641
|
}>, Schemastery.ObjectT<{
|
|
600
642
|
enabled: z<boolean, boolean>;
|
|
601
|
-
provider: z<
|
|
643
|
+
provider: z<"tailscale-funnel", "tailscale-funnel">;
|
|
602
644
|
hostname: z<string, string>;
|
|
603
645
|
statePath: z<string, string>;
|
|
604
646
|
helperPath: z<string, string>;
|
|
605
|
-
funnelPort: z<
|
|
647
|
+
funnelPort: z<443 | 8443 | 10000, 443 | 8443 | 10000>;
|
|
648
|
+
maxConnectionsPerSource: z<number, number>;
|
|
606
649
|
}>>;
|
|
607
650
|
push: z<Schemastery.ObjectS<{
|
|
608
|
-
provider: z<
|
|
651
|
+
provider: z<"none" | "apns" | "relay", "none" | "apns" | "relay">;
|
|
609
652
|
teamId: z<string, string>;
|
|
610
653
|
keyId: z<string, string>;
|
|
611
654
|
keyPath: z<string, string>;
|
|
@@ -613,7 +656,7 @@ declare const Config: z<Schemastery.ObjectS<{
|
|
|
613
656
|
relayUrl: z<string, string>;
|
|
614
657
|
relayToken: z<string, string>;
|
|
615
658
|
}>, Schemastery.ObjectT<{
|
|
616
|
-
provider: z<
|
|
659
|
+
provider: z<"none" | "apns" | "relay", "none" | "apns" | "relay">;
|
|
617
660
|
teamId: z<string, string>;
|
|
618
661
|
keyId: z<string, string>;
|
|
619
662
|
keyPath: z<string, string>;
|
|
@@ -622,9 +665,41 @@ declare const Config: z<Schemastery.ObjectS<{
|
|
|
622
665
|
relayToken: z<string, string>;
|
|
623
666
|
}>>;
|
|
624
667
|
}>>;
|
|
625
|
-
|
|
626
|
-
|
|
668
|
+
//#endregion
|
|
669
|
+
//#region src/push-policy.d.ts
|
|
670
|
+
/** Prune only when the provider supplies an authoritative token-lifecycle verdict. */
|
|
671
|
+
declare function shouldPrunePushToken(outcome: 'sent' | 'invalid-token' | 'failed', reason?: string): boolean;
|
|
672
|
+
/**
|
|
673
|
+
* Zero-touch relay self-heal: HTTP 401 means the relay no longer honors the
|
|
674
|
+
* cached credential. Only auto-enrolled cells with a still-current token may
|
|
675
|
+
* re-derive it; an explicitly configured relay token remains user-owned
|
|
676
|
+
* configuration and is never silently rewritten.
|
|
677
|
+
*/
|
|
678
|
+
declare function shouldReEnrollRelayToken(transport: 'apns' | 'relay', outcome: 'sent' | 'invalid-token' | 'failed', reason: string | undefined, opts: {
|
|
679
|
+
usedCellToken: boolean;
|
|
680
|
+
hasEnrollKey: boolean;
|
|
681
|
+
tokenStillCurrent: boolean;
|
|
682
|
+
}): boolean;
|
|
683
|
+
//#endregion
|
|
684
|
+
//#region src/index.d.ts
|
|
685
|
+
/**
|
|
686
|
+
* dsh-deeppilot — data bridge between the DSH host and DeepPilot
|
|
687
|
+
* clients. Registers exactly one WebSocket upgrade route (/phone) plus an
|
|
688
|
+
* optional health probe (/phone/health) on the existing web server. The web
|
|
689
|
+
* UI is never touched.
|
|
690
|
+
*
|
|
691
|
+
* Data plane: an in-process HostBridge consumes a local compatibility façade
|
|
692
|
+
* over DSH 0.1.2 Session/Workspace controllers, mirrors session summaries,
|
|
693
|
+
* tracks pending approvals/questions, and fans projected protocol-v2 pushes
|
|
694
|
+
* out to every connected device.
|
|
695
|
+
*
|
|
696
|
+
* Protocol: PROTOCOL.md is normative; src/protocol.ts and the private app's
|
|
697
|
+
* Swift models mirror that v2 contract.
|
|
698
|
+
*/
|
|
699
|
+
declare const name = "deeppilot";
|
|
700
|
+
/** No eager service requirement: profiles without a web stack simply skip. */
|
|
701
|
+
declare const inject: string[];
|
|
627
702
|
declare function apply(ctx: Context, options: unknown): void;
|
|
628
703
|
//#endregion
|
|
629
|
-
export { Config, HostBridge, apply, inject, name,
|
|
704
|
+
export { Config, HostBridge, apply, inject, name, shouldPrunePushToken, shouldReEnrollRelayToken };
|
|
630
705
|
//# sourceMappingURL=index.d.ts.map
|