@deepseek-ai/dsh-client-ui-subagent 0.2.0-rc.2 → 0.2.1-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
@@ -9,13 +9,13 @@
9
9
  en: 930db612ece65ad4
10
10
  zh: ad7e9d9afb4545ac
11
11
  /deepseek-ai-dsh-client-ui-subagent/summary:
12
- en: 50f267d55833a683
13
- zh: 89d6b827576baa8b
12
+ en: 6e0bbf514ad3bef7
13
+ zh: 5a29d88c124d35cc
14
14
  /deepseek-ai-dsh-client-ui-subagent/table-of-contents:
15
15
  en: d152484eb41ac6b4
16
16
  zh: 09388d293f9be9cb
17
17
  /deepseek-ai-dsh-client-ui-subagent/use-this-package:
18
- en: 06f6bac3153361f5
18
+ en: 9a72f6fbd3828d1f
19
19
  zh: e8b23941cbd16036
20
20
  /deepseek-ai-dsh-client-ui-subagent/use-this-package/browsing-the-tree:
21
21
  en: 3508631091820123
@@ -27,11 +27,11 @@
27
27
  en: 6a5f91b7dfcefafe
28
28
  zh: 2d11441952cfea53
29
29
  /deepseek-ai-dsh-client-ui-subagent/understand-the-implementation:
30
- en: 8dc3c556cd57bdd8
31
- zh: f5c86a690bba7f7d
30
+ en: c158f12dcaed87b7
31
+ zh: e5d315e7b1fb4fa9
32
32
  /deepseek-ai-dsh-client-ui-subagent/understand-the-implementation/catalog-derivation:
33
- en: 5e1c83ef8eb26c52
34
- zh: f5be8f1e78c74859
33
+ en: 5531dcc1fb976cff
34
+ zh: 6fe779f4f1c34266
35
35
  /deepseek-ai-dsh-client-ui-subagent/understand-the-implementation/duration-completion-and-tokens:
36
36
  en: b817e9907392f59c
37
37
  zh: e42feb97d572a989
@@ -39,8 +39,8 @@
39
39
  en: 1c15af4dd7c0b791
40
40
  zh: f789737ab4dd8cb2
41
41
  /deepseek-ai-dsh-client-ui-subagent/further-exploration:
42
- en: 3b9b3cb4ad8f65f6
43
- zh: 63a2c10a4613cca1
42
+ en: 1766e9012e307178
43
+ zh: f3ee637f5941aae5
44
44
  /deepseek-ai-dsh-client-ui-subagent/model-experience:
45
45
  en: 215e7ba838619b7b
46
46
  zh: a311da3843709f90
@@ -60,5 +60,5 @@
60
60
  en: ee310ff3cd487639
61
61
  zh: 23793aa1c28a23af
62
62
  /deepseek-ai-dsh-client-ui-subagent/known-limitations-and-deferred-work/dev-note:
63
- en: 3dd148cecbb1a4df
64
- zh: 626cc5ed9f65c72a
63
+ en: e67f633dc6fe7773
64
+ zh: 3bb0c20c93f16f98
package/README.md CHANGED
@@ -9,7 +9,7 @@ English | [中文](README.zh.md)
9
9
 
10
10
  ## Summary
11
11
 
12
- Use this package to browse every subagent conversation beneath a parent session, open any descendant, and see whether it is running together with its token usage and active-turn duration. Completed one-shot conversations open as read-only execution records. Continuable conversations accept follow-up prompts in submission order while they run and provide Stop independently. The ordinary session sidebar omits subagent conversations, so the parent header catalog is their navigation entry point. The separate `@` source inserts a running child's label into a user message without resolving it into a continuation address.
12
+ Browse local subagent conversations and external tasks from the parent header. Local conversations show activity, token usage, and duration; continuable children accept follow-up prompts and support Stop. External tasks appear as non-navigable leaves without an execution status. Historical one-shot conversations open as read-only records. The ordinary sidebar omits subagent conversations, and the separate `@` source inserts a running child's label without granting continuation authority.
13
13
 
14
14
  ## Table of Contents
15
15
 
@@ -25,7 +25,7 @@ Use this package to browse every subagent conversation beneath a parent session,
25
25
  <a id="use-this-package"></a>
26
26
  ## Use this package
27
27
 
28
- The session header keeps the current session title as the lineage breadcrumb; when the session's direct catalog has entries or a read has failed, the descendant-count trigger renders at the start of the header actions band, with no breadcrumb separator. An absent catalog, an empty loading catalog, or a successfully loaded empty catalog hides the count trigger. The trigger opens that direct catalog, reports its total and running counts, and loads nested catalogs only when their rows expand. Select any depth to open that child's conversation with its exact `{parentSessionId, childSessionId, mode}` address, or use the row's trailing arrow to open the same address in the right Sidebar, preferring a separate pane when room permits.
28
+ The session header keeps the current session title as the lineage breadcrumb; when the session's direct catalog has entries or a read has failed, the descendant-count trigger renders at the start of the header actions band, with no breadcrumb separator. An absent catalog, an empty loading catalog, or a successfully loaded empty catalog hides the count trigger. The trigger opens that direct catalog, reports its total and running counts, and loads nested catalogs only when their rows expand. Select a local child at any depth to open that child's conversation with its exact `{parentSessionId, childSessionId, mode}` address, or use the row's trailing arrow to open the same address in the right Sidebar, preferring a separate pane when room permits.
29
29
 
30
30
  This package registers the `dsh-resource://subagentchat/session/<child>?parent=<parent>&mode=<mode>` resource and builtin Sidebar tab type. The resource retains the child `SessionReference` directly from its address without refreshing the parent catalog, and releases the reference when the tab record closes. The tab renders the shared `conversation.content` Factory through `sidebar.chat.conversation`, fixes the local View to Chat, and omits the main Conversation header and width controls.
31
31
 
@@ -51,15 +51,15 @@ The `@` source remains deliberately separate and inert: candidates are zero-RPC
51
51
  <details>
52
52
  <summary>Implementation internals — click to expand</summary>
53
53
 
54
- The catalog and composer behavior are specified by the [Web subagent conversations note](../../../.agents/notes/implemented/feature/2026-07-27-web-subagent-conversations.md) and the [current-turn interrupt note](../../../.agents/notes/implemented/feature/2026-08-06-continuable-subagent-interrupt.md).
54
+ The [subagent runtime](../../subagent/subagent/README.md) owns continuation and interruption; the [conversation reference](../ui-conversation/README.md) documents composer behavior.
55
55
 
56
56
  ### Catalog derivation
57
57
 
58
- The header lineage renderer reads `projectionsBySession` through the standard `useSessions` hook. The renderer selects `subagentCatalog` from each Session’s shared values for membership, disclosure, and counts; Activity prefers the unified UI status and falls back to Session summaries; summaries supply titles and usage. Expanding a row loads its initial catalog when needed. Live projection frames update every loaded level without menu subscriptions or repeated membership queries. A row remains expandable while its catalog is absent, loading, or failed, and becomes a known leaf after a ready empty catalog.
58
+ The header lineage renderer reads `projectionsBySession` through the standard `useSessions` hook. The renderer selects `subagentCatalog` from each Session’s shared values for membership, disclosure, and counts; Activity prefers the unified UI status and falls back to Session summaries; summaries supply titles and usage. Expanding a row reads its target's projections, including ordinary cold history. A list row with `formatStatus: migration-required` displays “Migration required” before expansion and keeps its history-opening actions without descendant expansion or changing its subagent mode; a projection read requiring migration without a catalog supplies the same notice. Opening the Session supplies its catalog through history and control projections. Otherwise, an available catalog remains usable, including an explicit empty catalog. Live projection frames update every loaded level without menu subscriptions or repeated membership queries. Other rows remain expandable while their catalogs are absent, loading, or failed, and become known leaves after ready empty catalogs. External rows are always leaves and do not load child Sessions.
59
59
 
60
60
  Opening a catalog dropdown does not request its root catalog. Child-catalog expansion and failed-read retries call `refreshProjection`; shared projection-value changes update the display automatically.
61
61
 
62
- Breadcrumb addresses derive from the Provider-bound Session address and loaded parent catalogs, including never-selected ancestors.
62
+ Breadcrumb addresses derive from the Provider-bound Session address, loaded parent catalogs, or already-listed subagent lineage, including never-selected ancestors.
63
63
 
64
64
  ### Duration, completion, and tokens
65
65
 
@@ -83,8 +83,8 @@ These pages cover the conversation surface, the host seam, and the design notes.
83
83
  - [ui-conversation](../ui-conversation/README.md) — the chat surface hosting the header action and composer chain.
84
84
  - [ui-input-trigger](../ui-input-trigger/README.md) — the suggestion machinery hosting the `@` source.
85
85
  - [subagent](../../subagent/subagent/README.md) — the host-side capability seam behind continuable children.
86
- - [Web subagent conversations](../../../.agents/notes/implemented/feature/2026-07-27-web-subagent-conversations.md) — the catalog and composer specification.
87
- - [Current-turn interrupt](../../../.agents/notes/implemented/feature/2026-08-06-continuable-subagent-interrupt.md) — the independent Stop semantics.
86
+ - [historical Web subagent conversations](../../../.agents/notes/archived/feature/2026-07-27-web-subagent-conversations.md) — the catalog and composer specification.
87
+ - [Current-turn interrupt](../../subagent/subagent/README.md) — the independent Stop semantics.
88
88
 
89
89
  -----
90
90
 
@@ -124,5 +124,3 @@ These limits define what the catalog can show and what `@` references mean; they
124
124
  None.
125
125
 
126
126
  </details>
127
-
128
- **Runtime invariant:** No companion is published. The plugin registers a single slash source whose disposal is proven by the HMR-safety spec; it emits no Cordis events and owns no cross-plugin mutable state.
package/README.zh.md CHANGED
@@ -9,7 +9,7 @@ kind: "package-reference"
9
9
 
10
10
  ## 概述
11
11
 
12
- 使用本包可浏览父会话下的每个 subagent 对话、打开任意后代,并查看其是否正在运行以及 token 用量和活跃轮次耗时。已完成的 one-shot 对话会作为只读执行记录打开。可继续对话在运行期间按提交顺序接收后续提示词,并独立提供 Stop。普通会话侧边栏会省略 subagent 对话,因此父会话页头目录是它们的导航入口。独立的 `@` source 会把运行中 child 的 label 插入用户消息,但不会把它解析成继续执行地址。
12
+ 从父会话页头浏览本地子代理对话与外部任务。本地对话展示活跃状态、token 用量和耗时;可继续子代理接受后续提示词并支持 Stop。外部任务显示为不可打开的叶子项,不展示执行状态。历史一次性对话以只读记录打开。普通侧边栏省略子代理对话;独立的 `@` 来源插入运行中子代理的标签,不授予继续执行权限。
13
13
 
14
14
  ## 目录
15
15
 
@@ -51,15 +51,15 @@ kind: "package-reference"
51
51
  <details>
52
52
  <summary>实现细节——点击展开</summary>
53
53
 
54
- 目录与编辑器行为由 [Web subagent 对话笔记](../../../.agents/notes/implemented/feature/2026-07-27-web-subagent-conversations.zh.md) 与[当前轮次中断笔记](../../../.agents/notes/implemented/feature/2026-08-06-continuable-subagent-interrupt.zh.md) 规定。
54
+ [子代理运行时](../../subagent/subagent/README.zh.md)负责 continuation 与中断;[对话参考](../ui-conversation/README.zh.md)说明编辑器行为。
55
55
 
56
56
  ### 目录派生
57
57
 
58
- 页头谱系 renderer 通过标准 `useSessions` 钩子读取 `projectionsBySession`。renderer 从每个 Session 的共享值中选择 `subagentCatalog`,用于成员关系、展开控件与数量;活动状态优先使用统一 UI status,缺少时使用 Session 摘要;摘要提供标题与用量。展开行会按需加载初始目录。实时 projection 帧更新所有已加载层级,无需菜单订阅或重复成员查询。行在目录缺席、加载中或失败时保持可展开,并在目录就绪且为空后成为已知叶子。
58
+ 页头谱系 renderer 通过标准 `useSessions` 钩子读取 `projectionsBySession`。renderer 从每个 Session 的共享值中选择 `subagentCatalog`,用于成员关系、展开控件与数量;活动状态优先使用统一 UI status,缺少时使用 Session 摘要;摘要提供标题与用量。展开行读取目标投影,包括普通冷历史。列表行的 `formatStatus` 为 `migration-required` 时,行在展开前即显示“需要迁移”,保留打开历史的操作,但不能展开下级,也不改变子会话的 mode;投影读取需要迁移且缺少目录时,也显示同一提示。打开会话后,历史与 control 投影提供其目录。其他情况下,已有目录仍可使用,包括显式空目录。实时 projection 帧更新所有已加载层级,无需菜单订阅或重复成员查询。其他行在目录缺席、加载中或失败时保持可展开,并在目录就绪且为空后成为已知叶子。外部行始终为叶子,不加载子 Session。
59
59
 
60
60
  打开目录下拉菜单不会请求其根目录。展开子节点目录或重试失败读取时调用 `refreshProjection`;共享投影值的变化会自动更新显示。
61
61
 
62
- 面包屑地址从 Provider 所绑定的 Session 地址和已加载的 parent 目录推导,也包括从未选中过的祖先。
62
+ 面包屑地址从 Provider 所绑定的 Session 地址、已加载的 parent 目录或已列出的 subagent 谱系推导,也包括从未选中过的祖先。
63
63
 
64
64
  ### 耗时、完成状态与 token
65
65
 
@@ -83,8 +83,8 @@ one-shot child 始终选用只读编辑器。可继续 child 仅在其确切 par
83
83
  - [ui-conversation](../ui-conversation/README.zh.md)——承载页头操作与编辑器链的聊天界面。
84
84
  - [ui-input-trigger](../ui-input-trigger/README.zh.md)——承载 `@` source 的建议机制。
85
85
  - [subagent](../../subagent/subagent/README.zh.md)——可继续 child 背后的宿主能力 seam。
86
- - [Web subagent 对话](../../../.agents/notes/implemented/feature/2026-07-27-web-subagent-conversations.zh.md)——目录与编辑器规范。
87
- - [当前轮次中断](../../../.agents/notes/implemented/feature/2026-08-06-continuable-subagent-interrupt.zh.md)——独立 Stop 的语义。
86
+ - [历史Web subagent 对话](../../../.agents/notes/archived/feature/2026-07-27-web-subagent-conversations.md)——目录与编辑器规范。
87
+ - [当前轮次中断](../../subagent/subagent/README.zh.md)——独立 Stop 的语义。
88
88
 
89
89
  -----
90
90
 
@@ -124,5 +124,3 @@ one-shot child 始终选用只读编辑器。可继续 child 仅在其确切 par
124
124
  无。
125
125
 
126
126
  </details>
127
-
128
- **运行时不变式:** 不发布伴生入口。插件只注册一个 slash source,其资源释放已由 HMR(热模块替换)安全规范验证;它不发出 Cordis 事件,也不持有跨插件可变状态。
package/lib/client.js CHANGED
@@ -174,7 +174,7 @@ window.__ModuleLoader__.load({
174
174
  };
175
175
  }, [running]);
176
176
  const emptyLoading = catalog.state === "loading" && catalog.entries.length === 0;
177
- const reserveDisclosure = catalog.entries.some((entry) => !isKnownLeaf(catalogs[entry.id]));
177
+ const reserveDisclosure = catalog.entries.some((entry) => entry.mode !== "external" && !isKnownLeaf(catalogs[entry.id]) && summaries[entry.id]?.formatStatus !== "migration-required" && catalogs[entry.id]?.state !== "migration-required");
178
178
  return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
179
179
  emptyLoading && (0, react_jsx_runtime.jsx)(CatalogLoadingRows, { t }),
180
180
  catalog.state === "error" && (0, react_jsx_runtime.jsxs)("div", {
@@ -189,19 +189,22 @@ window.__ModuleLoader__.load({
189
189
  })]
190
190
  }),
191
191
  catalog.entries.map((entry) => {
192
+ const external = entry.mode === "external";
192
193
  const childCatalog = catalogs[entry.id];
193
194
  const isCurrent = entry.id === currentSessionId;
194
- const isExpanded = expanded.has(entry.id);
195
- const knownLeaf = isKnownLeaf(childCatalog);
195
+ const knownLeaf = external || isKnownLeaf(childCatalog);
196
+ const requiresOpening = summaries[entry.id]?.formatStatus === "migration-required" || childCatalog?.state === "migration-required";
197
+ const canExpand = !knownLeaf && !requiresOpening;
198
+ const isExpanded = canExpand && expanded.has(entry.id);
196
199
  const childLoading = childCatalog === void 0 || childCatalog.state === "loading" && childCatalog.entries.length === 0;
197
200
  const summary = summaries[entry.id];
198
201
  const label = entry.label ?? entry.id;
199
- const mode = entry.mode === "unknown" ? t("mode.unknown") : entry.mode === "one-shot" ? t("mode.oneShot") : t("mode.continuable");
200
- const completed = entry.activity === "inactive" && summary?.projectionValues?.subagentTiming?.lastTurnCompleted === true;
201
- const activity = entry.activity === "running" ? t("activity.running") : completed ? t("activity.completed") : t("activity.inactive");
202
+ const mode = external ? t("mode.external") : entry.mode === "unknown" ? t("mode.unknown") : entry.mode === "one-shot" ? t("mode.oneShot") : t("mode.continuable");
203
+ const completed = !external && entry.activity === "inactive" && summary?.projectionValues?.subagentTiming?.lastTurnCompleted === true;
204
+ const activity = external ? void 0 : entry.activity === "running" ? t("activity.running") : completed ? t("activity.completed") : t("activity.inactive");
202
205
  const secondary = [
203
206
  summary?.title,
204
- mode,
207
+ requiresOpening ? t("catalog.migrationRequired") : mode,
205
208
  activity
206
209
  ].filter((value) => value !== void 0).join(" · ");
207
210
  const totalTokens = tokenTotal(summary?.projectionValues?.tokenUsage);
@@ -213,6 +216,7 @@ window.__ModuleLoader__.load({
213
216
  };
214
217
  const metrics = [tokenMetric, durationMetric?.exact].filter((value) => value !== void 0).join(" · ");
215
218
  const open = () => {
219
+ if (external) return;
216
220
  openChild({
217
221
  parentSessionId,
218
222
  childSessionId: entry.id,
@@ -220,22 +224,12 @@ window.__ModuleLoader__.load({
220
224
  });
221
225
  closeCatalog();
222
226
  };
223
- const openAside = (event) => {
224
- event.preventDefault();
225
- event.stopPropagation();
226
- openChildAside({
227
- parentSessionId,
228
- childSessionId: entry.id,
229
- mode: entry.mode
230
- });
231
- closeCatalog();
232
- };
233
227
  const handleKey = (event) => {
234
228
  if (event.key === "Enter" || event.key === " ") {
235
229
  event.preventDefault();
236
230
  event.stopPropagation();
237
231
  open();
238
- } else if (event.key === "ArrowRight" && !knownLeaf && !isExpanded || event.key === "ArrowLeft" && isExpanded) {
232
+ } else if (event.key === "ArrowRight" && canExpand && !isExpanded || event.key === "ArrowLeft" && isExpanded) {
239
233
  event.preventDefault();
240
234
  event.stopPropagation();
241
235
  toggleBranch(entry.id);
@@ -250,7 +244,8 @@ window.__ModuleLoader__.load({
250
244
  className: SubagentHeaderLineage_module_css_default.node,
251
245
  children: [(0, react_jsx_runtime.jsxs)("div", {
252
246
  role: "treeitem",
253
- tabIndex: 0,
247
+ tabIndex: external ? -1 : 0,
248
+ "aria-disabled": external || void 0,
254
249
  "aria-level": level,
255
250
  "aria-current": isCurrent || void 0,
256
251
  "aria-label": [
@@ -258,11 +253,11 @@ window.__ModuleLoader__.load({
258
253
  secondary,
259
254
  metrics
260
255
  ].filter((value) => value !== "").join(" "),
261
- ...knownLeaf ? {} : { "aria-expanded": isExpanded },
256
+ ...canExpand ? { "aria-expanded": isExpanded } : {},
262
257
  className: SubagentHeaderLineage_module_css_default.row,
263
258
  onClick: open,
264
259
  onKeyDown: handleKey,
265
- children: [knownLeaf ? reserveDisclosure && (0, react_jsx_runtime.jsx)("span", { className: SubagentHeaderLineage_module_css_default.disclosureSpace }) : (0, react_jsx_runtime.jsx)("button", {
260
+ children: [!canExpand ? reserveDisclosure && (0, react_jsx_runtime.jsx)("span", { className: SubagentHeaderLineage_module_css_default.disclosureSpace }) : (0, react_jsx_runtime.jsx)("button", {
266
261
  type: "button",
267
262
  tabIndex: -1,
268
263
  className: `${SubagentHeaderLineage_module_css_default.disclosure} ${isExpanded ? SubagentHeaderLineage_module_css_default.disclosureOpen : ""}`,
@@ -297,7 +292,7 @@ window.__ModuleLoader__.load({
297
292
  children: durationMetric.compact
298
293
  })]
299
294
  }),
300
- !isCurrent && (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
295
+ !isCurrent && !external && (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
301
296
  label: t("open.sidebar"),
302
297
  side: "bottom",
303
298
  align: "end",
@@ -305,7 +300,16 @@ window.__ModuleLoader__.load({
305
300
  type: "button",
306
301
  className: SubagentHeaderLineage_module_css_default.sidebarButton,
307
302
  "aria-label": t("open.sidebar.aria", { label }),
308
- onClick: openAside,
303
+ onClick: (event) => {
304
+ event.preventDefault();
305
+ event.stopPropagation();
306
+ openChildAside({
307
+ parentSessionId,
308
+ childSessionId: entry.id,
309
+ mode: entry.mode
310
+ });
311
+ closeCatalog();
312
+ },
309
313
  onKeyDown: (event) => {
310
314
  event.stopPropagation();
311
315
  },
@@ -314,7 +318,7 @@ window.__ModuleLoader__.load({
314
318
  })
315
319
  ]
316
320
  })]
317
- }), isExpanded && !knownLeaf && (0, react_jsx_runtime.jsx)("div", {
321
+ }), isExpanded && (0, react_jsx_runtime.jsx)("div", {
318
322
  role: "group",
319
323
  className: SubagentHeaderLineage_module_css_default.children,
320
324
  "aria-busy": childLoading || void 0,
@@ -354,14 +358,19 @@ window.__ModuleLoader__.load({
354
358
  const projections = useSessions((state) => state.projectionsBySession);
355
359
  const summaries = useSessions((state) => state.byId);
356
360
  const statuses = useSessionStatus((value) => value);
357
- const catalogs = (0, react.useMemo)(() => Object.fromEntries(Object.entries(projections).map(([id, snapshot]) => [id, {
358
- state: snapshot.state === "idle" ? snapshot.values.subagentCatalog === void 0 ? "loading" : "ready" : snapshot.state,
359
- error: snapshot.error,
360
- entries: (snapshot.values.subagentCatalog ?? []).map((entry) => ({
361
- ...entry,
362
- activity: (statuses.get(entry.id)?.running ?? summaries[entry.id]?.running) === true ? "running" : "inactive"
363
- }))
364
- }])), [
361
+ const catalogs = (0, react.useMemo)(() => {
362
+ return Object.fromEntries(Object.entries(projections).map(([id, snapshot]) => {
363
+ const projected = snapshot.values.subagentCatalog;
364
+ return [id, {
365
+ state: snapshot.state === "idle" ? projected === void 0 ? "loading" : "ready" : snapshot.state === "migration-required" && projected !== void 0 ? "ready" : snapshot.state,
366
+ error: snapshot.error,
367
+ entries: (projected ?? []).map((entry) => ({
368
+ ...entry,
369
+ activity: (statuses.get(entry.id)?.running ?? summaries[entry.id]?.running) === true ? "running" : "inactive"
370
+ }))
371
+ }];
372
+ }));
373
+ }, [
365
374
  projections,
366
375
  summaries,
367
376
  statuses
@@ -376,7 +385,7 @@ window.__ModuleLoader__.load({
376
385
  const hoverOpenTimer = (0, react.useRef)(void 0);
377
386
  const hoverCloseTimer = (0, react.useRef)(void 0);
378
387
  const pinnedRef = (0, react.useRef)(false);
379
- const currentEntry = currentSessionId === void 0 ? void 0 : catalog?.entries.find((entry) => entry.id === currentSessionId);
388
+ const currentEntry = currentSessionId === void 0 ? void 0 : projections[rootSessionId]?.values.subagentCatalog?.find((entry) => entry.id === currentSessionId);
380
389
  const switcherDisplayTitle = currentEntry !== void 0 ? currentEntry.label ?? currentEntry.id : displayTitle;
381
390
  const directChildren = catalog?.entries ?? [];
382
391
  const directCount = directChildren.length;
@@ -622,6 +631,8 @@ window.__ModuleLoader__.load({
622
631
  const parentId = useSessions((state) => {
623
632
  if (address?.childSessionId === lineageSessionId) return address.parentSessionId;
624
633
  for (const [parentId, snapshot] of Object.entries(state.projectionsBySession)) if (snapshot.values.subagentCatalog?.some((entry) => entry.id === lineageSessionId)) return parentId;
634
+ const summary = state.byId[lineageSessionId];
635
+ return summary?.origin === "subagent" ? summary.parentId : void 0;
625
636
  });
626
637
  const shared = {
627
638
  useSessions,
@@ -639,11 +650,11 @@ window.__ModuleLoader__.load({
639
650
  displayTitle,
640
651
  ...openTitle === void 0 ? {} : { openTitle },
641
652
  ...shared
642
- }, lineageSessionId), openTitle === void 0 && (0, react_jsx_runtime.jsx)(CatalogDropdown, {
653
+ }, `switcher:${lineageSessionId}`), openTitle === void 0 && (0, react_jsx_runtime.jsx)(CatalogDropdown, {
643
654
  rootSessionId: lineageSessionId,
644
655
  variant: "count",
645
656
  ...shared
646
- }, lineageSessionId)] });
657
+ }, `children:${lineageSessionId}`)] });
647
658
  }
648
659
  //#endregion
649
660
  //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-subagent/src/client/SubagentReadOnlyComposer.module.css.mjs
@@ -849,7 +860,9 @@ window.__ModuleLoader__.load({
849
860
  "tokens.total": "{value} tok",
850
861
  "loading.label": "正在加载子智能体…",
851
862
  "load.error": "无法加载子智能体",
863
+ "catalog.migrationRequired": "需要迁移",
852
864
  "retry": "重试",
865
+ "mode.external": "外部任务",
853
866
  "mode.oneShot": "一次性",
854
867
  "mode.continuable": "可继续",
855
868
  "mode.unknown": "模式未知",
@@ -891,7 +904,9 @@ window.__ModuleLoader__.load({
891
904
  "tokens.total": "{value} tok",
892
905
  "loading.label": "Loading subagents…",
893
906
  "load.error": "Unable to load subagents",
907
+ "catalog.migrationRequired": "Migration required",
894
908
  "retry": "Retry",
909
+ "mode.external": "External task",
895
910
  "mode.oneShot": "one-shot",
896
911
  "mode.continuable": "continuable",
897
912
  "mode.unknown": "unknown mode",
@@ -19,7 +19,9 @@ export declare const zh: {
19
19
  readonly 'tokens.total': "{value} tok";
20
20
  readonly 'loading.label': "正在加载子智能体…";
21
21
  readonly 'load.error': "无法加载子智能体";
22
+ readonly 'catalog.migrationRequired': "需要迁移";
22
23
  readonly retry: "重试";
24
+ readonly 'mode.external': "外部任务";
23
25
  readonly 'mode.oneShot': "一次性";
24
26
  readonly 'mode.continuable': "可继续";
25
27
  readonly 'mode.unknown': "模式未知";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-client-ui-subagent",
3
3
  "description": "Subagent conversation catalog, continuation routing UI, and '@' reference source",
4
- "version": "0.2.0-rc.2",
4
+ "version": "0.2.1-alpha.2",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -43,31 +43,31 @@
43
43
  },
44
44
  "license": "MIT",
45
45
  "peerDependencies": {
46
- "@deepseek-ai/cordis": "~4.0.4"
46
+ "@deepseek-ai/cordis": "~4.0.5-alpha.1"
47
47
  },
48
48
  "devDependencies": {
49
+ "@deepseek-ai/dsh-client-locale": "0.2.1-alpha.2",
50
+ "@deepseek-ai/dsh-client-resources": "0.2.1-alpha.2",
51
+ "@deepseek-ai/dsh-client-test-runtime": "0.2.1-alpha.2",
52
+ "@deepseek-ai/dsh-client-ui-chat": "0.2.1-alpha.2",
53
+ "@deepseek-ai/dsh-client-ui-conversation": "0.2.1-alpha.2",
54
+ "@deepseek-ai/dsh-client-ui-input-trigger": "0.2.1-alpha.2",
55
+ "@deepseek-ai/dsh-client-ui-primitives": "0.2.1-alpha.2",
56
+ "@deepseek-ai/dsh-client-ui-slots": "0.2.1-alpha.2",
57
+ "@deepseek-ai/dsh-subagent": "0.2.1-alpha.2",
58
+ "@deepseek-ai/dsh-token-meter": "0.2.1-alpha.2",
49
59
  "@types/react": "~18.3.1",
50
60
  "@types/react-dom": "~18.3.0",
61
+ "@deepseek-ai/cordis": "~4.0.5-alpha.1",
51
62
  "react": "^18.2.0",
52
63
  "react-dom": "^18.2.0",
53
- "@deepseek-ai/dsh-client-locale": "0.2.0-rc.2",
54
- "@deepseek-ai/dsh-client-resources": "0.2.0-rc.2",
55
- "@deepseek-ai/dsh-client-ui-chat": "0.2.0-rc.2",
56
- "@deepseek-ai/dsh-client-ui-conversation": "0.2.0-rc.2",
57
- "@deepseek-ai/dsh-client-ui-input-trigger": "0.2.0-rc.2",
58
- "@deepseek-ai/dsh-client-test-runtime": "0.2.0-rc.2",
59
- "@deepseek-ai/dsh-client-ui-primitives": "0.2.0-rc.2",
60
- "@deepseek-ai/dsh-client-ui-slots": "0.2.0-rc.2",
61
- "@deepseek-ai/dsh-subagent": "0.2.0-rc.2",
62
- "@deepseek-ai/dsh-token-meter": "0.2.0-rc.2",
63
- "@deepseek-ai/cordis": "~4.0.4",
64
- "@deepseek-ai/dsh-api-session-controller": "0.2.0-rc.2",
65
- "@deepseek-ai/dsh-client-connection": "0.2.0-rc.2",
66
- "@deepseek-ai/dsh-session": "0.2.0-rc.2",
67
- "@deepseek-ai/dsh-client-ui-session": "0.2.0-rc.2",
68
- "@deepseek-ai/dsh-client-ui-workspace": "0.2.0-rc.2",
69
- "@deepseek-ai/dsh-client-ui-sidebar-right": "0.2.0-rc.2",
70
- "@deepseek-ai/dsh-client-ui-renderer": "0.2.0-rc.2"
64
+ "@deepseek-ai/dsh-api-session-controller": "0.2.1-alpha.2",
65
+ "@deepseek-ai/dsh-client-connection": "0.2.1-alpha.2",
66
+ "@deepseek-ai/dsh-session": "0.2.1-alpha.2",
67
+ "@deepseek-ai/dsh-client-ui-renderer": "0.2.1-alpha.2",
68
+ "@deepseek-ai/dsh-client-ui-sidebar-right": "0.2.1-alpha.2",
69
+ "@deepseek-ai/dsh-client-ui-session": "0.2.1-alpha.2",
70
+ "@deepseek-ai/dsh-client-ui-workspace": "0.2.1-alpha.2"
71
71
  },
72
72
  "files": [
73
73
  "lib/index.js",