@deepseek-ai/dsh-client-ui-workspace 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/client/ui-workspace/README.md
5
- README.md: c7e0e7e53886b6ae1a4de7c40ed6041a61280446
6
- README.zh.md: 695e89acb967924f0f617b7c17b6581ee38f8ba5
5
+ README.md: 857b38c2ca08ca4e9078d8f9dfcfe8462be50722
6
+ README.zh.md: cf6f2d273f00add793cc5ac588db968c22007256
package/README.md CHANGED
@@ -9,7 +9,7 @@ English | [中文](README.zh.md)
9
9
 
10
10
  ## Summary
11
11
 
12
- `dsh-client-ui-workspace` is the shared Workspace browser and picker of the dsh web client: users browse grouped or flat Session rows in the sidebar, pick a Workspace for a new session from the Session Intent hero, and manage Workspaces and Sessions with add, rename, reorder, search, fork, and archive actions; the same Workspace menu and add flow serve both surfaces. Pending user interactions surface as amber warning dots, active Schedule projections surface as non-interactive alarm markers in ordinary and search rows, and the shared sidebar projection hides subagent-origin sessions. Distinct canonical paths remain separate id-keyed Workspaces, and adding a folder goes through a directory-flow child hole that a composed picker package's client half fills.
12
+ This package lets users browse grouped or flat Session lists, choose a Workspace for a new Session, and manage Workspaces and Sessions through add, rename, reorder, search, fork, archive, and Workspace deletion. Pending interactions appear as warning dots, active scheduled tasks as alarm markers, and subagent-origin Sessions remain hidden. Canonically distinct folder paths remain separate Workspaces. Adding a Workspace requires a composed directory picker; without one, the add action is unavailable.
13
13
 
14
14
  ## Table of Contents
15
15
 
@@ -51,6 +51,8 @@ The value is intentionally best effort for cold Sessions. An identity-matching u
51
51
 
52
52
  -----
53
53
 
54
+ `ctx.uiWorkspace.openSession(id)` selects the Session and returns the main area to the Conversation as one UI navigation action, including when that Session was already current. `openWorkspace(id, beforeOpen?)` and `forkSession(id)` open their result only if no later navigation has superseded the request; New Session uses `openWorkspace`. The optional synchronous preparation callback runs only for a current Workspace request, so superseded requests do not move composer drafts. Navigation or owner disposal suppresses the late UI commit, not the underlying Session creation. Selection failure leaves a global panel visible. Session rows read `usePanelInfo` to suppress their selected appearance while a global panel is active; search and directory-picker focus alone do not leave that panel.
55
+
54
56
  <a id="understand-the-implementation"></a>
55
57
  ## Understand the implementation
56
58
 
package/README.zh.md CHANGED
@@ -9,7 +9,7 @@ kind: "package-reference"
9
9
 
10
10
  ## 概述
11
11
 
12
- `dsh-client-ui-workspace` 是 dsh Web 客户端的共享 Workspace 浏览器与选择器:用户在侧边栏浏览分组或扁平的 Session 行,在 Session Intent 主视觉区为新会话选择 Workspace,并可用添加、重命名、重排序、搜索、fork 与归档操作管理 Workspace 与 Session;两个界面共用同一套 Workspace 菜单与添加流程。待处理的用户交互以琥珀色警告点呈现,活动 Schedule projection 会在普通行与搜索结果中显示不可交互的闹钟,共享侧边栏投影还会隐藏 subagent 来源的会话。不同的规范化路径仍作为由 id 区分的独立 Workspace;添加文件夹走目录流子 slot,由组合的选择器包 client half 填充。
12
+ 本包让用户浏览分组或扁平的 Session 列表、为新 Session 选择 Workspace,并通过添加、重命名、重排序、搜索、fork、归档和删除 Workspace 来管理 Workspace 与 Session。待处理交互显示为警告点,活动定时任务显示为闹钟标识,subagent 来源的 Session 则保持隐藏。规范化后仍有差异的文件夹路径会保留为独立 Workspace。添加 Workspace 需要组合目录选择器;没有目录选择器时,添加操作不可用。
13
13
 
14
14
  ## 目录
15
15
 
@@ -51,6 +51,8 @@ Session 行渲染运行时的实时 `pendingInteraction` 分类:审批显示**
51
51
 
52
52
  -----
53
53
 
54
+ `ctx.uiWorkspace.openSession(id)` 将选中会话与中央区域返回会话界面作为一次 UI 导航操作,包括目标会话已经是当前会话的情况。`openWorkspace(id, beforeOpen?)` 和 `forkSession(id)` 仅在请求未被后续导航替代时打开结果;新会话使用 `openWorkspace`。可选的同步准备回调仅对仍有效的工作区请求执行,因此过期请求不会搬移 composer 草稿。后续导航或所有者释放会阻止晚到的 UI 提交,但不取消底层会话创建。选中失败时保留当前全局面板。会话行读取 `usePanelInfo`,在全局面板活跃时不显示会话选中样式;仅把焦点移到搜索框或目录选择器不会离开该面板。
55
+
54
56
  <a id="understand-the-implementation"></a>
55
57
  ## 理解实现
56
58
 
package/lib/client.js CHANGED
@@ -27,6 +27,7 @@ window.__ModuleLoader__.load({
27
27
  workspaces;
28
28
  sessions;
29
29
  connecting = /* @__PURE__ */ new Map();
30
+ lifetime = new AbortController();
30
31
  /**
31
32
  * @param ctx - Client root Context.
32
33
  * @param directoryPicker - the directory-picking Remote namespace.
@@ -57,6 +58,26 @@ window.__ModuleLoader__.load({
57
58
  this.connecting.set(workspaceId, attempt);
58
59
  return attempt;
59
60
  }
61
+ openSession(sessionId) {
62
+ this.sessions.open(sessionId);
63
+ this.ctx.layout.selectPanel(null);
64
+ }
65
+ async openWorkspace(workspaceId, beforeOpen) {
66
+ const navigation = AbortSignal.any([this.ctx.layout.beginNavigation(), this.lifetime.signal]);
67
+ const isCurrent = () => !navigation.aborted;
68
+ const sessionId = await this.connectWorkspace(workspaceId);
69
+ if (!isCurrent()) return;
70
+ beforeOpen?.(sessionId);
71
+ if (isCurrent()) this.openSession(sessionId);
72
+ }
73
+ async forkSession(sessionId) {
74
+ const navigation = AbortSignal.any([this.ctx.layout.beginNavigation(), this.lifetime.signal]);
75
+ const childId = await this.sessions.fork({
76
+ sessionId,
77
+ increaseTitle: true
78
+ });
79
+ if (!navigation.aborted) this.openSession(childId);
80
+ }
60
81
  startSession(workspaceId) {
61
82
  const workspace = this.workspaces.list.getSnapshot();
62
83
  const sessions = this.sessions.list.getSnapshot();
@@ -66,11 +87,10 @@ window.__ModuleLoader__.load({
66
87
  const target = workspaceId ?? currentWorkspaceId ?? recent;
67
88
  if (target === void 0) {
68
89
  this.sessions.clear();
90
+ this.ctx.layout.selectPanel(null);
69
91
  return;
70
92
  }
71
- this.connectWorkspace(target).then((sessionId) => {
72
- this.sessions.open(sessionId);
73
- }, (reason) => {
93
+ this.openWorkspace(target).catch((reason) => {
74
94
  console.warn("new session failed:", reason);
75
95
  });
76
96
  }
@@ -94,9 +114,8 @@ window.__ModuleLoader__.load({
94
114
  }
95
115
  watchNavigation() {
96
116
  let initial = "waiting";
97
- let disposed = false;
98
117
  const reconcile = () => {
99
- if (disposed) return;
118
+ if (this.lifetime.signal.aborted) return;
100
119
  if (this.clearArchivedCurrent()) return;
101
120
  if (initial !== "waiting") return;
102
121
  const workspace = this.workspaces.list.getSnapshot();
@@ -113,11 +132,11 @@ window.__ModuleLoader__.load({
113
132
  }
114
133
  initial = "connecting";
115
134
  this.connectWorkspace(target).then((sessionId) => {
116
- if (disposed) return;
135
+ if (this.lifetime.signal.aborted) return;
117
136
  if (this.sessions.list.getSnapshot().current === void 0) this.sessions.open(sessionId);
118
137
  initial = "done";
119
138
  }, (reason) => {
120
- if (disposed) return;
139
+ if (this.lifetime.signal.aborted) return;
121
140
  initial = "waiting";
122
141
  console.warn("initial workspace selection failed:", reason);
123
142
  });
@@ -126,7 +145,7 @@ window.__ModuleLoader__.load({
126
145
  const disposeSessions = this.sessions.list.subscribe(reconcile);
127
146
  reconcile();
128
147
  return () => {
129
- disposed = true;
148
+ this.lifetime.abort();
130
149
  disposeSessions();
131
150
  disposeWorkspaces();
132
151
  };
@@ -225,10 +244,6 @@ window.__ModuleLoader__.load({
225
244
  }
226
245
  //#endregion
227
246
  //#region ../../util/workspace-path/src/index.ts
228
- /**
229
- * Browser-safe Workspace path and display helpers.
230
- * @module @deepseek-ai/dsh-util-workspace-path
231
- */
232
247
  /** Whether a path uses a Windows drive or UNC prefix. */
233
248
  function isWindowsStylePath(value) {
234
249
  return /^[A-Za-z]:[/\\]/.test(value) || value.startsWith("\\\\");
@@ -1446,10 +1461,11 @@ window.__ModuleLoader__.load({
1446
1461
  return e.clientY < rect.top + rect.height / 2 ? "before" : "after";
1447
1462
  }
1448
1463
  /** The scrolling session tree; unmounting drops the sessions subscription and expand-all state. */
1449
- function SessionTree({ useSessions, useSessionPendingInteraction, startSession, open, forkSession, workspaces, archivedSessionIds, workspaceReady, onRenameRequest, onDeleteRequest, onSessionRename, onSessionArchive, insertWorkspaceBefore, insertSessionBefore, orderBy, groupExpansion, setGroupExpanded, sessionOrderByAccount, sessionUpdatedAtByAccount, syncSessionOrderAccount, setSessionOrder, home, t, revealSessionId, onSessionRevealed }) {
1464
+ function SessionTree({ useSessions, useSessionPendingInteraction, startSession, open, forkSession, workspaces, archivedSessionIds, workspaceReady, usePanelInfo, onRenameRequest, onDeleteRequest, onSessionRename, onSessionArchive, insertWorkspaceBefore, insertSessionBefore, orderBy, groupExpansion, setGroupExpanded, sessionOrderByAccount, sessionUpdatedAtByAccount, syncSessionOrderAccount, setSessionOrder, home, t, revealSessionId, onSessionRevealed }) {
1465
+ const panelActive = usePanelInfo((info) => info.activePanelId !== null);
1450
1466
  const list = useSessions((s) => s);
1451
1467
  const pendingInteractions = useSessionPendingInteraction((s) => s);
1452
- const current = list.current;
1468
+ const current = panelActive ? void 0 : list.current;
1453
1469
  const revealGroup = revealSessionId === void 0 || !workspaceReady ? void 0 : owningGroupKey(workspaces, revealSessionId);
1454
1470
  const [expandedSessionGroups, setExpandedSessionGroups] = (0, react.useState)([]);
1455
1471
  const [drag, setDrag] = (0, react.useState)(null);
@@ -1766,7 +1782,8 @@ window.__ModuleLoader__.load({
1766
1782
  });
1767
1783
  }
1768
1784
  /** The flat "In one list" body: every session is one draggable top-level row. */
1769
- function FlatList({ useSessions, useSessionPendingInteraction, open, forkSession, onSessionRename, onSessionArchive, archivedSessionIds, orderBy, sessionOrderByAccount, sessionUpdatedAtByAccount, syncSessionOrderAccount, setSessionOrder, revealSessionId, onSessionRevealed, t }) {
1785
+ function FlatList({ useSessions, useSessionPendingInteraction, open, forkSession, onSessionRename, onSessionArchive, archivedSessionIds, usePanelInfo, orderBy, sessionOrderByAccount, sessionUpdatedAtByAccount, syncSessionOrderAccount, setSessionOrder, revealSessionId, onSessionRevealed, t }) {
1786
+ const panelActive = usePanelInfo((info) => info.activePanelId !== null);
1770
1787
  const list = useSessions((s) => s);
1771
1788
  const pendingInteractions = useSessionPendingInteraction((s) => s);
1772
1789
  const baseRows = (0, react.useMemo)(() => deriveFlat(list, archivedSessionIds, pendingInteractions), [
@@ -1843,7 +1860,7 @@ window.__ModuleLoader__.load({
1843
1860
  const active = drag !== null;
1844
1861
  return (0, react_jsx_runtime.jsx)(SessionNodeItem, {
1845
1862
  node,
1846
- currentId: list.current,
1863
+ currentId: panelActive ? void 0 : list.current,
1847
1864
  now,
1848
1865
  onOpen: open,
1849
1866
  onRename: onSessionRename,
@@ -1892,7 +1909,8 @@ window.__ModuleLoader__.load({
1892
1909
  });
1893
1910
  }
1894
1911
  /** Flat search body: local metadata matches plus the current Host result page. */
1895
- function SearchResults({ useSessions, useSessionPendingInteraction, open, workspaces, archivedSessionIds, query, remote, resultLimit, t }) {
1912
+ function SearchResults({ useSessions, useSessionPendingInteraction, open, workspaces, archivedSessionIds, query, remote, resultLimit, usePanelInfo, t }) {
1913
+ const panelActive = usePanelInfo((info) => info.activePanelId !== null);
1896
1914
  const list = useSessions((s) => s);
1897
1915
  const pendingInteractions = useSessionPendingInteraction((s) => s);
1898
1916
  const currentRemote = remote.query === query ? remote : {
@@ -1923,7 +1941,7 @@ window.__ModuleLoader__.load({
1923
1941
  "aria-label": t("search.results.aria"),
1924
1942
  children: results.items.map((result) => (0, react_jsx_runtime.jsx)(SearchResultItem, {
1925
1943
  result,
1926
- currentId: list.current,
1944
+ currentId: panelActive ? void 0 : list.current,
1927
1945
  onOpen: open,
1928
1946
  t
1929
1947
  }, result.id))
@@ -1955,7 +1973,7 @@ window.__ModuleLoader__.load({
1955
1973
  * @param props - composed slot props (shell owner share + store + injected actions).
1956
1974
  * @returns the region element tree.
1957
1975
  */
1958
- function WorkspaceBrowser({ wide, expandSidebar, useSessions, useSessionPendingInteraction, useWorkspaces, useStore, actions, startSession, open, renameSession, forkSession, renameWorkspace, deleteWorkspace, insertWorkspaceBefore, archiveSession, insertSessionBefore, createWorkspace, searchSessions, searchResultLimit, useDirectoryFlow, useHostInfo, renderSlot, t }) {
1976
+ function WorkspaceBrowser({ wide, usePanelInfo, expandSidebar, useSessions, useSessionPendingInteraction, useWorkspaces, useStore, actions, startSession, open, renameSession, forkSession, renameWorkspace, deleteWorkspace, insertWorkspaceBefore, archiveSession, insertSessionBefore, createWorkspace, searchSessions, searchResultLimit, useDirectoryFlow, useHostInfo, renderSlot, t }) {
1959
1977
  const home = useHostInfo((info) => info.home);
1960
1978
  const workspaces = useWorkspaces((state) => state.items);
1961
1979
  const workspacePhase = useWorkspaces((state) => state.phase);
@@ -2337,6 +2355,7 @@ window.__ModuleLoader__.load({
2337
2355
  (0, react_jsx_runtime.jsx)("div", {
2338
2356
  className: WorkspaceBrowser_module_css_default.listArea,
2339
2357
  children: wide && (normalizedQuery !== "" ? (0, react_jsx_runtime.jsx)(SearchResults, {
2358
+ usePanelInfo,
2340
2359
  useSessions,
2341
2360
  useSessionPendingInteraction,
2342
2361
  open: openSearchResult,
@@ -2347,6 +2366,7 @@ window.__ModuleLoader__.load({
2347
2366
  resultLimit: searchResultLimit,
2348
2367
  t
2349
2368
  }) : groupBy === "flat" ? (0, react_jsx_runtime.jsx)(FlatList, {
2369
+ usePanelInfo,
2350
2370
  useSessions,
2351
2371
  useSessionPendingInteraction,
2352
2372
  open,
@@ -2363,6 +2383,7 @@ window.__ModuleLoader__.load({
2363
2383
  onSessionRevealed: acknowledgeSessionReveal,
2364
2384
  t
2365
2385
  }) : (0, react_jsx_runtime.jsx)(SessionTree, {
2386
+ usePanelInfo,
2366
2387
  useSessions,
2367
2388
  useSessionPendingInteraction,
2368
2389
  onSessionRename,
@@ -2693,7 +2714,8 @@ window.__ModuleLoader__.load({
2693
2714
  "workspaces",
2694
2715
  "locale",
2695
2716
  "remote",
2696
- "remote.directoryPicker"
2717
+ "remote.directoryPicker",
2718
+ "layout"
2697
2719
  ];
2698
2720
  /**
2699
2721
  * Register the browser and picker once their slot declarations are on the
@@ -2725,13 +2747,14 @@ window.__ModuleLoader__.load({
2725
2747
  subscribe: (listener) => ctx.on("connection/reset", listener)
2726
2748
  };
2727
2749
  const pickerFlowSource = flowSource("conversation.hero.workspace.directoryFlow");
2750
+ const openSession = (sessionId) => {
2751
+ uiWorkspace.openSession(sessionId);
2752
+ };
2728
2753
  const browserInjected = () => ({
2729
2754
  startSession: (workspaceId) => {
2730
2755
  uiWorkspace.startSession(workspaceId);
2731
2756
  },
2732
- open: (sessionId) => {
2733
- sessions.open(sessionId);
2734
- },
2757
+ open: openSession,
2735
2758
  searchSessions,
2736
2759
  searchResultLimit: sessions.searchResultLimit,
2737
2760
  renameSession: async (sessionId, title) => {
@@ -2741,12 +2764,7 @@ window.__ModuleLoader__.load({
2741
2764
  if (!result.ok) throw new Error(result.error.message);
2742
2765
  },
2743
2766
  forkSession: (sessionId) => {
2744
- sessions.fork({
2745
- sessionId,
2746
- increaseTitle: true
2747
- }).then((childId) => {
2748
- sessions.open(childId);
2749
- }).catch(() => {});
2767
+ uiWorkspace.forkSession(sessionId).catch(() => {});
2750
2768
  },
2751
2769
  renameWorkspace: async (workspaceId, title) => {
2752
2770
  await workspaces.rename(workspaceId, title);
@@ -6,6 +6,24 @@ import type { IWorkspaces, WorkspaceId } from '@deepseek-ai/dsh-api-workspace-co
6
6
  import type { SessionId } from '@deepseek-ai/dsh-session/types';
7
7
  /** Workspace archive and directory operations consumed by Client UI domains. */
8
8
  export interface UiWorkspace {
9
+ /**
10
+ * Select a Session and show its Conversation as one UI navigation action.
11
+ * @param sessionId - listed or retained Session to display.
12
+ */
13
+ openSession(sessionId: SessionId): void;
14
+ /**
15
+ * Connect a Workspace and open its Session unless a later navigation supersedes it.
16
+ * @param workspaceId - target Workspace.
17
+ * @param beforeOpen - optional synchronous preparation for the selected Session, skipped after supersession.
18
+ * @returns completion; a superseded request may create a Session but does not open it.
19
+ */
20
+ openWorkspace(workspaceId: WorkspaceId, beforeOpen?: (sessionId: SessionId) => void): Promise<void>;
21
+ /**
22
+ * Fork a Session and open the child unless a later navigation supersedes it.
23
+ * @param sessionId - source Session.
24
+ * @returns completion; a superseded request leaves its child available without selecting it.
25
+ */
26
+ forkSession(sessionId: SessionId): Promise<void>;
9
27
  /**
10
28
  * Resolve the reusable or newly created blank Session for a Workspace.
11
29
  * @param workspaceId - target Workspace.
@@ -61,6 +79,7 @@ declare class UiWorkspaceService extends Service implements UiWorkspace {
61
79
  private readonly workspaces;
62
80
  private readonly sessions;
63
81
  private readonly connecting;
82
+ private readonly lifetime;
64
83
  /**
65
84
  * @param ctx - Client root Context.
66
85
  * @param directoryPicker - the directory-picking Remote namespace.
@@ -69,6 +88,9 @@ declare class UiWorkspaceService extends Service implements UiWorkspace {
69
88
  */
70
89
  constructor(ctx: Context, directoryPicker: ClientRemote['directoryPicker'], workspaces: IWorkspaces, sessions: ISessions);
71
90
  connectWorkspace(workspaceId: WorkspaceId): Promise<SessionId>;
91
+ openSession(sessionId: SessionId): void;
92
+ openWorkspace(workspaceId: WorkspaceId, beforeOpen?: (sessionId: SessionId) => void): Promise<void>;
93
+ forkSession(sessionId: SessionId): Promise<void>;
72
94
  startSession(workspaceId?: WorkspaceId): void;
73
95
  archiveSession(sessionId: SessionId): Promise<void>;
74
96
  pickDirectory(): Promise<string | null>;
@@ -4,5 +4,5 @@ import type { WorkspaceBrowserProps } from '../contract/slots.ts';
4
4
  * @param props - composed slot props (shell owner share + store + injected actions).
5
5
  * @returns the region element tree.
6
6
  */
7
- export declare function WorkspaceBrowser({ wide, expandSidebar, useSessions, useSessionPendingInteraction, useWorkspaces, useStore, actions, startSession, open, renameSession, forkSession, renameWorkspace, deleteWorkspace, insertWorkspaceBefore, archiveSession, insertSessionBefore, createWorkspace, searchSessions, searchResultLimit, useDirectoryFlow, useHostInfo, renderSlot, t, }: WorkspaceBrowserProps): import("react").JSX.Element;
7
+ export declare function WorkspaceBrowser({ wide, usePanelInfo, expandSidebar, useSessions, useSessionPendingInteraction, useWorkspaces, useStore, actions, startSession, open, renameSession, forkSession, renameWorkspace, deleteWorkspace, insertWorkspaceBefore, archiveSession, insertSessionBefore, createWorkspace, searchSessions, searchResultLimit, useDirectoryFlow, useHostInfo, renderSlot, t, }: WorkspaceBrowserProps): import("react").JSX.Element;
8
8
  //# sourceMappingURL=WorkspaceBrowser.d.ts.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-client-ui-workspace",
3
3
  "description": "Workspace picker plugin: one WorkspacePicker registered into the sidebar and empty-state workspace slots",
4
- "version": "0.1.3-alpha.2",
4
+ "version": "0.1.5-alpha.2",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -34,6 +34,7 @@
34
34
  "@deepseek-ai/dsh-client-connection",
35
35
  "@deepseek-ai/dsh-client-locale",
36
36
  "@deepseek-ai/dsh-client-ui-conversation",
37
+ "@deepseek-ai/dsh-client-ui-layout",
37
38
  "@deepseek-ai/dsh-client-ui-renderer",
38
39
  "@deepseek-ai/dsh-client-ui-session",
39
40
  "@deepseek-ai/dsh-client-ui-sidebar"
@@ -42,32 +43,31 @@
42
43
  }
43
44
  },
44
45
  "license": "MIT",
45
- "dependencies": {
46
- "clsx": "^2.0.0"
47
- },
48
46
  "peerDependencies": {
49
47
  "@deepseek-ai/cordis": "^4.0.2"
50
48
  },
51
49
  "devDependencies": {
52
50
  "@types/react": "~18.3.1",
53
51
  "react": "^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-api-remotes": "^0.1.3-alpha.2",
57
- "@deepseek-ai/dsh-client-locale": "^0.1.3-alpha.2",
58
- "@deepseek-ai/dsh-client-store": "^0.1.3-alpha.2",
59
- "@deepseek-ai/dsh-client-test-runtime": "^0.1.3-alpha.2",
60
- "@deepseek-ai/dsh-client-connection": "^0.1.3-alpha.2",
61
- "@deepseek-ai/dsh-client-ui-conversation": "^0.1.3-alpha.2",
62
- "@deepseek-ai/dsh-client-ui-primitives": "^0.1.3-alpha.2",
63
- "@deepseek-ai/dsh-client-ui-renderer": "^0.1.3-alpha.2",
64
- "@deepseek-ai/dsh-client-ui-session": "^0.1.3-alpha.2",
65
- "@deepseek-ai/dsh-client-ui-sidebar": "^0.1.3-alpha.2",
66
- "@deepseek-ai/dsh-client-ui-slots": "^0.1.3-alpha.2",
67
- "@deepseek-ai/dsh-schedule": "^0.1.3-alpha.2",
68
- "@deepseek-ai/dsh-typert-protocol": "^0.1.3-alpha.2",
69
- "@deepseek-ai/dsh-session": "^0.1.3-alpha.2",
70
- "@deepseek-ai/dsh-util-workspace-path": "^0.1.3-alpha.2",
52
+ "clsx": "^2.0.0",
53
+ "@deepseek-ai/dsh-api-remotes": "^0.1.5-alpha.2",
54
+ "@deepseek-ai/dsh-client-locale": "^0.1.5-alpha.2",
55
+ "@deepseek-ai/dsh-client-store": "^0.1.5-alpha.2",
56
+ "@deepseek-ai/dsh-api-session-controller": "^0.1.5-alpha.2",
57
+ "@deepseek-ai/dsh-api-workspace-controller": "^0.1.5-alpha.2",
58
+ "@deepseek-ai/dsh-client-connection": "^0.1.5-alpha.2",
59
+ "@deepseek-ai/dsh-client-test-runtime": "^0.1.5-alpha.2",
60
+ "@deepseek-ai/dsh-client-ui-conversation": "^0.1.5-alpha.2",
61
+ "@deepseek-ai/dsh-client-ui-layout": "^0.1.5-alpha.2",
62
+ "@deepseek-ai/dsh-client-ui-primitives": "^0.1.5-alpha.2",
63
+ "@deepseek-ai/dsh-client-ui-renderer": "^0.1.5-alpha.2",
64
+ "@deepseek-ai/dsh-client-ui-session": "^0.1.5-alpha.2",
65
+ "@deepseek-ai/dsh-client-ui-sidebar": "^0.1.5-alpha.2",
66
+ "@deepseek-ai/dsh-client-ui-slots": "^0.1.5-alpha.2",
67
+ "@deepseek-ai/dsh-schedule": "^0.1.5-alpha.2",
68
+ "@deepseek-ai/dsh-typert-protocol": "^0.1.5-alpha.2",
69
+ "@deepseek-ai/dsh-session": "^0.1.5-alpha.2",
70
+ "@deepseek-ai/dsh-util-workspace-path": "^0.1.5-alpha.2",
71
71
  "@deepseek-ai/cordis": "^4.0.2"
72
72
  },
73
73
  "files": [