dsh-zen-remote 2.0.1 → 2.0.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-zen-remote",
3
- "version": "2.0.1",
3
+ "version": "2.0.2",
4
4
  "description": "一个插件、两种角色:主服务端把 DeepSeek Harness 变成手机能安全访问的 PWA(移动端界面、配对码网关、Web Push),并把选定会话共享给已配对的桌面端;子客户端在另一台 DSH 桌面端的侧边栏里远程使用这些会话。One DSH plugin, two roles: the host turns DeepSeek Harness into a phone-reachable PWA (mobile UI, pairing-code gateway behind your own reverse proxy, Web Push) and shares chosen sessions to paired desktops; the client uses those sessions remotely from another DSH desktop app's sidebar.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -82,18 +82,18 @@
82
82
  },
83
83
  "peerDependencies": {
84
84
  "@deepseek-ai/cordis": "*",
85
- "@deepseek-ai/dsh-client-locale": "^0.1.7-rc.2 || ^0.2.0-rc.1",
86
- "@deepseek-ai/dsh-client-ui-conversation": "^0.1.7-rc.2 || ^0.2.0-rc.1",
87
- "@deepseek-ai/dsh-client-ui-layout": "^0.1.7-rc.2 || ^0.2.0-rc.1",
88
- "@deepseek-ai/dsh-client-ui-primitives": "^0.1.7-rc.2 || ^0.2.0-rc.1",
89
- "@deepseek-ai/dsh-client-ui-sidebar": "^0.1.7-rc.2 || ^0.2.0-rc.1",
90
- "@deepseek-ai/dsh-client-ui-slots": "^0.1.7-rc.2 || ^0.2.0-rc.1",
91
- "@deepseek-ai/dsh-host-webserver": "^0.1.7-rc.2 || ^0.2.0-rc.1",
92
- "@deepseek-ai/dsh-session": "^0.1.7-rc.2 || ^0.2.0-rc.1",
93
- "@deepseek-ai/dsh-session-log-export": "^0.1.7-rc.2 || ^0.2.0-rc.1",
94
- "@deepseek-ai/dsh-session-query": "^0.1.7-rc.2 || ^0.2.0-rc.1",
95
- "@deepseek-ai/dsh-tools": "^0.1.7-rc.2 || ^0.2.0-rc.1",
96
- "@deepseek-ai/dsh-workspace": "^0.1.7-rc.2 || ^0.2.0-rc.1",
85
+ "@deepseek-ai/dsh-client-locale": "^0.1.7-rc.2 || ^0.2.0-rc.1 || ^0.2.1-alpha.1",
86
+ "@deepseek-ai/dsh-client-ui-conversation": "^0.1.7-rc.2 || ^0.2.0-rc.1 || ^0.2.1-alpha.1",
87
+ "@deepseek-ai/dsh-client-ui-layout": "^0.1.7-rc.2 || ^0.2.0-rc.1 || ^0.2.1-alpha.1",
88
+ "@deepseek-ai/dsh-client-ui-primitives": "^0.1.7-rc.2 || ^0.2.0-rc.1 || ^0.2.1-alpha.1",
89
+ "@deepseek-ai/dsh-client-ui-sidebar": "^0.1.7-rc.2 || ^0.2.0-rc.1 || ^0.2.1-alpha.1",
90
+ "@deepseek-ai/dsh-client-ui-slots": "^0.1.7-rc.2 || ^0.2.0-rc.1 || ^0.2.1-alpha.1",
91
+ "@deepseek-ai/dsh-host-webserver": "^0.1.7-rc.2 || ^0.2.0-rc.1 || ^0.2.1-alpha.1",
92
+ "@deepseek-ai/dsh-session": "^0.1.7-rc.2 || ^0.2.0-rc.1 || ^0.2.1-alpha.1",
93
+ "@deepseek-ai/dsh-session-log-export": "^0.1.7-rc.2 || ^0.2.0-rc.1 || ^0.2.1-alpha.1",
94
+ "@deepseek-ai/dsh-session-query": "^0.1.7-rc.2 || ^0.2.0-rc.1 || ^0.2.1-alpha.1",
95
+ "@deepseek-ai/dsh-tools": "^0.1.7-rc.2 || ^0.2.0-rc.1 || ^0.2.1-alpha.1",
96
+ "@deepseek-ai/dsh-workspace": "^0.1.7-rc.2 || ^0.2.0-rc.1 || ^0.2.1-alpha.1",
97
97
  "@deepseek-ai/schemastery": "*",
98
98
  "react": "^18.2.0"
99
99
  },
@@ -115,43 +115,42 @@
115
115
  }
116
116
  },
117
117
  "devDependencies": {
118
- "@deepseek-ai/cordis": "4.0.4",
118
+ "@deepseek-ai/cordis": "4.0.5-alpha.1",
119
119
  "@deepseek-ai/cosmokit": "1.8.5",
120
- "@deepseek-ai/dsh-agent": "0.1.7-rc.2",
121
- "@deepseek-ai/dsh-api-remotes": "0.1.7-rc.2",
122
- "@deepseek-ai/dsh-api-session-controller": "0.1.7-rc.2",
123
- "@deepseek-ai/dsh-api-workspace-controller": "0.1.7-rc.2",
124
- "@deepseek-ai/dsh-brand": "0.1.7-rc.2",
125
- "@deepseek-ai/dsh-client-connection": "0.1.7-rc.2",
126
- "@deepseek-ai/dsh-client-locale": "0.1.7-rc.2",
127
- "@deepseek-ai/dsh-client-store": "0.1.7-rc.2",
128
- "@deepseek-ai/dsh-client-ui-conversation": "0.1.7-rc.2",
129
- "@deepseek-ai/dsh-client-ui-layout": "0.1.7-rc.2",
130
- "@deepseek-ai/dsh-client-ui-primitives": "0.1.7-rc.2",
131
- "@deepseek-ai/dsh-client-ui-renderer": "0.1.7-rc.2",
132
- "@deepseek-ai/dsh-client-ui-session": "0.1.7-rc.2",
133
- "@deepseek-ai/dsh-client-ui-sidebar": "0.1.7-rc.2",
134
- "@deepseek-ai/dsh-client-ui-slots": "0.1.7-rc.2",
135
- "@deepseek-ai/dsh-host-webserver": "0.1.7-rc.2",
136
- "@deepseek-ai/dsh-invariants": "0.1.7-rc.2",
137
- "@deepseek-ai/dsh-llm": "0.1.7-rc.2",
138
- "@deepseek-ai/dsh-ptc-runtime": "0.1.7-rc.2",
139
- "@deepseek-ai/dsh-sandbox": "0.1.7-rc.2",
140
- "@deepseek-ai/dsh-sandbox-policy": "0.1.7-rc.2",
141
- "@deepseek-ai/dsh-scope": "0.1.7-rc.2",
142
- "@deepseek-ai/dsh-session": "0.1.7-rc.2",
143
- "@deepseek-ai/dsh-session-log-export": "0.1.7-rc.2",
144
- "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2",
145
- "@deepseek-ai/dsh-session-query": "0.1.7-rc.2",
146
- "@deepseek-ai/dsh-session-stats": "0.1.7-rc.2",
147
- "@deepseek-ai/dsh-subagent": "0.1.7-rc.2",
148
- "@deepseek-ai/dsh-timeout": "0.1.7-rc.2",
149
- "@deepseek-ai/dsh-token-meter": "0.1.7-rc.2",
150
- "@deepseek-ai/dsh-tools": "0.1.7-rc.2",
151
- "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2",
152
- "@deepseek-ai/dsh-util-crypto": "0.1.7-rc.2",
153
- "@deepseek-ai/dsh-util-values": "0.1.7-rc.2",
154
- "@deepseek-ai/dsh-workspace": "0.1.7-rc.2",
120
+ "@deepseek-ai/dsh-agent": "0.2.1-alpha.2",
121
+ "@deepseek-ai/dsh-api-remotes": "0.2.1-alpha.2",
122
+ "@deepseek-ai/dsh-api-session-controller": "0.2.1-alpha.2",
123
+ "@deepseek-ai/dsh-api-workspace-controller": "0.2.1-alpha.2",
124
+ "@deepseek-ai/dsh-brand": "0.2.1-alpha.2",
125
+ "@deepseek-ai/dsh-client-connection": "0.2.1-alpha.2",
126
+ "@deepseek-ai/dsh-client-locale": "0.2.1-alpha.2",
127
+ "@deepseek-ai/dsh-client-store": "0.2.1-alpha.2",
128
+ "@deepseek-ai/dsh-client-ui-conversation": "0.2.1-alpha.2",
129
+ "@deepseek-ai/dsh-client-ui-layout": "0.2.1-alpha.2",
130
+ "@deepseek-ai/dsh-client-ui-primitives": "0.2.1-alpha.2",
131
+ "@deepseek-ai/dsh-client-ui-renderer": "0.2.1-alpha.2",
132
+ "@deepseek-ai/dsh-client-ui-session": "0.2.1-alpha.2",
133
+ "@deepseek-ai/dsh-client-ui-sidebar": "0.2.1-alpha.2",
134
+ "@deepseek-ai/dsh-client-ui-slots": "0.2.1-alpha.2",
135
+ "@deepseek-ai/dsh-host-webserver": "0.2.1-alpha.2",
136
+ "@deepseek-ai/dsh-llm": "0.2.1-alpha.2",
137
+ "@deepseek-ai/dsh-ptc-runtime": "0.2.1-alpha.2",
138
+ "@deepseek-ai/dsh-sandbox": "0.2.1-alpha.2",
139
+ "@deepseek-ai/dsh-sandbox-policy": "0.2.1-alpha.2",
140
+ "@deepseek-ai/dsh-scope": "0.2.1-alpha.2",
141
+ "@deepseek-ai/dsh-session": "0.2.1-alpha.2",
142
+ "@deepseek-ai/dsh-session-log-export": "0.2.1-alpha.2",
143
+ "@deepseek-ai/dsh-session-projection": "0.2.1-alpha.2",
144
+ "@deepseek-ai/dsh-session-query": "0.2.1-alpha.2",
145
+ "@deepseek-ai/dsh-session-stats": "0.2.1-alpha.2",
146
+ "@deepseek-ai/dsh-subagent": "0.2.1-alpha.2",
147
+ "@deepseek-ai/dsh-timeout": "0.2.1-alpha.2",
148
+ "@deepseek-ai/dsh-token-meter": "0.2.1-alpha.2",
149
+ "@deepseek-ai/dsh-tools": "0.2.1-alpha.2",
150
+ "@deepseek-ai/dsh-typert-protocol": "0.2.1-alpha.2",
151
+ "@deepseek-ai/dsh-util-crypto": "0.2.1-alpha.2",
152
+ "@deepseek-ai/dsh-util-values": "0.2.1-alpha.2",
153
+ "@deepseek-ai/dsh-workspace": "0.2.1-alpha.2",
155
154
  "@deepseek-ai/schemastery": "3.18.4",
156
155
  "@types/node": "^26.2.0",
157
156
  "@types/react": "~18.3.1",
@@ -440,14 +440,20 @@ export const COMPAT_CSS = ` /* ---------- dsh-web-ui family compatibility -----
440
440
  cache) is long. It is the single entry the official StatsLine puts in
441
441
  conversation.composer.dock, so the structural anchor below reaches it
442
442
  without any DOM marking (S3 deleted the text-matching effect that used
443
- to set [data-slot="conversation.composer.dock"] > [class$="_root"]). Layout: ONE fixed-height (28px) flex
443
+ to set the dock-entry marker). Layout: ONE fixed-height (28px) flex
444
444
  strip that scrolls horizontally — the full metrics stream stays
445
445
  reachable by swiping, the row never grows vertically, no ellipsis or
446
446
  fade, 12px gaps between metric groups, a 2px scrollbar as the swipe
447
447
  affordance. The phone breakpoint hides the strip outright instead
448
448
  (styles/composer.css.ts — its data moves into the session info card). */
449
449
 
450
- [data-slot="conversation.composer.dock"] > [class$="_root"] {
450
+ /* Marker set is deliberately dual: 0.2.0-rc.2 renders the strip root with
451
+ data-composer-stats (plural, dsh-client-ui-chat rc.2 lib), 0.2.1-alpha.2
452
+ dropped the strip wrapper and registers activity/usage as separate dock
453
+ entries whose pill spans carry data-composer-stat (singular). Keeping
454
+ both lets this plugin style the strip on a host that has NOT upgraded to
455
+ alpha.2 — verified against both npm tarballs 2026-10-09. */
456
+ [data-slot="conversation.composer.dock"] > :is([data-composer-stat], [data-composer-stats]) {
451
457
  display: flex !important;
452
458
  flex-flow: row nowrap !important;
453
459
  align-items: center !important;
@@ -469,17 +475,17 @@ export const COMPAT_CSS = ` /* ---------- dsh-web-ui family compatibility -----
469
475
  line-height: 20px !important;
470
476
  font-size: 12px !important;
471
477
  }
472
- [data-slot="conversation.composer.dock"] > [class$="_root"]::-webkit-scrollbar {
478
+ [data-slot="conversation.composer.dock"] > :is([data-composer-stat], [data-composer-stats])::-webkit-scrollbar {
473
479
  height: 2px !important;
474
480
  }
475
- [data-slot="conversation.composer.dock"] > [class$="_root"]::-webkit-scrollbar-thumb {
481
+ [data-slot="conversation.composer.dock"] > :is([data-composer-stat], [data-composer-stats])::-webkit-scrollbar-thumb {
476
482
  background: var(--dsw-alias-label-tertiary, rgba(0, 0, 0, .3)) !important;
477
483
  border-radius: 2px !important;
478
484
  }
479
- [data-slot="conversation.composer.dock"] > [class$="_root"]::-webkit-scrollbar-track {
485
+ [data-slot="conversation.composer.dock"] > :is([data-composer-stat], [data-composer-stats])::-webkit-scrollbar-track {
480
486
  background: transparent !important;
481
487
  }
482
- [data-slot="conversation.composer.dock"] > [class$="_root"] > * {
488
+ [data-slot="conversation.composer.dock"] > :is([data-composer-stat], [data-composer-stats]) > * {
483
489
  display: flex !important;
484
490
  flex: 0 0 auto !important;
485
491
  flex-flow: row nowrap !important;
@@ -491,10 +497,10 @@ export const COMPAT_CSS = ` /* ---------- dsh-web-ui family compatibility -----
491
497
  margin-right: 12px !important;
492
498
  padding: 0 !important;
493
499
  }
494
- [data-slot="conversation.composer.dock"] > [class$="_root"] > *:last-child {
500
+ [data-slot="conversation.composer.dock"] > :is([data-composer-stat], [data-composer-stats]) > *:last-child {
495
501
  margin-right: 0 !important;
496
502
  }
497
- [data-slot="conversation.composer.dock"] > [class$="_root"] * {
503
+ [data-slot="conversation.composer.dock"] > :is([data-composer-stat], [data-composer-stats]) * {
498
504
  white-space: nowrap !important;
499
505
  }
500
506
 
@@ -803,7 +803,8 @@ export const COMPOSER_CSS = `/* ---------- phone composer (< 768px) ---------- *
803
803
  /* --- 8. the official stats strip leaves the composer ---
804
804
  Its data moves into the session info card (S4). The row is the composer
805
805
  dock's own \`_root\` entry; the slot itself stays live for later entries. */
806
- [data-slot="conversation.composer.dock"] > [class$="_root"] {
806
+ [data-slot="conversation.composer.dock"] > [class$="_root"],
807
+ [data-slot="conversation.composer.dock"] > [data-composer-stat] {
807
808
  display: none !important;
808
809
  }
809
810
 
package/src/intercept.ts CHANGED
@@ -1100,9 +1100,16 @@ export function rewriteResult(endpoint: string, value: unknown, serverId: string
1100
1100
  // mergeSessionList rewrite instead, merge-streams.ts.)
1101
1101
  if (!isPlainObject(value) || !isPlainObject(value.values)) return value
1102
1102
  const values: Record<string, unknown> = { ...value.values }
1103
- if (!Object.hasOwn(values, 'modelSelection')) return value
1103
+ // alpha.2 clients validate list/control projections with kind:'cached'|'sequenced'.
1104
+ // Older hosts (rc.2) omit it on the session/projections control-key result — synthesize.
1105
+ const withKind = typeof value.kind === 'string'
1106
+ ? value
1107
+ : (typeof value.asOfSeq === 'number' ? { ...value, kind: 'sequenced' as const } : value)
1108
+ if (!Object.hasOwn(values, 'modelSelection')) {
1109
+ return withKind === value ? value : { ...withKind, values }
1110
+ }
1104
1111
  values.modelSelection = virtualizeModelSelectionValue(values.modelSelection, serverId)
1105
- return { ...value, values }
1112
+ return { ...withKind, values }
1106
1113
  }
1107
1114
  if (endpoint === 'session/selectModel') {
1108
1115
  // T52: the result echoes the selection it accepted (`{selected: