@deepseek-ai/dsh-client-ui-tool 0.1.0-rc.7 → 0.1.0-rc.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.i18n.yaml CHANGED
@@ -2,5 +2,5 @@
2
2
  # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
3
  # after editing either side, bring the other along and re-record with:
4
4
  # pnpm run verify-translation-pairing --write packages/client/ui-tool/README.md
5
- README.md: 6e2bef2f5ad4b136510c3acbb8f8b8e83c4c9212
6
- README.zh.md: 169417747541db9e02cb552b175ca7c100420aeb
5
+ README.md: b87236309c9bafe3e35d3d5977d56bd62a24de31
6
+ README.zh.md: 3bae0b3f4cb3ad695371ec7a66fb531a935a4d2f
package/README.md CHANGED
@@ -28,7 +28,7 @@ ctx.slots.inject('tool.call.toolview', () =>
28
28
  }, BusinessToolRow))
29
29
  ```
30
30
 
31
- The owner payload is `ToolCallOwnerProps`: `callId`, `toolName`, the frozen `block`, optional `cwd`, and plain `openFile`/`inspect` callbacks. The registration receives the normal session slot runtime share. It does not receive React nodes, Runtime services, or root/subcall knowledge.
31
+ The owner payload is `ToolCallOwnerProps`: `callId`, `toolName`, the frozen `block`, optional `cwd` and `home`, and plain `openFile`/`inspect` callbacks. Path summaries relativize to the session cwd first, then replace a leftover POSIX host home with `~`; `filePath` and Host open keep the authored filesystem path. The registration receives the normal session slot runtime share. It does not receive React nodes, Runtime services, or root/subcall knowledge.
32
32
 
33
33
  This package currently owns the generic fallback and the built-in shell/pwsh, read, write/edit, grep/glob, web, todo, question, and Code Dispatch presentations. `ui-skill` demonstrates a business-owned registration for `skill`.
34
34
 
package/README.zh.md CHANGED
@@ -28,7 +28,7 @@ ctx.slots.inject('tool.call.toolview', () =>
28
28
  }, BusinessToolRow))
29
29
  ```
30
30
 
31
- owner 载荷为 `ToolCallOwnerProps`:`callId`、`toolName`、冻结的 `block`、可选 `cwd`,以及普通的 `openFile`、`inspect` 回调。注册项会收到常规的会话 slot 运行时共享数据,但不会收到 React node、运行时服务或 root/subcall 知识。
31
+ owner 载荷为 `ToolCallOwnerProps`:`callId`、`toolName`、冻结的 `block`、可选 `cwd` 与 `home`,以及普通的 `openFile`、`inspect` 回调。路径摘要先相对会话 cwd 缩短,再把剩余的 POSIX 宿主家目录写成 `~`;`filePath` 与 Host 打开仍使用作者给出的文件系统路径。注册项会收到常规的会话 slot 运行时共享数据,但不会收到 React node、运行时服务或 root/subcall 知识。
32
32
 
33
33
  本包当前拥有 generic fallback,以及 shell/pwsh、read、write/edit、grep/glob、web、todo、question 和 Code Dispatch 的内置展示。`ui-skill` 展示了业务包自行拥有的 `skill` 注册项。
34
34
 
package/lib/client.js CHANGED
@@ -9,6 +9,14 @@ window.__ModuleLoader__.load({
9
9
  let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
10
10
  let _deepseek_ai_dsh_client_runtime_client = require("@deepseek-ai/dsh-client-runtime/client");
11
11
  //#region lib/types/client/tool/models/tool-call-model.js
12
+ /**
13
+ * Pure row-model derivation for tool summary rows: variant classification,
14
+ * one-line summary, expanded-body text, and flattened result output from the
15
+ * frozen call slice. Input material comes from the call ARGUMENTS; output and
16
+ * error material from the settled result node. A call whose render intent is
17
+ * a terminal card gets its expanded body from the views instead, through
18
+ * `terminalCardModel` in terminal-card-model.ts.
19
+ */
12
20
  /** Figma row titles per variant (design literals, not translatable copy). */
13
21
  const VARIANT_TITLES = {
14
22
  search: "Search",
@@ -127,6 +135,10 @@ window.__ModuleLoader__.load({
127
135
  const parsed = parseArgs(argsRaw);
128
136
  if (typeof parsed !== "object" || parsed === null) return firstLine(argsRaw);
129
137
  const args = parsed;
138
+ if (variant === "search" && Array.isArray(args.queries)) {
139
+ const queries = args.queries.filter((query) => typeof query === "string" && query !== "");
140
+ if (queries.length > 0) return queries.map(firstLine).join(", ");
141
+ }
130
142
  const picked = pickString(args, SUMMARY_KEYS[variant]);
131
143
  if (picked !== void 0) return firstLine(picked);
132
144
  for (const v of Object.values(args)) if (typeof v === "string" && v !== "") return firstLine(v);
@@ -162,14 +174,15 @@ window.__ModuleLoader__.load({
162
174
  * @param toolName - wire tool name (dispatch-supplied; survives windowless results).
163
175
  * @param block - RunningToolCall or ToolResultNode off the snapshot caches.
164
176
  * @param cwd - session workspace root; workspace-rooted path summaries display relative to it.
177
+ * @param home - host account home; a leftover POSIX home path displays as `~`.
165
178
  * @returns the row model.
166
179
  */
167
- function toolRowModel(toolName, block, cwd) {
180
+ function toolRowModel(toolName, block, cwd, home) {
168
181
  const variant = classifyTool(toolName);
169
182
  const done = "kind" in block;
170
183
  const argsRaw = (done ? block.call?.argsRaw : block.argsRaw) ?? "";
171
184
  const state = !done ? "running" : block.error?.code === "interrupted" ? "stopped" : block.isError ? "error" : "ok";
172
- const base = argsRaw === "" ? block.callId : relativizeToCwd(deriveSummary(variant, argsRaw), cwd);
185
+ const base = argsRaw === "" ? block.callId : (0, _deepseek_ai_dsh_client_runtime_client.abbreviateHomePath)(relativizeToCwd(deriveSummary(variant, argsRaw), cwd), home);
173
186
  const toolTitle = TOOL_TITLES[toolName];
174
187
  const summary = variant === "others" && toolName !== "" && toolTitle === void 0 ? `${toolName} · ${base}` : base;
175
188
  const output = done ? resultText(block) || null : null;
@@ -188,6 +201,21 @@ window.__ModuleLoader__.load({
188
201
  //#endregion
189
202
  //#region lib/types/client/tool/models/read-card-model.js
190
203
  /**
204
+ * Pure derivation of the read-card props from a frozen call slice: the
205
+ * `card:'read'` render intent the read tool declares arrives on the snapshot as
206
+ * the settled result node's `resultView`, and this is the one place that turns
207
+ * it into what {@link ReadBlock} draws. Both conversation render sites (the chat
208
+ * tool row's resident body and the details panel's Output section) call this, so
209
+ * the path, lines, total, and language they show are derived once.
210
+ *
211
+ * The read card is result-side only ([read card note](../../../../../../.agents/notes/implemented/feature/2026-07-30-web-read-card.md)):
212
+ * a call carries no file content until `execute` returns, so the pending call
213
+ * stays a generic card (`kind: 'read'`). A running read therefore has no read
214
+ * card, and this returns null for it — the row keeps its args-derived summary
215
+ * until the result arrives.
216
+ * @module
217
+ */
218
+ /**
191
219
  * Derive the read-card props for a tool call, or null when this call is not a
192
220
  * read card and belongs on the generic path.
193
221
  *
@@ -204,14 +232,15 @@ window.__ModuleLoader__.load({
204
232
  *
205
233
  * The label is the read view's `title` when the tool supplied one (the
206
234
  * presentation contract's replacement-title rule), otherwise the file path
207
- * relativized to the session workspace so a workspace-rooted absolute path
208
- * displays the same short form the row summary shows.
235
+ * shortened the same way the row summary is: workspace-relative first, then
236
+ * POSIX `~` for a leftover host-home path.
209
237
  * @param block - RunningToolCall or ToolResultNode off the snapshot caches.
210
238
  * @param sessionCwd - the session workspace root; a workspace-rooted absolute
211
239
  * path label displays relative to it. Absent leaves the path as authored.
240
+ * @param home - host account home; a leftover POSIX home path displays as `~`.
212
241
  * @returns the read-card props, or null for the generic path.
213
242
  */
214
- function readCardModel(block, sessionCwd) {
243
+ function readCardModel(block, sessionCwd, home) {
215
244
  if (!("kind" in block)) return null;
216
245
  const result = block.resultView?.card === "read" ? block.resultView : null;
217
246
  if (result === null) return null;
@@ -220,7 +249,7 @@ window.__ModuleLoader__.load({
220
249
  text: line.text
221
250
  }));
222
251
  return {
223
- label: result.title ?? relativizeToCwd(result.path, sessionCwd),
252
+ label: result.title ?? (0, _deepseek_ai_dsh_client_runtime_client.abbreviateHomePath)(relativizeToCwd(result.path, sessionCwd), home),
224
253
  lines,
225
254
  totalLines: result.totalLines,
226
255
  lang: result.lang
@@ -605,33 +634,33 @@ window.__ModuleLoader__.load({
605
634
  document.head.appendChild(tag);
606
635
  }
607
636
  var ToolRow_module_css_default = {
608
- "inspectButton": "o3BgMG_inspectButton",
609
- "leading": "o3BgMG_leading",
610
- "ioSection": "o3BgMG_ioSection",
611
- "row": "o3BgMG_row",
612
- "ioDivider": "o3BgMG_ioDivider",
613
- "terminalBody": "o3BgMG_terminalBody",
637
+ "bodyScroll": "o3BgMG_bodyScroll",
638
+ "bodyWrap": "o3BgMG_bodyWrap",
639
+ "chevron": "o3BgMG_chevron",
640
+ "codeBody": "o3BgMG_codeBody",
614
641
  "diffBody": "o3BgMG_diffBody",
615
- "title": "o3BgMG_title",
616
- "searchBody": "o3BgMG_searchBody",
617
642
  "dsh-tool-row-sweep": "o3BgMG_dsh-tool-row-sweep",
618
- "webBody": "o3BgMG_webBody",
643
+ "errorSummary": "o3BgMG_errorSummary",
644
+ "fileLink": "o3BgMG_fileLink",
645
+ "inspectButton": "o3BgMG_inspectButton",
619
646
  "ioCard": "o3BgMG_ioCard",
620
- "searchRecovery": "o3BgMG_searchRecovery",
621
- "visuallyHidden": "o3BgMG_visuallyHidden",
622
- "bodyScroll": "o3BgMG_bodyScroll",
647
+ "ioDivider": "o3BgMG_ioDivider",
648
+ "ioLabel": "o3BgMG_ioLabel",
649
+ "ioSection": "o3BgMG_ioSection",
623
650
  "ioText": "o3BgMG_ioText",
624
- "bodyWrap": "o3BgMG_bodyWrap",
651
+ "leading": "o3BgMG_leading",
625
652
  "readBody": "o3BgMG_readBody",
653
+ "root": "o3BgMG_root",
654
+ "row": "o3BgMG_row",
655
+ "searchBody": "o3BgMG_searchBody",
656
+ "searchRecovery": "o3BgMG_searchRecovery",
626
657
  "sep": "o3BgMG_sep",
627
- "errorSummary": "o3BgMG_errorSummary",
628
- "ioLabel": "o3BgMG_ioLabel",
629
658
  "summary": "o3BgMG_summary",
630
- "fileLink": "o3BgMG_fileLink",
631
- "codeBody": "o3BgMG_codeBody",
632
659
  "summarySuffix": "o3BgMG_summarySuffix",
633
- "chevron": "o3BgMG_chevron",
634
- "root": "o3BgMG_root"
660
+ "terminalBody": "o3BgMG_terminalBody",
661
+ "title": "o3BgMG_title",
662
+ "visuallyHidden": "o3BgMG_visuallyHidden",
663
+ "webBody": "o3BgMG_webBody"
635
664
  };
636
665
  //#endregion
637
666
  //#region lib/types/client/tool/components/ToolRow.js
@@ -808,10 +837,10 @@ window.__ModuleLoader__.load({
808
837
  code: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCodeOutline16, { size: 14 }),
809
838
  others: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSparkle16, { size: 14 })
810
839
  };
811
- function GenericToolCard({ toolName, block, cwd, openFile, inspect, t }) {
812
- const model = toolRowModel(toolName, block, cwd);
840
+ function GenericToolCard({ toolName, block, cwd, home, openFile, inspect, t }) {
841
+ const model = toolRowModel(toolName, block, cwd, home);
813
842
  const terminal = terminalCardModel(block, cwd);
814
- const read = readCardModel(block, cwd);
843
+ const read = readCardModel(block, cwd, home);
815
844
  const diff = diffCardModel(block);
816
845
  const search = searchCardModel(block);
817
846
  const web = webCardModel(block);
@@ -861,13 +890,14 @@ window.__ModuleLoader__.load({
861
890
  return "kind" in node ? node.call?.name ?? "" : node.name;
862
891
  }
863
892
  /** One atomic call dispatched through the Tool-owned keyed slot. */
864
- const ToolCall = (0, react.memo)(function ToolCall({ renderSlot, callId, toolName, block, openFile, selected, cwd, inspectCall, t, children }) {
893
+ const ToolCall = (0, react.memo)(function ToolCall({ renderSlot, callId, toolName, block, openFile, selected, cwd, home, inspectCall, t, children }) {
865
894
  const owner = (0, react.useMemo)(() => ({
866
895
  callId,
867
896
  toolName,
868
897
  block,
869
898
  openFile,
870
899
  cwd,
900
+ home,
871
901
  inspect: () => {
872
902
  inspectCall(callId);
873
903
  }
@@ -877,6 +907,7 @@ window.__ModuleLoader__.load({
877
907
  block,
878
908
  openFile,
879
909
  cwd,
910
+ home,
880
911
  inspectCall
881
912
  ]);
882
913
  return (0, react_jsx_runtime.jsxs)("div", {
@@ -893,7 +924,7 @@ window.__ModuleLoader__.load({
893
924
  }), children]
894
925
  });
895
926
  });
896
- const ToolCallBranch = (0, react.memo)(function ToolCallBranch({ renderSlot, block, selectedCallId, cwd, openFile, inspectCall, t }) {
927
+ const ToolCallBranch = (0, react.memo)(function ToolCallBranch({ renderSlot, block, selectedCallId, cwd, home, openFile, inspectCall, t }) {
897
928
  return (0, react_jsx_runtime.jsx)(ToolCall, {
898
929
  renderSlot,
899
930
  callId: block.callId,
@@ -902,6 +933,7 @@ window.__ModuleLoader__.load({
902
933
  openFile,
903
934
  selected: block.callId === selectedCallId,
904
935
  cwd,
936
+ home,
905
937
  inspectCall,
906
938
  t,
907
939
  children: block.subCalls.length > 0 ? (0, react_jsx_runtime.jsx)("div", {
@@ -912,6 +944,7 @@ window.__ModuleLoader__.load({
912
944
  block: child,
913
945
  selectedCallId,
914
946
  cwd,
947
+ home,
915
948
  openFile,
916
949
  inspectCall,
917
950
  t
@@ -925,13 +958,15 @@ window.__ModuleLoader__.load({
925
958
  * @param props - whole-Tool owner data and the Tool-owned child-slot share.
926
959
  * @returns the Tool call tree.
927
960
  */
928
- function ToolCallTree({ renderSlot, node, selectedCallId, cwd, openFile, inspectCall, t }) {
961
+ function ToolCallTree({ renderSlot, node, selectedCallId, cwd, openFile, inspectCall, useHostDescription, t }) {
962
+ const home = useHostDescription((description) => description?.home);
929
963
  const block = node.data.root;
930
964
  return (0, react_jsx_runtime.jsx)(ToolCallBranch, {
931
965
  renderSlot,
932
966
  block,
933
967
  selectedCallId,
934
968
  cwd,
969
+ home,
935
970
  openFile,
936
971
  inspectCall,
937
972
  t
@@ -949,13 +984,13 @@ window.__ModuleLoader__.load({
949
984
  document.head.appendChild(tag);
950
985
  }
951
986
  var ToolDetails_module_css_default = {
952
- "read": "xDAfVq_read",
953
- "empty": "xDAfVq_empty",
954
- "web": "xDAfVq_web",
955
- "description": "xDAfVq_description",
956
987
  "cardBody": "xDAfVq_cardBody",
988
+ "code": "xDAfVq_code",
989
+ "description": "xDAfVq_description",
990
+ "empty": "xDAfVq_empty",
991
+ "read": "xDAfVq_read",
957
992
  "recovery": "xDAfVq_recovery",
958
- "code": "xDAfVq_code"
993
+ "web": "xDAfVq_web"
959
994
  };
960
995
  //#endregion
961
996
  //#region lib/types/client/tool/ToolDetails.js
@@ -963,10 +998,11 @@ window.__ModuleLoader__.load({
963
998
  /**
964
999
  * Render the selected Tool call's structured output when its presentation
965
1000
  * intent is known, otherwise preserve the flattened result text.
966
- * @param props - selected call slice, workspace root, and locale seat.
1001
+ * @param props - selected call slice, workspace root, host home, and locale seat.
967
1002
  * @returns the details output body.
968
1003
  */
969
- function ToolDetails({ block, cwd, t }) {
1004
+ function ToolDetails({ block, cwd, useHostDescription, t }) {
1005
+ const home = useHostDescription((description) => description?.home);
970
1006
  const terminal = terminalCardModel(block, cwd);
971
1007
  if (terminal !== null) return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [terminal.description !== void 0 ? (0, react_jsx_runtime.jsx)("div", {
972
1008
  className: ToolDetails_module_css_default.description,
@@ -976,7 +1012,7 @@ window.__ModuleLoader__.load({
976
1012
  labels: terminalBlockLabels(t),
977
1013
  className: ToolDetails_module_css_default.cardBody
978
1014
  })] });
979
- const read = readCardModel(block, cwd);
1015
+ const read = readCardModel(block, cwd, home);
980
1016
  if (read !== null) return (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.ReadBlock, {
981
1017
  ...read,
982
1018
  className: ToolDetails_module_css_default.read
@@ -1099,26 +1135,26 @@ window.__ModuleLoader__.load({
1099
1135
  document.head.appendChild(tag);
1100
1136
  }
1101
1137
  var bash_sample_module_css_default = {
1102
- "ioLabel": "CY-8Ka_ioLabel",
1138
+ "bodyWrap": "CY-8Ka_bodyWrap",
1139
+ "card": "CY-8Ka_card",
1103
1140
  "chevron": "CY-8Ka_chevron",
1104
- "leading": "CY-8Ka_leading",
1105
- "ioSection": "CY-8Ka_ioSection",
1106
1141
  "chevronHover": "CY-8Ka_chevronHover",
1107
- "inspectButton": "CY-8Ka_inspectButton",
1142
+ "dsh-bash-row-sweep": "CY-8Ka_dsh-bash-row-sweep",
1143
+ "errorSummary": "CY-8Ka_errorSummary",
1108
1144
  "iconIdle": "CY-8Ka_iconIdle",
1109
- "card": "CY-8Ka_card",
1145
+ "inspectButton": "CY-8Ka_inspectButton",
1110
1146
  "ioCard": "CY-8Ka_ioCard",
1111
- "dsh-bash-row-sweep": "CY-8Ka_dsh-bash-row-sweep",
1112
- "sep": "CY-8Ka_sep",
1113
- "title": "CY-8Ka_title",
1114
- "terminal": "CY-8Ka_terminal",
1115
- "bodyWrap": "CY-8Ka_bodyWrap",
1147
+ "ioDivider": "CY-8Ka_ioDivider",
1148
+ "ioLabel": "CY-8Ka_ioLabel",
1149
+ "ioSection": "CY-8Ka_ioSection",
1116
1150
  "ioText": "CY-8Ka_ioText",
1151
+ "leading": "CY-8Ka_leading",
1117
1152
  "root": "CY-8Ka_root",
1118
- "ioDivider": "CY-8Ka_ioDivider",
1119
- "errorSummary": "CY-8Ka_errorSummary",
1120
- "visuallyHidden": "CY-8Ka_visuallyHidden",
1121
- "summary": "CY-8Ka_summary"
1153
+ "sep": "CY-8Ka_sep",
1154
+ "summary": "CY-8Ka_summary",
1155
+ "terminal": "CY-8Ka_terminal",
1156
+ "title": "CY-8Ka_title",
1157
+ "visuallyHidden": "CY-8Ka_visuallyHidden"
1122
1158
  };
1123
1159
  //#endregion
1124
1160
  //#region lib/types/client/tool/toolviews/bash-sample.js
@@ -1275,8 +1311,8 @@ window.__ModuleLoader__.load({
1275
1311
  * model-facing error text through its Output section and its first line in the
1276
1312
  * collapsed summary instead.
1277
1313
  */
1278
- function FileMutationRow({ toolName, block, cwd, openFile, inspect, t }) {
1279
- const model = toolRowModel(toolName, block, cwd);
1314
+ function FileMutationRow({ toolName, block, cwd, home, openFile, inspect, t }) {
1315
+ const model = toolRowModel(toolName, block, cwd, home);
1280
1316
  const diff = diffCardModel(block);
1281
1317
  return (0, react_jsx_runtime.jsx)(ToolRow, {
1282
1318
  t,
@@ -1329,9 +1365,9 @@ window.__ModuleLoader__.load({
1329
1365
  * read card as the row's collapsed-by-default card body. The summary path is an
1330
1366
  * openable host link when the row names a single file.
1331
1367
  */
1332
- function ReadRow({ toolName, block, cwd, openFile, inspect, t }) {
1333
- const model = toolRowModel(toolName, block, cwd);
1334
- const read = readCardModel(block, cwd);
1368
+ function ReadRow({ toolName, block, cwd, home, openFile, inspect, t }) {
1369
+ const model = toolRowModel(toolName, block, cwd, home);
1370
+ const read = readCardModel(block, cwd, home);
1335
1371
  return (0, react_jsx_runtime.jsx)(ToolRow, {
1336
1372
  t,
1337
1373
  variant: model.variant,
@@ -1592,13 +1628,15 @@ window.__ModuleLoader__.load({
1592
1628
  };
1593
1629
  //#endregion
1594
1630
  //#region lib/types/client/apply.js
1595
- /** Required service: the slot registry that owns both Tool render seats. */
1596
- const inject = ["slots"];
1631
+ /** Required services: the slot registry and the Host description used for POSIX `~`. */
1632
+ const inject = ["slots", "connection"];
1597
1633
  /**
1598
1634
  * Mount the whole-Tool renderers and built-in atomic Tool registrations.
1599
1635
  * @param ctx - Client root context.
1600
1636
  */
1601
1637
  function apply(ctx) {
1638
+ const connection = ctx.get("connection");
1639
+ const toolInject = () => ({ hooks: { hostDescription: connection.hostDescription } });
1602
1640
  ctx.slots.inject("conversation.chat.node", () => ctx.slots.register({
1603
1641
  name: "conversation.chat.node",
1604
1642
  key: "tool-call",
@@ -1606,11 +1644,13 @@ window.__ModuleLoader__.load({
1606
1644
  children: { "tool.call.toolview": {
1607
1645
  kind: "keyed",
1608
1646
  scope: "session"
1609
- } }
1647
+ } },
1648
+ inject: toolInject
1610
1649
  }, ToolCallTree));
1611
1650
  ctx.slots.inject("conversation.details.tool", () => ctx.slots.register({
1612
1651
  name: "conversation.details.tool",
1613
- locale: CONVERSATION_NS
1652
+ locale: CONVERSATION_NS,
1653
+ inject: toolInject
1614
1654
  }, ToolDetails));
1615
1655
  ctx.plugin(bashToolviewSample);
1616
1656
  ctx.plugin(readToolview);
@@ -1,6 +1,5 @@
1
- /** Register the Tool call tree, details renderer, and built-in atomic views. */
2
1
  import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client';
3
- /** Required service: the slot registry that owns both Tool render seats. */
2
+ /** Required services: the slot registry and the Host description used for POSIX `~`. */
4
3
  export declare const inject: string[];
5
4
  /**
6
5
  * Mount the whole-Tool renderers and built-in atomic Tool registrations.
@@ -1,5 +1,6 @@
1
1
  /** Tool UI slot declarations and their composed component props. */
2
- import type { PropsLocale, PropsRenderSlots, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
2
+ import type { HostDescriptionSource } from '@deepseek-ai/dsh-client-connection/client';
3
+ import type { InjectFace, PropsLocale, PropsRenderSlots, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
3
4
  import type { ToolCallBlock } from '@deepseek-ai/dsh-client-runtime/client';
4
5
  declare module '@deepseek-ai/dsh-client-ui-slots' {
5
6
  interface SlotMap {
@@ -34,6 +35,8 @@ export interface ToolCallOwnerProps {
34
35
  block: ToolCallBlock;
35
36
  /** Session workspace root for relative summaries. */
36
37
  cwd?: string | undefined;
38
+ /** Host account home; POSIX home-rooted summaries display as `~`. */
39
+ home?: string | undefined;
37
40
  /** Open a Tool argument path through the Host. */
38
41
  openFile: (path: string) => void;
39
42
  /** Inspect this call in the trajectory view when available. */
@@ -41,8 +44,15 @@ export interface ToolCallOwnerProps {
41
44
  }
42
45
  /** Full props of a registered atomic Tool view. */
43
46
  export type ToolCallViewProps = PropsRuntime<'tool.call.toolview'>;
47
+ /** Injected Host description for POSIX home-path display. */
48
+ export type ToolHostDescriptionInjected = {
49
+ hooks: {
50
+ /** Current generation's Host description, bound by the slot renderer. */
51
+ hostDescription: HostDescriptionSource;
52
+ };
53
+ };
44
54
  /** Full props of the Tool call-tree renderer registered as a `tool-call` Chat Node. */
45
- export type ToolTreeProps = PropsRuntime<'conversation.chat.node', 'tool-call'> & PropsRenderSlots<'tool.call.toolview'> & PropsLocale<'conversation'>;
55
+ export type ToolTreeProps = PropsRuntime<'conversation.chat.node', 'tool-call'> & PropsRenderSlots<'tool.call.toolview'> & PropsLocale<'conversation'> & InjectFace<ToolHostDescriptionInjected>;
46
56
  /** Full props of the selected Tool output renderer in the details panel. */
47
- export type ToolDetailsProps = PropsRuntime<'conversation.details.tool'> & PropsLocale<'conversation'>;
57
+ export type ToolDetailsProps = PropsRuntime<'conversation.details.tool'> & PropsLocale<'conversation'> & InjectFace<ToolHostDescriptionInjected>;
48
58
  //# sourceMappingURL=slots.d.ts.map
@@ -1,4 +1,4 @@
1
1
  /** Browser Tool plugin: whole-call composition and keyed atomic Tool views. */
2
2
  export { apply, inject } from './apply.ts';
3
- export type { ToolCallOwnerProps, ToolCallViewProps, ToolDetailsProps, ToolTreeProps } from './contract/slots.ts';
3
+ export type { ToolCallOwnerProps, ToolCallViewProps, ToolDetailsProps, ToolHostDescriptionInjected, ToolTreeProps, } from './contract/slots.ts';
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -5,5 +5,5 @@ import type { ToolTreeProps } from '../contract/slots.ts';
5
5
  * @param props - whole-Tool owner data and the Tool-owned child-slot share.
6
6
  * @returns the Tool call tree.
7
7
  */
8
- export declare function ToolCallTree({ renderSlot, node, selectedCallId, cwd, openFile, inspectCall, t, }: ToolTreeProps): import("react").JSX.Element;
8
+ export declare function ToolCallTree({ renderSlot, node, selectedCallId, cwd, openFile, inspectCall, useHostDescription, t, }: ToolTreeProps): import("react").JSX.Element;
9
9
  //# sourceMappingURL=ToolCallTree.d.ts.map
@@ -1,16 +1,9 @@
1
1
  import type { ToolDetailsProps } from '../contract/slots.ts';
2
- /** Pure details-body inputs; framework session seats stay at the slot boundary. */
3
- interface ToolDetailsContentProps {
4
- block: ToolDetailsProps['block'];
5
- cwd?: ToolDetailsProps['cwd'];
6
- t: ToolDetailsProps['t'];
7
- }
8
2
  /**
9
3
  * Render the selected Tool call's structured output when its presentation
10
4
  * intent is known, otherwise preserve the flattened result text.
11
- * @param props - selected call slice, workspace root, and locale seat.
5
+ * @param props - selected call slice, workspace root, host home, and locale seat.
12
6
  * @returns the details output body.
13
7
  */
14
- export declare function ToolDetails({ block, cwd, t }: ToolDetailsContentProps): import("react").JSX.Element;
15
- export {};
8
+ export declare function ToolDetails({ block, cwd, useHostDescription, t, }: Pick<ToolDetailsProps, 'block' | 'cwd' | 'useHostDescription' | 't'>): import("react").JSX.Element;
16
9
  //# sourceMappingURL=ToolDetails.d.ts.map
@@ -1,18 +1,3 @@
1
- /**
2
- * Pure derivation of the read-card props from a frozen call slice: the
3
- * `card:'read'` render intent the read tool declares arrives on the snapshot as
4
- * the settled result node's `resultView`, and this is the one place that turns
5
- * it into what {@link ReadBlock} draws. Both conversation render sites (the chat
6
- * tool row's resident body and the details panel's Output section) call this, so
7
- * the path, lines, total, and language they show are derived once.
8
- *
9
- * The read card is result-side only ([read card note](../../../../../../.agents/notes/implemented/feature/2026-07-30-web-read-card.md)):
10
- * a call carries no file content until `execute` returns, so the pending call
11
- * stays a generic card (`kind: 'read'`). A running read therefore has no read
12
- * card, and this returns null for it — the row keeps its args-derived summary
13
- * until the result arrives.
14
- * @module
15
- */
16
1
  import type { ReadBlockProps } from '@deepseek-ai/dsh-client-ui-primitives';
17
2
  import { type ToolCallBlock } from './tool-call-model.ts';
18
3
  /**
@@ -49,12 +34,13 @@ export type ReadCardModel = Pick<ReadBlockProps, 'label' | 'lines' | 'totalLines
49
34
  *
50
35
  * The label is the read view's `title` when the tool supplied one (the
51
36
  * presentation contract's replacement-title rule), otherwise the file path
52
- * relativized to the session workspace so a workspace-rooted absolute path
53
- * displays the same short form the row summary shows.
37
+ * shortened the same way the row summary is: workspace-relative first, then
38
+ * POSIX `~` for a leftover host-home path.
54
39
  * @param block - RunningToolCall or ToolResultNode off the snapshot caches.
55
40
  * @param sessionCwd - the session workspace root; a workspace-rooted absolute
56
41
  * path label displays relative to it. Absent leaves the path as authored.
42
+ * @param home - host account home; a leftover POSIX home path displays as `~`.
57
43
  * @returns the read-card props, or null for the generic path.
58
44
  */
59
- export declare function readCardModel(block: ToolCallBlock, sessionCwd?: string): ReadCardModel | null;
45
+ export declare function readCardModel(block: ToolCallBlock, sessionCwd?: string, home?: string): ReadCardModel | null;
60
46
  //# sourceMappingURL=read-card-model.d.ts.map
@@ -1,11 +1,3 @@
1
- /**
2
- * Pure row-model derivation for tool summary rows: variant classification,
3
- * one-line summary, expanded-body text, and flattened result output from the
4
- * frozen call slice. Input material comes from the call ARGUMENTS; output and
5
- * error material from the settled result node. A call whose render intent is
6
- * a terminal card gets its expanded body from the views instead, through
7
- * `terminalCardModel` in terminal-card-model.ts.
8
- */
9
1
  import type { ToolCallBlock, ToolResultNode } from '@deepseek-ai/dsh-client-runtime/client';
10
2
  export type { ToolCallBlock } from '@deepseek-ai/dsh-client-runtime/client';
11
3
  /** Tool-call row variants selected by the generic atomic renderer. */
@@ -59,7 +51,8 @@ export declare function relativizeToCwd(text: string, cwd: string | undefined):
59
51
  * @param toolName - wire tool name (dispatch-supplied; survives windowless results).
60
52
  * @param block - RunningToolCall or ToolResultNode off the snapshot caches.
61
53
  * @param cwd - session workspace root; workspace-rooted path summaries display relative to it.
54
+ * @param home - host account home; a leftover POSIX home path displays as `~`.
62
55
  * @returns the row model.
63
56
  */
64
- export declare function toolRowModel(toolName: string, block: ToolCallBlock, cwd?: string): ToolRowModel;
57
+ export declare function toolRowModel(toolName: string, block: ToolCallBlock, cwd?: string, home?: string): ToolRowModel;
65
58
  //# sourceMappingURL=tool-call-model.d.ts.map
@@ -3,5 +3,5 @@ import type { ToolCallOwnerProps, ToolTreeProps } from '../../contract/slots.ts'
3
3
  export interface GenericToolCardProps extends ToolCallOwnerProps {
4
4
  t: ToolTreeProps['t'];
5
5
  }
6
- export declare function GenericToolCard({ toolName, block, cwd, openFile, inspect, t }: GenericToolCardProps): import("react").JSX.Element;
6
+ export declare function GenericToolCard({ toolName, block, cwd, home, openFile, inspect, t }: GenericToolCardProps): import("react").JSX.Element;
7
7
  //# sourceMappingURL=GenericToolCard.d.ts.map
@@ -12,7 +12,7 @@ type FileMutationRowProps = ToolCallViewProps & PropsLocale<'conversation'>;
12
12
  * model-facing error text through its Output section and its first line in the
13
13
  * collapsed summary instead.
14
14
  */
15
- export declare function FileMutationRow({ toolName, block, cwd, openFile, inspect, t }: FileMutationRowProps): import("react").JSX.Element;
15
+ export declare function FileMutationRow({ toolName, block, cwd, home, openFile, inspect, t }: FileMutationRowProps): import("react").JSX.Element;
16
16
  /**
17
17
  * The file-mutation rows as a plain registrant plugin following the chat
18
18
  * toolview declaration across independent activation and reload lifetimes.
@@ -8,7 +8,7 @@ type ReadRowProps = ToolCallViewProps & PropsLocale<'conversation'>;
8
8
  * read card as the row's collapsed-by-default card body. The summary path is an
9
9
  * openable host link when the row names a single file.
10
10
  */
11
- export declare function ReadRow({ toolName, block, cwd, openFile, inspect, t }: ReadRowProps): import("react").JSX.Element;
11
+ export declare function ReadRow({ toolName, block, cwd, home, openFile, inspect, t }: ReadRowProps): import("react").JSX.Element;
12
12
  /**
13
13
  * The read row as a plain registrant plugin following the atomic Tool-view
14
14
  * declaration across independent activation and reload lifetimes.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-client-ui-tool",
3
3
  "description": "Client Tool call-tree renderer and keyed per-tool presentation slot",
4
- "version": "0.1.0-rc.7",
4
+ "version": "0.1.0-rc.8",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -32,6 +32,7 @@
32
32
  "dsh": {
33
33
  "client": {
34
34
  "inject": [
35
+ "@deepseek-ai/dsh-client-connection",
35
36
  "@deepseek-ai/dsh-client-runtime",
36
37
  "@deepseek-ai/dsh-client-locale",
37
38
  "@deepseek-ai/dsh-client-ui-conversation"
@@ -44,32 +45,29 @@
44
45
  "clsx": "^2.0.0"
45
46
  },
46
47
  "peerDependencies": {
47
- "react": "^18.2.0",
48
+ "@deepseek-ai/dsh-api-remotes": "^0.1.0-rc.8",
48
49
  "@deepseek-ai/cordis": "^4.0.1",
49
- "@deepseek-ai/dsh-api-remotes": "^0.1.0-rc.7",
50
- "@deepseek-ai/dsh-client-locale": "^0.1.0-rc.7",
51
- "@deepseek-ai/dsh-client-runtime": "^0.1.0-rc.7",
52
- "@deepseek-ai/dsh-client-ui-conversation": "^0.1.0-rc.7",
53
- "@deepseek-ai/dsh-client-ui-primitives": "^0.1.0-rc.7",
54
- "@deepseek-ai/dsh-client-ui-slots": "^0.1.0-rc.7",
55
- "@deepseek-ai/dsh-invariants": "^0.1.0-rc.7"
50
+ "@deepseek-ai/dsh-client-connection": "^0.1.0-rc.8",
51
+ "@deepseek-ai/dsh-client-locale": "^0.1.0-rc.8",
52
+ "@deepseek-ai/dsh-client-runtime": "^0.1.0-rc.8",
53
+ "@deepseek-ai/dsh-client-ui-conversation": "^0.1.0-rc.8",
54
+ "@deepseek-ai/dsh-invariants": "^0.1.0-rc.8"
56
55
  },
57
56
  "devDependencies": {
58
57
  "@testing-library/react": "^16.1.0",
59
58
  "@types/react": "~18.3.1",
60
59
  "react": "^18.2.0",
61
60
  "react-dom": "^18.2.0",
62
- "@deepseek-ai/dsh-api-remotes": "^0.1.0-rc.7",
63
- "@deepseek-ai/dsh-client-connection": "^0.1.0-rc.7",
61
+ "@deepseek-ai/dsh-client-connection": "^0.1.0-rc.8",
62
+ "@deepseek-ai/dsh-api-remotes": "^0.1.0-rc.8",
64
63
  "@deepseek-ai/cordis": "^4.0.1",
65
- "@deepseek-ai/dsh-client-locale": "^0.1.0-rc.7",
66
- "@deepseek-ai/dsh-client-runtime": "^0.1.0-rc.7",
67
- "@deepseek-ai/dsh-client-test-runtime": "^0.1.0-rc.7",
68
- "@deepseek-ai/dsh-client-ui-primitives": "^0.1.0-rc.7",
69
- "@deepseek-ai/dsh-client-ui-slots": "^0.1.0-rc.7",
70
- "@deepseek-ai/dsh-client-ui-conversation": "^0.1.0-rc.7",
71
- "@deepseek-ai/dsh-client-web-react": "^0.1.0-rc.7",
72
- "@deepseek-ai/dsh-invariants": "^0.1.0-rc.7"
64
+ "@deepseek-ai/dsh-client-locale": "^0.1.0-rc.8",
65
+ "@deepseek-ai/dsh-client-runtime": "^0.1.0-rc.8",
66
+ "@deepseek-ai/dsh-client-test-runtime": "^0.1.0-rc.8",
67
+ "@deepseek-ai/dsh-client-ui-conversation": "^0.1.0-rc.8",
68
+ "@deepseek-ai/dsh-client-ui-primitives": "^0.1.0-rc.8",
69
+ "@deepseek-ai/dsh-client-ui-slots": "^0.1.0-rc.8",
70
+ "@deepseek-ai/dsh-invariants": "^0.1.0-rc.8"
73
71
  },
74
72
  "files": [
75
73
  "lib/index.js",