@michengai/dsh-archive-manager 0.1.43 → 0.1.44

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
@@ -6,21 +6,16 @@ Published release notes are retained below; new versions are added without remov
6
6
 
7
7
  ## Unreleased
8
8
 
9
+ ## 0.1.44 - 2026-09-18
10
+
11
+ - Opening an archived session from Settings no longer falsely reports that the host did not keep the conversation.
12
+ - Support DeepSeek Harness `0.1.6-alpha.2` while remaining compatible with earlier hosts. The archive page, opening archives, and permanent deletion keep working after the official API changes.
13
+
9
14
  ## 0.1.43 - 2026-09-16
10
15
 
11
- - Disable the official DSH 0.1.6+ Archived sessions settings plugin (`ui-settings-unarchive-sessions`) on install, so only this plugin's archive manager remains in Settings.
12
- - Declare DeepSeek Harness `0.1.6-alpha.1` in the DSH peer range and pin development dependencies to `0.1.6-alpha.1`. Host `workspace` and `session-projection-cache` remain replaced so batch archive and permanent delete keep working.
13
- - Treat unknown session ids as a no-op on archive and unarchive: skip them instead of throwing `UNKNOWN_SESSION`, and drop orphan archive markers on restore.
14
- - Opening the archived-sessions page drops an archive id from the durable set only when `persistence.stat` confirms the transcript is gone. Unreadable headers stay archived and are omitted from the visible metadata list. Hosts without `stat` do not persist-drop.
15
- - Batch archive and restore run serially and can succeed in part: a later failure leaves earlier changes written and shows the error. DSH 0.1.6+ success counts come from the official workspace snapshot and can lag; older hosts use the plugin remote archive set.
16
- - Treat missing sessions the same on delete as on archive: clean leftover traces without throwing `UNKNOWN_SESSION`.
17
- - Register the archive sidebar without waiting for official `uiWorkspace`, so the session menu is not stuck on the official three-item archive menu on DSH 0.1.6.
18
- - Bind archived-session navigation after official `uiWorkspace` is ready so Open session is not immediately cleared.
19
- - Restore and open now aborts in-flight workspace navigation and reveals the original group, then unarchives and opens. A selected workspace can still be collapsed. If open fails after restore, the settings page stays on Unarchived.
20
- - While a session remains archived, missing path-index entries are not pruned from workspace accounting. Unarchive reindexes by cwd and re-attaches if needed. Live unarchived membership filtering is unchanged.
21
- - Settings and sidebar batch archive now call official `archiveSession` serially instead of the plugin `archiveSessions` channel.
22
- - Batch restore still calls single-session unarchive serially. DSH 0.1.6+ uses official `ctx.workspaces.unarchiveSession`; older hosts fall back to this plugin's `workspaceRegistry.unarchiveSession`. Unused plugin batch `archiveSessions` / `archiveWorkspaceSessions` / `unarchiveSessions` endpoints and client sync helpers are removed.
23
- - Copy existing sidebar grouping, expansion, and sort prefs from `dsh.workspace.view.v5` onto `dsh.archive-manager.workspace.view.v1` once, so the persist-key split does not reset them.
16
+ - Support DeepSeek Harness 0.1.6 while remaining compatible with earlier hosts. Settings keeps only this plugin's archive page, and the sidebar archive menu works on 0.1.6.
17
+ - Opening an archived session, or restoring and opening it, returns to the original workspace and group instead of being cleared immediately.
18
+ - Batch archive and restore continue one session at a time. A later failure keeps earlier changes, and missing sessions no longer break the action.
24
19
 
25
20
  ## 0.1.42 - 2026-09-14
26
21
 
@@ -6,21 +6,16 @@
6
6
 
7
7
  ## Unreleased
8
8
 
9
+ ## 0.1.44 - 2026-09-18
10
+
11
+ - 设置里点「打开会话」不再误报「宿主未保留」。
12
+ - 支持 DeepSeek Harness `0.1.6-alpha.2`,并继续兼容更早版本。归档页、打开归档和永久删除在官方接口变更后仍可用。
13
+
9
14
  ## 0.1.43 - 2026-09-16
10
15
 
11
- - 安装时禁用 DSH 0.1.6+ 官方「已归档会话」设置页(`ui-settings-unarchive-sessions`),设置里只保留本插件的归档管理入口。
12
- - DSH peer 范围纳入 `0.1.6-alpha.1`,开发依赖固定到同一版本。仍替换官方 `workspace` 与 `session-projection-cache`,以保留批量归档和永久删除。
13
- - 归档和恢复遇到未知 id 都不再抛 `UNKNOWN_SESSION`:跳过不存在的会话,恢复时清掉孤儿归档标记。
14
- - 打开归档列表时,只有 `persistence.stat` 确认转录已不在才从持久集合摘掉 id。头部读不出的归档仍保留,只是不出现在本次元数据里。没有 `stat` 的宿主不落盘删除。
15
- - 批量归档和批量恢复都是串行执行,可以为部分成功:中途失败会留下已经改掉的部分,并显示错误。DSH 0.1.6+ 的成功计数取自官方工作区快照,可能滞后;更早宿主用插件 remote 返回的归档集合。
16
- - 删除与归档对失踪会话同一套逻辑:清掉残留痕迹,不抛 `UNKNOWN_SESSION`。
17
- - 侧栏不再等待官方 `uiWorkspace` 才注册,避免 0.1.6 上官方三项菜单一直占着、删除进不来。
18
- - 打开归档会话改为在官方 `uiWorkspace` 就绪后再适配 `clearArchivedCurrent`,避免点「打开会话」被官方立刻清掉。
19
- - 「恢复并打开」先中止其他工作区正在进行的导航并展开原分组,再恢复并打开;打开失败则留在未归档列表。选中工作区仍可折叠。
20
- - 仍在归档集合中、但路径索引缺失的记账,恢复前不被官方 mutate 写丢;恢复时按 cwd 重新编入索引,必要时挂回原工作区。不改未归档会话的官方成员过滤。
21
- - 设置页与侧栏批量归档改为串行调用官方 `archiveSession`,不再走插件 `archiveSessions` 通道。
22
- - 批量恢复仍串行调用单条恢复。DSH 0.1.6+ 走官方 `ctx.workspaces.unarchiveSession`;更早宿主回退到本插件一直提供的 `workspaceRegistry.unarchiveSession`。删除插件批量 `archiveSessions`、`archiveWorkspaceSessions`、`unarchiveSessions` 以及已无调用方的客户端同步辅助方法。
23
- - 换 persist 键时把已有的分组/展开/排序偏好从 `dsh.workspace.view.v5` 迁到 `dsh.archive-manager.workspace.view.v1`,避免老用户侧栏偏好被静默重置。
16
+ - 支持 DeepSeek Harness 0.1.6,并继续兼容更早版本。设置里只保留本插件的归档页,侧栏归档菜单在 0.1.6 上也能用。
17
+ - 打开归档会话或「恢复并打开」会回到原来的工作区和分组,不再被立刻清掉。
18
+ - 批量归档和恢复改为逐条处理:中途失败会保留已完成的部分,找不到的会话不再报错打断。
24
19
 
25
20
  ## 0.1.42 - 2026-09-14
26
21
 
package/README.md CHANGED
@@ -40,7 +40,7 @@ Find, restore, and clean up chats in **Settings → Archived sessions**:
40
40
  ## Prerequisites
41
41
 
42
42
  - A working [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) Web installation with `dsh` available in your terminal.
43
- - Supported DSH versions: `0.1.0-rc.8`, `0.1.1-rc.2`, `0.1.2-rc.1`, `0.1.5-rc.1`, `0.1.5-rc.2`, and `0.1.6-alpha.1`. Other versions are not currently supported.
43
+ - Supported DSH versions: `0.1.0-rc.8`, `0.1.1-rc.2`, `0.1.2-rc.1`, `0.1.5-rc.1`, `0.1.5-rc.2`, `0.1.6-alpha.1`, and `0.1.6-alpha.2`. Other versions are not currently supported.
44
44
  - Node.js matching `^22.19.0 || >=24.0.0`. Source installation also requires pnpm.
45
45
 
46
46
  ## Installation
package/README.zh-CN.md CHANGED
@@ -40,7 +40,7 @@
40
40
  ## 前置条件
41
41
 
42
42
  - 已能正常使用 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) Web,并可在终端运行 `dsh`。
43
- - 当前支持 DSH `0.1.0-rc.8`、`0.1.1-rc.2`、`0.1.2-rc.1`、`0.1.5-rc.1`、`0.1.5-rc.2`、`0.1.6-alpha.1`;其他版本暂未纳入支持范围。
43
+ - 当前支持 DSH `0.1.0-rc.8`、`0.1.1-rc.2`、`0.1.2-rc.1`、`0.1.5-rc.1`、`0.1.5-rc.2`、`0.1.6-alpha.1`、`0.1.6-alpha.2`;其他版本暂未纳入支持范围。
44
44
  - Node.js 版本需满足 `^22.19.0 || >=24.0.0`;从源码安装还需要 pnpm。
45
45
 
46
46
  ## 安装
@@ -8,6 +8,27 @@ class ArchiveNavigationError extends Error {
8
8
  function formatArchiveNavigationError(error, t) {
9
9
  return error instanceof ArchiveNavigationError ? t(`archives.${error.code}`) : String(error?.message ?? error);
10
10
  }
11
+ function retainInfoSnapshot(sessions, id) {
12
+ if (typeof sessions?.retainInfo !== "function") return;
13
+ const source = sessions.retainInfo(id);
14
+ return typeof source?.getSnapshot === "function" ? source.getSnapshot() : source;
15
+ }
16
+ function mainViewSessionId(list) {
17
+ const byId = list?.byId;
18
+ if (byId === void 0) return;
19
+ for (const session of Object.values(byId)) {
20
+ if ((session?.retainedBy?.mainView ?? 0) > 0) return session.id;
21
+ }
22
+ }
23
+ function currentSessionId(list) {
24
+ return mainViewSessionId(list) ?? list?.current;
25
+ }
26
+ function sessionIsCurrent(list, id, sessions) {
27
+ if (id === void 0 || id === "") return false;
28
+ if ((list?.byId?.[id]?.retainedBy?.mainView ?? 0) > 0) return true;
29
+ if ((retainInfoSnapshot(sessions, id)?.retainedBy?.mainView ?? 0) > 0) return true;
30
+ return list?.current === id;
31
+ }
11
32
  async function openArchivedConversation(actions, sessionId, restore, isActive = () => true) {
12
33
  if (restore) {
13
34
  if (typeof actions.prepare === "function") await actions.prepare(sessionId);
@@ -21,9 +42,9 @@ function allowArchivedNavigation(navigation, sessions, workspaces, { onOpened =
21
42
  let allowed;
22
43
  const original = navigation?.clearArchivedCurrent;
23
44
  const descriptor = navigation && Object.getOwnPropertyDescriptor(navigation, "clearArchivedCurrent");
45
+ const viewing = (id) => sessionIsCurrent(sessions.list.getSnapshot(), id, sessions);
24
46
  const wrapped = function(...args) {
25
- const current = sessions.list.getSnapshot().current;
26
- if (current === allowed && current !== void 0 && workspaces.list.getSnapshot().archivedSessionIds.includes(current)) return false;
47
+ if (allowed !== void 0 && viewing(allowed) && workspaces.list.getSnapshot().archivedSessionIds.includes(allowed)) return false;
27
48
  allowed = void 0;
28
49
  return original.apply(this, args);
29
50
  };
@@ -45,8 +66,14 @@ function allowArchivedNavigation(navigation, sessions, workspaces, { onOpened =
45
66
  throw new ArchiveNavigationError("navigationUnavailable");
46
67
  }
47
68
  beginNavigation?.();
48
- sessions.open(id);
49
- if (sessions.list.getSnapshot().current !== id) {
69
+ if (typeof sessions.retain === "function" && typeof navigation?.openSession === "function") navigation.openSession(id);
70
+ else if (typeof sessions.open === "function") sessions.open(id);
71
+ else if (typeof navigation?.openSession === "function") navigation.openSession(id);
72
+ else {
73
+ warn("archive-manager: \u5BBF\u4E3B\u672A\u63D0\u4F9B\u4F1A\u8BDD\u6253\u5F00\u63A5\u53E3\u3002");
74
+ throw new ArchiveNavigationError("navigationUnavailable");
75
+ }
76
+ if (!viewing(id)) {
50
77
  warn("archive-manager: \u5BBF\u4E3B\u672A\u4FDD\u7559\u76EE\u6807\u4F1A\u8BDD\u3002", { cleanupAvailable: typeof original === "function" });
51
78
  throw new ArchiveNavigationError("sessionNotRetained");
52
79
  }
@@ -68,6 +95,8 @@ function allowArchivedNavigation(navigation, sessions, workspaces, { onOpened =
68
95
  export {
69
96
  ArchiveNavigationError,
70
97
  allowArchivedNavigation,
98
+ currentSessionId,
71
99
  formatArchiveNavigationError,
72
- openArchivedConversation
100
+ openArchivedConversation,
101
+ sessionIsCurrent
73
102
  };
package/lib/client.js CHANGED
@@ -10,6 +10,27 @@
10
10
  function formatArchiveNavigationError(error, t) {
11
11
  return error instanceof ArchiveNavigationError ? t(`archives.${error.code}`) : String(error?.message ?? error);
12
12
  }
13
+ function retainInfoSnapshot(sessions, id) {
14
+ if (typeof sessions?.retainInfo !== "function") return;
15
+ const source = sessions.retainInfo(id);
16
+ return typeof source?.getSnapshot === "function" ? source.getSnapshot() : source;
17
+ }
18
+ function mainViewSessionId(list) {
19
+ const byId = list?.byId;
20
+ if (byId === void 0) return;
21
+ for (const session of Object.values(byId)) {
22
+ if ((session?.retainedBy?.mainView ?? 0) > 0) return session.id;
23
+ }
24
+ }
25
+ function currentSessionId(list) {
26
+ return mainViewSessionId(list) ?? list?.current;
27
+ }
28
+ function sessionIsCurrent(list, id, sessions) {
29
+ if (id === void 0 || id === "") return false;
30
+ if ((list?.byId?.[id]?.retainedBy?.mainView ?? 0) > 0) return true;
31
+ if ((retainInfoSnapshot(sessions, id)?.retainedBy?.mainView ?? 0) > 0) return true;
32
+ return list?.current === id;
33
+ }
13
34
  async function openArchivedConversation(actions, sessionId, restore, isActive = () => true) {
14
35
  if (restore) {
15
36
  if (typeof actions.prepare === "function") await actions.prepare(sessionId);
@@ -23,9 +44,9 @@
23
44
  let allowed;
24
45
  const original = navigation?.clearArchivedCurrent;
25
46
  const descriptor = navigation && Object.getOwnPropertyDescriptor(navigation, "clearArchivedCurrent");
47
+ const viewing = (id) => sessionIsCurrent(sessions.list.getSnapshot(), id, sessions);
26
48
  const wrapped = function(...args) {
27
- const current = sessions.list.getSnapshot().current;
28
- if (current === allowed && current !== void 0 && workspaces.list.getSnapshot().archivedSessionIds.includes(current)) return false;
49
+ if (allowed !== void 0 && viewing(allowed) && workspaces.list.getSnapshot().archivedSessionIds.includes(allowed)) return false;
29
50
  allowed = void 0;
30
51
  return original.apply(this, args);
31
52
  };
@@ -47,8 +68,14 @@
47
68
  throw new ArchiveNavigationError("navigationUnavailable");
48
69
  }
49
70
  beginNavigation?.();
50
- sessions.open(id);
51
- if (sessions.list.getSnapshot().current !== id) {
71
+ if (typeof sessions.retain === "function" && typeof navigation?.openSession === "function") navigation.openSession(id);
72
+ else if (typeof sessions.open === "function") sessions.open(id);
73
+ else if (typeof navigation?.openSession === "function") navigation.openSession(id);
74
+ else {
75
+ warn("archive-manager: \u5BBF\u4E3B\u672A\u63D0\u4F9B\u4F1A\u8BDD\u6253\u5F00\u63A5\u53E3\u3002");
76
+ throw new ArchiveNavigationError("navigationUnavailable");
77
+ }
78
+ if (!viewing(id)) {
52
79
  warn("archive-manager: \u5BBF\u4E3B\u672A\u4FDD\u7559\u76EE\u6807\u4F1A\u8BDD\u3002", { cleanupAvailable: typeof original === "function" });
53
80
  throw new ArchiveNavigationError("sessionNotRetained");
54
81
  }
@@ -514,6 +541,9 @@
514
541
  return value;
515
542
  }
516
543
  };
544
+ function strictCodec(typeSymbol, schema) {
545
+ return { mode: "strict", typeSymbol, create: () => schema, schema };
546
+ }
517
547
  const ARCHIVE_MANAGER_REMOTE = {
518
548
  package: "@michengai/dsh-archive-manager",
519
549
  descriptors: [
@@ -527,13 +557,9 @@
527
557
  name: "sessionId",
528
558
  wire: "sessionId",
529
559
  source: "json",
530
- codec: { mode: "strict", typeSymbol: "@deepseek-ai/dsh-session/types#SessionId", schema: sessionIdSchema }
560
+ codec: strictCodec("@deepseek-ai/dsh-session/types#SessionId", sessionIdSchema)
531
561
  }],
532
- result: {
533
- mode: "strict",
534
- typeSymbol: "@michengai/dsh-archive-manager/types#ArchivedSessionIds",
535
- schema: archivedSetSchema
536
- },
562
+ result: strictCodec("@michengai/dsh-archive-manager/types#ArchivedSessionIds", archivedSetSchema),
537
563
  sourceLocation: { file: "@michengai/dsh-archive-manager/lib/workspace.js", line: 1, column: 1 }
538
564
  },
539
565
  {
@@ -546,13 +572,9 @@
546
572
  name: "sessionId",
547
573
  wire: "sessionId",
548
574
  source: "json",
549
- codec: { mode: "strict", typeSymbol: "@deepseek-ai/dsh-session/types#SessionId", schema: sessionIdSchema }
575
+ codec: strictCodec("@deepseek-ai/dsh-session/types#SessionId", sessionIdSchema)
550
576
  }],
551
- result: {
552
- mode: "strict",
553
- typeSymbol: "@michengai/dsh-archive-manager/types#Deleted",
554
- schema: deletedSchema
555
- },
577
+ result: strictCodec("@michengai/dsh-archive-manager/types#Deleted", deletedSchema),
556
578
  sourceLocation: { file: "@michengai/dsh-archive-manager/lib/workspace.js", line: 1, column: 1 }
557
579
  },
558
580
  {
@@ -565,13 +587,9 @@
565
587
  name: "target",
566
588
  wire: "target",
567
589
  source: "json",
568
- codec: { mode: "strict", typeSymbol: "@michengai/dsh-archive-manager/types#ArchivedBatchTarget", schema: archivedBatchTargetSchema }
590
+ codec: strictCodec("@michengai/dsh-archive-manager/types#ArchivedBatchTarget", archivedBatchTargetSchema)
569
591
  }],
570
- result: {
571
- mode: "strict",
572
- typeSymbol: "@michengai/dsh-archive-manager/types#DeletedBatch",
573
- schema: deletedBatchSchema
574
- },
592
+ result: strictCodec("@michengai/dsh-archive-manager/types#DeletedBatch", deletedBatchSchema),
575
593
  sourceLocation: { file: "@michengai/dsh-archive-manager/lib/workspace.js", line: 1, column: 1 }
576
594
  },
577
595
  {
@@ -581,11 +599,7 @@
581
599
  method: "archivedSessionMetadata",
582
600
  invocation: { kind: "direct" },
583
601
  parameters: [],
584
- result: {
585
- mode: "strict",
586
- typeSymbol: "@michengai/dsh-archive-manager/types#ArchivedSessionMetadata",
587
- schema: archivedSessionMetadataSchema
588
- },
602
+ result: strictCodec("@michengai/dsh-archive-manager/types#ArchivedSessionMetadata", archivedSessionMetadataSchema),
589
603
  sourceLocation: { file: "@michengai/dsh-archive-manager/lib/workspace.js", line: 1, column: 1 }
590
604
  }
591
605
  ]
@@ -1105,12 +1119,12 @@
1105
1119
  const summary = list.byId[id];
1106
1120
  if (summary === void 0) continue;
1107
1121
  accounted.add(id);
1108
- if (!sessionVisible(summary, list.current, archived, showArchived)) continue;
1122
+ if (!sessionVisible(summary, currentSessionId(list), archived, showArchived)) continue;
1109
1123
  members.push(summary);
1110
1124
  }
1111
1125
  groups.push(buildGroup(workspace.workspaceId, workspace.workspaceId, workspace.path, Date.parse(workspace.createdAt), workspace.title, members, "account"));
1112
1126
  }
1113
- const stray = list.ids.map((id) => list.byId[id]).filter((s) => s !== void 0 && !accounted.has(s.id) && sessionVisible(s, list.current, archived, showArchived));
1127
+ const stray = list.ids.map((id) => list.byId[id]).filter((s) => s !== void 0 && !accounted.has(s.id) && sessionVisible(s, currentSessionId(list), archived, showArchived));
1114
1128
  if (stray.length > 0) groups.push(buildGroup("", void 0, void 0, void 0, UNGROUPED_LABEL, ungroupedOrder === void 0 ? stray : orderedUngrouped(stray, ungroupedOrder), ungroupedOrder === void 0 ? "recency" : "account"));
1115
1129
  return groups;
1116
1130
  }
@@ -1143,18 +1157,49 @@
1143
1157
  return visiblePendingKind(kind);
1144
1158
  }
1145
1159
  const EMPTY_PENDING_INTERACTIONS = /* @__PURE__ */ new Map();
1160
+ const EMPTY_COMPLETED_SESSIONS = /* @__PURE__ */ new Set();
1161
+ const EMPTY_SESSION_STATUS = /* @__PURE__ */ new Map();
1146
1162
  function useEmptySessionPendingInteraction(selector) {
1147
1163
  return selector(EMPTY_PENDING_INTERACTIONS);
1148
1164
  }
1165
+ function useEmptySessionStatus(selector) {
1166
+ return selector(EMPTY_SESSION_STATUS);
1167
+ }
1168
+ function pendingFacts(pendingInteractions) {
1169
+ if (pendingInteractions instanceof Map || pendingInteractions == null) {
1170
+ return { pending: pendingInteractions ?? EMPTY_PENDING_INTERACTIONS, completed: EMPTY_COMPLETED_SESSIONS };
1171
+ }
1172
+ return {
1173
+ pending: pendingInteractions.pending ?? EMPTY_PENDING_INTERACTIONS,
1174
+ completed: pendingInteractions.completed ?? EMPTY_COMPLETED_SESSIONS
1175
+ };
1176
+ }
1177
+ function factsFromSessionStatus(status) {
1178
+ const pending = /* @__PURE__ */ new Map();
1179
+ const completed = /* @__PURE__ */ new Set();
1180
+ if (status instanceof Map) {
1181
+ for (const [id, entry] of status) {
1182
+ if (entry?.pendingInteraction !== void 0) pending.set(id, entry.pendingInteraction);
1183
+ if (entry?.completionUnread === true) completed.add(id);
1184
+ }
1185
+ }
1186
+ return { pending, completed };
1187
+ }
1188
+ function useSessionUiFacts(usePending, useStatus, preferStatus) {
1189
+ const pending = usePending((s) => s);
1190
+ const status = useStatus((s) => s);
1191
+ return preferStatus ? factsFromSessionStatus(status) : { pending, completed: EMPTY_COMPLETED_SESSIONS };
1192
+ }
1149
1193
  function sessionNode(s, descendants, archived, pendingInteractions) {
1150
- const pendingInteraction = pendingInteractionForSession(s, pendingInteractions);
1194
+ const facts = pendingFacts(pendingInteractions);
1195
+ const pendingInteraction = pendingInteractionForSession(s, facts.pending);
1151
1196
  return {
1152
1197
  id: s.id,
1153
1198
  title: sessionTitle(s),
1154
1199
  blank: s.blank,
1155
1200
  running: s.running,
1156
1201
  runningSubagentCount: descendants.get(s.id)?.runningCount ?? 0,
1157
- completed: s.completed === true,
1202
+ completed: s.completed === true || facts.completed.has(s.id),
1158
1203
  updatedAt: s.updatedAt,
1159
1204
  archived: archived.has(s.id),
1160
1205
  ...pendingInteraction === void 0 ? {} : { pendingInteraction }
@@ -1164,7 +1209,8 @@
1164
1209
  const archived = new Set(archivedSessionIds);
1165
1210
  const expandedGroups = new Set(view.expandedGroups);
1166
1211
  const descendants = indexSubagentDescendants(list.byId);
1167
- const currentGroup = list.current === void 0 ? void 0 : workspaces.find((w) => w.sessionIds.includes(list.current))?.workspaceId ?? "";
1212
+ const current = currentSessionId(list);
1213
+ const currentGroup = current === void 0 ? void 0 : workspaces.find((w) => w.sessionIds.includes(current))?.workspaceId ?? "";
1168
1214
  const groups = [];
1169
1215
  for (const g of groupByWorkspace(list, workspaces, archived, view.ungroupedOrder, view.showArchived)) {
1170
1216
  const expanded = expandedGroups.has(g.key);
@@ -1188,7 +1234,7 @@
1188
1234
  const rows = [];
1189
1235
  for (const id of list.ids) {
1190
1236
  const s = list.byId[id];
1191
- if (s === void 0 || !sessionVisible(s, list.current, archived, showArchived)) continue;
1237
+ if (s === void 0 || !sessionVisible(s, currentSessionId(list), archived, showArchived)) continue;
1192
1238
  rows.push(s);
1193
1239
  }
1194
1240
  rows.sort(byRecency);
@@ -1210,7 +1256,7 @@
1210
1256
  const local = [];
1211
1257
  for (const id of list.ids) {
1212
1258
  const summary = list.byId[id];
1213
- if (summary === void 0 || summary.blank || !sessionVisible(summary, list.current, archived, showArchived)) continue;
1259
+ if (summary === void 0 || summary.blank || !sessionVisible(summary, currentSessionId(list), archived, showArchived)) continue;
1214
1260
  if (sessionTitle(summary).toLowerCase().includes(q) || labelOf(summary).toLowerCase().includes(q)) local.push(summary);
1215
1261
  }
1216
1262
  local.sort(byRecency);
@@ -1224,12 +1270,13 @@
1224
1270
  for (const summary of local) include(summary);
1225
1271
  for (const item of content.items) {
1226
1272
  const summary = list.byId[item.sessionId];
1227
- if (summary !== void 0 && !summary.blank && sessionVisible(summary, list.current, archived, showArchived)) include(summary);
1273
+ if (summary !== void 0 && !summary.blank && sessionVisible(summary, currentSessionId(list), archived, showArchived)) include(summary);
1228
1274
  }
1275
+ const facts = pendingFacts(pendingInteractions);
1229
1276
  return {
1230
1277
  items: ordered.slice(0, limit).map((summary) => {
1231
1278
  const match = contentBySession.get(summary.id);
1232
- const pendingInteraction = pendingInteractionForSession(summary, pendingInteractions);
1279
+ const pendingInteraction = pendingInteractionForSession(summary, facts.pending);
1233
1280
  return {
1234
1281
  id: summary.id,
1235
1282
  title: sessionTitle(summary),
@@ -1238,7 +1285,7 @@
1238
1285
  runningSubagentCount: descendants.get(summary.id)?.runningCount ?? 0,
1239
1286
  archived: archived.has(summary.id),
1240
1287
  ...pendingInteraction === void 0 ? {} : { pendingInteraction },
1241
- completed: summary.completed === true,
1288
+ completed: summary.completed === true || facts.completed.has(summary.id),
1242
1289
  ...match === void 0 ? {} : { snippet: match.snippet }
1243
1290
  };
1244
1291
  }),
@@ -2085,10 +2132,10 @@
2085
2132
  const rect = e.currentTarget.getBoundingClientRect();
2086
2133
  return e.clientY < rect.top + rect.height / 2 ? "before" : "after";
2087
2134
  }
2088
- function SessionTree({ useSessions, useSessionPendingInteraction, startSession, open, forkSession, workspaces, archivedSessionIds, showArchived, onRenameRequest, onArchiveRequest, onDeleteRequest, onSessionRename, onSessionArchive, onSessionUnarchive, onSessionDelete, insertWorkspaceBefore, insertSessionBefore, orderBy, groupExpansion, setGroupExpanded, sessionOrderByAccount, sessionUpdatedAtByAccount, syncSessionOrderAccount, setSessionOrder, t, revealSessionId, onSessionRevealed }) {
2135
+ function SessionTree({ useSessions, useSessionPendingInteraction, useSessionStatus, preferSessionStatus, startSession, open, forkSession, workspaces, archivedSessionIds, showArchived, onRenameRequest, onArchiveRequest, onDeleteRequest, onSessionRename, onSessionArchive, onSessionUnarchive, onSessionDelete, insertWorkspaceBefore, insertSessionBefore, orderBy, groupExpansion, setGroupExpanded, sessionOrderByAccount, sessionUpdatedAtByAccount, syncSessionOrderAccount, setSessionOrder, t, revealSessionId, onSessionRevealed }) {
2089
2136
  const list = useSessions((s) => s);
2090
- const pendingInteractions = useSessionPendingInteraction((s) => s);
2091
- const current = list.current;
2137
+ const pendingInteractions = useSessionUiFacts(useSessionPendingInteraction, useSessionStatus, preferSessionStatus);
2138
+ const current = currentSessionId(list);
2092
2139
  const [expandedSessionGroups, setExpandedSessionGroups] = (0, react.useState)([]);
2093
2140
  const [drag, setDrag] = (0, react.useState)(null);
2094
2141
  const sessionDropCommitted = (0, react.useRef)(false);
@@ -2389,9 +2436,10 @@
2389
2436
  ]
2390
2437
  });
2391
2438
  }
2392
- function FlatList({ useSessions, useSessionPendingInteraction, open, forkSession, onSessionRename, onSessionArchive, onSessionUnarchive, onSessionDelete, archivedSessionIds, showArchived, orderBy, sessionOrderByAccount, sessionUpdatedAtByAccount, syncSessionOrderAccount, setSessionOrder, t, revealSessionId, onSessionRevealed }) {
2439
+ function FlatList({ useSessions, useSessionPendingInteraction, useSessionStatus, preferSessionStatus, open, forkSession, onSessionRename, onSessionArchive, onSessionUnarchive, onSessionDelete, archivedSessionIds, showArchived, orderBy, sessionOrderByAccount, sessionUpdatedAtByAccount, syncSessionOrderAccount, setSessionOrder, t, revealSessionId, onSessionRevealed }) {
2393
2440
  const list = useSessions((s) => s);
2394
- const pendingInteractions = useSessionPendingInteraction((s) => s);
2441
+ const pendingInteractions = useSessionUiFacts(useSessionPendingInteraction, useSessionStatus, preferSessionStatus);
2442
+ const current = currentSessionId(list);
2395
2443
  const baseRows = (0, react.useMemo)(() => deriveFlat(list, archivedSessionIds, pendingInteractions, showArchived), [
2396
2444
  list,
2397
2445
  archivedSessionIds,
@@ -2467,7 +2515,7 @@
2467
2515
  const active = drag !== null;
2468
2516
  return (0, react_jsx_runtime.jsx)(SessionNodeItem, {
2469
2517
  node,
2470
- currentId: list.current,
2518
+ currentId: current,
2471
2519
  now,
2472
2520
  onOpen: open,
2473
2521
  onRename: onSessionRename,
@@ -2495,8 +2543,8 @@
2495
2543
  active,
2496
2544
  marker: active && drag.over?.id === node.id ? drag.over.half : null,
2497
2545
  hover: (half) => {
2498
- setDrag((current) => current === null ? current : {
2499
- ...current,
2546
+ setDrag((current2) => current2 === null ? current2 : {
2547
+ ...current2,
2500
2548
  over: {
2501
2549
  id: node.id,
2502
2550
  half
@@ -2521,9 +2569,9 @@
2521
2569
  }), (0, react_jsx_runtime.jsx)("span", { className: WorkspaceBrowser_module_css_default.fade })]
2522
2570
  });
2523
2571
  }
2524
- function SearchResults({ useSessions, useSessionPendingInteraction, open, workspaces, archivedSessionIds, showArchived, query, remote, resultLimit, t }) {
2572
+ function SearchResults({ useSessions, useSessionPendingInteraction, useSessionStatus, preferSessionStatus, open, workspaces, archivedSessionIds, showArchived, query, remote, resultLimit, t }) {
2525
2573
  const list = useSessions((s) => s);
2526
- const pendingInteractions = useSessionPendingInteraction((s) => s);
2574
+ const pendingInteractions = useSessionUiFacts(useSessionPendingInteraction, useSessionStatus, preferSessionStatus);
2527
2575
  const ungroupedLabel = t("group.ungrouped");
2528
2576
  const currentRemote = remote.query === query ? remote : {
2529
2577
  query,
@@ -2555,7 +2603,7 @@
2555
2603
  "aria-label": t("search.results.aria"),
2556
2604
  children: results.items.map((result) => (0, react_jsx_runtime.jsx)(SearchResultItem, {
2557
2605
  result,
2558
- currentId: list.current,
2606
+ currentId: currentSessionId(list),
2559
2607
  onOpen: open,
2560
2608
  t
2561
2609
  }, result.id))
@@ -2594,8 +2642,10 @@
2594
2642
  };
2595
2643
  }
2596
2644
  };
2597
- function WorkspaceBrowser({ wide, expandSidebar, useSessions, useSessionPendingInteraction, useWorkspaces, useStore, actions, startSession, open, renameSession, forkSession, renameWorkspace, deleteWorkspace, insertWorkspaceBefore, archiveSession, archiveWorkspaceSessions, unarchiveSession, deleteSession, insertSessionBefore, createWorkspace, searchSessions, searchResultLimit, useDirectoryFlow, renderSlot, t }) {
2645
+ function WorkspaceBrowser({ wide, expandSidebar, useSessions, useSessionPendingInteraction, useSessionStatus, useWorkspaces, useStore, actions, startSession, open, renameSession, forkSession, renameWorkspace, deleteWorkspace, insertWorkspaceBefore, archiveSession, archiveWorkspaceSessions, unarchiveSession, deleteSession, insertSessionBefore, createWorkspace, searchSessions, searchResultLimit, useDirectoryFlow, renderSlot, t }) {
2646
+ const preferSessionStatus = typeof useSessionStatus === "function";
2598
2647
  const useEffectiveSessionPendingInteraction = useSessionPendingInteraction ?? useEmptySessionPendingInteraction;
2648
+ const useEffectiveSessionStatus = useSessionStatus ?? useEmptySessionStatus;
2599
2649
  const workspaces = useWorkspaces((state) => state.items);
2600
2650
  const workspacePhase = useWorkspaces((state) => state.phase);
2601
2651
  const archivedSessionIds = useWorkspaces((state) => state.archivedSessionIds);
@@ -3020,6 +3070,8 @@
3020
3070
  children: wide && (normalizedQuery !== "" ? (0, react_jsx_runtime.jsx)(SearchResults, {
3021
3071
  useSessions,
3022
3072
  useSessionPendingInteraction: useEffectiveSessionPendingInteraction,
3073
+ useSessionStatus: useEffectiveSessionStatus,
3074
+ preferSessionStatus,
3023
3075
  open: (sessionId) => {
3024
3076
  setRevealSessionId(sessionId);
3025
3077
  setQuery("");
@@ -3036,6 +3088,8 @@
3036
3088
  }) : groupBy === "flat" ? (0, react_jsx_runtime.jsx)(FlatList, {
3037
3089
  useSessions,
3038
3090
  useSessionPendingInteraction: useEffectiveSessionPendingInteraction,
3091
+ useSessionStatus: useEffectiveSessionStatus,
3092
+ preferSessionStatus,
3039
3093
  open: guardedOpen,
3040
3094
  revealSessionId,
3041
3095
  onSessionRevealed: acknowledgeSessionReveal,
@@ -3058,6 +3112,8 @@
3058
3112
  }) : (0, react_jsx_runtime.jsx)(SessionTree, {
3059
3113
  useSessions,
3060
3114
  useSessionPendingInteraction: useEffectiveSessionPendingInteraction,
3115
+ useSessionStatus: useEffectiveSessionStatus,
3116
+ preferSessionStatus,
3061
3117
  revealSessionId,
3062
3118
  onSessionRevealed: acknowledgeSessionReveal,
3063
3119
  onSessionRename,
@@ -4099,16 +4155,24 @@
4099
4155
  searchSessions,
4100
4156
  searchResultLimit: ctx.sessions.searchResultLimit,
4101
4157
  renameSession: async (sessionId, title) => {
4158
+ const rename = async (session2) => {
4159
+ const result = await session2.rename(title);
4160
+ if (!result.ok) throw new Error(result.error.message);
4161
+ };
4162
+ if (typeof ctx.sessions.using === "function") {
4163
+ await ctx.sessions.using(sessionId, { source: "workspaceOperation" }, (reference) => rename(reference.binding.session));
4164
+ return;
4165
+ }
4102
4166
  const session = ctx.sessions.binding(sessionId)?.session;
4103
4167
  if (session === void 0) throw new Error(`unknown session "${sessionId}"`);
4104
- const result = await session.rename(title);
4105
- if (!result.ok) throw new Error(result.error.message);
4168
+ await rename(session);
4106
4169
  },
4107
4170
  forkSession: (sessionId) => {
4108
4171
  const uiWorkspace = uiWorkspaceAt();
4109
4172
  if (typeof uiWorkspace?.forkSession === "function") return uiWorkspace.forkSession(sessionId);
4110
4173
  return ctx.sessions.fork({ sessionId, increaseTitle: true }).then((childId) => {
4111
- ctx.sessions.open(childId);
4174
+ if (typeof uiWorkspace?.openSession === "function") uiWorkspace.openSession(childId);
4175
+ else ctx.sessions.open(childId);
4112
4176
  });
4113
4177
  },
4114
4178
  renameWorkspace: async (workspaceId, title) => {
@@ -4211,7 +4275,8 @@
4211
4275
  hasSplitClientStore,
4212
4276
  groupByWorkspace,
4213
4277
  byRecency,
4214
- ARCHIVE_MANAGER_REMOTE
4278
+ ARCHIVE_MANAGER_REMOTE,
4279
+ currentSessionId
4215
4280
  };
4216
4281
  exports.apply = apply;
4217
4282
  exports.inject = inject;
package/lib/workspace.js CHANGED
@@ -30,6 +30,14 @@ function jsonlSessionDirectory(persistence, header, location) {
30
30
  if (location.path !== join(directory, basename(location.path))) return;
31
31
  return directory;
32
32
  }
33
+ function strictCodec(typeSymbol, schema) {
34
+ return {
35
+ mode: "strict",
36
+ typeSymbol,
37
+ create: () => schema,
38
+ schema
39
+ };
40
+ }
33
41
  function markRemoteMethod(instance, method) {
34
42
  const context = {
35
43
  private: false,
@@ -131,18 +139,10 @@ const ARCHIVE_MANAGER_INVOCATIONS = [
131
139
  name: "sessionId",
132
140
  wire: "sessionId",
133
141
  source: "json",
134
- codec: {
135
- mode: "strict",
136
- typeSymbol: "@deepseek-ai/dsh-session/types#SessionId",
137
- schema: sessionIdSchema
138
- }
142
+ codec: strictCodec("@deepseek-ai/dsh-session/types#SessionId", sessionIdSchema)
139
143
  }
140
144
  ],
141
- result: {
142
- mode: "strict",
143
- typeSymbol: "@michengai/dsh-archive-manager/types#ArchivedSessionIds",
144
- schema: archivedSetSchema
145
- },
145
+ result: strictCodec("@michengai/dsh-archive-manager/types#ArchivedSessionIds", archivedSetSchema),
146
146
  sourceLocation: {
147
147
  file: "@michengai/dsh-archive-manager/lib/workspace.js",
148
148
  line: 1,
@@ -160,18 +160,10 @@ const ARCHIVE_MANAGER_INVOCATIONS = [
160
160
  name: "sessionId",
161
161
  wire: "sessionId",
162
162
  source: "json",
163
- codec: {
164
- mode: "strict",
165
- typeSymbol: "@deepseek-ai/dsh-session/types#SessionId",
166
- schema: sessionIdSchema
167
- }
163
+ codec: strictCodec("@deepseek-ai/dsh-session/types#SessionId", sessionIdSchema)
168
164
  }
169
165
  ],
170
- result: {
171
- mode: "strict",
172
- typeSymbol: "@michengai/dsh-archive-manager/types#Deleted",
173
- schema: deletedSchema
174
- },
166
+ result: strictCodec("@michengai/dsh-archive-manager/types#Deleted", deletedSchema),
175
167
  sourceLocation: {
176
168
  file: "@michengai/dsh-archive-manager/lib/workspace.js",
177
169
  line: 1,
@@ -189,18 +181,10 @@ const ARCHIVE_MANAGER_INVOCATIONS = [
189
181
  name: "target",
190
182
  wire: "target",
191
183
  source: "json",
192
- codec: {
193
- mode: "strict",
194
- typeSymbol: "@michengai/dsh-archive-manager/types#ArchivedBatchTarget",
195
- schema: archivedBatchTargetSchema
196
- }
184
+ codec: strictCodec("@michengai/dsh-archive-manager/types#ArchivedBatchTarget", archivedBatchTargetSchema)
197
185
  }
198
186
  ],
199
- result: {
200
- mode: "strict",
201
- typeSymbol: "@michengai/dsh-archive-manager/types#DeletedBatch",
202
- schema: deletedBatchSchema
203
- },
187
+ result: strictCodec("@michengai/dsh-archive-manager/types#DeletedBatch", deletedBatchSchema),
204
188
  sourceLocation: {
205
189
  file: "@michengai/dsh-archive-manager/lib/workspace.js",
206
190
  line: 1,
@@ -214,11 +198,7 @@ const ARCHIVE_MANAGER_INVOCATIONS = [
214
198
  method: "archivedSessionMetadata",
215
199
  invocation: { kind: "direct" },
216
200
  parameters: [],
217
- result: {
218
- mode: "strict",
219
- typeSymbol: "@michengai/dsh-archive-manager/types#ArchivedSessionMetadata",
220
- schema: archivedSessionMetadataSchema
221
- },
201
+ result: strictCodec("@michengai/dsh-archive-manager/types#ArchivedSessionMetadata", archivedSessionMetadataSchema),
222
202
  sourceLocation: {
223
203
  file: "@michengai/dsh-archive-manager/lib/workspace.js",
224
204
  line: 1,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@michengai/dsh-archive-manager",
3
- "version": "0.1.43",
3
+ "version": "0.1.44",
4
4
  "description": "NPM-installable DSH Web plugin for managing archived sessions.",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@11.22.0",
@@ -38,22 +38,22 @@
38
38
  },
39
39
  "peerDependencies": {
40
40
  "@deepseek-ai/cordis": "^4.0.1",
41
- "@deepseek-ai/dsh-client-connection": "0.1.0-rc.8 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1",
42
- "@deepseek-ai/dsh-client-locale": "0.1.0-rc.8 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1",
43
- "@deepseek-ai/dsh-client-runtime": "0.1.0-rc.8 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1",
44
- "@deepseek-ai/dsh-client-store": "0.1.0-rc.8 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1",
45
- "@deepseek-ai/dsh-client-ui-conversation": "0.1.0-rc.8 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1",
46
- "@deepseek-ai/dsh-client-ui-primitives": "0.1.0-rc.8 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1",
47
- "@deepseek-ai/dsh-client-ui-sidebar": "0.1.0-rc.8 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1",
48
- "@deepseek-ai/dsh-client-ui-workspace": "0.1.0-rc.8 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1",
49
- "@deepseek-ai/dsh-host-webserver": "0.1.0-rc.8 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1",
50
- "@deepseek-ai/dsh-session": "0.1.0-rc.8 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1",
51
- "@deepseek-ai/dsh-session-projection-cache": "0.1.0-rc.8 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1",
52
- "@deepseek-ai/dsh-spill-local": "0.1.0-rc.8 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1",
53
- "@deepseek-ai/dsh-storage-domain": "0.1.0-rc.8 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1",
54
- "@deepseek-ai/dsh-typert-protocol": "0.1.0-rc.8 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1",
55
- "@deepseek-ai/dsh-typert-registry": "0.1.0-rc.8 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1",
56
- "@deepseek-ai/dsh-workspace": "0.1.0-rc.8 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1"
41
+ "@deepseek-ai/dsh-client-connection": "0.1.0-rc.8 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
42
+ "@deepseek-ai/dsh-client-locale": "0.1.0-rc.8 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
43
+ "@deepseek-ai/dsh-client-runtime": "0.1.0-rc.8 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
44
+ "@deepseek-ai/dsh-client-store": "0.1.0-rc.8 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
45
+ "@deepseek-ai/dsh-client-ui-conversation": "0.1.0-rc.8 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
46
+ "@deepseek-ai/dsh-client-ui-primitives": "0.1.0-rc.8 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
47
+ "@deepseek-ai/dsh-client-ui-sidebar": "0.1.0-rc.8 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
48
+ "@deepseek-ai/dsh-client-ui-workspace": "0.1.0-rc.8 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
49
+ "@deepseek-ai/dsh-host-webserver": "0.1.0-rc.8 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
50
+ "@deepseek-ai/dsh-session": "0.1.0-rc.8 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
51
+ "@deepseek-ai/dsh-session-projection-cache": "0.1.0-rc.8 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
52
+ "@deepseek-ai/dsh-spill-local": "0.1.0-rc.8 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
53
+ "@deepseek-ai/dsh-storage-domain": "0.1.0-rc.8 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
54
+ "@deepseek-ai/dsh-typert-protocol": "0.1.0-rc.8 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
55
+ "@deepseek-ai/dsh-typert-registry": "0.1.0-rc.8 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
56
+ "@deepseek-ai/dsh-workspace": "0.1.0-rc.8 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2"
57
57
  },
58
58
  "peerDependenciesMeta": {
59
59
  "@deepseek-ai/dsh-client-runtime": {
@@ -65,30 +65,30 @@
65
65
  },
66
66
  "devDependencies": {
67
67
  "@deepseek-ai/cordis": "4.0.2",
68
- "@deepseek-ai/dsh-api-gateway": "0.1.6-alpha.1",
69
- "@deepseek-ai/dsh-client-connection": "0.1.6-alpha.1",
70
- "@deepseek-ai/dsh-client-locale": "0.1.6-alpha.1",
71
- "@deepseek-ai/dsh-client-store": "0.1.6-alpha.1",
72
- "@deepseek-ai/dsh-client-ui-conversation": "0.1.6-alpha.1",
73
- "@deepseek-ai/dsh-client-ui-primitives": "0.1.6-alpha.1",
74
- "@deepseek-ai/dsh-client-ui-renderer": "0.1.6-alpha.1",
75
- "@deepseek-ai/dsh-client-ui-sidebar": "0.1.6-alpha.1",
76
- "@deepseek-ai/dsh-client-ui-slots": "0.1.6-alpha.1",
77
- "@deepseek-ai/dsh-client-ui-workspace": "0.1.6-alpha.1",
78
- "@deepseek-ai/dsh-host-webserver": "0.1.6-alpha.1",
79
- "@deepseek-ai/dsh-invariants": "0.1.6-alpha.1",
80
- "@deepseek-ai/dsh-scope": "0.1.6-alpha.1",
81
- "@deepseek-ai/dsh-session": "0.1.6-alpha.1",
82
- "@deepseek-ai/dsh-session-persistence": "0.1.6-alpha.1",
83
- "@deepseek-ai/dsh-session-projection": "0.1.6-alpha.1",
84
- "@deepseek-ai/dsh-session-projection-cache": "0.1.6-alpha.1",
85
- "@deepseek-ai/dsh-spill": "0.1.6-alpha.1",
86
- "@deepseek-ai/dsh-spill-local": "0.1.6-alpha.1",
87
- "@deepseek-ai/dsh-storage": "0.1.6-alpha.1",
88
- "@deepseek-ai/dsh-storage-domain": "0.1.6-alpha.1",
89
- "@deepseek-ai/dsh-typert-protocol": "0.1.6-alpha.1",
90
- "@deepseek-ai/dsh-typert-registry": "0.1.6-alpha.1",
91
- "@deepseek-ai/dsh-workspace": "0.1.6-alpha.1",
68
+ "@deepseek-ai/dsh-api-gateway": "0.1.6-alpha.2",
69
+ "@deepseek-ai/dsh-client-connection": "0.1.6-alpha.2",
70
+ "@deepseek-ai/dsh-client-locale": "0.1.6-alpha.2",
71
+ "@deepseek-ai/dsh-client-store": "0.1.6-alpha.2",
72
+ "@deepseek-ai/dsh-client-ui-conversation": "0.1.6-alpha.2",
73
+ "@deepseek-ai/dsh-client-ui-primitives": "0.1.6-alpha.2",
74
+ "@deepseek-ai/dsh-client-ui-renderer": "0.1.6-alpha.2",
75
+ "@deepseek-ai/dsh-client-ui-sidebar": "0.1.6-alpha.2",
76
+ "@deepseek-ai/dsh-client-ui-slots": "0.1.6-alpha.2",
77
+ "@deepseek-ai/dsh-client-ui-workspace": "0.1.6-alpha.2",
78
+ "@deepseek-ai/dsh-host-webserver": "0.1.6-alpha.2",
79
+ "@deepseek-ai/dsh-invariants": "0.1.6-alpha.2",
80
+ "@deepseek-ai/dsh-scope": "0.1.6-alpha.2",
81
+ "@deepseek-ai/dsh-session": "0.1.6-alpha.2",
82
+ "@deepseek-ai/dsh-session-persistence": "0.1.6-alpha.2",
83
+ "@deepseek-ai/dsh-session-projection": "0.1.6-alpha.2",
84
+ "@deepseek-ai/dsh-session-projection-cache": "0.1.6-alpha.2",
85
+ "@deepseek-ai/dsh-spill": "0.1.6-alpha.2",
86
+ "@deepseek-ai/dsh-spill-local": "0.1.6-alpha.2",
87
+ "@deepseek-ai/dsh-storage": "0.1.6-alpha.2",
88
+ "@deepseek-ai/dsh-storage-domain": "0.1.6-alpha.2",
89
+ "@deepseek-ai/dsh-typert-protocol": "0.1.6-alpha.2",
90
+ "@deepseek-ai/dsh-typert-registry": "0.1.6-alpha.2",
91
+ "@deepseek-ai/dsh-workspace": "0.1.6-alpha.2",
92
92
  "react": "18.3.1",
93
93
  "react-dom": "18.3.1",
94
94
  "esbuild": "0.25.0",