dsh-connect-trae 3.6.1 → 3.7.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/CHANGELOG.md CHANGED
@@ -1,5 +1,45 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.7.0 (2026-10-17)
4
+
5
+ > **对齐 DSH 0.2.1-rc.1。** 宿主把 `@earendil-works/pi-ai` 从 `^0.85.1` 抬到 `^1.1.0`,
6
+ > 这是 0.2 线里唯一有行为影响的变更。本插件的请求体**没有**回归——但那是靠 3.4.2 的双向适配
7
+ > 兜住的,本版把这条结论从「推理」变成「被测住的对照」。
8
+
9
+ ### 变更
10
+
11
+ - **开发树对齐宿主实际随包版本**:13 个 `@deepseek-ai/dsh-*` devDependency 固定为 `0.2.1-rc.1`,
12
+ `cordis` → `^4.0.5`,`schemastery` → `3.18.5`(`pnpm-workspace.yaml` 的 override 同步抬升),
13
+ `@earendil-works/pi-ai` → **`1.1.0`(精确固定,不用 `^`)**,使本地 typecheck 与测试
14
+ 跑在与用户**字节一致**的契约上。
15
+ - **`@earendil-works/pi-ai` peer 上界收窄为 `<2.0.0`**:原先 `>=0.85.1` 无上界,会默默放行
16
+ 未审阅的 2.x。两端均已实测(0.85.1 ✅、1.1.0 ✅、1.3.0 ✅、2.0.0 ❌)。
17
+
18
+ ### 修复
19
+
20
+ - **pi-ai 1.1.0 的类型契约**:1.1.0 把 `ProviderStreams` 的第二参改成带 `unique symbol`
21
+ 品牌标记的 `TranscriptContext`,只有 `normalizeContext()` 能产出,于是 `withContextAdaptation`
22
+ 在两处调用点报 `TS2345`(升级后才暴露,0.85.1 下类型可通)。适配层本来就在归一化器
23
+ **下方**、且旧代分支**必须**产出无品牌形状,所以在这唯一一条边界上做显式转型,
24
+ 并在 `src/adapter.ts` 与测试侧 `send()` helper 处写明理由。
25
+
26
+ ### 测试
27
+
28
+ - 新增 **线上请求体矩阵**(`tests/pi-ai-context.spec.ts`):起一个真实 SSE 端点,走
29
+ `createProvider` + 真实 `openAICompletionsApi()`,断言线上 body 里 `roles[0] === 'system'`、
30
+ system 文本等于原提示、`tools` 长度为 1;并覆盖「已归一化输入不二次包裹」的幂等性。
31
+ - 新增 **反向对照**:**不**套适配器时,现代副本会把提示与工具全部丢光(`roles: ["user"]`、
32
+ `system: null`、`tools: 0`,且**不报错**)——这条钉住适配器为什么是承重的。
33
+ - 全仓 **663** 例测试通过(原 660 + 3),双 tsconfig 类型检查通过,构建通过。
34
+
35
+ ### 已核对、无需改动
36
+
37
+ - **peer 范围**:DSH 用 `satisfies(runtime, range, { includePrerelease: true })` 求值且只校验
38
+ `@deepseek-ai/dsh*`,`0.2.1-rc.1` 对 `>=0.1.7-rc.1 <0.3.0-0` 已判通过(实测)。预发布悬崖
39
+ 只在**默认选项**下成立,不适用于本插件的门禁。
40
+ - **宿主 API**:`dsh-llm` / `dsh-settings` / `dsh-host-webserver` / `dsh-llm-pi-ai` 消费点签名未变。
41
+ - **客户端外壳**:产物仍只 `require` react / react-dom / react/jsx-runtime,槽位与主题令牌未变。
42
+
3
43
  ## 3.6.1 (2026-10-16)
4
44
 
5
45
  > **「自动续期」不再是一句没有期限的承诺。** 卡片现在会告诉你**刷新令牌**何时到期 ——
package/README.en.md CHANGED
@@ -138,7 +138,7 @@ Restart the DSH process after install/update/uninstall.
138
138
  ## DSH version compatibility
139
139
 
140
140
  **Requires DSH 0.1.7-rc.1 and up** (since 2.3.0 the plugin no longer targets hosts older than 0.1.7; the peer dependency ranges are narrowed accordingly).
141
- **The peer upper bound is `<0.3.0-0`, so both the 0.1.7 and the 0.2 line are supported.**
141
+ **The peer upper bound is `<0.3.0-0`, so both the 0.1.7 and the 0.2 line are supported (including 0.2.1-rc.1, verified).**
142
142
 
143
143
  ### Both pi-ai context generations are supported (since 3.4.2)
144
144
 
@@ -161,6 +161,17 @@ The boundary is **0.86**: `dist/utils/transcript.js`, `normalizeContext`, the es
161
161
 
162
162
  The 0.2.0 line breaks **no** contract this plugin consumes — a symbol-by-symbol check confirmed every API it imports is unchanged ([full 0.2.0-rc.1 impact check](https://github.com/dingminhua/dsh-connect-trae/blob/main/docs/DSH_0.2.0_RC1_IMPACT_CHECK.md)). But since 0.1.7 DSH enforces a **bundle-level peer gate**: a bundle whose peers are unsatisfied is skipped **whole**, with one line on stderr and nothing in the UI — the plugin simply disappears.
163
163
 
164
+ ### DSH 0.2.1-rc.1 (pi-ai 1.1.0) sync
165
+
166
+ The `0.2.1-rc.1` host moved `@earendil-works/pi-ai` from `^0.85.1` to **`^1.1.0`** — the only change on the 0.2 line with real behavioural impact. Three conclusions:
167
+
168
+ 1. **The request body did not regress (measured, not inferred).** The 1.1.0 api reads the prompt **only** from a transcript system message and never touches top-level `systemPrompt` / `tools`, while `dsh-llm-pi-ai`'s `piContext()` still emits the legacy envelope. The bidirectional adapter this plugin has shipped since 3.4.2 covers exactly that: feeding the real host envelope through real `1.1.0` with a local SSE capture yields `roles: ["system","user"]`, an intact system text and `tools: 1`; **without the adapter it degenerates to `roles: ["user"]`, system `null`, `tools: 0`** — with no error. That contrast is pinned as a wire-level matrix in `tests/pi-ai-context.spec.ts`.
169
+ 2. **Types were fixed.** 1.1.0 changed `ProviderStreams`' second parameter to a **branded** `TranscriptContext` (a `unique symbol` only `normalizeContext()` can produce). The adapter casts once at that single boundary (`withContextAdaptation` in `src/adapter.ts`) and documents why the brand cannot be obtained honestly there.
170
+ 3. **The peer range needed no change.** DSH evaluates with `semver.satisfies(runtime, range, { includePrerelease: true })` and checks only the `@deepseek-ai/dsh*` namespace, so `>=0.1.7-rc.1 <0.3.0-0` already admits `0.2.1-rc.1` (verified). Note the prerelease cliff only exists under **default** options — it is not this plugin's situation.
171
+
172
+ The dev tree pins `@earendil-works/pi-ai` at exactly **1.1.0** (the version the host actually bundles) rather than `^1.1.0`, so local typecheck and tests run against the same contract users do; the `schemastery` override moved to `3.18.5` (`dsh-llm-pi-ai@0.2.1-rc.1` declares `~3.18.5`).
173
+
174
+
164
175
  ### Why the upper bound is not `<0.2.0`
165
176
 
166
177
  2.3.1 wrote `<0.2.0-0`, meaning "not the 0.2.0 release yet". That spelling is **wrong**: in SemVer `0.2.0-rc.1 < 0.2.0-0`, so it excluded the entire 0.2.0 **prerelease** line, and the plugin went dead the moment a user installed the first 0.2.0 prerelease.
package/README.md CHANGED
@@ -150,7 +150,7 @@ npm install dsh-connect-trae
150
150
  ## DSH 版本兼容
151
151
 
152
152
  **要求 DSH 0.1.7-rc.1 及以上**(2.3.0 起不再支持 0.1.7 之前的宿主;peer 依赖范围已按此收窄)。
153
- **peer 上界为 `<0.3.0-0`:0.1.7 与 0.2 两条线均受支持。**
153
+ **peer 上界为 `<0.3.0-0`:0.1.7 与 0.2 两条线均受支持(含 0.2.1-rc.1,已实测)。**
154
154
 
155
155
  ### 同时支持 pi-ai 的两代上下文(3.4.2 起)
156
156
 
@@ -182,6 +182,30 @@ DSH 自己横跨 `@earendil-works/pi-ai` 的两代,而**本插件解析到哪
182
182
  0.2.0 线对本插件**没有契约破坏**——逐符号核对确认插件消费的 API 全部未变([完整的 0.2.0-rc.1 影响面核对](https://github.com/dingminhua/dsh-connect-trae/blob/main/docs/DSH_0.2.0_RC1_IMPACT_CHECK.md))。但 0.1.7 起 DSH 有一道**bundle 级 peer 门禁**:
183
183
  peer 范围不满足的 bundle 会被**整体跳过**,只往 stderr 写一行,界面上表现为「插件凭空消失」。
184
184
 
185
+ ### DSH 0.2.1-rc.1(pi-ai 1.1.0)同步结论
186
+
187
+ 宿主 `0.2.1-rc.1` 把 `@earendil-works/pi-ai` 从 `^0.85.1` 抬到了 **`^1.1.0`**,这是 0.2 线里
188
+ 唯一有实际行为影响的变化。三项结论:
189
+
190
+ 1. **请求体没有丢东西(已实测)**。1.1.0 的 api **只**读 transcript 里的 system 消息,
191
+ 顶层 `systemPrompt` / `tools` 完全不再读取;而 `dsh-llm-pi-ai` 的 `piContext()` 仍然产出
192
+ 旧版信封。本插件 3.4.2 起就有的双向适配正好覆盖这一点——把真实宿主信封喂进真实
193
+ `1.1.0` + 本地 SSE 捕获线上请求体,得到 `roles: ["system","user"]`、system 文本完好、
194
+ `tools: 1`;**去掉适配则变成 `roles: ["user"]`、system `null`、`tools: 0`**(不报错)。
195
+ 这条对照已固化为 `tests/pi-ai-context.spec.ts` 的线上请求体矩阵。
196
+ 2. **类型面补齐**。1.1.0 把 `ProviderStreams` 的第二参改成带 `unique symbol` 品牌标记的
197
+ `TranscriptContext`,只有 `normalizeContext()` 能产出。适配层在这条边界上做一次显式转型
198
+ (`src/adapter.ts` 的 `withContextAdaptation`),并在两处调用点写明为何品牌在此处不可诚实获得。
199
+ 3. **peer 范围无需改动**。DSH 用 `semver.satisfies(runtime, range, { includePrerelease: true })`
200
+ 求值,且只校验 `@deepseek-ai/dsh*` 命名空间,因此 `>=0.1.7-rc.1 <0.3.0-0` 对 `0.2.1-rc.1` 已判通过
201
+ (已实测)。**注意**:预发布悬崖只在**默认选项**下成立——那是 `dsh-connect-workbuddy` 侧
202
+ 调研文档所描述的困境,本插件不适用。
203
+
204
+ 开发树的 `@earendil-works/pi-ai` 钉在 **1.1.0**(宿主实际随包的版本)而非 `^1.1.0`,
205
+ 使本地 typecheck 与测试跑在与用户完全一致的契约上;`schemastery` 的 override 同步抬到
206
+ `3.18.5`(`dsh-llm-pi-ai@0.2.1-rc.1` 声明 `~3.18.5`)。
207
+
208
+
185
209
  ### peer 上界为什么不写 `<0.2.0`
186
210
 
187
211
  2.3.1 曾写 `<0.2.0-0`,意图是「先不支持 0.2.0 正式版」。这个写法**是错的**:
package/lib/index.d.ts CHANGED
@@ -319,9 +319,10 @@ declare class TraeCatalog {
319
319
  *
320
320
  * The mismatch is reachable in BOTH directions, because DSH itself spans both
321
321
  * generations (`dsh-llm-pi-ai` ≤0.2.0-rc.1 declares `^0.85.1`; 0.2.0-rc.2 and
322
- * later declare `^0.87.1`, 0.2.1-alpha.2 declares `^1.0.2`), while this plugin
323
- * accepts the whole range (`>=0.1.7-rc.1 <0.3.0-0`). Whichever side is newer,
324
- * the other one is wrong:
322
+ * later declare `^0.87.1`, 0.2.1-alpha.2 declares `^1.0.2`, and 0.2.1-rc.1 —
323
+ * the current desktop host — declares **`^1.1.0`**, which also stopped reading
324
+ * the top-level fields entirely), while this plugin accepts the whole range
325
+ * (`>=0.1.7-rc.1 <0.3.0-0`). Whichever side is newer, the other one is wrong:
325
326
  *
326
327
  * | host | resolved api | outcome |
327
328
  * |---|---|---|
@@ -494,13 +495,17 @@ declare function adaptLegacyPiAiContext(context: Context): Context;
494
495
  * transcript a MODERN (0.86+) api consumes — the reverse mismatch, and just as
495
496
  * silent.
496
497
  *
497
- * WHY. DSH spans both generations (`dsh-llm-pi-ai` ≤0.2.0-rc.1 pins `^0.85.1`)
498
+ * WHY. DSH spans both generations (`dsh-llm-pi-ai` ≤0.2.0-rc.1 pins `^0.85.1`,
499
+ * while the 0.2.1-rc.1 desktop host pins `^1.1.0` and still emits the legacy
500
+ * envelope from its own `piContext()`)
498
501
  * while this plugin may resolve a newer copy than its host. A LEGACY host never
499
502
  * normalizes, so it hands the api the legacy shape; a modern api reads the
500
503
  * prompt from a leading system message and the tools from its `toolsAdded`, and
501
504
  * never looks at the top-level fields — so both are dropped without a sound.
502
505
  * Verified against the published tarballs: the request that reaches the wire
503
- * carries no system turn and `tools: []`.
506
+ * carries no system turn and `tools: []`. This is exactly the shape that
507
+ * `dsh-llm-pi-ai@0.2.1-rc.1` + `pi-ai@1.1.0` would hit unaided, which is why
508
+ * the wire-level matrix in `tests/pi-ai-context.spec.ts` pins both directions.
504
509
  *
505
510
  * Identity for anything already in transcript shape, and for a context with
506
511
  * neither a prompt nor tools (pi-ai's own `createInitialSystemMessage` returns
@@ -518,6 +523,27 @@ declare function adaptModernPiAiContext(context: Context): Context;
518
523
  * no context and are passed through untouched, and each adapter function is an
519
524
  * identity unless the context is actually the other generation's shape. So a
520
525
  * healthy install does one `Array.some` per request.
526
+ *
527
+ * THE CAST IS THE CONTRACT (pi-ai 1.1.0). From 1.1.0 `ProviderStreams` takes
528
+ * `TranscriptContext`, a BRANDED type whose `unique symbol` member only
529
+ * `normalizeContext()` can produce — so a `Context` is no longer assignable and
530
+ * `tsc` reports `TS2345` at both call sites below. The brand cannot be acquired
531
+ * honestly here, for two reasons that are both deliberate:
532
+ *
533
+ * 1. This wrapper sits BELOW the normalizer. `Models.stream()`/`streamSimple()`
534
+ * call `normalizeContext()` and hand a real transcript to the provider;
535
+ * `createProvider()` passes it straight through to `api.stream`. So on the
536
+ * modern path `adapt()` is an identity and the value already IS a branded
537
+ * transcript at runtime — the type just cannot see it across that boundary.
538
+ * 2. The legacy path REQUIRES an unbranded shape. pi-ai ≤0.85 has no
539
+ * `normalizeContext` and no transcript type at all, so its api expects
540
+ * exactly the `{ systemPrompt, tools, messages }` object `adapt()` returns.
541
+ *
542
+ * So the value handed to `api` is "a context of the generation that api
543
+ * speaks", which no single edition's declared type names. Casting at this one
544
+ * boundary is what makes both generations expressible; deriving the type from
545
+ * the resolved copy instead would make the wrapper uncompilable against the
546
+ * other generation, which is the whole point of having it.
521
547
  */
522
548
  declare function withContextAdaptation(api: ProviderStreams, generation: PiAiGeneration): ProviderStreams;
523
549
  interface TraeAdapterOptions {
package/lib/index.js CHANGED
@@ -344,9 +344,10 @@ var TraeCatalog = class {
344
344
  *
345
345
  * The mismatch is reachable in BOTH directions, because DSH itself spans both
346
346
  * generations (`dsh-llm-pi-ai` ≤0.2.0-rc.1 declares `^0.85.1`; 0.2.0-rc.2 and
347
- * later declare `^0.87.1`, 0.2.1-alpha.2 declares `^1.0.2`), while this plugin
348
- * accepts the whole range (`>=0.1.7-rc.1 <0.3.0-0`). Whichever side is newer,
349
- * the other one is wrong:
347
+ * later declare `^0.87.1`, 0.2.1-alpha.2 declares `^1.0.2`, and 0.2.1-rc.1 —
348
+ * the current desktop host — declares **`^1.1.0`**, which also stopped reading
349
+ * the top-level fields entirely), while this plugin accepts the whole range
350
+ * (`>=0.1.7-rc.1 <0.3.0-0`). Whichever side is newer, the other one is wrong:
350
351
  *
351
352
  * | host | resolved api | outcome |
352
353
  * |---|---|---|
@@ -689,13 +690,17 @@ function adaptLegacyPiAiContext(context) {
689
690
  * transcript a MODERN (0.86+) api consumes — the reverse mismatch, and just as
690
691
  * silent.
691
692
  *
692
- * WHY. DSH spans both generations (`dsh-llm-pi-ai` ≤0.2.0-rc.1 pins `^0.85.1`)
693
+ * WHY. DSH spans both generations (`dsh-llm-pi-ai` ≤0.2.0-rc.1 pins `^0.85.1`,
694
+ * while the 0.2.1-rc.1 desktop host pins `^1.1.0` and still emits the legacy
695
+ * envelope from its own `piContext()`)
693
696
  * while this plugin may resolve a newer copy than its host. A LEGACY host never
694
697
  * normalizes, so it hands the api the legacy shape; a modern api reads the
695
698
  * prompt from a leading system message and the tools from its `toolsAdded`, and
696
699
  * never looks at the top-level fields — so both are dropped without a sound.
697
700
  * Verified against the published tarballs: the request that reaches the wire
698
- * carries no system turn and `tools: []`.
701
+ * carries no system turn and `tools: []`. This is exactly the shape that
702
+ * `dsh-llm-pi-ai@0.2.1-rc.1` + `pi-ai@1.1.0` would hit unaided, which is why
703
+ * the wire-level matrix in `tests/pi-ai-context.spec.ts` pins both directions.
699
704
  *
700
705
  * Identity for anything already in transcript shape, and for a context with
701
706
  * neither a prompt nor tools (pi-ai's own `createInitialSystemMessage` returns
@@ -730,13 +735,35 @@ function adaptModernPiAiContext(context) {
730
735
  * no context and are passed through untouched, and each adapter function is an
731
736
  * identity unless the context is actually the other generation's shape. So a
732
737
  * healthy install does one `Array.some` per request.
738
+ *
739
+ * THE CAST IS THE CONTRACT (pi-ai 1.1.0). From 1.1.0 `ProviderStreams` takes
740
+ * `TranscriptContext`, a BRANDED type whose `unique symbol` member only
741
+ * `normalizeContext()` can produce — so a `Context` is no longer assignable and
742
+ * `tsc` reports `TS2345` at both call sites below. The brand cannot be acquired
743
+ * honestly here, for two reasons that are both deliberate:
744
+ *
745
+ * 1. This wrapper sits BELOW the normalizer. `Models.stream()`/`streamSimple()`
746
+ * call `normalizeContext()` and hand a real transcript to the provider;
747
+ * `createProvider()` passes it straight through to `api.stream`. So on the
748
+ * modern path `adapt()` is an identity and the value already IS a branded
749
+ * transcript at runtime — the type just cannot see it across that boundary.
750
+ * 2. The legacy path REQUIRES an unbranded shape. pi-ai ≤0.85 has no
751
+ * `normalizeContext` and no transcript type at all, so its api expects
752
+ * exactly the `{ systemPrompt, tools, messages }` object `adapt()` returns.
753
+ *
754
+ * So the value handed to `api` is "a context of the generation that api
755
+ * speaks", which no single edition's declared type names. Casting at this one
756
+ * boundary is what makes both generations expressible; deriving the type from
757
+ * the resolved copy instead would make the wrapper uncompilable against the
758
+ * other generation, which is the whole point of having it.
733
759
  */
734
760
  function withContextAdaptation(api, generation) {
735
761
  const adapt = generation === "modern" ? adaptModernPiAiContext : adaptLegacyPiAiContext;
762
+ const forApi = (context) => adapt(context);
736
763
  return {
737
764
  ...api,
738
- stream: (model, context, options) => api.stream(model, adapt(context), options),
739
- streamSimple: (model, context, options) => api.streamSimple(model, adapt(context), options)
765
+ stream: (model, context, options) => api.stream(model, forApi(context), options),
766
+ streamSimple: (model, context, options) => api.streamSimple(model, forApi(context), options)
740
767
  };
741
768
  }
742
769
  function createTraeAdapter(options) {
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "dsh-connect-trae",
3
3
  "displayName": "DSH Connect Trae",
4
4
  "description": "把本机登录的 Trae 模型接入 DeepSeek Harness:国内版与国际版双供应商并行,提供用量/积分概览与每日签到领取。",
5
- "version": "3.6.1",
5
+ "version": "3.7.0",
6
6
  "author": "dingminhua",
7
7
  "copyright": "Copyright (c) 2026 LaoDing",
8
8
  "license": "MIT",
@@ -85,26 +85,26 @@
85
85
  "@deepseek-ai/dsh-llm-pi-ai": ">=0.1.7-rc.1 <0.3.0-0",
86
86
  "@deepseek-ai/dsh-settings": ">=0.1.7-rc.1 <0.3.0-0",
87
87
  "@deepseek-ai/schemastery": ">=3.18.4 <4.0.0",
88
- "@earendil-works/pi-ai": ">=0.85.1",
88
+ "@earendil-works/pi-ai": ">=0.85.1 <2.0.0",
89
89
  "react": "^18.2.0"
90
90
  },
91
91
  "devDependencies": {
92
- "@deepseek-ai/cordis": "^4.0.4",
93
- "@deepseek-ai/dsh-atomic-write": "0.2.0-rc.1",
94
- "@deepseek-ai/dsh-attachment": "0.2.0-rc.1",
95
- "@deepseek-ai/dsh-client-locale": "0.2.0-rc.1",
96
- "@deepseek-ai/dsh-client-ui-primitives": "0.2.0-rc.1",
97
- "@deepseek-ai/dsh-client-ui-renderer": "0.2.0-rc.1",
98
- "@deepseek-ai/dsh-client-ui-settings": "0.2.0-rc.1",
99
- "@deepseek-ai/dsh-client-ui-settings-plugins": "0.2.0-rc.1",
100
- "@deepseek-ai/dsh-client-ui-slots": "0.2.0-rc.1",
101
- "@deepseek-ai/dsh-home-paths": "0.2.0-rc.1",
102
- "@deepseek-ai/dsh-host-webserver": "0.2.0-rc.1",
103
- "@deepseek-ai/dsh-llm": "0.2.0-rc.1",
104
- "@deepseek-ai/dsh-llm-pi-ai": "0.2.0-rc.1",
105
- "@deepseek-ai/dsh-settings": "0.2.0-rc.1",
106
- "@deepseek-ai/schemastery": "3.18.4",
107
- "@earendil-works/pi-ai": "^0.85.1",
92
+ "@deepseek-ai/cordis": "^4.0.5",
93
+ "@deepseek-ai/dsh-atomic-write": "0.2.1-rc.1",
94
+ "@deepseek-ai/dsh-attachment": "0.2.1-rc.1",
95
+ "@deepseek-ai/dsh-client-locale": "0.2.1-rc.1",
96
+ "@deepseek-ai/dsh-client-ui-primitives": "0.2.1-rc.1",
97
+ "@deepseek-ai/dsh-client-ui-renderer": "0.2.1-rc.1",
98
+ "@deepseek-ai/dsh-client-ui-settings": "0.2.1-rc.1",
99
+ "@deepseek-ai/dsh-client-ui-settings-plugins": "0.2.1-rc.1",
100
+ "@deepseek-ai/dsh-client-ui-slots": "0.2.1-rc.1",
101
+ "@deepseek-ai/dsh-home-paths": "0.2.1-rc.1",
102
+ "@deepseek-ai/dsh-host-webserver": "0.2.1-rc.1",
103
+ "@deepseek-ai/dsh-llm": "0.2.1-rc.1",
104
+ "@deepseek-ai/dsh-llm-pi-ai": "0.2.1-rc.1",
105
+ "@deepseek-ai/dsh-settings": "0.2.1-rc.1",
106
+ "@deepseek-ai/schemastery": "3.18.5",
107
+ "@earendil-works/pi-ai": "1.1.0",
108
108
  "@testing-library/dom": "^10.4.2",
109
109
  "@testing-library/react": "^16.3.3",
110
110
  "@types/node": "^22.20.0",