@monotykamary/dsh-client-ui-subagent 0.1.0-rc.8 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.i18n.yaml +2 -2
- package/README.md +2 -2
- package/README.zh.md +3 -3
- package/lib/client.js +282 -162
- package/lib/types/client/SubagentHeaderLineage.d.ts +18 -0
- package/lib/types/client/index.d.ts +4 -16
- package/lib/types/client/locales.d.ts +1 -0
- package/package.json +22 -24
- package/lib/types/client/SubagentCatalogAction.d.ts +0 -18
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-subagent/README.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: 38fea1750d8e7122dee0a0f4a6e2b592de421528
|
|
6
|
+
README.zh.md: c5e60f8a1c324444a1d4f3d4f66c4f988bcb5aa2
|
package/README.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
English | [中文](README.zh.md)
|
|
4
4
|
|
|
5
|
-
Web subagent feature owner: contributes
|
|
5
|
+
Web subagent feature owner: contributes current-title lineage navigation to `conversation.session.header.lineage`, reason-specific read-only replacements to the conversation composer chain, and the existing `@` reference source to `ctx.inputTriggers`.
|
|
6
6
|
|
|
7
|
-
The header
|
|
7
|
+
The header lineage renderer reads `subagentsByParent` and session summaries through the standard `useSessions` hook. On an ordinary session it preserves the current title and, when descendants exist, appends `/` plus the descendant-count dropdown before the header action row. Every subagent breadcrumb uses the count trigger's 12px type scale and combines its title with a fixed double chevron; the current breadcrumb keeps primary color and weight 500, while ancestors use tertiary color and weight 400. Hovering a combined control for 150ms opens its direct-parent catalog, ArrowDown remains the keyboard entry path, and clicking an ancestor cancels a pending menu and navigates upward without opening it. Each catalog enables sibling switching and bolds its selected row; a catalog label overrides the session-summary title, and every switcher whose catalog has not loaded requests it automatically. Only the current subagent appends its own descendant-count dropdown. Long breadcrumb titles truncate while the chevron remains visible. The count trigger covers the complete subagent-only descendant lineage, stops at ordinary forks, and shows ongoing activity when any counted descendant is running. The compact tree remains direct-catalog authoritative: continuable and one-shot rows display mode plus `running`/`inactive` activity and an optional log-backed title, while the trailing column stacks total durable provider usage above active-turn duration. Token totals sum the four disjoint `tokenUsage` buckets. Visual duration stays exact to the second below one day, then uses at most two adjacent units—days/hours, approximate months/days, or approximate years/months—while hover and the accessible name retain the exact day/hour/minute/second value. Duration sums completed `subagentTiming` turns, advances once per second only for an open turn on a running child, and freezes after the child becomes inactive; an interrupted open turn is bounded by its same-cut `active.through`, never by newer session metadata. An unlabeled one-shot row falls back to its session id, while corrupt, unsupported, or unavailable rows remain readable but disabled. Each healthy row's `hasChildren` hint determines disclosure before interaction, so known leaves never show an arrow; a catalog level reserves the disclosure column only when at least one healthy row is a branch, allowing branchless levels to start at the leading status marker. Expanding a branch immediately reserves one disabled loading row per known direct descendant, then lazily replaces them with that child's authoritative catalog. Every visible branch is reported to the runtime so membership frames cause a debounced refresh only where the tree is being consumed. Selecting any depth calls `SessionRuntime.openSubagent()` with the row's exact `{parentSessionId, childSessionId, mode}` address. Component-local state owns tree visibility, expanded branches, keyboard focus, and the running-duration clock. ArrowRight/ArrowLeft expand and collapse branches; ArrowUp/ArrowDown, Home, End, and Escape navigate or close the tree; closing returns focus to the trigger. Styling uses tokens only.
|
|
8
8
|
|
|
9
9
|
A one-shot child always elects a read-only composer that identifies the transcript as a completed execution record. A continuable child does so only when its exact parent is unavailable and the child is not running, with copy explaining the recovery path; while such a child still runs, the selector yields to the ordinary composer, whose input and Send action are disabled but whose independent Stop stays usable, and the takeover returns once it stops. A continuable child with a live parent keeps the ordinary input chrome, whose Session routes prompts through `subagent.prompt`: typing and Send stay available while the child runs because every follow-up joins the child's FIFO inbox, while an independent Stop routes through `subagent.interrupt`. This package never receives host context or calls a model-facing tool. The catalog and composer behavior are specified by the [Web subagent conversations Agent Note](../../../.agents/notes/implemented/feature/2026-07-27-web-subagent-conversations.md) and the [current-turn interrupt Agent Note](../../../.agents/notes/implemented/feature/2026-08-06-continuable-subagent-interrupt.md).
|
|
10
10
|
|
package/README.zh.md
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
[English](README.md) | 中文
|
|
4
4
|
|
|
5
|
-
Web subagent 功能 owner:向 `conversation.session.header.
|
|
5
|
+
Web subagent 功能 owner:向 `conversation.session.header.lineage` 贡献当前 title 谱系导航,向会话编辑器链贡献按原因区分的只读替代呈现,并保留注册到 `ctx.inputTriggers` 的既有 `@` 引用 source。
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
页头谱系 renderer 通过标准 `useSessions` 钩子读取 `subagentsByParent` 与会话摘要。普通会话保留当前 title,并在存在后代时,于页头操作行之前追加 `/` 和后代数量下拉菜单。每一级 subagent 面包屑都使用数量触发器的 12px 字号,并将 title 与固定显示的双向箭头组合成一个控件;当前面包屑保留主标签颜色和 500 字重,祖先面包屑则使用三级标签颜色和 400 字重。悬停组合控件 150ms 后会打开其直接 parent 目录,ArrowDown 保留为键盘入口;点击祖先面包屑会取消待打开的菜单并仅向上导航。每个目录都可切换 sibling,并会加粗选中行;目录 label 优先于会话摘要 title,尚未加载目录的每个切换器都会自动请求该目录。只有当前 subagent 会追加自己的后代数量下拉菜单。过长的面包屑 title 会截断,而双向箭头始终保留。数量触发器会统计仅含 subagent 的完整后代谱系,在普通 fork 处停止,并在任一计入统计的后代处于 `running` 时显示活动仍在进行。紧凑树仍以直接目录为权威依据:可继续和 one-shot 行会显示 mode、`running`/`inactive` 活动状态和由日志支撑的可选 title,尾随列则在上行显示提供方的持久化 token 用量总计,在下行显示活跃轮次耗时。token 用量总计为四个互不重叠的 `tokenUsage` 桶之和。视觉耗时在不足一天时精确到秒,达到一天后则最多使用两个相邻单位——天/小时、近似月份/天或近似年份/月份——而悬停信息与无障碍名称会保留精确的天/小时/分钟/秒数值。耗时会累加已完成的 `subagentTiming` 轮次,仅在运行中 child 存在未结束轮次时每秒递增一次,并在 child 变为 inactive 后冻结;被中断的未结束轮次以其同一切面的 `active.through` 为上界,绝不使用更新的会话元数据。没有 label 的 one-shot 行会回退到其会话 id,而损坏、不受支持或不可用的行仍保持可读但禁用。每个健康行的 `hasChildren` 提示会在交互前决定是否显示展开控件,因此已知叶子节点从不显示箭头;每层目录仅在其中至少一个健康行是分支时才预留展开列,使完全不含分支的层级能从最前面的状态标记开始。展开分支时,会立即为每个已知直接后代预留一行禁用的加载行,随后再用该 child 的权威目录懒加载结果替换这些占位行。每个可见分支都会上报给运行时,使成员帧只在树正被消费的位置触发去抖动刷新。选择任意深度的条目都会使用该行的确切地址 `{parentSessionId, childSessionId, mode}` 调用 `SessionRuntime.openSubagent()`。组件局部状态负责树的可见性、已展开分支、键盘焦点与运行中耗时时钟。ArrowRight/ArrowLeft 展开和折叠分支;ArrowUp/ArrowDown、Home、End 与 Escape 用于导航或关闭树;关闭后焦点返回触发器。样式只使用 token。
|
|
8
8
|
|
|
9
|
-
one-shot child 始终选用只读编辑器,并将 transcript(文本记录)说明为已完成的执行记录。可继续 child 仅在其确切 parent 不可用且 child 未在运行时选用只读编辑器,并以文案说明恢复路径;此类 child 仍在运行期间,selector 会让位给普通编辑器——其输入区与 Send 操作被禁用,但独立的 Stop 保持可用,停止后只读替代恢复。确切 parent 存活时,可继续 child 保留普通输入 chrome,其会话通过 `subagent.prompt` 路由提示词:child 运行期间输入和 Send 保持可用,因为每条后续消息都会进入 child 的 FIFO inbox,而独立的 Stop 经由 `subagent.interrupt` 路由。本包绝不接收宿主上下文,也不调用面向模型的工具。目录与编辑器行为由 [Web subagent 对话 Agent Note](../../../.agents/notes/implemented/feature/2026-07-27-web-subagent-conversations.md) 与[当前轮次中断 Agent Note](../../../.agents/notes/implemented/feature/2026-08-06-continuable-subagent-interrupt.md) 规定。
|
|
9
|
+
one-shot child 始终选用只读编辑器,并将 transcript(文本记录)说明为已完成的执行记录。可继续 child 仅在其确切 parent 不可用且 child 未在运行时选用只读编辑器,并以文案说明恢复路径;此类 child 仍在运行期间,selector 会让位给普通编辑器——其输入区与 Send 操作被禁用,但独立的 Stop 保持可用,停止后只读替代恢复。确切 parent 存活时,可继续 child 保留普通输入 chrome,其会话通过 `subagent.prompt` 路由提示词:child 运行期间输入和 Send 保持可用,因为每条后续消息都会进入 child 的 FIFO inbox,而独立的 Stop 经由 `subagent.interrupt` 路由。本包绝不接收宿主上下文,也不调用面向模型的工具。目录与编辑器行为由 [Web subagent 对话 Agent Note](../../../.agents/notes/implemented/feature/2026-07-27-web-subagent-conversations.zh.md) 与[当前轮次中断 Agent Note](../../../.agents/notes/implemented/feature/2026-08-06-continuable-subagent-interrupt.zh.md) 规定。
|
|
10
10
|
|
|
11
11
|
普通侧边栏会省略带 subagent origin 的会话行,因此 parent 页头目录是它们的导航入口。普通 fork 仍保留在侧边栏中。
|
|
12
12
|
|
package/lib/client.js
CHANGED
|
@@ -6,11 +6,12 @@ window.__ModuleLoader__.load({
|
|
|
6
6
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
7
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
8
8
|
let react = require("react");
|
|
9
|
+
let react_dom = require("react-dom");
|
|
9
10
|
let _monotykamary_dsh_client_runtime_client = require("@monotykamary/dsh-client-runtime/client");
|
|
10
11
|
let _monotykamary_dsh_client_ui_primitives = require("@monotykamary/dsh-client-ui-primitives");
|
|
11
|
-
//#region \0dsh-css:/
|
|
12
|
-
const css$1 = ".
|
|
13
|
-
const tagId$1 = "@monotykamary/dsh-client-ui-subagent/
|
|
12
|
+
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-subagent/src/client/SubagentHeaderLineage.module.css.mjs
|
|
13
|
+
const css$1 = ".ZKlsPq_root{align-items:center;gap:10px;min-width:0;display:inline-flex;position:relative}.ZKlsPq_switcherRoot{min-width:0;margin-left:6px}.ZKlsPq_trigger,.ZKlsPq_switcherTrigger{min-height:28px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;border-radius:6px;align-items:center;padding:3px 2px;font-size:12px;line-height:18px;display:inline-flex}.ZKlsPq_trigger{gap:4px}.ZKlsPq_switcherTrigger{min-width:0;max-width:244px;color:var(--dsw-alias-label-primary);gap:4px;font-weight:500}.ZKlsPq_ancestorSwitcherTrigger{color:var(--dsw-alias-label-tertiary);font-weight:400}.ZKlsPq_switcherTitle{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.ZKlsPq_switcherTrigger svg{flex:none}.ZKlsPq_separator{color:var(--dsw-alias-label-caption);font-size:14px;line-height:20px}.ZKlsPq_activitySlot{flex:none;width:10px;height:10px;display:inline-flex}.ZKlsPq_trigger:hover,.ZKlsPq_trigger:focus-visible{color:var(--dsw-alias-label-secondary)}.ZKlsPq_switcherTrigger:hover,.ZKlsPq_switcherTrigger:focus-visible{color:var(--dsw-alias-label-primary)}.ZKlsPq_ancestorSwitcherTrigger:hover,.ZKlsPq_ancestorSwitcherTrigger:focus-visible{color:var(--dsw-alias-label-tertiary)}.ZKlsPq_trigger svg,.ZKlsPq_switcherTrigger svg{transition:transform .12s}.ZKlsPq_triggerOpen{transform:rotate(180deg)}.ZKlsPq_menu{z-index:100;box-sizing:border-box;background:var(--dsw-specific-menu);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);width:336px;max-width:min(400px,100vw - 32px);max-height:min(560px,100vh - 140px);box-shadow:var(--dsw-shadow-lv3);border-radius:12px;flex-direction:column;padding:4px;display:flex;position:fixed;overflow:auto}.ZKlsPq_node{min-width:0;position:relative}.ZKlsPq_menu>.ZKlsPq_node{margin-left:-3px}.ZKlsPq_row{box-sizing:border-box;width:100%;min-height:50px;color:var(--dsw-alias-label-primary);text-align:left;cursor:pointer;background:0 0;border:0;border-radius:8px;outline:none;align-items:flex-start;gap:8px;padding:7px 8px 7px 11px;font-size:13px;line-height:18px;display:flex;position:relative}.ZKlsPq_row:hover>.ZKlsPq_clickarea,.ZKlsPq_row:focus-visible>.ZKlsPq_clickarea{background:var(--dsw-alias-interactive-bg-hover)}.ZKlsPq_clickarea{box-sizing:border-box;border-radius:8px;flex:1;align-self:stretch;align-items:flex-start;gap:8px;min-width:0;margin:-7px -8px;padding:7px 8px;display:flex}.ZKlsPq_row>[data-state],.ZKlsPq_clickarea>[data-state]{margin-top:4px}.ZKlsPq_disabled{color:var(--dsw-alias-label-dimmed);cursor:not-allowed}.ZKlsPq_disabled:hover{background:0 0}.ZKlsPq_loadingRow{cursor:default}.ZKlsPq_disclosure,.ZKlsPq_disclosureSpace{flex:none;width:14px;height:18px}.ZKlsPq_disclosure{color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;justify-content:center;align-items:center;padding:0;transition:transform .12s;display:inline-flex}.ZKlsPq_disclosure:hover{color:var(--dsw-alias-label-primary)}.ZKlsPq_disclosureOpen{transform:rotate(90deg)}.ZKlsPq_content{flex-direction:column;flex:1;min-width:0;display:flex}.ZKlsPq_label,.ZKlsPq_summary{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.ZKlsPq_label{color:inherit;font-weight:400}.ZKlsPq_currentLabel{font-weight:600}.ZKlsPq_summary,.ZKlsPq_metrics{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px}.ZKlsPq_metrics{font-variant-numeric:tabular-nums;text-align:right;white-space:nowrap;flex:none;grid-template-rows:18px 16px;display:grid}.ZKlsPq_metricToken{grid-row:1;line-height:18px}.ZKlsPq_metricDuration{grid-row:2}.ZKlsPq_children{margin-left:18px;padding-left:4px;position:relative}.ZKlsPq_children:before,.ZKlsPq_children>.ZKlsPq_node:before{content:\"\";border-left:1px solid var(--dsw-alias-border-l2);position:absolute;left:0}.ZKlsPq_children:before{height:26px;top:-26px}.ZKlsPq_children[aria-busy=true]:before{content:none}.ZKlsPq_children>.ZKlsPq_node:before{top:0;bottom:0;left:-4px}.ZKlsPq_children>.ZKlsPq_node:last-child:before{height:17px;bottom:auto}.ZKlsPq_children>.ZKlsPq_node>.ZKlsPq_row:before{content:\"\";border-top:1px solid var(--dsw-alias-border-l2);width:14px;position:absolute;top:16px;left:-4px}.ZKlsPq_notice,.ZKlsPq_error{color:var(--dsw-alias-label-tertiary);padding:10px 12px;font-size:12px;line-height:18px}.ZKlsPq_error{color:var(--dsw-alias-state-error-primary);justify-content:space-between;align-items:center;gap:12px;display:flex}.ZKlsPq_refresh{color:inherit;cursor:pointer;background:0 0;border:0;border-radius:6px;flex:none;align-items:center;gap:4px;padding:4px 6px;display:inline-flex}.ZKlsPq_refresh:hover{background:var(--dsw-alias-interactive-bg-hover)}";
|
|
14
|
+
const tagId$1 = "@monotykamary/dsh-client-ui-subagent/SubagentHeaderLineage.module.css";
|
|
14
15
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
|
|
15
16
|
const tag = document.createElement("style");
|
|
16
17
|
tag.dataset.plugin = "@monotykamary/dsh-client-ui-subagent";
|
|
@@ -18,34 +19,39 @@ window.__ModuleLoader__.load({
|
|
|
18
19
|
tag.textContent = css$1;
|
|
19
20
|
document.head.appendChild(tag);
|
|
20
21
|
}
|
|
21
|
-
var
|
|
22
|
-
"activitySlot": "
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
22
|
+
var SubagentHeaderLineage_module_css_default = {
|
|
23
|
+
"activitySlot": "ZKlsPq_activitySlot",
|
|
24
|
+
"ancestorSwitcherTrigger": "ZKlsPq_ancestorSwitcherTrigger",
|
|
25
|
+
"children": "ZKlsPq_children",
|
|
26
|
+
"clickarea": "ZKlsPq_clickarea",
|
|
27
|
+
"content": "ZKlsPq_content",
|
|
28
|
+
"currentLabel": "ZKlsPq_currentLabel",
|
|
29
|
+
"disabled": "ZKlsPq_disabled",
|
|
30
|
+
"disclosure": "ZKlsPq_disclosure",
|
|
31
|
+
"disclosureOpen": "ZKlsPq_disclosureOpen",
|
|
32
|
+
"disclosureSpace": "ZKlsPq_disclosureSpace",
|
|
33
|
+
"error": "ZKlsPq_error",
|
|
34
|
+
"label": "ZKlsPq_label",
|
|
35
|
+
"loadingRow": "ZKlsPq_loadingRow",
|
|
36
|
+
"menu": "ZKlsPq_menu",
|
|
37
|
+
"metricDuration": "ZKlsPq_metricDuration",
|
|
38
|
+
"metricToken": "ZKlsPq_metricToken",
|
|
39
|
+
"metrics": "ZKlsPq_metrics",
|
|
40
|
+
"node": "ZKlsPq_node",
|
|
41
|
+
"notice": "ZKlsPq_notice",
|
|
42
|
+
"refresh": "ZKlsPq_refresh",
|
|
43
|
+
"root": "ZKlsPq_root",
|
|
44
|
+
"row": "ZKlsPq_row",
|
|
45
|
+
"separator": "ZKlsPq_separator",
|
|
46
|
+
"summary": "ZKlsPq_summary",
|
|
47
|
+
"switcherRoot": "ZKlsPq_switcherRoot",
|
|
48
|
+
"switcherTitle": "ZKlsPq_switcherTitle",
|
|
49
|
+
"switcherTrigger": "ZKlsPq_switcherTrigger",
|
|
50
|
+
"trigger": "ZKlsPq_trigger",
|
|
51
|
+
"triggerOpen": "ZKlsPq_triggerOpen"
|
|
46
52
|
};
|
|
47
53
|
//#endregion
|
|
48
|
-
//#region lib/types/client/
|
|
54
|
+
//#region lib/types/client/SubagentHeaderLineage.js
|
|
49
55
|
function diagnosticReason(entry, t) {
|
|
50
56
|
switch (entry.reason) {
|
|
51
57
|
case "corrupt": return t("diagnostic.corrupt");
|
|
@@ -137,28 +143,31 @@ window.__ModuleLoader__.load({
|
|
|
137
143
|
count: 0,
|
|
138
144
|
runningCount: 0
|
|
139
145
|
};
|
|
146
|
+
function SubagentSwitcherIcon() {
|
|
147
|
+
return (0, react_jsx_runtime.jsx)(_monotykamary_dsh_client_ui_primitives.UsersRound, { size: 16 });
|
|
148
|
+
}
|
|
140
149
|
/** Render the known direct-child shape while its authoritative catalog hydrates. */
|
|
141
150
|
function CatalogLoadingRows({ parentSessionId, summaries, level, t }) {
|
|
142
151
|
const children = Object.values(summaries).filter((summary) => summary.origin === "subagent" && summary.parentId === parentSessionId);
|
|
143
152
|
if (children.length === 0) return (0, react_jsx_runtime.jsx)("div", {
|
|
144
|
-
className:
|
|
153
|
+
className: SubagentHeaderLineage_module_css_default.notice,
|
|
145
154
|
children: t("loading.label")
|
|
146
155
|
});
|
|
147
156
|
return children.map((summary) => (0, react_jsx_runtime.jsx)("div", {
|
|
148
|
-
className:
|
|
157
|
+
className: SubagentHeaderLineage_module_css_default.node,
|
|
149
158
|
children: (0, react_jsx_runtime.jsxs)("div", {
|
|
150
159
|
role: "treeitem",
|
|
151
160
|
"aria-disabled": "true",
|
|
152
161
|
"aria-level": level,
|
|
153
162
|
"aria-label": t("loading.aria"),
|
|
154
|
-
className: `${
|
|
163
|
+
className: `${SubagentHeaderLineage_module_css_default.row} ${SubagentHeaderLineage_module_css_default.disabled} ${SubagentHeaderLineage_module_css_default.loadingRow}`,
|
|
155
164
|
children: [
|
|
156
|
-
(0, react_jsx_runtime.jsx)("span", { className:
|
|
165
|
+
(0, react_jsx_runtime.jsx)("span", { className: SubagentHeaderLineage_module_css_default.disclosureSpace }),
|
|
157
166
|
(0, react_jsx_runtime.jsx)(_monotykamary_dsh_client_ui_primitives.StateDot, { state: summary.running ? "ongoing" : "done" }),
|
|
158
167
|
(0, react_jsx_runtime.jsx)("span", {
|
|
159
|
-
className:
|
|
168
|
+
className: SubagentHeaderLineage_module_css_default.content,
|
|
160
169
|
children: (0, react_jsx_runtime.jsx)("span", {
|
|
161
|
-
className:
|
|
170
|
+
className: SubagentHeaderLineage_module_css_default.label,
|
|
162
171
|
children: t("loading.label")
|
|
163
172
|
})
|
|
164
173
|
})
|
|
@@ -167,7 +176,7 @@ window.__ModuleLoader__.load({
|
|
|
167
176
|
}, summary.id));
|
|
168
177
|
}
|
|
169
178
|
/** Render one catalog level and recurse only through explicitly expanded rows. */
|
|
170
|
-
function CatalogRows({ parentSessionId, catalog, catalogs, summaries, expanded, level, now, openChild, refresh, toggleBranch, closeCatalog, t }) {
|
|
179
|
+
function CatalogRows({ parentSessionId, currentSessionId, catalog, catalogs, summaries, expanded, level, now, openChild, refresh, toggleBranch, closeCatalog, t }) {
|
|
171
180
|
const emptyLoading = catalog.state === "loading" && catalog.entries.length === 0;
|
|
172
181
|
const reserveDisclosure = catalog.entries.some((entry) => entry.kind === "child" && entry.hasChildren);
|
|
173
182
|
return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
@@ -178,38 +187,38 @@ window.__ModuleLoader__.load({
|
|
|
178
187
|
t
|
|
179
188
|
}),
|
|
180
189
|
catalog.state === "error" && (0, react_jsx_runtime.jsxs)("div", {
|
|
181
|
-
className:
|
|
190
|
+
className: SubagentHeaderLineage_module_css_default.error,
|
|
182
191
|
children: [(0, react_jsx_runtime.jsx)("span", { children: catalog.error?.message ?? t("load.error") }), (0, react_jsx_runtime.jsxs)("button", {
|
|
183
192
|
type: "button",
|
|
184
|
-
className:
|
|
193
|
+
className: SubagentHeaderLineage_module_css_default.refresh,
|
|
185
194
|
onClick: () => {
|
|
186
195
|
refresh(parentSessionId);
|
|
187
196
|
},
|
|
188
|
-
children: [(0, react_jsx_runtime.jsx)(_monotykamary_dsh_client_ui_primitives.
|
|
197
|
+
children: [(0, react_jsx_runtime.jsx)(_monotykamary_dsh_client_ui_primitives.RefreshCw, { size: 14 }), t("retry")]
|
|
189
198
|
})]
|
|
190
199
|
}),
|
|
191
200
|
catalog.entries.map((entry) => {
|
|
192
201
|
if (entry.kind === "diagnostic") {
|
|
193
202
|
const reason = diagnosticReason(entry, t);
|
|
194
203
|
return (0, react_jsx_runtime.jsx)("div", {
|
|
195
|
-
className:
|
|
204
|
+
className: SubagentHeaderLineage_module_css_default.node,
|
|
196
205
|
children: (0, react_jsx_runtime.jsxs)("div", {
|
|
197
206
|
role: "treeitem",
|
|
198
207
|
"aria-disabled": "true",
|
|
199
208
|
"aria-level": level,
|
|
200
209
|
"aria-label": `${entry.id} ${reason}`,
|
|
201
|
-
className: `${
|
|
210
|
+
className: `${SubagentHeaderLineage_module_css_default.row} ${SubagentHeaderLineage_module_css_default.disabled}`,
|
|
202
211
|
title: reason,
|
|
203
212
|
children: [
|
|
204
|
-
reserveDisclosure && (0, react_jsx_runtime.jsx)("span", { className:
|
|
213
|
+
reserveDisclosure && (0, react_jsx_runtime.jsx)("span", { className: SubagentHeaderLineage_module_css_default.disclosureSpace }),
|
|
205
214
|
(0, react_jsx_runtime.jsx)(_monotykamary_dsh_client_ui_primitives.StateDot, { state: "error" }),
|
|
206
215
|
(0, react_jsx_runtime.jsxs)("span", {
|
|
207
|
-
className:
|
|
216
|
+
className: SubagentHeaderLineage_module_css_default.content,
|
|
208
217
|
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
209
|
-
className:
|
|
218
|
+
className: SubagentHeaderLineage_module_css_default.label,
|
|
210
219
|
children: entry.id
|
|
211
220
|
}), (0, react_jsx_runtime.jsx)("span", {
|
|
212
|
-
className:
|
|
221
|
+
className: SubagentHeaderLineage_module_css_default.summary,
|
|
213
222
|
children: reason
|
|
214
223
|
})]
|
|
215
224
|
})
|
|
@@ -218,6 +227,7 @@ window.__ModuleLoader__.load({
|
|
|
218
227
|
}, entry.id);
|
|
219
228
|
}
|
|
220
229
|
const childCatalog = catalogs[entry.id];
|
|
230
|
+
const isCurrent = entry.id === currentSessionId;
|
|
221
231
|
const isExpanded = expanded.has(entry.id);
|
|
222
232
|
const knownLeaf = !entry.hasChildren;
|
|
223
233
|
const childLoading = childCatalog === void 0 || childCatalog.state === "loading" && childCatalog.entries.length === 0;
|
|
@@ -263,48 +273,49 @@ window.__ModuleLoader__.load({
|
|
|
263
273
|
toggleBranch(entry.id);
|
|
264
274
|
};
|
|
265
275
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
266
|
-
className:
|
|
276
|
+
className: SubagentHeaderLineage_module_css_default.node,
|
|
267
277
|
children: [(0, react_jsx_runtime.jsxs)("div", {
|
|
268
278
|
role: "treeitem",
|
|
269
279
|
tabIndex: 0,
|
|
270
280
|
"aria-level": level,
|
|
281
|
+
"aria-current": isCurrent || void 0,
|
|
271
282
|
"aria-label": [
|
|
272
283
|
label,
|
|
273
284
|
secondary,
|
|
274
285
|
metrics
|
|
275
286
|
].filter((value) => value !== "").join(" "),
|
|
276
287
|
...knownLeaf ? {} : { "aria-expanded": isExpanded },
|
|
277
|
-
className:
|
|
288
|
+
className: SubagentHeaderLineage_module_css_default.row,
|
|
278
289
|
onClick: open,
|
|
279
290
|
onKeyDown: handleKey,
|
|
280
|
-
children: [knownLeaf ? reserveDisclosure && (0, react_jsx_runtime.jsx)("span", { className:
|
|
291
|
+
children: [knownLeaf ? reserveDisclosure && (0, react_jsx_runtime.jsx)("span", { className: SubagentHeaderLineage_module_css_default.disclosureSpace }) : (0, react_jsx_runtime.jsx)("button", {
|
|
281
292
|
type: "button",
|
|
282
293
|
tabIndex: -1,
|
|
283
|
-
className: `${
|
|
294
|
+
className: `${SubagentHeaderLineage_module_css_default.disclosure} ${isExpanded ? SubagentHeaderLineage_module_css_default.disclosureOpen : ""}`,
|
|
284
295
|
"aria-label": t(isExpanded ? "branch.collapse" : "branch.expand", { label }),
|
|
285
296
|
onClick: toggle,
|
|
286
|
-
children: (0, react_jsx_runtime.jsx)(_monotykamary_dsh_client_ui_primitives.
|
|
297
|
+
children: (0, react_jsx_runtime.jsx)(_monotykamary_dsh_client_ui_primitives.ChevronRight, { size: 14 })
|
|
287
298
|
}), (0, react_jsx_runtime.jsxs)("div", {
|
|
288
|
-
className:
|
|
299
|
+
className: SubagentHeaderLineage_module_css_default.clickarea,
|
|
289
300
|
children: [
|
|
290
301
|
(0, react_jsx_runtime.jsx)(_monotykamary_dsh_client_ui_primitives.StateDot, { state: entry.activity === "running" ? "ongoing" : "done" }),
|
|
291
302
|
(0, react_jsx_runtime.jsxs)("span", {
|
|
292
|
-
className:
|
|
303
|
+
className: SubagentHeaderLineage_module_css_default.content,
|
|
293
304
|
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
294
|
-
className:
|
|
305
|
+
className: `${SubagentHeaderLineage_module_css_default.label} ${isCurrent ? SubagentHeaderLineage_module_css_default.currentLabel : ""}`,
|
|
295
306
|
children: label
|
|
296
307
|
}), (0, react_jsx_runtime.jsx)("span", {
|
|
297
|
-
className:
|
|
308
|
+
className: SubagentHeaderLineage_module_css_default.summary,
|
|
298
309
|
children: secondary
|
|
299
310
|
})]
|
|
300
311
|
}),
|
|
301
312
|
metrics !== "" && (0, react_jsx_runtime.jsxs)("span", {
|
|
302
|
-
className:
|
|
313
|
+
className: SubagentHeaderLineage_module_css_default.metrics,
|
|
303
314
|
children: [tokenMetric !== void 0 && (0, react_jsx_runtime.jsx)("span", {
|
|
304
|
-
className:
|
|
315
|
+
className: SubagentHeaderLineage_module_css_default.metricToken,
|
|
305
316
|
children: tokenMetric
|
|
306
317
|
}), durationMetric !== void 0 && (0, react_jsx_runtime.jsx)("span", {
|
|
307
|
-
className:
|
|
318
|
+
className: SubagentHeaderLineage_module_css_default.metricDuration,
|
|
308
319
|
title: t("duration.exactTitle", { duration: durationMetric.exact }),
|
|
309
320
|
children: durationMetric.compact
|
|
310
321
|
})]
|
|
@@ -313,7 +324,7 @@ window.__ModuleLoader__.load({
|
|
|
313
324
|
})]
|
|
314
325
|
}), isExpanded && !knownLeaf && (0, react_jsx_runtime.jsx)("div", {
|
|
315
326
|
role: "group",
|
|
316
|
-
className:
|
|
327
|
+
className: SubagentHeaderLineage_module_css_default.children,
|
|
317
328
|
"aria-busy": childLoading || void 0,
|
|
318
329
|
children: childCatalog === void 0 ? (0, react_jsx_runtime.jsx)(CatalogLoadingRows, {
|
|
319
330
|
parentSessionId: entry.id,
|
|
@@ -322,6 +333,7 @@ window.__ModuleLoader__.load({
|
|
|
322
333
|
t
|
|
323
334
|
}) : (0, react_jsx_runtime.jsx)(CatalogRows, {
|
|
324
335
|
parentSessionId: entry.id,
|
|
336
|
+
currentSessionId,
|
|
325
337
|
catalog: childCatalog,
|
|
326
338
|
catalogs,
|
|
327
339
|
summaries,
|
|
@@ -339,34 +351,58 @@ window.__ModuleLoader__.load({
|
|
|
339
351
|
})
|
|
340
352
|
] });
|
|
341
353
|
}
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
354
|
+
const MENU_VIEWPORT_MARGIN = 16;
|
|
355
|
+
/** Place a portaled catalog below its trigger without crossing the viewport edge. */
|
|
356
|
+
function catalogMenuPosition(trigger) {
|
|
357
|
+
const rect = trigger.getBoundingClientRect();
|
|
358
|
+
const width = Math.min(336, window.innerWidth - MENU_VIEWPORT_MARGIN * 2);
|
|
359
|
+
return {
|
|
360
|
+
top: rect.bottom + 5,
|
|
361
|
+
left: Math.min(Math.max(MENU_VIEWPORT_MARGIN, rect.left), window.innerWidth - width - MENU_VIEWPORT_MARGIN)
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
/** One trigger-plus-tree dropdown over the catalog rooted at `rootSessionId`. */
|
|
365
|
+
function CatalogDropdown({ rootSessionId, currentSessionId, displayTitle, openTitle, variant, separator = false, useSessions, openChild, refresh, setCatalogOpen, t }) {
|
|
366
|
+
const ancestorSwitcher = variant === "switcher" && openTitle !== void 0;
|
|
348
367
|
const catalogs = useSessions((state) => state.subagentsByParent);
|
|
349
368
|
const summaries = useSessions((state) => state.byId);
|
|
350
|
-
const catalog = catalogs[
|
|
369
|
+
const catalog = catalogs[rootSessionId];
|
|
351
370
|
const [open, setOpen] = (0, react.useState)(false);
|
|
371
|
+
const [menuPosition, setMenuPosition] = (0, react.useState)();
|
|
352
372
|
const [now, setNow] = (0, react.useState)(() => Date.now());
|
|
353
373
|
const [expanded, setExpanded] = (0, react.useState)(() => /* @__PURE__ */ new Set());
|
|
354
374
|
const rootRef = (0, react.useRef)(null);
|
|
355
375
|
const triggerRef = (0, react.useRef)(null);
|
|
376
|
+
const menuRef = (0, react.useRef)(null);
|
|
377
|
+
const hoverOpenTimer = (0, react.useRef)(void 0);
|
|
378
|
+
const hoverCloseTimer = (0, react.useRef)(void 0);
|
|
356
379
|
const observedCatalogs = (0, react.useRef)(/* @__PURE__ */ new Set());
|
|
380
|
+
const requestedInitialCatalog = (0, react.useRef)();
|
|
357
381
|
const setCatalogOpenRef = (0, react.useRef)(setCatalogOpen);
|
|
358
382
|
setCatalogOpenRef.current = setCatalogOpen;
|
|
383
|
+
const currentEntry = currentSessionId === void 0 ? void 0 : catalog?.entries.find((entry) => entry.kind === "child" && entry.id === currentSessionId);
|
|
384
|
+
const switcherDisplayTitle = currentEntry?.kind === "child" ? currentEntry.label ?? currentEntry.id : displayTitle;
|
|
359
385
|
const healthy = catalog?.entries.filter((entry) => entry.kind === "child") ?? [];
|
|
360
|
-
const descendants = (0, react.useMemo)(() => (0, _monotykamary_dsh_client_runtime_client.indexSubagentDescendants)(summaries).get(
|
|
386
|
+
const descendants = (0, react.useMemo)(() => (0, _monotykamary_dsh_client_runtime_client.indexSubagentDescendants)(summaries).get(rootSessionId) ?? NO_DESCENDANTS, [rootSessionId, summaries]);
|
|
361
387
|
const descendantCount = Math.max(healthy.length, descendants.count);
|
|
362
388
|
const totalCountKey = descendantCount === 1 ? "count.total.one" : "count.total.other";
|
|
363
389
|
const runningCountKey = descendants.runningCount === 1 ? "count.running.one" : "count.running.other";
|
|
364
|
-
const presentedCatalog = descendants.count > 0 && (catalog === void 0 || catalog.state === "ready" && catalog.entries.length === 0) ? {
|
|
390
|
+
const presentedCatalog = (descendants.count > 0 || variant === "switcher") && (catalog === void 0 || catalog.state === "ready" && catalog.entries.length === 0) ? {
|
|
365
391
|
entries: [],
|
|
366
392
|
parentAvailable: catalog?.parentAvailable ?? false,
|
|
367
393
|
state: "loading",
|
|
368
394
|
error: null
|
|
369
395
|
} : catalog;
|
|
396
|
+
(0, react.useEffect)(() => {
|
|
397
|
+
if (variant !== "switcher" || catalog !== void 0 || requestedInitialCatalog.current === rootSessionId) return;
|
|
398
|
+
requestedInitialCatalog.current = rootSessionId;
|
|
399
|
+
refresh(rootSessionId);
|
|
400
|
+
}, [
|
|
401
|
+
catalog,
|
|
402
|
+
refresh,
|
|
403
|
+
rootSessionId,
|
|
404
|
+
variant
|
|
405
|
+
]);
|
|
370
406
|
const observeCatalog = (parentSessionId, next) => {
|
|
371
407
|
if (next) observedCatalogs.current.add(parentSessionId);
|
|
372
408
|
else observedCatalogs.current.delete(parentSessionId);
|
|
@@ -377,16 +413,53 @@ window.__ModuleLoader__.load({
|
|
|
377
413
|
observedCatalogs.current.clear();
|
|
378
414
|
setExpanded(/* @__PURE__ */ new Set());
|
|
379
415
|
};
|
|
416
|
+
const cancelHoverClose = () => {
|
|
417
|
+
if (hoverCloseTimer.current === void 0) return;
|
|
418
|
+
clearTimeout(hoverCloseTimer.current);
|
|
419
|
+
hoverCloseTimer.current = void 0;
|
|
420
|
+
};
|
|
421
|
+
const cancelHoverOpen = () => {
|
|
422
|
+
if (hoverOpenTimer.current === void 0) return;
|
|
423
|
+
clearTimeout(hoverOpenTimer.current);
|
|
424
|
+
hoverOpenTimer.current = void 0;
|
|
425
|
+
};
|
|
380
426
|
const changeOpen = (next, restoreFocus = false) => {
|
|
381
|
-
|
|
427
|
+
cancelHoverOpen();
|
|
428
|
+
cancelHoverClose();
|
|
382
429
|
if (next) {
|
|
430
|
+
const trigger = triggerRef.current;
|
|
431
|
+
/* v8 ignore next -- a queued callback can outlive the trigger */
|
|
432
|
+
if (trigger === null) return;
|
|
433
|
+
setOpen(true);
|
|
434
|
+
setMenuPosition(catalogMenuPosition(trigger));
|
|
383
435
|
setNow(Date.now());
|
|
384
|
-
observeCatalog(
|
|
385
|
-
} else
|
|
436
|
+
observeCatalog(rootSessionId, true);
|
|
437
|
+
} else {
|
|
438
|
+
setOpen(false);
|
|
439
|
+
setMenuPosition(void 0);
|
|
440
|
+
closeAllCatalogs();
|
|
441
|
+
}
|
|
386
442
|
if (restoreFocus) queueMicrotask(() => {
|
|
387
443
|
triggerRef.current?.focus();
|
|
388
444
|
});
|
|
389
445
|
};
|
|
446
|
+
const scheduleHoverOpen = () => {
|
|
447
|
+
cancelHoverOpen();
|
|
448
|
+
cancelHoverClose();
|
|
449
|
+
if (open) return;
|
|
450
|
+
hoverOpenTimer.current = setTimeout(() => {
|
|
451
|
+
hoverOpenTimer.current = void 0;
|
|
452
|
+
changeOpen(true);
|
|
453
|
+
}, 150);
|
|
454
|
+
};
|
|
455
|
+
const scheduleHoverClose = () => {
|
|
456
|
+
cancelHoverOpen();
|
|
457
|
+
cancelHoverClose();
|
|
458
|
+
hoverCloseTimer.current = setTimeout(() => {
|
|
459
|
+
hoverCloseTimer.current = void 0;
|
|
460
|
+
changeOpen(false);
|
|
461
|
+
}, 120);
|
|
462
|
+
};
|
|
390
463
|
const closeBranch = (root) => {
|
|
391
464
|
const closing = /* @__PURE__ */ new Set();
|
|
392
465
|
const visit = (parentSessionId) => {
|
|
@@ -410,13 +483,28 @@ window.__ModuleLoader__.load({
|
|
|
410
483
|
(0, react.useEffect)(() => {
|
|
411
484
|
if (!open) return;
|
|
412
485
|
const closeOutside = (event) => {
|
|
413
|
-
if (event.target instanceof Node && !rootRef.current?.contains(event.target)) changeOpen(false);
|
|
486
|
+
if (event.target instanceof Node && !rootRef.current?.contains(event.target) && !menuRef.current?.contains(event.target)) changeOpen(false);
|
|
414
487
|
};
|
|
415
488
|
document.addEventListener("pointerdown", closeOutside);
|
|
416
489
|
return () => {
|
|
417
490
|
document.removeEventListener("pointerdown", closeOutside);
|
|
418
491
|
};
|
|
419
492
|
}, [open]);
|
|
493
|
+
(0, react.useEffect)(() => {
|
|
494
|
+
if (!open) return;
|
|
495
|
+
const placeMenu = () => {
|
|
496
|
+
const trigger = triggerRef.current;
|
|
497
|
+
/* v8 ignore next -- native resize or scroll can outlive the trigger */
|
|
498
|
+
if (trigger === null) return;
|
|
499
|
+
setMenuPosition(catalogMenuPosition(trigger));
|
|
500
|
+
};
|
|
501
|
+
window.addEventListener("resize", placeMenu);
|
|
502
|
+
document.addEventListener("scroll", placeMenu, true);
|
|
503
|
+
return () => {
|
|
504
|
+
window.removeEventListener("resize", placeMenu);
|
|
505
|
+
document.removeEventListener("scroll", placeMenu, true);
|
|
506
|
+
};
|
|
507
|
+
}, [open]);
|
|
420
508
|
(0, react.useEffect)(() => {
|
|
421
509
|
if (!open || descendants.runningCount === 0) return;
|
|
422
510
|
const timer = setInterval(() => {
|
|
@@ -427,23 +515,28 @@ window.__ModuleLoader__.load({
|
|
|
427
515
|
};
|
|
428
516
|
}, [open, descendants.runningCount]);
|
|
429
517
|
(0, react.useEffect)(() => () => {
|
|
518
|
+
cancelHoverOpen();
|
|
519
|
+
cancelHoverClose();
|
|
430
520
|
for (const parentSessionId of observedCatalogs.current) setCatalogOpenRef.current(parentSessionId, false);
|
|
431
521
|
observedCatalogs.current.clear();
|
|
432
522
|
}, []);
|
|
433
|
-
const visible = presentedCatalog !== void 0 && (presentedCatalog.state === "error" || presentedCatalog.entries.length > 0 || descendantCount > 0);
|
|
523
|
+
const visible = presentedCatalog !== void 0 && (variant === "switcher" || presentedCatalog.state === "error" || presentedCatalog.entries.length > 0 || descendantCount > 0);
|
|
434
524
|
(0, react.useEffect)(() => {
|
|
435
|
-
if (visible
|
|
525
|
+
if (visible) return;
|
|
526
|
+
cancelHoverOpen();
|
|
527
|
+
cancelHoverClose();
|
|
528
|
+
if (!open) return;
|
|
436
529
|
setOpen(false);
|
|
437
530
|
closeAllCatalogs();
|
|
438
531
|
}, [visible, open]);
|
|
439
532
|
if (!visible) return null;
|
|
440
533
|
const focusAt = (index) => {
|
|
441
|
-
const items = treeItems(
|
|
534
|
+
const items = treeItems(menuRef.current);
|
|
442
535
|
if (items.length === 0) return;
|
|
443
536
|
items[(index + items.length) % items.length]?.focus();
|
|
444
537
|
};
|
|
445
538
|
const navigate = (event) => {
|
|
446
|
-
const items = treeItems(
|
|
539
|
+
const items = treeItems(menuRef.current);
|
|
447
540
|
const index = items.indexOf(document.activeElement);
|
|
448
541
|
if (event.key === "Escape") {
|
|
449
542
|
event.preventDefault();
|
|
@@ -463,64 +556,118 @@ window.__ModuleLoader__.load({
|
|
|
463
556
|
}
|
|
464
557
|
};
|
|
465
558
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
466
|
-
className:
|
|
559
|
+
className: `${SubagentHeaderLineage_module_css_default.root} ${variant === "switcher" ? SubagentHeaderLineage_module_css_default.switcherRoot : ""}`,
|
|
467
560
|
ref: rootRef,
|
|
468
561
|
onKeyDown: navigate,
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
children: [
|
|
488
|
-
(0, react_jsx_runtime.jsx)("span", {
|
|
489
|
-
className: SubagentCatalogAction_module_css_default.activitySlot,
|
|
490
|
-
children: descendants.runningCount > 0 && (0, react_jsx_runtime.jsx)(_monotykamary_dsh_client_ui_primitives.StateDot, { state: "ongoing" })
|
|
491
|
-
}),
|
|
492
|
-
(0, react_jsx_runtime.jsx)("span", {
|
|
493
|
-
className: SubagentCatalogAction_module_css_default.count,
|
|
494
|
-
children: t(totalCountKey, { count: descendantCount })
|
|
495
|
-
}),
|
|
496
|
-
(0, react_jsx_runtime.jsx)(_monotykamary_dsh_client_ui_primitives.IconChevronDownOutline14, { className: open ? SubagentCatalogAction_module_css_default.triggerOpen : void 0 })
|
|
497
|
-
]
|
|
498
|
-
}), open && (0, react_jsx_runtime.jsx)("div", {
|
|
499
|
-
className: SubagentCatalogAction_module_css_default.menu,
|
|
500
|
-
role: "tree",
|
|
501
|
-
"aria-label": t("tree.aria"),
|
|
502
|
-
children: (0, react_jsx_runtime.jsx)(CatalogRows, {
|
|
503
|
-
parentSessionId: sessionId,
|
|
504
|
-
catalog: presentedCatalog,
|
|
505
|
-
catalogs,
|
|
506
|
-
summaries,
|
|
507
|
-
expanded,
|
|
508
|
-
level: 1,
|
|
509
|
-
now,
|
|
510
|
-
openChild,
|
|
511
|
-
refresh,
|
|
512
|
-
toggleBranch,
|
|
513
|
-
closeCatalog: () => {
|
|
514
|
-
changeOpen(false);
|
|
562
|
+
onMouseEnter: scheduleHoverOpen,
|
|
563
|
+
onMouseLeave: scheduleHoverClose,
|
|
564
|
+
children: [
|
|
565
|
+
separator && (0, react_jsx_runtime.jsx)("span", {
|
|
566
|
+
className: SubagentHeaderLineage_module_css_default.separator,
|
|
567
|
+
children: "/"
|
|
568
|
+
}),
|
|
569
|
+
(0, react_jsx_runtime.jsxs)("button", {
|
|
570
|
+
ref: triggerRef,
|
|
571
|
+
type: "button",
|
|
572
|
+
className: variant === "switcher" ? `${SubagentHeaderLineage_module_css_default.switcherTrigger} ${ancestorSwitcher ? SubagentHeaderLineage_module_css_default.ancestorSwitcherTrigger : ""}` : SubagentHeaderLineage_module_css_default.trigger,
|
|
573
|
+
"aria-haspopup": "tree",
|
|
574
|
+
"aria-expanded": open,
|
|
575
|
+
"aria-label": variant === "switcher" ? t("switcher.aria", { title: switcherDisplayTitle }) : t(descendants.runningCount > 0 ? runningCountKey : totalCountKey, { count: descendants.runningCount > 0 ? descendants.runningCount : descendantCount }),
|
|
576
|
+
onClick: openTitle === void 0 ? void 0 : () => {
|
|
577
|
+
cancelHoverOpen();
|
|
578
|
+
if (open) changeOpen(false);
|
|
579
|
+
openTitle();
|
|
515
580
|
},
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
581
|
+
onKeyDown: (event) => {
|
|
582
|
+
if (event.key !== "ArrowDown") return;
|
|
583
|
+
event.preventDefault();
|
|
584
|
+
if (!open) changeOpen(true);
|
|
585
|
+
queueMicrotask(() => {
|
|
586
|
+
focusAt(0);
|
|
587
|
+
});
|
|
588
|
+
},
|
|
589
|
+
children: [variant === "switcher" ? (0, react_jsx_runtime.jsx)("span", {
|
|
590
|
+
className: SubagentHeaderLineage_module_css_default.switcherTitle,
|
|
591
|
+
children: switcherDisplayTitle
|
|
592
|
+
}) : (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [descendants.runningCount > 0 && (0, react_jsx_runtime.jsx)("span", {
|
|
593
|
+
className: SubagentHeaderLineage_module_css_default.activitySlot,
|
|
594
|
+
children: (0, react_jsx_runtime.jsx)(_monotykamary_dsh_client_ui_primitives.StateDot, { state: "ongoing" })
|
|
595
|
+
}), (0, react_jsx_runtime.jsx)("span", {
|
|
596
|
+
className: SubagentHeaderLineage_module_css_default.count,
|
|
597
|
+
children: t(totalCountKey, { count: descendantCount })
|
|
598
|
+
})] }), variant === "switcher" ? (0, react_jsx_runtime.jsx)(SubagentSwitcherIcon, {}) : (0, react_jsx_runtime.jsx)(_monotykamary_dsh_client_ui_primitives.ChevronDown, {
|
|
599
|
+
size: 14,
|
|
600
|
+
className: open ? SubagentHeaderLineage_module_css_default.triggerOpen : void 0
|
|
601
|
+
})]
|
|
602
|
+
}),
|
|
603
|
+
open && (0, react_dom.createPortal)((0, react_jsx_runtime.jsx)("div", {
|
|
604
|
+
ref: menuRef,
|
|
605
|
+
className: SubagentHeaderLineage_module_css_default.menu,
|
|
606
|
+
style: menuPosition,
|
|
607
|
+
role: "tree",
|
|
608
|
+
"aria-label": t("tree.aria"),
|
|
609
|
+
onMouseEnter: cancelHoverClose,
|
|
610
|
+
onMouseLeave: scheduleHoverClose,
|
|
611
|
+
children: (0, react_jsx_runtime.jsx)(CatalogRows, {
|
|
612
|
+
parentSessionId: rootSessionId,
|
|
613
|
+
currentSessionId,
|
|
614
|
+
catalog: presentedCatalog,
|
|
615
|
+
catalogs,
|
|
616
|
+
summaries,
|
|
617
|
+
expanded,
|
|
618
|
+
level: 1,
|
|
619
|
+
now,
|
|
620
|
+
openChild,
|
|
621
|
+
refresh,
|
|
622
|
+
toggleBranch,
|
|
623
|
+
closeCatalog: () => {
|
|
624
|
+
changeOpen(false);
|
|
625
|
+
},
|
|
626
|
+
t
|
|
627
|
+
})
|
|
628
|
+
}), document.body)
|
|
629
|
+
]
|
|
630
|
+
});
|
|
631
|
+
}
|
|
632
|
+
/**
|
|
633
|
+
* Render one breadcrumb title together with its subagent navigation.
|
|
634
|
+
* @param props - Breadcrumb title, session standard props, and catalog actions.
|
|
635
|
+
* @returns An ordinary-title descendant count, or a title-and-chevron sibling switcher.
|
|
636
|
+
*/
|
|
637
|
+
function SubagentHeaderLineage({ lineageSessionId, displayTitle, openTitle, useSessions, openChild, refresh, setCatalogOpen, t }) {
|
|
638
|
+
const parentId = useSessions((state) => {
|
|
639
|
+
const summary = state.byId[lineageSessionId];
|
|
640
|
+
return summary?.origin === "subagent" ? summary.parentId : void 0;
|
|
519
641
|
});
|
|
642
|
+
const shared = {
|
|
643
|
+
useSessions,
|
|
644
|
+
openChild,
|
|
645
|
+
refresh,
|
|
646
|
+
setCatalogOpen,
|
|
647
|
+
t
|
|
648
|
+
};
|
|
649
|
+
if (parentId === void 0) return (0, react_jsx_runtime.jsx)(CatalogDropdown, {
|
|
650
|
+
rootSessionId: lineageSessionId,
|
|
651
|
+
variant: "count",
|
|
652
|
+
separator: true,
|
|
653
|
+
...shared
|
|
654
|
+
}, lineageSessionId);
|
|
655
|
+
return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(CatalogDropdown, {
|
|
656
|
+
rootSessionId: parentId,
|
|
657
|
+
currentSessionId: lineageSessionId,
|
|
658
|
+
variant: "switcher",
|
|
659
|
+
displayTitle,
|
|
660
|
+
...openTitle === void 0 ? {} : { openTitle },
|
|
661
|
+
...shared
|
|
662
|
+
}, lineageSessionId), openTitle === void 0 && (0, react_jsx_runtime.jsx)(CatalogDropdown, {
|
|
663
|
+
rootSessionId: lineageSessionId,
|
|
664
|
+
variant: "count",
|
|
665
|
+
...shared
|
|
666
|
+
}, lineageSessionId)] });
|
|
520
667
|
}
|
|
521
668
|
//#endregion
|
|
522
|
-
//#region \0dsh-css:/
|
|
523
|
-
const css = ".
|
|
669
|
+
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-subagent/src/client/SubagentReadOnlyComposer.module.css.mjs
|
|
670
|
+
const css = ".XJ7liG_frame{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);min-height:54px;color:var(--dsw-alias-label-tertiary);border-radius:14px;justify-content:center;align-items:center;gap:8px;margin:0 24px 20px;padding:10px 16px;font-size:13px;line-height:20px;display:flex}.XJ7liG_frame strong{color:var(--dsw-alias-label-primary);font-weight:510}";
|
|
524
671
|
const tagId = "@monotykamary/dsh-client-ui-subagent/SubagentReadOnlyComposer.module.css";
|
|
525
672
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
526
673
|
const tag = document.createElement("style");
|
|
@@ -529,7 +676,7 @@ window.__ModuleLoader__.load({
|
|
|
529
676
|
tag.textContent = css;
|
|
530
677
|
document.head.appendChild(tag);
|
|
531
678
|
}
|
|
532
|
-
var SubagentReadOnlyComposer_module_css_default = { "frame": "
|
|
679
|
+
var SubagentReadOnlyComposer_module_css_default = { "frame": "XJ7liG_frame" };
|
|
533
680
|
//#endregion
|
|
534
681
|
//#region lib/types/client/SubagentReadOnlyComposer.js
|
|
535
682
|
/**
|
|
@@ -580,6 +727,7 @@ window.__ModuleLoader__.load({
|
|
|
580
727
|
"count.total.other": "{count} 个子代理",
|
|
581
728
|
"count.running.one": "{count} 个子代理,正在运行",
|
|
582
729
|
"count.running.other": "{count} 个子代理,正在运行",
|
|
730
|
+
"switcher.aria": "切换子代理:{title}",
|
|
583
731
|
"tree.aria": "子代理会话",
|
|
584
732
|
"readonly.oneShot.title": "一次性子代理记录",
|
|
585
733
|
"readonly.title": "此子代理暂时只读",
|
|
@@ -616,6 +764,7 @@ window.__ModuleLoader__.load({
|
|
|
616
764
|
"count.total.other": "{count} subagents",
|
|
617
765
|
"count.running.one": "{count} subagent running",
|
|
618
766
|
"count.running.other": "{count} subagents running",
|
|
767
|
+
"switcher.aria": "Switch subagent: {title}",
|
|
619
768
|
"tree.aria": "Subagent sessions",
|
|
620
769
|
"readonly.oneShot.title": "One-shot subagent record",
|
|
621
770
|
"readonly.title": "This subagent is read-only for now",
|
|
@@ -624,9 +773,8 @@ window.__ModuleLoader__.load({
|
|
|
624
773
|
};
|
|
625
774
|
//#endregion
|
|
626
775
|
//#region lib/types/client/index.js
|
|
627
|
-
/** Required services for
|
|
776
|
+
/** Required services for conversation slots and session navigation. */
|
|
628
777
|
const inject = [
|
|
629
|
-
"inputTriggers",
|
|
630
778
|
"sessions",
|
|
631
779
|
"slots",
|
|
632
780
|
"locale"
|
|
@@ -640,7 +788,7 @@ window.__ModuleLoader__.load({
|
|
|
640
788
|
return owner.session?.running === true ? null : { reason: "parent-unavailable" };
|
|
641
789
|
}
|
|
642
790
|
/**
|
|
643
|
-
* Client plugin body: register the
|
|
791
|
+
* Client plugin body: register the subagent catalog and read-only composer seats.
|
|
644
792
|
* @param ctx - client root context.
|
|
645
793
|
*/
|
|
646
794
|
function apply(ctx) {
|
|
@@ -649,32 +797,6 @@ window.__ModuleLoader__.load({
|
|
|
649
797
|
en
|
|
650
798
|
}), "ui-subagent: dictionaries");
|
|
651
799
|
const sessions = ctx.sessions;
|
|
652
|
-
const childLabels = (session, query) => {
|
|
653
|
-
const { byId } = sessions.list.getSnapshot();
|
|
654
|
-
return Object.values(byId).filter((child) => child.parentId === session.sessionId && child.running && child.displayTitle.includes(query)).map((child) => child.displayTitle);
|
|
655
|
-
};
|
|
656
|
-
const source = {
|
|
657
|
-
trigger: "@",
|
|
658
|
-
name: "subagent",
|
|
659
|
-
candidates(session, { query }) {
|
|
660
|
-
return Promise.resolve(childLabels(session, query).map((name) => ({ name })));
|
|
661
|
-
},
|
|
662
|
-
lexicon(session) {
|
|
663
|
-
return childLabels(session, "");
|
|
664
|
-
},
|
|
665
|
-
subscribeLexicon(_session, listener) {
|
|
666
|
-
return sessions.list.subscribe(listener);
|
|
667
|
-
},
|
|
668
|
-
onPick({ candidate }) {
|
|
669
|
-
return { text: `@${candidate.name} ` };
|
|
670
|
-
},
|
|
671
|
-
codec: {
|
|
672
|
-
clipboardText: (ref) => `@${ref}`,
|
|
673
|
-
serialize: (ref) => Promise.resolve(`@${ref}`)
|
|
674
|
-
}
|
|
675
|
-
};
|
|
676
|
-
const inputTriggers = ctx.get("inputTriggers");
|
|
677
|
-
ctx.effect(() => inputTriggers.registerSource(source), "ui-subagent: @ source");
|
|
678
800
|
const catalogActions = (_parentSessionId) => ({
|
|
679
801
|
openChild(address) {
|
|
680
802
|
sessions.openSubagent(address);
|
|
@@ -686,13 +808,11 @@ window.__ModuleLoader__.load({
|
|
|
686
808
|
sessions.setSubagentCatalogOpen(parentSessionId, open);
|
|
687
809
|
}
|
|
688
810
|
});
|
|
689
|
-
ctx.slots.inject("conversation.session.header.
|
|
690
|
-
name: "conversation.session.header.
|
|
691
|
-
id: "subagent-catalog",
|
|
692
|
-
order: 10,
|
|
811
|
+
ctx.slots.inject("conversation.session.header.lineage", () => ctx.slots.register({
|
|
812
|
+
name: "conversation.session.header.lineage",
|
|
693
813
|
locale: NS,
|
|
694
814
|
inject: catalogActions
|
|
695
|
-
},
|
|
815
|
+
}, SubagentHeaderLineage));
|
|
696
816
|
ctx.slots.inject("conversation.composer", () => ctx.slots.register({
|
|
697
817
|
name: "conversation.composer",
|
|
698
818
|
priority: -10,
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type SessionId, type SubagentAddress } from '@monotykamary/dsh-client-runtime/client';
|
|
2
|
+
import type { PropsLocale, PropsRuntime } from '@monotykamary/dsh-client-ui-slots';
|
|
3
|
+
import { NS } from './locales.ts';
|
|
4
|
+
/** Business actions supplied by the slot registration. */
|
|
5
|
+
export interface SubagentCatalogInjected {
|
|
6
|
+
openChild: (address: SubagentAddress) => void;
|
|
7
|
+
refresh: (parentSessionId: SessionId) => void;
|
|
8
|
+
setCatalogOpen: (parentSessionId: SessionId, open: boolean) => void;
|
|
9
|
+
}
|
|
10
|
+
/** Full props for the session-header lineage renderer. */
|
|
11
|
+
export type SubagentHeaderLineageProps = PropsRuntime<'conversation.session.header.lineage'> & SubagentCatalogInjected & PropsLocale<typeof NS>;
|
|
12
|
+
/**
|
|
13
|
+
* Render one breadcrumb title together with its subagent navigation.
|
|
14
|
+
* @param props - Breadcrumb title, session standard props, and catalog actions.
|
|
15
|
+
* @returns An ordinary-title descendant count, or a title-and-chevron sibling switcher.
|
|
16
|
+
*/
|
|
17
|
+
export declare function SubagentHeaderLineage({ lineageSessionId, displayTitle, openTitle, useSessions, openChild, refresh, setCatalogOpen, t, }: SubagentHeaderLineageProps): import("react").JSX.Element;
|
|
18
|
+
//# sourceMappingURL=SubagentHeaderLineage.d.ts.map
|
|
@@ -1,16 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Subagent reference plugin, browser half: registers the '@' source —
|
|
3
|
-
* candidates filtered from the session list snapshot's running children
|
|
4
|
-
* (zero RPC; the list rides the plugin's root-context sessions service, the
|
|
5
|
-
* scoped session comes from the per-call projection), pick inserts the
|
|
6
|
-
* literal `@label ` text (plain-text-reference decision, see
|
|
7
|
-
* .agents/notes/implemented/architecture/2026-07-25-web-input-machine-and-slash-pipeline.md:
|
|
8
|
-
* the draft carries plain text, chip
|
|
9
|
-
* visuals are derived by scanning against the source lexicon, and the
|
|
10
|
-
* prompt ships the same literal). Consumption semantics stay with future
|
|
11
|
-
* business work. No adjudication hooks: subagent
|
|
12
|
-
* references never enter command adjudication.
|
|
13
|
-
*/
|
|
1
|
+
/** Web subagent catalog, navigation, and addressed-session composer owner. */
|
|
14
2
|
import type { ClientContext } from '@monotykamary/dsh-client-runtime/client';
|
|
15
3
|
import { type SubagentKey } from './locales.ts';
|
|
16
4
|
declare module '@monotykamary/dsh-client-ui-slots' {
|
|
@@ -19,12 +7,12 @@ declare module '@monotykamary/dsh-client-ui-slots' {
|
|
|
19
7
|
'subagent': SubagentKey;
|
|
20
8
|
}
|
|
21
9
|
}
|
|
22
|
-
export type {
|
|
10
|
+
export type { SubagentCatalogInjected, SubagentHeaderLineageProps, } from './SubagentHeaderLineage.tsx';
|
|
23
11
|
export type { SubagentReadOnlyComposerProps, SubagentReadOnlyMatch, } from './SubagentReadOnlyComposer.tsx';
|
|
24
|
-
/** Required services for
|
|
12
|
+
/** Required services for conversation slots and session navigation. */
|
|
25
13
|
export declare const inject: string[];
|
|
26
14
|
/**
|
|
27
|
-
* Client plugin body: register the
|
|
15
|
+
* Client plugin body: register the subagent catalog and read-only composer seats.
|
|
28
16
|
* @param ctx - client root context.
|
|
29
17
|
*/
|
|
30
18
|
export declare function apply(ctx: ClientContext): void;
|
|
@@ -31,6 +31,7 @@ export declare const zh: {
|
|
|
31
31
|
readonly 'count.total.other': "{count} 个子代理";
|
|
32
32
|
readonly 'count.running.one': "{count} 个子代理,正在运行";
|
|
33
33
|
readonly 'count.running.other': "{count} 个子代理,正在运行";
|
|
34
|
+
readonly 'switcher.aria': "切换子代理:{title}";
|
|
34
35
|
readonly 'tree.aria': "子代理会话";
|
|
35
36
|
readonly 'readonly.oneShot.title': "一次性子代理记录";
|
|
36
37
|
readonly 'readonly.title': "此子代理暂时只读";
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@monotykamary/dsh-client-ui-subagent",
|
|
3
3
|
"description": "Subagent conversation catalog, continuation routing UI, and '@' reference source",
|
|
4
|
-
"version": "0.1.0
|
|
4
|
+
"version": "0.1.0",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -42,34 +42,32 @@
|
|
|
42
42
|
}
|
|
43
43
|
},
|
|
44
44
|
"license": "MIT",
|
|
45
|
-
"dependencies": {
|
|
46
|
-
"react": "^18.2.0"
|
|
47
|
-
},
|
|
48
45
|
"peerDependencies": {
|
|
49
|
-
"@monotykamary/dsh-client-locale": "^0.1.0
|
|
50
|
-
"@monotykamary/dsh-client-
|
|
51
|
-
"@monotykamary/dsh-client-ui-
|
|
52
|
-
"@monotykamary/dsh-client-
|
|
53
|
-
"@monotykamary/dsh-invariants": "^0.1.0
|
|
54
|
-
"@monotykamary/dsh-
|
|
55
|
-
"@monotykamary/dsh-
|
|
56
|
-
"@monotykamary/dsh-token-meter": "^0.1.0-rc.8",
|
|
57
|
-
"@monotykamary/dsh-subagent": "^0.1.0-rc.8",
|
|
46
|
+
"@monotykamary/dsh-client-locale": "^0.1.0",
|
|
47
|
+
"@monotykamary/dsh-client-runtime": "^0.1.0",
|
|
48
|
+
"@monotykamary/dsh-client-ui-conversation": "^0.1.0",
|
|
49
|
+
"@monotykamary/dsh-client-ui-input-trigger": "^0.1.0",
|
|
50
|
+
"@monotykamary/dsh-invariants": "^0.1.0",
|
|
51
|
+
"@monotykamary/dsh-subagent": "^0.1.0",
|
|
52
|
+
"@monotykamary/dsh-token-meter": "^0.1.0",
|
|
58
53
|
"@monotykamary/cordis": "^4.0.1"
|
|
59
54
|
},
|
|
60
55
|
"devDependencies": {
|
|
61
56
|
"@types/react": "~18.3.1",
|
|
62
|
-
"@
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"@monotykamary/dsh-client-
|
|
66
|
-
"@monotykamary/dsh-client-
|
|
67
|
-
"@monotykamary/dsh-client-
|
|
68
|
-
"@monotykamary/dsh-
|
|
69
|
-
"@monotykamary/dsh-
|
|
70
|
-
"@monotykamary/
|
|
71
|
-
"@monotykamary/dsh-
|
|
72
|
-
"@monotykamary/dsh-
|
|
57
|
+
"@types/react-dom": "~18.3.0",
|
|
58
|
+
"react": "^18.2.0",
|
|
59
|
+
"react-dom": "^18.2.0",
|
|
60
|
+
"@monotykamary/dsh-client-locale": "^0.1.0",
|
|
61
|
+
"@monotykamary/dsh-client-runtime": "^0.1.0",
|
|
62
|
+
"@monotykamary/dsh-client-test-runtime": "^0.1.0",
|
|
63
|
+
"@monotykamary/dsh-client-ui-input-trigger": "^0.1.0",
|
|
64
|
+
"@monotykamary/dsh-client-ui-conversation": "^0.1.0",
|
|
65
|
+
"@monotykamary/dsh-client-ui-primitives": "^0.1.0",
|
|
66
|
+
"@monotykamary/dsh-client-ui-slots": "^0.1.0",
|
|
67
|
+
"@monotykamary/dsh-subagent": "^0.1.0",
|
|
68
|
+
"@monotykamary/dsh-invariants": "^0.1.0",
|
|
69
|
+
"@monotykamary/dsh-token-meter": "^0.1.0",
|
|
70
|
+
"@monotykamary/cordis": "^4.0.1"
|
|
73
71
|
},
|
|
74
72
|
"files": [
|
|
75
73
|
"lib/index.js",
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { type SessionId, type SubagentAddress } from '@monotykamary/dsh-client-runtime/client';
|
|
2
|
-
import type { PropsLocale, PropsRuntime } from '@monotykamary/dsh-client-ui-slots';
|
|
3
|
-
import { NS } from './locales.ts';
|
|
4
|
-
/** Business actions supplied by the slot registration. */
|
|
5
|
-
export interface SubagentCatalogInjected {
|
|
6
|
-
openChild: (address: SubagentAddress) => void;
|
|
7
|
-
refresh: (parentSessionId: SessionId) => void;
|
|
8
|
-
setCatalogOpen: (parentSessionId: SessionId, open: boolean) => void;
|
|
9
|
-
}
|
|
10
|
-
/** Full props for the session-header catalog action. */
|
|
11
|
-
export type SubagentCatalogActionProps = PropsRuntime<'conversation.session.header.actions'> & SubagentCatalogInjected & PropsLocale<typeof NS>;
|
|
12
|
-
/**
|
|
13
|
-
* Render the current session's direct catalog and lazily expanded descendants.
|
|
14
|
-
* @param props - session standard props plus catalog navigation actions.
|
|
15
|
-
* @returns The action while the catalog is pending or summaries establish descendants.
|
|
16
|
-
*/
|
|
17
|
-
export declare function SubagentCatalogAction({ sessionId, useSessions, openChild, refresh, setCatalogOpen, t, }: SubagentCatalogActionProps): import("react").JSX.Element | null;
|
|
18
|
-
//# sourceMappingURL=SubagentCatalogAction.d.ts.map
|