@deepseek-ai/dsh-client-test-runtime 0.1.3-alpha.2 → 0.1.5-alpha.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/README.i18n.yaml CHANGED
@@ -2,5 +2,5 @@
2
2
  # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
3
  # after editing either side, bring the other along and re-record with:
4
4
  # pnpm run verify-translation-pairing --write packages/test-support/client-runtime/README.md
5
- README.md: 4ab70ecb6db7ae7d1844d8141b34daf7bd19a3dc
6
- README.zh.md: c3265d7cdcadaf55c0744b13267ac5e64d6b47a6
5
+ README.md: 0b6caf7237520ca1a10fe0bbdf3c12c6d793461f
6
+ README.zh.md: 40d27ac534f0f93d539101e2006a37a918318a81
package/README.md CHANGED
@@ -9,7 +9,7 @@ English | [中文](README.zh.md)
9
9
 
10
10
  ## Summary
11
11
 
12
- `dsh-client-test-runtime` gives a browser feature spec a real jsdom test bench: it assembles a Cordis context, the renderer-owned slot registry, and the production `UiSession` adapter around typed Session and Workspace Controller doubles. A default file-upload stub satisfies features that declare the service and rejects if a test starts an upload without replacing it. Feature suites exercise declaration, registration, scoping, stores, injection, rendering, updates, and disposal without copying production renderer or adapter logic. Suites publish Session lifecycle state, Workspace state, projection values, and Conversation events through typed fixtures, then use local DOM snapshot roots, scoped Testing Library queries, and fail-loud service checks. It is not part of the product plugin graph (no `dsh.client`); feature packages depend on it in `devDependencies` only.
12
+ `dsh-client-test-runtime` lets browser feature specs exercise production slot, store, rendering, update, and disposal behavior in jsdom without reimplementing the UI runtime. Test authors can publish typed Session, Workspace, projection, and Conversation fixtures, query slot-local DOM roots, and script Remote replies or failures. Missing services, unstubbed session behavior, and unexpected file uploads fail at the call site, while disposal is idempotent. Use it only from in-repository browser-oriented Vitest suites through `devDependencies`; it is not a product plugin or general Node test harness.
13
13
 
14
14
  ## Table of Contents
15
15
 
@@ -29,7 +29,7 @@ This package gives a browser feature spec a real runtime to mount against: creat
29
29
 
30
30
  ### Setting up a feature spec
31
31
 
32
- `SlotTestRuntime.create()` assembles the runtime, `declare(children)` registers an auto frame whose per-key `<div data-slot>` wrappers become snapshot roots, `mount(plugin)` runs the feature on a real fiber, and `renderSlot(key, owner)` returns the slot-local view with scoped queries and in-place updates:
32
+ `SlotTestRuntime.create()` assembles the runtime, `declare(children)` registers an auto frame whose per-key `<div data-slot>` wrappers become snapshot roots, `mount(plugin)` runs the feature on a real fiber, and `renderSlot(key, owner, opts?)` returns the slot-local view with scoped queries and in-place updates:
33
33
 
34
34
  ```text
35
35
  const runtime = await SlotTestRuntime.create()
@@ -42,6 +42,8 @@ await runtime.dispose()
42
42
 
43
43
  `mount` prechecks required services and fails loud when one is missing — `provide(name, value)` supplies an extra service first. The runtime provides an unavailable `fileUpload` stub so assemblies can mount; replace `runtime.fileUpload.upload` before mounting when a test exercises upload behavior. `storeOf(key, scopeKey)` returns the live store instance the renderer hands a slot's component for identity and action-driven-write assertions.
44
44
 
45
+ The optional render options select a keyed entry with `entryKey` or a list item with `only`; `view.update(owner)` retains that selection. `runtime.panelInfo` supplies the default `usePanelInfo` source with no global panel selected. Release it with `releasePanelInfoSource()` before mounting the production Layout owner. `dispose()` releases both default Workspace and panel-info root sources; early release is idempotent and does not remove replacement owners.
46
+
45
47
  ### Local DOM snapshots
46
48
 
47
49
  A registered snapshot serializer folds CSS-module class hashes (`_frame_a1b2c3` → `frame`) so `.snap` files stay structural, and collapses `<svg>` internals to a `data-content` fingerprint. Suites needing a custom page frame use `root.declare(children, Frame)` instead of the auto frame; `dispose()` tears down views, feature fibers, minted scopes, and persisted store state on one axis and is idempotent.
package/README.zh.md CHANGED
@@ -9,7 +9,7 @@ kind: "package-library"
9
9
 
10
10
  ## 概述
11
11
 
12
- `dsh-client-test-runtime` 让浏览器功能测试拥有真实的 jsdom 测试台:它把 Cordis 上下文、渲染器拥有的 slot 注册表与生产 `UiSession` 适配器组装在带类型的 SessionWorkspace Controller 替身周围。默认文件上传替身可满足声明该服务的功能;测试若没有替换它却发起上传,就会明确失败。功能套件无需复制生产渲染器或适配器逻辑,即可检验声明、注册、作用域、store、注入、渲染、更新与销毁。套件通过带类型 fixture 发布 Session 生命周期状态、Workspace 状态、projection 值与 Conversation 事件,再使用局部 DOM 快照根、限定范围的 Testing Library 查询与自明的服务缺失检查。它不属于产品插件图(无 `dsh.client`);feature 包仅以 `devDependencies` 依赖之。
12
+ `dsh-client-test-runtime` 让浏览器功能测试在 jsdom 中检验生产 slot、store、渲染、更新与销毁行为,而无需重实现 UI 运行时。测试作者可以发布带类型的 SessionWorkspace、projection Conversation fixture,查询 slot 局部 DOM 根,并脚本化 Remote 应答或失败。缺失服务、未打桩的会话行为与意外文件上传都会在调用点失败,销毁则保持幂等。仅限仓内、面向浏览器的 Vitest 套件通过 `devDependencies` 使用本包;它不是产品插件或通用 Node 测试框架。
13
13
 
14
14
  ## 目录
15
15
 
@@ -29,7 +29,7 @@ kind: "package-library"
29
29
 
30
30
  ### 搭建功能测试
31
31
 
32
- `SlotTestRuntime.create()` 组装运行时,`declare(children)` 注册一个自动 frame,其逐 key 的 `<div data-slot>` 包裹层成为快照根,`mount(plugin)` 在真实 fiber 上运行功能,`renderSlot(key, owner)` 返回带限定查询与原位更新的 slot 局部视图:
32
+ `SlotTestRuntime.create()` 组装运行时,`declare(children)` 注册一个自动 frame,其逐 key 的 `<div data-slot>` 包裹层成为快照根,`mount(plugin)` 在真实 fiber 上运行功能,`renderSlot(key, owner, opts?)` 返回带限定查询与原位更新的 slot 局部视图:
33
33
 
34
34
  ```text
35
35
  const runtime = await SlotTestRuntime.create()
@@ -42,6 +42,8 @@ await runtime.dispose()
42
42
 
43
43
  `mount` 会预检必需服务,缺失时自明报错——先用 `provide(name, value)` 提供额外服务。运行时会提供不可用的 `fileUpload` 替身,使装配可以挂载;测试上传行为时,需要在挂载前替换 `runtime.fileUpload.upload`。`storeOf(key, scopeKey)` 返回渲染器交给 slot 组件的实时 store 实例,用于身份与动作驱动写入断言。
44
44
 
45
+ 可选渲染参数通过 `entryKey` 选择 keyed 条目,或通过 `only` 选择 list 条目;`view.update(owner)` 保留该选择。`runtime.panelInfo` 提供默认的 `usePanelInfo` 数据源,初始不选中全局面板。挂载生产 Layout 所有者之前,先调用 `releasePanelInfoSource()` 释放该数据源。`dispose()` 同时释放默认的工作区与面板信息根数据源;提前释放是幂等的,不会移除替代它们的所有者。
46
+
45
47
  ### 局部 DOM 快照
46
48
 
47
49
  注册的快照序列化器把 CSS-module 哈希类名折回语义名(`_frame_a1b2c3` → `frame`),使 `.snap` 文件只含结构,并把 `<svg>` 内部折叠为 `data-content` 指纹。需要自定义页面 frame 的套件改用 `root.declare(children, Frame)` 而非自动 frame;`dispose()` 沿单一轴拆除视图、feature fiber、已铸 scope 与持久化 store 状态,且幂等。
package/lib/index.js CHANGED
@@ -5,9 +5,9 @@ import { SlotRegistry } from "@deepseek-ai/dsh-client-ui-renderer/client";
5
5
  import { bindSnapshotSelector as bindSnapshotSelector$1 } from "@deepseek-ai/dsh-client-ui-renderer/src/client/bind.ts";
6
6
  import { createSlotRenderer as createSlotRenderer$1 } from "@deepseek-ai/dsh-client-ui-renderer/src/client/scoped-slots.tsx";
7
7
  import { apply, inject } from "@deepseek-ai/dsh-client-ui-session/client";
8
+ import { createSnapshotStore } from "@deepseek-ai/dsh-client-store";
8
9
  import { afterEach, beforeEach, expect, vi } from "vitest";
9
10
  import { MutableSessionEventSource, SESSION_SEARCH_RESULT_LIMIT, createScope, scopeOf } from "@deepseek-ai/dsh-api-session-controller/client";
10
- import { createSnapshotStore } from "@deepseek-ai/dsh-client-store";
11
11
  import { EMPTY_CONVERSATION_SNAPSHOT } from "@deepseek-ai/dsh-client-ui-conversation/client";
12
12
  import { EMPTY_CHAT_SNAPSHOT } from "@deepseek-ai/dsh-client-ui-chat/client";
13
13
  import { RemoteError } from "@deepseek-ai/dsh-typert-protocol";
@@ -1115,9 +1115,13 @@ var OwnerPropsCell = class {
1115
1115
  * caller wraps in act).
1116
1116
  * @param key - slot key.
1117
1117
  * @param owner - owner props share.
1118
+ * @param opts - explicit keyed or list selection for the render site.
1118
1119
  */
1119
- set(key, owner) {
1120
- this.owners.set(key, owner);
1120
+ set(key, owner, opts) {
1121
+ this.owners.set(key, {
1122
+ owner,
1123
+ opts
1124
+ });
1121
1125
  this.version += 1;
1122
1126
  for (const fn of [...this.listeners]) fn();
1123
1127
  }
@@ -1182,6 +1186,8 @@ var SlotTestRuntime = class SlotTestRuntime {
1182
1186
  sessions;
1183
1187
  /** Workspaces double (list observable, recorded intent actions). */
1184
1188
  workspaces;
1189
+ /** Test-owned panel selection used by the framework's usePanelInfo hook. */
1190
+ panelInfo = createSnapshotStore({ activePanelId: null });
1185
1191
  /** Mutable file-upload stub; replace `upload` in suites that exercise the capability. */
1186
1192
  fileUpload;
1187
1193
  stabilizer = async (fn) => {
@@ -1198,6 +1204,7 @@ var SlotTestRuntime = class SlotTestRuntime {
1198
1204
  autoDeclared = /* @__PURE__ */ new Set();
1199
1205
  autoRootView;
1200
1206
  disposeWorkspaceSource;
1207
+ disposePanelInfoSource;
1201
1208
  constructor(ctx, slots) {
1202
1209
  this.ctx = ctx;
1203
1210
  this.slots = slots;
@@ -1212,6 +1219,7 @@ var SlotTestRuntime = class SlotTestRuntime {
1212
1219
  ctx.provide("workspaces", this.workspaces);
1213
1220
  ctx.provide("fileUpload", this.fileUpload);
1214
1221
  this.disposeWorkspaceSource = slots.provideRoot({ hooks: { workspaces: this.workspaces.list } });
1222
+ this.disposePanelInfoSource = slots.provideRoot({ hooks: { panelInfo: this.panelInfo } });
1215
1223
  const renderer = createSlotRenderer();
1216
1224
  slots.install({ renderRoot: (host, ownerProps) => {
1217
1225
  this.host = host;
@@ -1264,6 +1272,10 @@ var SlotTestRuntime = class SlotTestRuntime {
1264
1272
  releaseWorkspaceSource() {
1265
1273
  this.disposeWorkspaceSource();
1266
1274
  }
1275
+ /** Release the default panel hook before mounting the production Layout owner. */
1276
+ releasePanelInfoSource() {
1277
+ this.disposePanelInfoSource();
1278
+ }
1267
1279
  /**
1268
1280
  * Render the root slot tree through the ctx-level entry (the shell's own
1269
1281
  * entry point): `ctx.slots.renderSlot('root', {})` under Testing Library.
@@ -1289,7 +1301,7 @@ var SlotTestRuntime = class SlotTestRuntime {
1289
1301
  const cell = this.ownerCell;
1290
1302
  const AutoFrame = (props) => {
1291
1303
  useSyncExternalStore(cell.subscribe, cell.getVersion);
1292
- return createElement(Fragment, null, cell.entries().map(([key, owner]) => createElement(Fragment, { key }, props.renderSlot(key, owner))));
1304
+ return createElement(Fragment, null, cell.entries().map(([key, { owner, opts }]) => createElement(Fragment, { key }, props.renderSlot(key, owner, opts))));
1293
1305
  };
1294
1306
  await this.root.declare(children, AutoFrame);
1295
1307
  }
@@ -1301,13 +1313,14 @@ var SlotTestRuntime = class SlotTestRuntime {
1301
1313
  * slot of the same tree.
1302
1314
  * @param key - a key declared through {@link SlotTestRuntime.declare}.
1303
1315
  * @param owner - owner props share for the render site.
1316
+ * @param opts - explicit keyed or list selection; retained by view updates.
1304
1317
  * @returns the slot-local view (snapshot container, scoped queries, owner updates).
1305
1318
  */
1306
- renderSlot(key, owner) {
1319
+ renderSlot(key, owner, opts) {
1307
1320
  if (!this.autoDeclared.has(key)) throw new Error(`renderSlot('${key}') without declare() — declare the key first (or use root.declare for a custom frame)`);
1308
1321
  const install = (next) => {
1309
1322
  act(() => {
1310
- this.ownerCell.set(key, next);
1323
+ this.ownerCell.set(key, next, opts);
1311
1324
  });
1312
1325
  };
1313
1326
  install(owner);
@@ -1349,7 +1362,7 @@ var SlotTestRuntime = class SlotTestRuntime {
1349
1362
  }
1350
1363
  /**
1351
1364
  * Tear down: unmount React trees first, then dispose feature fibers, the
1352
- * root registration, minted session scopes, and persisted test state.
1365
+ * root registration and standard sources, minted session scopes, and persisted test state.
1353
1366
  * Idempotent.
1354
1367
  * @returns completion of the teardown.
1355
1368
  */
@@ -1360,6 +1373,8 @@ var SlotTestRuntime = class SlotTestRuntime {
1360
1373
  for (const view of this.views.splice(0)) view.unmount();
1361
1374
  for (const handle of this.handles.splice(0)) await handle.dispose();
1362
1375
  this.root.release();
1376
+ this.disposeWorkspaceSource();
1377
+ this.disposePanelInfoSource();
1363
1378
  await this.sessions.disposeScopes();
1364
1379
  localStorage.clear();
1365
1380
  }
@@ -17,7 +17,8 @@ import type { queries } from '@testing-library/dom';
17
17
  import type { BoundFunctions } from '@testing-library/dom';
18
18
  import { SlotRegistry } from '@deepseek-ai/dsh-client-ui-renderer/client';
19
19
  import type { SessionId } from '@deepseek-ai/dsh-session/types';
20
- import type { ChildrenDecl, ComposedProps, HostObservable, OwnerOf, SlotComponent, SlotMap, SlotRenderer, SnapshotSelectorHook, StoreInstanceLike } from '@deepseek-ai/dsh-client-ui-slots';
20
+ import type { PanelInfo } from '@deepseek-ai/dsh-client-ui-layout/client';
21
+ import type { ChildrenDecl, ComposedProps, HostObservable, OwnerOf, RenderOpts, SlotComponent, SlotMap, SlotRenderer, SnapshotSelectorHook, StoreInstanceLike } from '@deepseek-ai/dsh-client-ui-slots';
21
22
  import { TestSessions } from './sessions.ts';
22
23
  import { TestWorkspaces } from './workspaces.ts';
23
24
  import type { Stabilizer } from './fixtures.ts';
@@ -128,6 +129,8 @@ export declare class SlotTestRuntime {
128
129
  readonly sessions: TestSessions;
129
130
  /** Workspaces double (list observable, recorded intent actions). */
130
131
  readonly workspaces: TestWorkspaces;
132
+ /** Test-owned panel selection used by the framework's usePanelInfo hook. */
133
+ readonly panelInfo: import("@deepseek-ai/dsh-client-store").SnapshotStore<PanelInfo>;
131
134
  /** Mutable file-upload stub; replace `upload` in suites that exercise the capability. */
132
135
  readonly fileUpload: TestFileUpload;
133
136
  private readonly stabilizer;
@@ -140,6 +143,7 @@ export declare class SlotTestRuntime {
140
143
  private readonly autoDeclared;
141
144
  private autoRootView;
142
145
  private readonly disposeWorkspaceSource;
146
+ private readonly disposePanelInfoSource;
143
147
  private constructor();
144
148
  /**
145
149
  * Assemble a runtime: real Context, mounted SlotRegistry, installed
@@ -157,6 +161,8 @@ export declare class SlotTestRuntime {
157
161
  mount(plugin: Plugin): Promise<FeatureHandle>;
158
162
  /** Release the default Workspace hook before mounting its production owner. */
159
163
  releaseWorkspaceSource(): void;
164
+ /** Release the default panel hook before mounting the production Layout owner. */
165
+ releasePanelInfoSource(): void;
160
166
  /**
161
167
  * Render the root slot tree through the ctx-level entry (the shell's own
162
168
  * entry point): `ctx.slots.renderSlot('root', {})` under Testing Library.
@@ -182,9 +188,10 @@ export declare class SlotTestRuntime {
182
188
  * slot of the same tree.
183
189
  * @param key - a key declared through {@link SlotTestRuntime.declare}.
184
190
  * @param owner - owner props share for the render site.
191
+ * @param opts - explicit keyed or list selection; retained by view updates.
185
192
  * @returns the slot-local view (snapshot container, scoped queries, owner updates).
186
193
  */
187
- renderSlot<K extends keyof SlotMap & string>(key: K, owner: OwnerOf<K>): SlotView<K>;
194
+ renderSlot<K extends keyof SlotMap & string>(key: K, owner: OwnerOf<K>, opts?: RenderOpts): SlotView<K>;
188
195
  /**
189
196
  * Resolve the store instance the renderer would hand a slot's component
190
197
  * (identity assertions, action-driven writes). Requires a prior
@@ -203,7 +210,7 @@ export declare class SlotTestRuntime {
203
210
  flush(): Promise<void>;
204
211
  /**
205
212
  * Tear down: unmount React trees first, then dispose feature fibers, the
206
- * root registration, minted session scopes, and persisted test state.
213
+ * root registration and standard sources, minted session scopes, and persisted test state.
207
214
  * Idempotent.
208
215
  * @returns completion of the teardown.
209
216
  */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-client-test-runtime",
3
3
  "description": "jsdom slot test runtime: real Cordis Context + SlotRegistry + UI renderer with test-owned session/workspace doubles for feature specs",
4
- "version": "0.1.3-alpha.2",
4
+ "version": "0.1.5-alpha.2",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -30,41 +30,42 @@
30
30
  "peerDependencies": {
31
31
  "react": "^18.2.0",
32
32
  "react-dom": "^18.2.0",
33
- "@deepseek-ai/dsh-api-session-controller": "^0.1.3-alpha.2",
34
- "@deepseek-ai/dsh-attachment": "^0.1.3-alpha.2",
35
- "@deepseek-ai/dsh-client-connection": "^0.1.3-alpha.2",
36
- "@deepseek-ai/dsh-client-store": "^0.1.3-alpha.2",
37
- "@deepseek-ai/dsh-client-ui-chat": "^0.1.3-alpha.2",
38
- "@deepseek-ai/dsh-client-ui-conversation": "^0.1.3-alpha.2",
39
- "@deepseek-ai/dsh-client-ui-session": "^0.1.3-alpha.2",
40
- "@deepseek-ai/dsh-client-ui-settings": "^0.1.3-alpha.2",
41
- "@deepseek-ai/dsh-client-ui-slots": "^0.1.3-alpha.2",
42
- "@deepseek-ai/dsh-client-ui-renderer": "^0.1.3-alpha.2",
43
- "@deepseek-ai/dsh-subagent": "^0.1.3-alpha.2",
44
- "@deepseek-ai/dsh-session": "^0.1.3-alpha.2",
45
- "@deepseek-ai/cordis": "^4.0.2",
46
- "@deepseek-ai/dsh-typert-protocol": "^0.1.3-alpha.2",
47
- "@deepseek-ai/dsh-api-workspace-controller": "^0.1.3-alpha.2"
33
+ "@deepseek-ai/dsh-api-session-controller": "^0.1.5-alpha.2",
34
+ "@deepseek-ai/dsh-api-workspace-controller": "^0.1.5-alpha.2",
35
+ "@deepseek-ai/dsh-attachment": "^0.1.5-alpha.2",
36
+ "@deepseek-ai/dsh-client-store": "^0.1.5-alpha.2",
37
+ "@deepseek-ai/dsh-client-ui-chat": "^0.1.5-alpha.2",
38
+ "@deepseek-ai/dsh-client-connection": "^0.1.5-alpha.2",
39
+ "@deepseek-ai/dsh-client-ui-conversation": "^0.1.5-alpha.2",
40
+ "@deepseek-ai/dsh-client-ui-renderer": "^0.1.5-alpha.2",
41
+ "@deepseek-ai/dsh-client-ui-session": "^0.1.5-alpha.2",
42
+ "@deepseek-ai/dsh-client-ui-settings": "^0.1.5-alpha.2",
43
+ "@deepseek-ai/dsh-client-ui-slots": "^0.1.5-alpha.2",
44
+ "@deepseek-ai/dsh-session": "^0.1.5-alpha.2",
45
+ "@deepseek-ai/dsh-subagent": "^0.1.5-alpha.2",
46
+ "@deepseek-ai/dsh-typert-protocol": "^0.1.5-alpha.2",
47
+ "@deepseek-ai/cordis": "^4.0.2"
48
48
  },
49
49
  "devDependencies": {
50
50
  "@types/react": "~18.3.1",
51
51
  "@types/react-dom": "~18.3.0",
52
52
  "react": "^18.2.0",
53
53
  "react-dom": "^18.2.0",
54
- "@deepseek-ai/dsh-api-session-controller": "^0.1.3-alpha.2",
55
- "@deepseek-ai/dsh-api-workspace-controller": "^0.1.3-alpha.2",
56
- "@deepseek-ai/dsh-attachment": "^0.1.3-alpha.2",
57
- "@deepseek-ai/dsh-client-connection": "^0.1.3-alpha.2",
58
- "@deepseek-ai/dsh-client-store": "^0.1.3-alpha.2",
59
- "@deepseek-ai/dsh-client-ui-chat": "^0.1.3-alpha.2",
60
- "@deepseek-ai/dsh-client-ui-renderer": "^0.1.3-alpha.2",
61
- "@deepseek-ai/dsh-client-ui-session": "^0.1.3-alpha.2",
62
- "@deepseek-ai/dsh-client-ui-settings": "^0.1.3-alpha.2",
63
- "@deepseek-ai/dsh-client-ui-slots": "^0.1.3-alpha.2",
64
- "@deepseek-ai/dsh-session": "^0.1.3-alpha.2",
65
- "@deepseek-ai/dsh-client-ui-conversation": "^0.1.3-alpha.2",
66
- "@deepseek-ai/dsh-subagent": "^0.1.3-alpha.2",
67
- "@deepseek-ai/dsh-typert-protocol": "^0.1.3-alpha.2",
54
+ "@deepseek-ai/dsh-api-session-controller": "^0.1.5-alpha.2",
55
+ "@deepseek-ai/dsh-api-workspace-controller": "^0.1.5-alpha.2",
56
+ "@deepseek-ai/dsh-attachment": "^0.1.5-alpha.2",
57
+ "@deepseek-ai/dsh-client-connection": "^0.1.5-alpha.2",
58
+ "@deepseek-ai/dsh-client-store": "^0.1.5-alpha.2",
59
+ "@deepseek-ai/dsh-client-ui-chat": "^0.1.5-alpha.2",
60
+ "@deepseek-ai/dsh-client-ui-layout": "^0.1.5-alpha.2",
61
+ "@deepseek-ai/dsh-client-ui-conversation": "^0.1.5-alpha.2",
62
+ "@deepseek-ai/dsh-client-ui-renderer": "^0.1.5-alpha.2",
63
+ "@deepseek-ai/dsh-client-ui-session": "^0.1.5-alpha.2",
64
+ "@deepseek-ai/dsh-client-ui-settings": "^0.1.5-alpha.2",
65
+ "@deepseek-ai/dsh-client-ui-slots": "^0.1.5-alpha.2",
66
+ "@deepseek-ai/dsh-session": "^0.1.5-alpha.2",
67
+ "@deepseek-ai/dsh-subagent": "^0.1.5-alpha.2",
68
+ "@deepseek-ai/dsh-typert-protocol": "^0.1.5-alpha.2",
68
69
  "@deepseek-ai/cordis": "^4.0.2"
69
70
  },
70
71
  "files": [