@deepseek-ai/dsh-client-ui-tool 0.2.0-rc.1 → 0.2.1-alpha.1

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/lib/client.js CHANGED
@@ -239,6 +239,26 @@ window.__ModuleLoader__.load({
239
239
  "write",
240
240
  "edit"
241
241
  ]);
242
+ /**
243
+ * Summary material read the same way at every stage from the argument view: a
244
+ * complete `file_path` for file tools, otherwise the `description` text so far.
245
+ * Empty when the view carries neither, so the caller falls back to the raw text.
246
+ */
247
+ function argumentSummary(variant, args, cwd, home) {
248
+ if (FILE_PATH_VARIANTS.has(variant)) {
249
+ const path = args.complete("file_path") ? args.text("file_path") : void 0;
250
+ const filePath = path !== void 0 && path !== "" && args.complete("file_path") ? firstLine(path) : void 0;
251
+ return {
252
+ summary: filePath === void 0 ? "" : abbreviateHomePath(relativizeToCwd(filePath, cwd), home),
253
+ filePath
254
+ };
255
+ }
256
+ const description = args.text("description");
257
+ return {
258
+ summary: description === void 0 ? "" : firstLine(description),
259
+ filePath: void 0
260
+ };
261
+ }
242
262
  function deriveFilePath(variant, argsRaw) {
243
263
  if (!FILE_PATH_VARIANTS.has(variant)) return void 0;
244
264
  const parsed = parseArgs(argsRaw);
@@ -276,7 +296,8 @@ window.__ModuleLoader__.load({
276
296
  const done = "kind" in block;
277
297
  const argsRaw = done ? block.call?.argsRaw ?? "" : block.phase === "start" ? block.argsRaw : null;
278
298
  const state = !done ? block.phase === "preparing" ? "preparing" : "running" : block.error?.code === "interrupted" ? "stopped" : block.isError ? "error" : "ok";
279
- const base = argsRaw === null ? "" : argsRaw === "" ? block.callId : abbreviateHomePath(relativizeToCwd(deriveSummary(variant, argsRaw), cwd), home);
299
+ const primary = argumentSummary(variant, block.args, cwd, home);
300
+ const base = primary.summary !== "" || argsRaw === null ? primary.summary : argsRaw === "" ? block.callId : abbreviateHomePath(relativizeToCwd(deriveSummary(variant, argsRaw), cwd), home);
280
301
  const summary = [titleKey === "tool.title.generic" ? toolName : "", base].filter(Boolean).join(" · ");
281
302
  const output = done ? resultText(block) || null : null;
282
303
  const errorSummary = state === "error" && output !== null ? firstLine(output) : null;
@@ -285,7 +306,7 @@ window.__ModuleLoader__.load({
285
306
  variant,
286
307
  titleKey,
287
308
  summary,
288
- filePath: argsRaw === null ? void 0 : deriveFilePath(variant, argsRaw),
309
+ filePath: primary.filePath ?? (argsRaw === null ? void 0 : deriveFilePath(variant, argsRaw)),
289
310
  bodyRaw,
290
311
  output,
291
312
  errorSummary,
@@ -338,19 +359,6 @@ window.__ModuleLoader__.load({
338
359
  const only = block.content[0];
339
360
  return only?.type === "text" ? only.text : void 0;
340
361
  }
341
- /**
342
- * Validate the optional escalation pair shared by first-party shell and file
343
- * mutation tools.
344
- * @param args - parsed open-root Tool arguments.
345
- * @returns whether the declared escalation fields form a valid pair.
346
- */
347
- function validEscalationFields(args) {
348
- const permission = args.sandbox_permissions;
349
- const justification = args.justification;
350
- if (permission === void 0 && justification === void 0) return true;
351
- if (permission !== "workspace-write" && permission !== "danger-full-access") return false;
352
- return typeof justification === "string" && justification.trim() !== "";
353
- }
354
362
  //#endregion
355
363
  //#region lib/types/client/tool/models/read-card-model.js
356
364
  /** Whether a model-supplied argument is a 1-based line position or count: an integer of at least 1. */
@@ -490,7 +498,6 @@ window.__ModuleLoader__.load({
490
498
  }
491
499
  const { file_path: path } = parsed.args;
492
500
  if (typeof path !== "string" || path.trim() === "") return null;
493
- if (!validEscalationFields(parsed.args)) return null;
494
501
  if (parsed.name === "write") {
495
502
  const { content } = parsed.args;
496
503
  return typeof content === "string" ? {
@@ -835,7 +842,6 @@ window.__ModuleLoader__.load({
835
842
  if (timeoutMs !== void 0 && (typeof timeoutMs !== "number" || !Number.isFinite(timeoutMs) || timeoutMs <= 0)) return null;
836
843
  if (workdir !== void 0 && typeof workdir !== "string") return null;
837
844
  if (background !== void 0 && typeof background !== "boolean") return null;
838
- if (!validEscalationFields(args)) return null;
839
845
  if (description === void 0) return {
840
846
  kind: "shell",
841
847
  command,
@@ -1194,13 +1200,13 @@ window.__ModuleLoader__.load({
1194
1200
  }
1195
1201
  //#endregion
1196
1202
  //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-tool/src/client/tool/components/AskQuestionCard.module.css.mjs
1197
- const css$4 = ".fsXYAq_card{border:.5px solid var(--dsw-alias-border-l1);border-radius:var(--dsw-radius-lg);background:var(--dsw-alias-bg-base);flex-direction:column;gap:16px;max-height:360px;margin:4px 0 4px 4px;padding:16px 20px;display:flex;overflow-y:auto}.fsXYAq_item{flex-direction:column;gap:2px;min-width:0;display:flex}.fsXYAq_question,.fsXYAq_answer{white-space:pre-wrap;overflow-wrap:anywhere;font-size:var(--dsh-content-font-size,14px);line-height:calc(24px + var(--dsh-content-font-delta,0px));margin:0}.fsXYAq_question{color:var(--dsw-alias-label-tertiary)}.fsXYAq_answer{color:var(--dsw-alias-label-primary)}.fsXYAq_answerLine{display:block}.fsXYAq_skipped{color:var(--dsw-alias-label-tertiary)}.fsXYAq_verdict{color:var(--dsw-alias-label-primary);font-size:var(--dsh-content-font-size,14px);line-height:calc(24px + var(--dsh-content-font-delta,0px));margin:0}.fsXYAq_questionList{flex-direction:column;gap:8px;margin:0;padding-left:20px;display:flex}.fsXYAq_unansweredQuestion{color:var(--dsw-alias-label-tertiary);white-space:pre-wrap;overflow-wrap:anywhere;font-size:var(--dsh-content-font-size,14px);line-height:calc(24px + var(--dsh-content-font-delta,0px))}";
1198
- const tagId$4 = "@deepseek-ai/dsh-client-ui-tool/AskQuestionCard.module.css";
1199
- if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$4) + "]") === null) {
1203
+ const css$5 = ".fsXYAq_card{border:.5px solid var(--dsw-alias-border-l1);border-radius:var(--dsw-radius-lg);background:var(--dsw-alias-bg-base);flex-direction:column;gap:16px;max-height:360px;margin:4px 0 4px 4px;padding:16px 20px;display:flex;overflow-y:auto}.fsXYAq_item{flex-direction:column;gap:2px;min-width:0;display:flex}.fsXYAq_question,.fsXYAq_answer{white-space:pre-wrap;overflow-wrap:anywhere;font-size:var(--dsh-content-font-size,14px);line-height:calc(24px + var(--dsh-content-font-delta,0px));margin:0}.fsXYAq_question{color:var(--dsw-alias-label-tertiary)}.fsXYAq_answer{color:var(--dsw-alias-label-primary)}.fsXYAq_answerLine{display:block}.fsXYAq_skipped{color:var(--dsw-alias-label-tertiary)}.fsXYAq_verdict{color:var(--dsw-alias-label-primary);font-size:var(--dsh-content-font-size,14px);line-height:calc(24px + var(--dsh-content-font-delta,0px));margin:0}.fsXYAq_questionList{flex-direction:column;gap:8px;margin:0;padding-left:20px;display:flex}.fsXYAq_unansweredQuestion{color:var(--dsw-alias-label-tertiary);white-space:pre-wrap;overflow-wrap:anywhere;font-size:var(--dsh-content-font-size,14px);line-height:calc(24px + var(--dsh-content-font-delta,0px))}";
1204
+ const tagId$5 = "@deepseek-ai/dsh-client-ui-tool/AskQuestionCard.module.css";
1205
+ if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$5) + "]") === null) {
1200
1206
  const tag = document.createElement("style");
1201
1207
  tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-tool";
1202
- tag.dataset.pluginCss = tagId$4;
1203
- tag.textContent = css$4;
1208
+ tag.dataset.pluginCss = tagId$5;
1209
+ tag.textContent = css$5;
1204
1210
  document.head.appendChild(tag);
1205
1211
  }
1206
1212
  var AskQuestionCard_module_css_default = {
@@ -1257,13 +1263,13 @@ window.__ModuleLoader__.load({
1257
1263
  }
1258
1264
  //#endregion
1259
1265
  //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-tool/src/client/tool/components/ToolDetails.module.css.mjs
1260
- const css$3 = ".DXqwVW_root{border:.5px solid var(--dsw-alias-border-l1);border-radius:var(--dsw-radius-lg);background:var(--dsw-alias-markdown-code-block);color:var(--dsw-alias-label-secondary);font:var(--dsw-font-xs-13);margin:4px 0 4px 4px;overflow:hidden}.DXqwVW_list{max-height:320px;margin:0;padding:0;list-style:none;overflow-y:auto}.DXqwVW_item,.DXqwVW_empty{margin:0;padding:10px 14px}.DXqwVW_item+.DXqwVW_item{border-top:.5px solid var(--dsw-alias-border-l2)}.DXqwVW_root[data-inspect]:not([data-caption])>.DXqwVW_list>.DXqwVW_item,.DXqwVW_root[data-inspect]:not([data-caption]) .DXqwVW_empty,.DXqwVW_root[data-inspect] .DXqwVW_caption{padding-inline-end:88px}.DXqwVW_caption{color:var(--dsw-alias-label-caption);padding:10px 14px 6px;font-size:12px}.DXqwVW_heading{flex-wrap:wrap;align-items:baseline;gap:8px;display:flex}.DXqwVW_text{white-space:pre-wrap;overflow-wrap:anywhere;flex:1;min-width:0}.DXqwVW_status{flex:none;justify-content:center;align-self:flex-start;align-items:center;width:14px;height:18px;font-size:16px;line-height:18px;display:inline-flex}.DXqwVW_pending{box-sizing:border-box;border:1px solid var(--dsw-alias-label-tertiary);border-radius:2px;width:10px;height:10px}.DXqwVW_heading:has(.DXqwVW_statusText) .DXqwVW_text{flex-basis:12em}.DXqwVW_statusText{color:var(--dsw-alias-label-caption);white-space:nowrap;margin-inline-start:auto;font-size:12px}.DXqwVW_previous,.DXqwVW_unchanged{color:var(--dsw-alias-label-tertiary)}.DXqwVW_item[data-change=added] .DXqwVW_status{color:var(--dsw-alias-state-success-primary)}.DXqwVW_item[data-change=removed] .DXqwVW_status{color:var(--dsw-alias-state-error-primary)}.DXqwVW_item[data-change=removed] .DXqwVW_text{color:var(--dsw-alias-label-tertiary);text-decoration:line-through}.DXqwVW_unchanged{border-top:.5px solid var(--dsw-alias-border-l2)}.DXqwVW_unchanged summary{cursor:pointer;align-items:center;gap:6px;padding:9px 14px;list-style:none;display:flex}.DXqwVW_unchanged summary::-webkit-details-marker{display:none}.DXqwVW_unchanged[open] summary svg{transform:rotate(90deg)}.DXqwVW_fields{margin:0}.DXqwVW_heading+.DXqwVW_fields{margin-top:6px}.DXqwVW_field{grid-template-columns:5.5em minmax(0,1fr);gap:12px;display:grid}.DXqwVW_field+.DXqwVW_field{margin-top:4px}.DXqwVW_field dt{color:var(--dsw-alias-label-caption)}.DXqwVW_field dd{white-space:pre-wrap;overflow-wrap:anywhere;margin:0}.DXqwVW_badge{color:var(--dsw-alias-label-caption);flex:none;align-items:center;gap:5px;font-size:12px;display:inline-flex}.DXqwVW_badge:before{content:\"\";corner-shape:round;background:currentColor;border-radius:50%;width:5px;height:5px}.DXqwVW_badge[data-tone=info]{color:var(--dsw-alias-state-business-primary)}.DXqwVW_badge[data-tone=success]{color:var(--dsw-alias-state-success-primary)}.DXqwVW_badge[data-tone=warning]{color:var(--dsw-alias-state-warn-primary)}.DXqwVW_badge[data-tone=error]{color:var(--dsw-alias-state-error-primary)}.DXqwVW_subtitle{color:var(--dsw-alias-label-tertiary);overflow-wrap:anywhere;margin-top:3px;font-size:12px}.DXqwVW_description{color:var(--dsw-alias-label-caption);white-space:pre-wrap;overflow-wrap:anywhere;margin:6px 0}.DXqwVW_lines{white-space:pre-wrap;overflow-wrap:anywhere;margin:6px 0 0;padding-inline-start:18px}.DXqwVW_lines li+li{margin-top:4px}.DXqwVW_group{border-top:.5px solid var(--dsw-alias-border-l2);margin-top:8px}.DXqwVW_group>summary{color:var(--dsw-alias-label-caption);cursor:pointer;overflow-wrap:anywhere;align-items:center;gap:6px;padding:8px 0 0;list-style:none;display:flex}.DXqwVW_group>summary::-webkit-details-marker{display:none}.DXqwVW_group[open]>summary svg{transform:rotate(90deg)}.DXqwVW_group>summary svg{flex:none}.DXqwVW_group .DXqwVW_list{max-height:none;overflow:visible}.DXqwVW_group .DXqwVW_item{padding:9px 0 2px 20px}.DXqwVW_prose,.DXqwVW_code{max-width:100%;font-size:13px}.DXqwVW_prose{margin-top:8px}.DXqwVW_root .DXqwVW_item>.DXqwVW_code{max-height:240px;margin:8px 0 0;overflow:auto}.DXqwVW_root .DXqwVW_item:has(>.DXqwVW_code:only-child){padding:0}.DXqwVW_root .DXqwVW_item>.DXqwVW_code:only-child{margin:0}.DXqwVW_root .DXqwVW_group .DXqwVW_item:has(>.DXqwVW_code:only-child){padding:4px 0 0 20px}.DXqwVW_path{min-width:0;color:inherit;font:inherit;text-align:start;overflow-wrap:anywhere;cursor:pointer;background:0 0;border:none;flex:1;padding:0}.DXqwVW_path:hover{text-decoration:underline}.DXqwVW_path:focus-visible{outline:var(--dsw-focus-ring-width) solid var(--dsw-focus-ring-color,var(--dsw-alias-state-business-primary));outline-offset:3px}";
1261
- const tagId$3 = "@deepseek-ai/dsh-client-ui-tool/ToolDetails.module.css";
1262
- if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]") === null) {
1266
+ const css$4 = ".DXqwVW_root{border:.5px solid var(--dsw-alias-border-l1);border-radius:var(--dsw-radius-lg);background:var(--dsw-alias-markdown-code-block);color:var(--dsw-alias-label-secondary);font:var(--dsw-font-xs-13);margin:4px 0 4px 4px;overflow:hidden}.DXqwVW_list{max-height:320px;margin:0;padding:0;list-style:none;overflow-y:auto}.DXqwVW_item,.DXqwVW_empty{margin:0;padding:10px 14px}.DXqwVW_item+.DXqwVW_item{border-top:.5px solid var(--dsw-alias-border-l2)}.DXqwVW_root[data-inspect]:not([data-caption])>.DXqwVW_list>.DXqwVW_item,.DXqwVW_root[data-inspect]:not([data-caption]) .DXqwVW_empty,.DXqwVW_root[data-inspect] .DXqwVW_caption{padding-inline-end:88px}.DXqwVW_caption{color:var(--dsw-alias-label-caption);padding:10px 14px 6px;font-size:12px}.DXqwVW_heading{flex-wrap:wrap;align-items:baseline;gap:8px;display:flex}.DXqwVW_text{white-space:pre-wrap;overflow-wrap:anywhere;flex:1;min-width:0}.DXqwVW_status{flex:none;justify-content:center;align-self:flex-start;align-items:center;width:14px;height:18px;font-size:16px;line-height:18px;display:inline-flex}.DXqwVW_pending{box-sizing:border-box;border:1px solid var(--dsw-alias-label-tertiary);border-radius:2px;width:10px;height:10px}.DXqwVW_heading:has(.DXqwVW_statusText) .DXqwVW_text{flex-basis:12em}.DXqwVW_statusText{color:var(--dsw-alias-label-caption);white-space:nowrap;margin-inline-start:auto;font-size:12px}.DXqwVW_previous,.DXqwVW_unchanged{color:var(--dsw-alias-label-tertiary)}.DXqwVW_item[data-change=added] .DXqwVW_status{color:var(--dsw-alias-state-success-primary)}.DXqwVW_item[data-change=removed] .DXqwVW_status{color:var(--dsw-alias-state-error-primary)}.DXqwVW_item[data-change=removed] .DXqwVW_text{color:var(--dsw-alias-label-tertiary);text-decoration:line-through}.DXqwVW_unchanged{border-top:.5px solid var(--dsw-alias-border-l2)}.DXqwVW_unchanged summary{cursor:pointer;align-items:center;gap:6px;padding:9px 14px;list-style:none;display:flex}.DXqwVW_unchanged summary::-webkit-details-marker{display:none}.DXqwVW_unchanged[open] summary svg{transform:rotate(90deg)}.DXqwVW_fields{margin:0}.DXqwVW_heading+.DXqwVW_fields{margin-top:6px}.DXqwVW_field{grid-template-columns:5.5em minmax(0,1fr);gap:12px;display:grid}.DXqwVW_field+.DXqwVW_field{margin-top:4px}.DXqwVW_field dt{color:var(--dsw-alias-label-caption)}.DXqwVW_field dd{white-space:pre-wrap;overflow-wrap:anywhere;margin:0}.DXqwVW_badge{color:var(--dsw-alias-label-caption);flex:none;align-items:center;gap:5px;font-size:12px;display:inline-flex}.DXqwVW_badge:before{content:\"\";corner-shape:round;background:currentColor;border-radius:50%;width:5px;height:5px}.DXqwVW_badge[data-tone=info]{color:var(--dsw-alias-state-business-primary)}.DXqwVW_badge[data-tone=success]{color:var(--dsw-alias-state-success-primary)}.DXqwVW_badge[data-tone=warning]{color:var(--dsw-alias-state-warn-primary)}.DXqwVW_badge[data-tone=error]{color:var(--dsw-alias-state-error-primary)}.DXqwVW_subtitle{color:var(--dsw-alias-label-tertiary);overflow-wrap:anywhere;margin-top:3px;font-size:12px}.DXqwVW_description{color:var(--dsw-alias-label-caption);white-space:pre-wrap;overflow-wrap:anywhere;margin:6px 0}.DXqwVW_lines{white-space:pre-wrap;overflow-wrap:anywhere;margin:6px 0 0;padding-inline-start:18px}.DXqwVW_lines li+li{margin-top:4px}.DXqwVW_group{border-top:.5px solid var(--dsw-alias-border-l2);margin-top:8px}.DXqwVW_group>summary{color:var(--dsw-alias-label-caption);cursor:pointer;overflow-wrap:anywhere;align-items:center;gap:6px;padding:8px 0 0;list-style:none;display:flex}.DXqwVW_group>summary::-webkit-details-marker{display:none}.DXqwVW_group[open]>summary svg{transform:rotate(90deg)}.DXqwVW_group>summary svg{flex:none}.DXqwVW_group .DXqwVW_list{max-height:none;overflow:visible}.DXqwVW_group .DXqwVW_item{padding:9px 0 2px 20px}.DXqwVW_prose,.DXqwVW_code{max-width:100%;font-size:13px}.DXqwVW_prose{margin-top:8px}.DXqwVW_root .DXqwVW_item>.DXqwVW_code{max-height:240px;margin:8px 0 0;overflow:auto}.DXqwVW_root .DXqwVW_item:has(>.DXqwVW_code:only-child){padding:0}.DXqwVW_root .DXqwVW_item>.DXqwVW_code:only-child{margin:0}.DXqwVW_root .DXqwVW_group .DXqwVW_item:has(>.DXqwVW_code:only-child){padding:4px 0 0 20px}.DXqwVW_path{min-width:0;color:inherit;font:inherit;text-align:start;overflow-wrap:anywhere;cursor:pointer;background:0 0;border:none;flex:1;padding:0}.DXqwVW_path:hover{text-decoration:underline}.DXqwVW_path:focus-visible{outline:var(--dsw-focus-ring-width) solid var(--dsw-focus-ring-color,var(--dsw-alias-state-business-primary));outline-offset:3px}";
1267
+ const tagId$4 = "@deepseek-ai/dsh-client-ui-tool/ToolDetails.module.css";
1268
+ if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$4) + "]") === null) {
1263
1269
  const tag = document.createElement("style");
1264
1270
  tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-tool";
1265
- tag.dataset.pluginCss = tagId$3;
1266
- tag.textContent = css$3;
1271
+ tag.dataset.pluginCss = tagId$4;
1272
+ tag.textContent = css$4;
1267
1273
  document.head.appendChild(tag);
1268
1274
  }
1269
1275
  var ToolDetails_module_css_default = {
@@ -1431,22 +1437,23 @@ window.__ModuleLoader__.load({
1431
1437
  }
1432
1438
  //#endregion
1433
1439
  //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-tool/src/client/tool/components/ToolRow.module.css.mjs
1434
- const css$2 = ".o3BgMG_root{flex-direction:column;display:flex}.o3BgMG_leading{flex-shrink:0}.o3BgMG_root[data-tool^=cordis_] .o3BgMG_leading,.o3BgMG_root[data-tool^=cordis_] .o3BgMG_title{color:var(--dsw-alias-state-business-primary)}.o3BgMG_root[data-tool^=cordis_] .o3BgMG_title{font-weight:500}.o3BgMG_root[data-tool^=cordis_] .o3BgMG_sep{background:var(--dsw-alias-state-business-primary)}.o3BgMG_chevron{color:var(--dsw-alias-label-secondary)}.o3BgMG_title{font-weight:400;transition:color .1s}.o3BgMG_sep{background:var(--dsw-alias-label-caption);border-radius:1px;flex:none;width:2px;height:2px;margin:0 8px}.o3BgMG_summary{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:var(--dsh-content-font-size-secondary,13px);line-height:calc(24px + var(--dsh-content-font-delta,0px));color:var(--dsw-alias-label-tertiary);flex:auto;transition:color .1s;overflow:hidden}.o3BgMG_summarySuffix{white-space:nowrap;font-size:var(--dsh-content-font-size-secondary,13px);line-height:calc(24px + var(--dsh-content-font-delta,0px));color:var(--dsw-alias-label-tertiary);flex:none;margin-left:4px;transition:color .1s}.o3BgMG_row:hover .o3BgMG_title,.o3BgMG_row:hover .o3BgMG_summary:not(.o3BgMG_errorSummary):not(.o3BgMG_stoppedSummary),.o3BgMG_row:hover .o3BgMG_summarySuffix{color:var(--dsw-alias-label-primary)}.o3BgMG_diffStat{font-family:var(--ds-font-family-code);font-size:calc(var(--dsh-content-font-size-secondary,13px) - 2px);color:var(--dsw-alias-label-caption);margin-left:10px;transform:translateY(.5px)}.o3BgMG_fileLink{text-overflow:ellipsis;white-space:nowrap;min-width:0;font:inherit;text-align:left;font-size:var(--dsh-content-font-size-secondary,13px);line-height:calc(24px + var(--dsh-content-font-delta,0px));color:var(--dsw-alias-label-secondary);text-decoration:underline dotted;text-decoration-color:var(--dsw-alias-label-tertiary);text-underline-offset:3px;cursor:pointer;background:0 0;border:none;flex:0 auto;margin:0;padding:0;text-decoration-thickness:1px;transition:color .1s;overflow:hidden}.o3BgMG_row:hover .o3BgMG_fileLink,.o3BgMG_fileLink:hover{color:var(--dsw-alias-label-primary);text-decoration-color:currentColor}.o3BgMG_errorSummary{color:var(--dsw-alias-state-error-primary)}.o3BgMG_stoppedSummary{color:var(--dsw-alias-state-warn-label)}.o3BgMG_bodyWrap{flex-direction:column;display:flex}.o3BgMG_inspectButton{border:.5px solid var(--dsw-alias-border-l3);corner-shape:round;background:var(--dsw-alias-bg-base);color:var(--dsw-alias-label-secondary);cursor:pointer;opacity:0;border-radius:999px;align-self:flex-start;align-items:center;gap:4px;margin:4px 0 2px 4px;padding:2px 8px;font-size:11px;line-height:16px;transition:opacity .1s;display:inline-flex}.o3BgMG_root:hover .o3BgMG_inspectButton,.o3BgMG_inspectButton:focus-visible{opacity:1}.o3BgMG_detailsBodyWrap{position:relative}.o3BgMG_detailsBodyWrap .o3BgMG_inspectButton{margin:0;position:absolute;top:12px;right:12px}.o3BgMG_inspectButton:hover{background:var(--dsw-alias-interactive-bg-hover-solid);color:var(--dsw-alias-label-primary)}.o3BgMG_bodyScroll{max-height:260px;overflow-y:auto}.o3BgMG_ioCard{border:.5px solid var(--dsw-alias-border-l1);border-radius:var(--dsw-radius-lg);background:var(--dsw-alias-markdown-code-block);font:var(--dsw-font-markdown-code-block-small);flex-direction:column;margin:4px 0 4px 4px;display:flex}.o3BgMG_ioSection{grid-template-columns:max-content 1fr;align-items:baseline;column-gap:14px;max-height:150px;padding:12px 16px;display:grid;overflow-y:auto}.o3BgMG_ioSection::-webkit-scrollbar-thumb{border-radius:var(--dsw-radius-sm);background-clip:padding-box;border:2px solid #0000}.o3BgMG_ioSection::-webkit-scrollbar-track{margin:6px 0}.o3BgMG_ioLabel{color:var(--dsw-alias-label-caption);align-self:start;position:sticky;top:0}.o3BgMG_ioDivider{background:var(--dsw-alias-border-l2);flex:none;height:.5px}.o3BgMG_ioText{white-space:pre-wrap;word-break:break-word;min-width:0;color:var(--dsw-alias-label-secondary)}.o3BgMG_ioText[data-error]{color:var(--dsw-alias-state-error-primary)}.o3BgMG_codeBody,.o3BgMG_terminalBody,.o3BgMG_diffBody,.o3BgMG_readBody,.o3BgMG_imageBody,.o3BgMG_searchBody,.o3BgMG_webBody{margin:4px 0 4px 4px}.o3BgMG_searchRecovery{white-space:pre-wrap;overflow-wrap:anywhere;font:var(--dsw-font-xs-13);color:var(--dsw-alias-label-tertiary);margin:4px 0 4px 4px}.o3BgMG_imageLabel{overflow-wrap:anywhere;font:var(--dsw-font-sm-13);color:var(--dsw-alias-label-secondary);margin-bottom:4px}.o3BgMG_imageMeta{white-space:pre-wrap;overflow-wrap:anywhere;font:var(--dsw-font-xs-13);color:var(--dsw-alias-label-tertiary)}.o3BgMG_terminalBody{--dsl-terminal-font:var(--dsw-font-markdown-code-block-small);--dsl-terminal-line-height:18px;--dsl-terminal-output-max-height:224px;border:.5px solid var(--dsw-alias-border-l1)}.o3BgMG_visuallyHidden{clip:rect(0 0 0 0);white-space:nowrap;width:1px;height:1px;position:absolute;overflow:hidden}";
1435
- const tagId$2 = "@deepseek-ai/dsh-client-ui-tool/ToolRow.module.css";
1436
- if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$2) + "]") === null) {
1440
+ const css$3 = ".o3BgMG_root{flex-direction:column;display:flex}.o3BgMG_leading{flex-shrink:0}.o3BgMG_root[data-tool^=cordis_] .o3BgMG_title{font-weight:500}.o3BgMG_title{font-weight:400}.o3BgMG_sep{background:var(--dsw-alias-label-caption);border-radius:1px;flex:none;width:2px;height:2px;margin:0 8px}.o3BgMG_summary{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:var(--dsh-content-font-size-secondary,13px);line-height:calc(24px + var(--dsh-content-font-delta,0px));flex:auto;overflow:hidden}.o3BgMG_summarySuffix{white-space:nowrap;font-size:var(--dsh-content-font-size-secondary,13px);line-height:calc(24px + var(--dsh-content-font-delta,0px));flex:none;margin-left:4px}.o3BgMG_diffStat{font-family:var(--ds-font-family-code);font-size:calc(var(--dsh-content-font-size-secondary,13px) - 2px);margin-left:10px;transform:translateY(.5px)}.o3BgMG_row:is(:hover,[aria-expanded=true]) .o3BgMG_diffAdded{color:var(--dsw-alias-state-success-primary)}.o3BgMG_row:is(:hover,[aria-expanded=true]) .o3BgMG_diffRemoved{color:var(--dsw-alias-state-error-primary)}.o3BgMG_fileLink{text-overflow:ellipsis;white-space:nowrap;min-width:0;font:inherit;text-align:left;font-size:var(--dsh-content-font-size-secondary,13px);line-height:calc(24px + var(--dsh-content-font-delta,0px));color:inherit;text-underline-offset:3px;cursor:pointer;background:0 0;border:none;flex:0 auto;margin:0;padding:0;text-decoration:underline 1px dotted;overflow:hidden}.o3BgMG_errorSummary{color:var(--dsw-alias-state-error-primary)}.o3BgMG_stoppedSummary{color:var(--dsw-alias-state-warn-label)}.o3BgMG_bodyWrap{flex-direction:column;display:flex}.o3BgMG_inspectButton{border:.5px solid var(--dsw-alias-border-l3);corner-shape:round;background:var(--dsw-alias-bg-base);color:var(--dsw-alias-label-secondary);cursor:pointer;opacity:0;border-radius:999px;align-self:flex-start;align-items:center;gap:4px;margin:4px 0 2px 4px;padding:2px 8px;font-size:11px;line-height:16px;transition:opacity .1s;display:inline-flex}.o3BgMG_root:hover .o3BgMG_inspectButton,.o3BgMG_inspectButton:focus-visible{opacity:1}.o3BgMG_detailsBodyWrap{position:relative}.o3BgMG_detailsBodyWrap .o3BgMG_inspectButton{margin:0;position:absolute;top:12px;right:12px}.o3BgMG_inspectButton:hover{background:var(--dsw-alias-interactive-bg-hover-solid);color:var(--dsw-alias-label-primary)}.o3BgMG_bodyScroll{max-height:260px;overflow-y:auto}.o3BgMG_ioCard{border:.5px solid var(--dsw-alias-border-l1);border-radius:var(--dsw-radius-lg);background:var(--dsw-alias-markdown-code-block);font:var(--dsw-font-markdown-code-block-small);flex-direction:column;margin:4px 0 4px 4px;display:flex}.o3BgMG_ioSection{grid-template-columns:max-content 1fr;align-items:baseline;column-gap:14px;max-height:150px;padding:12px 16px;display:grid;overflow-y:auto}.o3BgMG_ioSection::-webkit-scrollbar-thumb{border-radius:var(--dsw-radius-sm);background-clip:padding-box;border:2px solid #0000}.o3BgMG_ioSection::-webkit-scrollbar-track{margin:6px 0}.o3BgMG_ioLabel{color:var(--dsw-alias-label-caption);align-self:start;position:sticky;top:0}.o3BgMG_ioDivider{background:var(--dsw-alias-border-l2);flex:none;height:.5px}.o3BgMG_ioText{white-space:pre-wrap;word-break:break-word;min-width:0;color:var(--dsw-alias-label-secondary)}.o3BgMG_ioText[data-error]{color:var(--dsw-alias-state-error-primary)}.o3BgMG_codeBody,.o3BgMG_terminalBody,.o3BgMG_diffBody,.o3BgMG_readBody,.o3BgMG_imageBody,.o3BgMG_searchBody,.o3BgMG_webBody{margin:4px 0 4px 4px}.o3BgMG_searchRecovery{white-space:pre-wrap;overflow-wrap:anywhere;font:var(--dsw-font-xs-13);color:var(--dsw-alias-label-tertiary);margin:4px 0 4px 4px}.o3BgMG_imageLabel{overflow-wrap:anywhere;font:var(--dsw-font-sm-13);color:var(--dsw-alias-label-secondary);margin-bottom:4px}.o3BgMG_imageMeta{white-space:pre-wrap;overflow-wrap:anywhere;font:var(--dsw-font-xs-13);color:var(--dsw-alias-label-tertiary)}.o3BgMG_terminalBody{--dsl-terminal-font:var(--dsw-font-markdown-code-block-small);--dsl-terminal-line-height:18px;--dsl-terminal-output-max-height:224px;border:.5px solid var(--dsw-alias-border-l1)}.o3BgMG_visuallyHidden{clip:rect(0 0 0 0);white-space:nowrap;width:1px;height:1px;position:absolute;overflow:hidden}";
1441
+ const tagId$3 = "@deepseek-ai/dsh-client-ui-tool/ToolRow.module.css";
1442
+ if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]") === null) {
1437
1443
  const tag = document.createElement("style");
1438
1444
  tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-tool";
1439
- tag.dataset.pluginCss = tagId$2;
1440
- tag.textContent = css$2;
1445
+ tag.dataset.pluginCss = tagId$3;
1446
+ tag.textContent = css$3;
1441
1447
  document.head.appendChild(tag);
1442
1448
  }
1443
1449
  var ToolRow_module_css_default = {
1444
1450
  "bodyScroll": "o3BgMG_bodyScroll",
1445
1451
  "bodyWrap": "o3BgMG_bodyWrap",
1446
- "chevron": "o3BgMG_chevron",
1447
1452
  "codeBody": "o3BgMG_codeBody",
1448
1453
  "detailsBodyWrap": "o3BgMG_detailsBodyWrap",
1454
+ "diffAdded": "o3BgMG_diffAdded",
1449
1455
  "diffBody": "o3BgMG_diffBody",
1456
+ "diffRemoved": "o3BgMG_diffRemoved",
1450
1457
  "diffStat": "o3BgMG_diffStat",
1451
1458
  "errorSummary": "o3BgMG_errorSummary",
1452
1459
  "fileLink": "o3BgMG_fileLink",
@@ -1526,13 +1533,10 @@ window.__ModuleLoader__.load({
1526
1533
  const running = state === "running" || state === "preparing";
1527
1534
  const normalSummary = terminalBody?.description ?? (open ? detailsBody?.expandedSummary ?? summary : summary);
1528
1535
  const summaryText = (state === "error" ? errorSummary ?? normalSummary : null) ?? normalSummary;
1529
- const diffStat = (0, react.useMemo)(() => {
1530
- if (diffBody === null) return null;
1531
- const { added, removed } = (0, _deepseek_ai_dsh_client_ui_primitives.diffTotals)(diffBody.card.diffs);
1532
- return `+${added} -${removed}`;
1533
- }, [diffBody]);
1536
+ const diffStat = (0, react.useMemo)(() => diffBody === null ? null : (0, _deepseek_ai_dsh_client_ui_primitives.diffTotals)(diffBody.card.diffs), [diffBody]);
1534
1537
  const settledWithCue = state === "error" || state === "stopped";
1535
- const suffix = settledWithCue ? null : summarySuffix ?? diffStat;
1538
+ const suffix = settledWithCue ? null : summarySuffix ?? null;
1539
+ const totals = settledWithCue ? null : diffStat;
1536
1540
  const openFile = (0, react.useMemo)(() => filePath !== void 0 && onOpenFile !== void 0 && !settledWithCue ? (event) => {
1537
1541
  event.stopPropagation();
1538
1542
  if (filePathLine === void 0) onOpenFile(filePath);
@@ -1573,17 +1577,30 @@ window.__ModuleLoader__.load({
1573
1577
  children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.TextShimmer, { children: summaryText })
1574
1578
  }),
1575
1579
  suffix !== null && (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.TextShimmer, {
1576
- className: clsx(ToolRow_module_css_default.summarySuffix, suffix === diffStat && ToolRow_module_css_default.diffStat),
1580
+ className: ToolRow_module_css_default.summarySuffix,
1577
1581
  children: suffix
1582
+ }),
1583
+ totals !== null && (0, react_jsx_runtime.jsxs)(_deepseek_ai_dsh_client_ui_primitives.TextShimmer, {
1584
+ className: clsx(ToolRow_module_css_default.summarySuffix, ToolRow_module_css_default.diffStat),
1585
+ children: [
1586
+ (0, react_jsx_runtime.jsx)("span", {
1587
+ className: ToolRow_module_css_default.diffAdded,
1588
+ children: `+${totals.added}`
1589
+ }),
1590
+ " ",
1591
+ (0, react_jsx_runtime.jsx)("span", {
1592
+ className: ToolRow_module_css_default.diffRemoved,
1593
+ children: `-${totals.removed}`
1594
+ })
1595
+ ]
1578
1596
  })
1579
1597
  ] }), [
1580
- diffStat,
1581
1598
  summaryLinkKeyDown,
1582
1599
  linkHref,
1583
1600
  openFile,
1584
- running,
1585
1601
  state,
1586
1602
  suffix,
1603
+ totals,
1587
1604
  summaryText
1588
1605
  ]);
1589
1606
  const expandedContent = (0, react.useMemo)(() => open ? (0, react_jsx_runtime.jsxs)("div", {
@@ -1720,7 +1737,6 @@ window.__ModuleLoader__.load({
1720
1737
  rowClassName: ToolRow_module_css_default.row,
1721
1738
  leadingClassName: ToolRow_module_css_default.leading,
1722
1739
  titleClassName: ToolRow_module_css_default.title,
1723
- chevronClassName: ToolRow_module_css_default.chevron,
1724
1740
  icon,
1725
1741
  title,
1726
1742
  running,
@@ -1781,13 +1797,13 @@ window.__ModuleLoader__.load({
1781
1797
  }
1782
1798
  //#endregion
1783
1799
  //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-tool/src/client/tool/ToolCallTree.module.css.mjs
1784
- const css$1 = ".ztWv_q_callRow{border-radius:var(--dsw-radius-sm)}.ztWv_q_subCalls{border-left:.5px solid var(--dsw-alias-border-l2);flex-direction:column;gap:4px;margin:4px 0 2px 22px;padding-left:8px;display:flex}";
1785
- const tagId$1 = "@deepseek-ai/dsh-client-ui-tool/ToolCallTree.module.css";
1786
- if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
1800
+ const css$2 = ".ztWv_q_callRow{border-radius:var(--dsw-radius-sm)}.ztWv_q_subCalls{border-left:.5px solid var(--dsw-alias-border-l2);flex-direction:column;gap:4px;margin:4px 0 2px 22px;padding-left:8px;display:flex}";
1801
+ const tagId$2 = "@deepseek-ai/dsh-client-ui-tool/ToolCallTree.module.css";
1802
+ if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$2) + "]") === null) {
1787
1803
  const tag = document.createElement("style");
1788
1804
  tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-tool";
1789
- tag.dataset.pluginCss = tagId$1;
1790
- tag.textContent = css$1;
1805
+ tag.dataset.pluginCss = tagId$2;
1806
+ tag.textContent = css$2;
1791
1807
  document.head.appendChild(tag);
1792
1808
  }
1793
1809
  var ToolCallTree_module_css_default = {
@@ -1815,16 +1831,7 @@ window.__ModuleLoader__.load({
1815
1831
  return call.phase === "result" ? call.block.call?.name ?? "" : call.block.name;
1816
1832
  }
1817
1833
  /** One atomic call dispatched through the Tool-owned keyed slot. */
1818
- const ToolCall = (0, react.memo)(function ToolCall({ renderSlot, callId, toolName, call, assistant, openFile, cwd, home, inspectCall, loadImage, useDisclosure, t, children }) {
1819
- const preparing = call.phase === "preparing";
1820
- const hookContext = (0, react.useMemo)(() => ({
1821
- callId,
1822
- assistant: preparing ? assistant : void 0
1823
- }), [
1824
- assistant,
1825
- callId,
1826
- preparing
1827
- ]);
1834
+ const ToolCall = (0, react.memo)(function ToolCall({ renderSlot, callId, toolName, call, openFile, cwd, home, inspectCall, loadImage, useDisclosure, t, children }) {
1828
1835
  const owner = (0, react.useMemo)(() => ({
1829
1836
  callId,
1830
1837
  toolName,
@@ -1858,7 +1865,6 @@ window.__ModuleLoader__.load({
1858
1865
  t
1859
1866
  }) : renderSlot("tool.call.toolview", owner, {
1860
1867
  entryKey: toolName,
1861
- hookContext,
1862
1868
  fallback: (0, react_jsx_runtime.jsx)(GenericToolCard, {
1863
1869
  ...owner,
1864
1870
  t
@@ -1866,14 +1872,13 @@ window.__ModuleLoader__.load({
1866
1872
  }), children]
1867
1873
  });
1868
1874
  });
1869
- const ToolCallBranch = (0, react.memo)(function ToolCallBranch({ renderSlot, block, assistant, cwd, home, openFile, inspectCall, loadImage, useDisclosure, t }) {
1875
+ const ToolCallBranch = (0, react.memo)(function ToolCallBranch({ renderSlot, block, cwd, home, openFile, inspectCall, loadImage, useDisclosure, t }) {
1870
1876
  const call = (0, react.useMemo)(() => toolCallPhase(block), [block]);
1871
1877
  return (0, react_jsx_runtime.jsx)(ToolCall, {
1872
1878
  renderSlot,
1873
1879
  callId: call.block.callId,
1874
1880
  toolName: callName(call),
1875
1881
  call,
1876
- assistant,
1877
1882
  openFile,
1878
1883
  cwd,
1879
1884
  home,
@@ -1887,7 +1892,6 @@ window.__ModuleLoader__.load({
1887
1892
  children: call.block.subCalls.map((child) => (0, react_jsx_runtime.jsx)(ToolCallBranch, {
1888
1893
  renderSlot,
1889
1894
  block: child,
1890
- assistant,
1891
1895
  cwd,
1892
1896
  home,
1893
1897
  openFile,
@@ -1907,11 +1911,9 @@ window.__ModuleLoader__.load({
1907
1911
  */
1908
1912
  function ToolCallTree({ renderSlot, node, cwd, openFile, inspectCall, loadImage, useDisclosure, useHostInfo, t }) {
1909
1913
  const home = useHostInfo((info) => info.home);
1910
- const assistant = node.location.kind === "step" ? node.location.step.data.source("assistant-step") : void 0;
1911
1914
  return (0, react_jsx_runtime.jsx)(ToolCallBranch, {
1912
1915
  renderSlot,
1913
1916
  block: node.data.root,
1914
- assistant,
1915
1917
  cwd,
1916
1918
  home,
1917
1919
  openFile,
@@ -1922,31 +1924,115 @@ window.__ModuleLoader__.load({
1922
1924
  });
1923
1925
  }
1924
1926
  //#endregion
1925
- //#region lib/types/client/tool/tool-call-arguments-partial.js
1926
- /** Call-local argument subscription bound by the atomic Tool slot. */
1927
- const subscribeEmpty = () => () => {};
1928
- /**
1929
- * Bind one call without subscribing until its component invokes the Hook.
1930
- * @param _standard - framework-provided scope props.
1931
- * @param context - the preparing call's Step source and identity.
1932
- * @returns a Hook that reads only this call's raw argument prefix.
1933
- */
1934
- const bindToolCallArgumentsPartial = (_standard, context) => {
1935
- const { assistant, callId } = context;
1936
- const subscribe = assistant === void 0 ? subscribeEmpty : (listener) => assistant.subscribe(listener);
1937
- const getSnapshot = () => {
1938
- const block = assistant?.getSnapshot()?.blocks.find((candidate) => candidate.kind === "tool-call" && candidate.callId === callId);
1939
- return block?.kind === "tool-call" ? block.argsRaw : "";
1940
- };
1941
- return function useToolCallArgumentsPartial() {
1942
- return (0, react.useSyncExternalStore)(subscribe, getSnapshot);
1943
- };
1944
- };
1945
- //#endregion
1946
1927
  //#region lib/types/client/locale.js
1947
1928
  /** Locale namespace supplied by the conversation owner to Tool renderers. */
1948
1929
  const CONVERSATION_NS = "conversation";
1949
1930
  //#endregion
1931
+ //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-tool/src/client/tool/components/QuestionToolRow.module.css.mjs
1932
+ const css$1 = ".nvmz7W_panelButton{height:calc(22px + var(--dsh-content-font-delta,0px));corner-shape:round;background:var(--dsw-alias-button-floating-fill);color:var(--dsw-alias-label-primary);font-family:inherit;font-size:calc(var(--dsh-content-font-size-secondary,13px) - 1px);white-space:nowrap;cursor:pointer;border:none;border-radius:999px;flex:none;align-items:center;gap:4px;margin-left:8px;padding:0 10px;line-height:1;transition:background .1s;display:inline-flex}.nvmz7W_panelButton svg{width:13px;height:13px}.nvmz7W_panelButton:hover{background:var(--dsw-alias-button-floating-hover)}";
1933
+ const tagId$1 = "@deepseek-ai/dsh-client-ui-tool/QuestionToolRow.module.css";
1934
+ if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
1935
+ const tag = document.createElement("style");
1936
+ tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-tool";
1937
+ tag.dataset.pluginCss = tagId$1;
1938
+ tag.textContent = css$1;
1939
+ document.head.appendChild(tag);
1940
+ }
1941
+ var QuestionToolRow_module_css_default = { "panelButton": "nvmz7W_panelButton" };
1942
+ //#endregion
1943
+ //#region lib/types/client/tool/components/QuestionToolRow.js
1944
+ /** Question-owned summary action and transcript disclosure. */
1945
+ /**
1946
+ * Render a question with its answer-panel entry point.
1947
+ * @param props - Question transcript, panel action, and disclosure state.
1948
+ * @returns The question's summary and optional expanded record.
1949
+ */
1950
+ function QuestionToolRow({ useDisclosure, t, summary, bodyRaw, output, askQuestion, state, inspect, openPanel, panelLabel }) {
1951
+ const { expanded, toggle } = useDisclosure();
1952
+ const expandable = bodyRaw != null || output != null || askQuestion != null;
1953
+ const open = expanded && expandable;
1954
+ return (0, react_jsx_runtime.jsxs)("div", {
1955
+ className: ToolRow_module_css_default.root,
1956
+ "data-variant": "others",
1957
+ "data-tool": "ask_user_question",
1958
+ "data-state": state,
1959
+ children: [state === "running" && (0, react_jsx_runtime.jsx)("span", {
1960
+ className: ToolRow_module_css_default.visuallyHidden,
1961
+ children: t("row.running")
1962
+ }), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.DisclosureRow, {
1963
+ rowClassName: ToolRow_module_css_default.row,
1964
+ leadingClassName: ToolRow_module_css_default.leading,
1965
+ titleClassName: ToolRow_module_css_default.title,
1966
+ chevronClassName: ToolRow_module_css_default.chevron,
1967
+ icon: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconQuestionOutlineRegular, {}),
1968
+ title: t("ask.rowTitle"),
1969
+ running: state === "running",
1970
+ open,
1971
+ expandable,
1972
+ keepContentWhenOpen: true,
1973
+ onToggle: toggle,
1974
+ collapsedContent: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [summary !== "" && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)("span", {
1975
+ className: ToolRow_module_css_default.sep,
1976
+ "aria-hidden": true
1977
+ }), (0, react_jsx_runtime.jsx)("span", {
1978
+ className: ToolRow_module_css_default.summary,
1979
+ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.TextShimmer, {
1980
+ active: state === "running",
1981
+ children: summary
1982
+ })
1983
+ })] }), (0, react_jsx_runtime.jsxs)("button", {
1984
+ type: "button",
1985
+ className: QuestionToolRow_module_css_default.panelButton,
1986
+ onClick: (event) => {
1987
+ event.stopPropagation();
1988
+ if (!openPanel()) toggle();
1989
+ },
1990
+ onKeyDown: (event) => {
1991
+ if (event.key === "Enter" || event.key === " ") event.stopPropagation();
1992
+ },
1993
+ children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconQuestionOutlineRegular, {}), panelLabel]
1994
+ })] }),
1995
+ children: open && (0, react_jsx_runtime.jsxs)("div", {
1996
+ className: ToolRow_module_css_default.bodyWrap,
1997
+ children: [askQuestion != null ? (0, react_jsx_runtime.jsx)(AskQuestionCard, { card: askQuestion }) : (0, react_jsx_runtime.jsxs)("div", {
1998
+ className: ToolRow_module_css_default.ioCard,
1999
+ children: [
2000
+ bodyRaw != null && (0, react_jsx_runtime.jsxs)("div", {
2001
+ className: ToolRow_module_css_default.ioSection,
2002
+ children: [(0, react_jsx_runtime.jsx)("span", {
2003
+ className: ToolRow_module_css_default.ioLabel,
2004
+ children: t("row.input")
2005
+ }), (0, react_jsx_runtime.jsx)("span", {
2006
+ className: ToolRow_module_css_default.ioText,
2007
+ children: formatToolBody("others", bodyRaw)
2008
+ })]
2009
+ }),
2010
+ bodyRaw != null && output != null && (0, react_jsx_runtime.jsx)("span", {
2011
+ className: ToolRow_module_css_default.ioDivider,
2012
+ "aria-hidden": true
2013
+ }),
2014
+ output != null && (0, react_jsx_runtime.jsxs)("div", {
2015
+ className: ToolRow_module_css_default.ioSection,
2016
+ children: [(0, react_jsx_runtime.jsx)("span", {
2017
+ className: ToolRow_module_css_default.ioLabel,
2018
+ children: t("row.output")
2019
+ }), (0, react_jsx_runtime.jsx)("span", {
2020
+ className: ToolRow_module_css_default.ioText,
2021
+ children: output
2022
+ })]
2023
+ })
2024
+ ]
2025
+ }), inspect !== void 0 && (0, react_jsx_runtime.jsxs)("button", {
2026
+ type: "button",
2027
+ className: ToolRow_module_css_default.inspectButton,
2028
+ onClick: inspect,
2029
+ children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconInspectOutlineRegular, {}), t("row.inspect")]
2030
+ })]
2031
+ })
2032
+ })]
2033
+ });
2034
+ }
2035
+ //#endregion
1950
2036
  //#region lib/types/client/tool/toolviews/ask-question-row.js
1951
2037
  function isRecord(value) {
1952
2038
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -1975,7 +2061,35 @@ window.__ModuleLoader__.load({
1975
2061
  }
1976
2062
  return entries;
1977
2063
  }
1978
- /** Questions from call JSON; null when pairing with answers would be ambiguous. */
2064
+ /** Answers from a submitted steer that still awaits admission to a step. */
2065
+ function queuedAnswerEntries(message, callId) {
2066
+ if (!isRecord(message) || !Array.isArray(message.content)) return null;
2067
+ const content = message.content[0];
2068
+ if (!isRecord(content) || content.type !== "text" || typeof content.text !== "string") return null;
2069
+ const parsed = parseJson(content.text);
2070
+ if (!isRecord(parsed) || parsed.kind !== "answer_to_pending_question" || parsed.callId !== callId) return null;
2071
+ return answerEntries(content.text);
2072
+ }
2073
+ /** One question's choices from call JSON; absent when any entry is malformed. */
2074
+ function optionEntries(value) {
2075
+ if (!Array.isArray(value)) return void 0;
2076
+ const options = [];
2077
+ for (const option of value) {
2078
+ if (!isRecord(option) || typeof option.label !== "string") return void 0;
2079
+ options.push({
2080
+ label: option.label,
2081
+ ...typeof option.description === "string" ? { description: option.description } : {}
2082
+ });
2083
+ }
2084
+ return options;
2085
+ }
2086
+ /**
2087
+ * Questions from call JSON; null when pairing with answers would be ambiguous.
2088
+ * The optional presentation fields are carried for the read-only answer panel,
2089
+ * which renders the same option lists the user chose from; a malformed one is
2090
+ * dropped rather than failing the whole call, because the transcript card needs
2091
+ * only the id and the question text.
2092
+ */
1979
2093
  function questionEntries(argsRaw) {
1980
2094
  const parsed = parseJson(argsRaw);
1981
2095
  if (!isRecord(parsed) || !Array.isArray(parsed.questions) || parsed.questions.length === 0) return null;
@@ -1984,17 +2098,21 @@ window.__ModuleLoader__.load({
1984
2098
  for (const question of parsed.questions) {
1985
2099
  if (!isRecord(question) || typeof question.id !== "string" || typeof question.question !== "string" || ids.has(question.id)) return null;
1986
2100
  ids.add(question.id);
2101
+ const options = optionEntries(question.options);
1987
2102
  questions.push({
1988
2103
  id: question.id,
1989
- question: question.question
2104
+ question: question.question,
2105
+ ...typeof question.header === "string" ? { header: question.header } : {},
2106
+ ...typeof question.detail === "string" ? { detail: question.detail } : {},
2107
+ ...options === void 0 ? {} : { options },
2108
+ ...typeof question.multi_select === "boolean" ? { multiSelect: question.multi_select } : {}
1990
2109
  });
1991
2110
  }
1992
2111
  return questions;
1993
2112
  }
1994
2113
  /** Pair questions with result entries by their echoed stable ids. */
1995
- function pairAnswers(argsRaw, answers) {
1996
- const questions = questionEntries(argsRaw);
1997
- if (questions === null || questions.length !== answers.length) return null;
2114
+ function pairAnswers(questions, answers) {
2115
+ if (questions.length !== answers.length) return null;
1998
2116
  const byId = /* @__PURE__ */ new Map();
1999
2117
  for (const answer of answers) {
2000
2118
  if (byId.has(answer.id)) return null;
@@ -2005,23 +2123,38 @@ window.__ModuleLoader__.load({
2005
2123
  const answer = byId.get(question.id);
2006
2124
  if (answer === void 0) return null;
2007
2125
  paired.push({
2008
- ...question,
2126
+ id: question.id,
2127
+ question: question.question,
2009
2128
  answers: [...answer.selected, ...answer.custom === void 0 || answer.custom === "" ? [] : [answer.custom]]
2010
2129
  });
2011
2130
  }
2012
2131
  return paired;
2013
2132
  }
2014
- /** Answer summary plus structured transcript content from the two wire JSON documents. */
2015
- function answeredPresentation(argsRaw, text, t) {
2016
- const answers = answerEntries(text);
2017
- if (answers === null) return null;
2133
+ /**
2134
+ * Answer summary, transcript content, and panel material from one recorded
2135
+ * answer batch, whether the result carried it in time or a late reply did.
2136
+ * @param questions - The call's questions, or null when they failed validation.
2137
+ * @param answers - The recorded answer batch.
2138
+ * @param t - Row translator.
2139
+ * @returns What the answered row shows.
2140
+ */
2141
+ function answeredPresentation(questions, answers, t) {
2018
2142
  const answered = answers.filter((answer) => answer.selected.length > 0 || (answer.custom ?? "") !== "").length;
2143
+ const paired = questions === null ? null : pairAnswers(questions, answers);
2019
2144
  return {
2020
2145
  summary: t("ask.answered", {
2021
2146
  answered,
2022
2147
  total: answers.length
2023
2148
  }),
2024
- questions: pairAnswers(argsRaw, answers)
2149
+ transcript: paired === null ? null : {
2150
+ kind: "answered",
2151
+ questions: paired,
2152
+ skippedLabel: t("ask.skipped")
2153
+ },
2154
+ record: paired === null || questions === null ? void 0 : {
2155
+ questions,
2156
+ answers
2157
+ }
2025
2158
  };
2026
2159
  }
2027
2160
  /** Best-effort answered-count summary when strict transcript pairing fails. */
@@ -2036,14 +2169,31 @@ window.__ModuleLoader__.load({
2036
2169
  total: answers.length
2037
2170
  });
2038
2171
  }
2172
+ /** Whether a successful tool result records a still-answerable timed question. */
2173
+ function isPendingResult(text) {
2174
+ const parsed = parseJson(text);
2175
+ return isRecord(parsed) && parsed.pending === true && typeof parsed.callId === "string";
2176
+ }
2039
2177
  /** Summarizes a pending, answered, cancelled, or interrupted question set. */
2040
- function AskQuestionRow({ toolName, block, inspect, useDisclosure, t }) {
2178
+ function AskQuestionRow({ callId, toolName, block, inspect, useDisclosure, useProjection, revealPanel, reviewPanel, t }) {
2041
2179
  const model = toolRowModel(toolName, block);
2180
+ const answerable = useProjection("userQuestions", (view) => view?.active.some((row) => row.callId === callId) ?? false);
2181
+ const settled = useProjection("userQuestions", (view) => view?.settled.find((row) => row.callId === callId));
2182
+ const queuedReply = useProjection("inbox", (view) => {
2183
+ const matches = (message) => {
2184
+ const source = isRecord(message) ? message.source : void 0;
2185
+ return isRecord(source) && source.kind === "user-question-reply" && source.callId === callId;
2186
+ };
2187
+ return view?.["next-step"].find(matches) ?? view?.["next-turn"].find(matches);
2188
+ });
2189
+ const reopen = (0, react.useCallback)(() => revealPanel(callId), [callId, revealPanel]);
2042
2190
  const code = "kind" in block ? block.error?.code : void 0;
2043
2191
  const argsRaw = model.bodyRaw ?? "";
2044
2192
  let summary = model.summary;
2045
2193
  let state = model.state;
2046
2194
  let transcript = null;
2195
+ let rowAction;
2196
+ let rowActionLabel = t("ask.reopen");
2047
2197
  if (code === "ASK_CANCELLED") {
2048
2198
  summary = t("ask.cancelled");
2049
2199
  state = "ok";
@@ -2062,19 +2212,92 @@ window.__ModuleLoader__.load({
2062
2212
  questions,
2063
2213
  verdict: t("ask.interruptedDetail")
2064
2214
  };
2065
- } else if (model.state === "running") summary = t("ask.waiting");
2066
- else if ("kind" in block && model.state === "ok") {
2215
+ } else if (model.state === "running") {
2216
+ summary = t("ask.waiting");
2217
+ if (answerable) rowAction = reopen;
2218
+ } else if (code === "TOOL_OUTCOME_UNKNOWN" && (answerable || settled !== void 0)) {
2219
+ state = "ok";
2220
+ const questions = questionEntries(argsRaw);
2221
+ if (answerable) {
2222
+ summary = t("ask.pending");
2223
+ if (questions !== null) transcript = {
2224
+ kind: "unanswered",
2225
+ questions,
2226
+ verdict: t("ask.pendingDetail")
2227
+ };
2228
+ rowAction = reopen;
2229
+ } else if (settled?.answers.length === 0) {
2230
+ summary = t("ask.closed");
2231
+ if (questions !== null) transcript = {
2232
+ kind: "unanswered",
2233
+ questions,
2234
+ verdict: t("ask.closedDetail")
2235
+ };
2236
+ } else if (settled !== void 0) {
2237
+ const presentation = answeredPresentation(questions, settled.answers, t);
2238
+ summary = presentation.summary;
2239
+ transcript = presentation.transcript;
2240
+ const record = presentation.record;
2241
+ if (record !== void 0) {
2242
+ rowAction = () => reviewPanel(callId, record);
2243
+ rowActionLabel = t("ask.review");
2244
+ }
2245
+ }
2246
+ } else if ("kind" in block && model.state === "ok") {
2067
2247
  const text = singleResultText(block);
2068
2248
  if (text !== void 0) {
2069
- const presentation = answeredPresentation(argsRaw, text, t);
2070
- summary = presentation?.summary ?? answeredSummary(text, t) ?? model.summary;
2071
- if (presentation?.questions !== null && presentation?.questions !== void 0) transcript = {
2072
- kind: "answered",
2073
- questions: presentation.questions,
2074
- skippedLabel: t("ask.skipped")
2075
- };
2249
+ const questions = questionEntries(argsRaw);
2250
+ const pending = isPendingResult(text);
2251
+ if (pending && answerable) {
2252
+ summary = t("ask.pending");
2253
+ if (questions !== null) transcript = {
2254
+ kind: "unanswered",
2255
+ questions,
2256
+ verdict: t("ask.pendingDetail")
2257
+ };
2258
+ rowAction = reopen;
2259
+ } else if (pending && (settled === void 0 || settled.answers.length === 0)) {
2260
+ summary = t("ask.closed");
2261
+ if (questions !== null) transcript = {
2262
+ kind: "unanswered",
2263
+ questions,
2264
+ verdict: t("ask.closedDetail")
2265
+ };
2266
+ } else {
2267
+ const answers = settled?.answers ?? answerEntries(text);
2268
+ const presentation = answers === null ? null : answeredPresentation(questions, answers, t);
2269
+ summary = presentation?.summary ?? answeredSummary(text, t) ?? model.summary;
2270
+ transcript = presentation?.transcript ?? null;
2271
+ const record = settled === void 0 ? void 0 : presentation?.record;
2272
+ if (record !== void 0) {
2273
+ rowAction = () => reviewPanel(callId, record);
2274
+ rowActionLabel = t("ask.review");
2275
+ }
2276
+ }
2076
2277
  }
2077
2278
  }
2279
+ if (answerable && queuedReply !== void 0 && rowAction === reopen) {
2280
+ const answers = queuedAnswerEntries(queuedReply, callId);
2281
+ const presentation = answers === null ? null : answeredPresentation(questionEntries(argsRaw), answers, t);
2282
+ if (presentation?.record !== void 0) {
2283
+ summary = presentation.summary;
2284
+ transcript = presentation.transcript;
2285
+ rowAction = () => false;
2286
+ rowActionLabel = t("ask.review");
2287
+ }
2288
+ }
2289
+ if (rowAction !== void 0) return (0, react_jsx_runtime.jsx)(QuestionToolRow, {
2290
+ useDisclosure,
2291
+ t,
2292
+ summary,
2293
+ bodyRaw: transcript === null ? model.bodyRaw : null,
2294
+ output: transcript === null ? model.output : null,
2295
+ askQuestion: transcript,
2296
+ state,
2297
+ inspect,
2298
+ openPanel: rowAction,
2299
+ panelLabel: rowActionLabel
2300
+ });
2078
2301
  return (0, react_jsx_runtime.jsx)(ToolRow, {
2079
2302
  useDisclosure,
2080
2303
  t,
@@ -2098,32 +2321,17 @@ window.__ModuleLoader__.load({
2098
2321
  ctx.slots.inject("tool.call.toolview", () => ctx.slots.register({
2099
2322
  name: "tool.call.toolview",
2100
2323
  key: "ask_user_question",
2101
- locale: CONVERSATION_NS
2324
+ locale: CONVERSATION_NS,
2325
+ inject: (sessionId) => ({
2326
+ revealPanel: (callId) => ctx.get("userQuestionPanels")?.reveal(sessionId, callId) ?? false,
2327
+ reviewPanel: (callId, record) => ctx.get("userQuestionPanels")?.review(sessionId, callId, record) ?? false
2328
+ })
2102
2329
  }, AskQuestionRow));
2103
2330
  }
2104
2331
  };
2105
2332
  //#endregion
2106
- //#region lib/types/client/tool/components/PreparingToolRow.js
2107
- /**
2108
- * Render a non-expandable tool prefix with an optional preparation summary.
2109
- * @param props - tool prefix and locale.
2110
- * @returns the preparation row.
2111
- */
2112
- function PreparingToolRow({ toolName, useDisclosure, icon, title, summary = "", t }) {
2113
- return (0, react_jsx_runtime.jsx)(ToolRow, {
2114
- useDisclosure,
2115
- t,
2116
- variant: classifyTool(toolName),
2117
- toolName,
2118
- icon,
2119
- title,
2120
- summary,
2121
- state: "preparing"
2122
- });
2123
- }
2124
- //#endregion
2125
2333
  //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-tool/src/client/tool/toolviews/bash-sample.module.css.mjs
2126
- const css = ".CY-8Ka_card{flex-direction:column;display:flex}.CY-8Ka_terminal{--dsl-terminal-font:var(--dsw-font-markdown-code-block-small);--dsl-terminal-line-height:18px;--dsl-terminal-output-max-height:224px;border:.5px solid var(--dsw-alias-border-l1);margin:4px 0 4px 4px}.CY-8Ka_ioCard{border:.5px solid var(--dsw-alias-border-l1);border-radius:var(--dsw-radius-lg);background:var(--dsw-alias-markdown-code-block);font:var(--dsw-font-markdown-code-block-small);flex-direction:column;margin:4px 0 4px 4px;display:flex}.CY-8Ka_ioSection{grid-template-columns:max-content 1fr;align-items:baseline;column-gap:14px;max-height:150px;padding:12px 16px;display:grid;overflow-y:auto}.CY-8Ka_ioSection::-webkit-scrollbar-thumb{border-radius:var(--dsw-radius-sm);background-clip:padding-box;border:2px solid #0000}.CY-8Ka_ioSection::-webkit-scrollbar-track{margin:6px 0}.CY-8Ka_ioLabel{color:var(--dsw-alias-label-caption);align-self:start;position:sticky;top:0}.CY-8Ka_ioDivider{background:var(--dsw-alias-border-l2);flex:none;height:.5px}.CY-8Ka_ioText{white-space:pre-wrap;word-break:break-word;min-width:0;color:var(--dsw-alias-label-secondary)}.CY-8Ka_ioText[data-error]{color:var(--dsw-alias-state-error-primary)}.CY-8Ka_root[data-expandable]{cursor:pointer}.CY-8Ka_root{height:calc(24px + var(--dsh-content-font-delta,0px));align-items:center;min-width:0;display:flex}.CY-8Ka_leading{width:calc(16px + var(--dsh-content-font-delta,0px));height:calc(16px + var(--dsh-content-font-delta,0px));color:var(--dsw-alias-label-tertiary);flex:none;justify-content:center;align-items:center;margin-right:6px;display:inline-flex;position:relative}.CY-8Ka_leading svg:not([data-state]){width:calc(14px + var(--dsh-content-font-delta,0px));height:calc(14px + var(--dsh-content-font-delta,0px))}.CY-8Ka_chevron{color:var(--dsw-alias-label-secondary)}.CY-8Ka_iconIdle{opacity:1;transition:opacity .1s;display:inline-flex}.CY-8Ka_chevronHover{opacity:0;margin:auto;transition:opacity .1s;position:absolute;inset:0}.CY-8Ka_root:hover .CY-8Ka_iconIdle{opacity:0}.CY-8Ka_root:hover .CY-8Ka_chevronHover{opacity:1}.CY-8Ka_title{font-size:var(--dsh-content-font-size-secondary,13px);line-height:calc(24px + var(--dsh-content-font-delta,0px));color:var(--dsw-alias-label-secondary);flex:none;transition:color .1s}.CY-8Ka_sep{background:var(--dsw-alias-label-caption);border-radius:1px;flex:none;width:2px;height:2px;margin:0 8px}.CY-8Ka_summary{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:var(--dsh-content-font-size-secondary,13px);line-height:calc(24px + var(--dsh-content-font-delta,0px));color:var(--dsw-alias-label-tertiary);flex:auto;transition:color .1s;overflow:hidden}.CY-8Ka_root:hover .CY-8Ka_title,.CY-8Ka_root:hover .CY-8Ka_summary:not(.CY-8Ka_errorSummary):not(.CY-8Ka_stoppedSummary){color:var(--dsw-alias-label-primary)}.CY-8Ka_errorSummary{color:var(--dsw-alias-state-error-primary)}.CY-8Ka_stoppedSummary{color:var(--dsw-alias-state-warn-label)}.CY-8Ka_bodyWrap{flex-direction:column;display:flex}.CY-8Ka_inspectButton{border:.5px solid var(--dsw-alias-border-l4);corner-shape:round;background:var(--dsw-alias-bg-base);color:var(--dsw-alias-label-secondary);cursor:pointer;opacity:0;border-radius:999px;align-self:flex-start;align-items:center;gap:4px;margin:4px 0 2px 4px;padding:2px 8px;font-size:11px;line-height:16px;transition:opacity .1s;display:inline-flex}.CY-8Ka_card:hover .CY-8Ka_inspectButton,.CY-8Ka_inspectButton:focus-visible{opacity:1}.CY-8Ka_inspectButton:hover{background:var(--dsw-alias-interactive-bg-hover-solid);color:var(--dsw-alias-label-primary)}.CY-8Ka_visuallyHidden{clip:rect(0 0 0 0);white-space:nowrap;width:1px;height:1px;position:absolute;overflow:hidden}";
2334
+ const css = ".CY-8Ka_card{flex-direction:column;display:flex}.CY-8Ka_terminal{--dsl-terminal-font:var(--dsw-font-markdown-code-block-small);--dsl-terminal-line-height:18px;--dsl-terminal-output-max-height:224px;border:.5px solid var(--dsw-alias-border-l1);margin:4px 0 4px 4px}.CY-8Ka_ioCard{border:.5px solid var(--dsw-alias-border-l1);border-radius:var(--dsw-radius-lg);background:var(--dsw-alias-markdown-code-block);font:var(--dsw-font-markdown-code-block-small);flex-direction:column;margin:4px 0 4px 4px;display:flex}.CY-8Ka_ioSection{grid-template-columns:max-content 1fr;align-items:baseline;column-gap:14px;max-height:150px;padding:12px 16px;display:grid;overflow-y:auto}.CY-8Ka_ioSection::-webkit-scrollbar-thumb{border-radius:var(--dsw-radius-sm);background-clip:padding-box;border:2px solid #0000}.CY-8Ka_ioSection::-webkit-scrollbar-track{margin:6px 0}.CY-8Ka_ioLabel{color:var(--dsw-alias-label-caption);align-self:start;position:sticky;top:0}.CY-8Ka_ioDivider{background:var(--dsw-alias-border-l2);flex:none;height:.5px}.CY-8Ka_ioText{white-space:pre-wrap;word-break:break-word;min-width:0;color:var(--dsw-alias-label-secondary)}.CY-8Ka_ioText[data-error]{color:var(--dsw-alias-state-error-primary)}.CY-8Ka_root[data-expandable]{cursor:pointer}.CY-8Ka_root{height:calc(24px + var(--dsh-content-font-delta,0px));min-width:0;color:var(--dsw-alias-label-tertiary);align-items:center;transition:color .1s;display:flex}.CY-8Ka_root:hover{color:var(--dsw-alias-label-secondary)}@media (prefers-reduced-motion:reduce){.CY-8Ka_root{transition:none}}.CY-8Ka_leading{width:calc(16px + var(--dsh-content-font-delta,0px));height:calc(16px + var(--dsh-content-font-delta,0px));color:inherit;flex:none;justify-content:center;align-items:center;margin-right:6px;display:inline-flex;position:relative}.CY-8Ka_leading svg:not([data-state]){width:calc(14px + var(--dsh-content-font-delta,0px));height:calc(14px + var(--dsh-content-font-delta,0px))}.CY-8Ka_chevron{color:inherit}.CY-8Ka_iconIdle{opacity:1;transition:opacity .1s;display:inline-flex}.CY-8Ka_chevronHover{opacity:0;margin:auto;transition:opacity .1s;position:absolute;inset:0}.CY-8Ka_root:hover .CY-8Ka_iconIdle{opacity:0}.CY-8Ka_root:hover .CY-8Ka_chevronHover{opacity:1}.CY-8Ka_title{font-size:var(--dsh-content-font-size-secondary,13px);line-height:calc(24px + var(--dsh-content-font-delta,0px));flex:none}.CY-8Ka_sep{background:var(--dsw-alias-label-caption);border-radius:1px;flex:none;width:2px;height:2px;margin:0 8px}.CY-8Ka_summary{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:var(--dsh-content-font-size-secondary,13px);line-height:calc(24px + var(--dsh-content-font-delta,0px));flex:auto;overflow:hidden}.CY-8Ka_errorSummary{color:var(--dsw-alias-state-error-primary)}.CY-8Ka_stoppedSummary{color:var(--dsw-alias-state-warn-label)}.CY-8Ka_bodyWrap{flex-direction:column;display:flex}.CY-8Ka_inspectButton{border:.5px solid var(--dsw-alias-border-l4);corner-shape:round;background:var(--dsw-alias-bg-base);color:var(--dsw-alias-label-secondary);cursor:pointer;opacity:0;border-radius:999px;align-self:flex-start;align-items:center;gap:4px;margin:4px 0 2px 4px;padding:2px 8px;font-size:11px;line-height:16px;transition:opacity .1s;display:inline-flex}.CY-8Ka_card:hover .CY-8Ka_inspectButton,.CY-8Ka_inspectButton:focus-visible{opacity:1}.CY-8Ka_inspectButton:hover{background:var(--dsw-alias-interactive-bg-hover-solid);color:var(--dsw-alias-label-primary)}.CY-8Ka_visuallyHidden{clip:rect(0 0 0 0);white-space:nowrap;width:1px;height:1px;position:absolute;overflow:hidden}";
2127
2335
  const tagId = "@deepseek-ai/dsh-client-ui-tool/bash-sample.module.css";
2128
2336
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
2129
2337
  const tag = document.createElement("style");
@@ -2160,6 +2368,7 @@ window.__ModuleLoader__.load({
2160
2368
  /** Visually hidden status for the color-only running sweep and error tone. */
2161
2369
  function stateStatus(state, t) {
2162
2370
  switch (state) {
2371
+ case "preparing": return t("row.preparing");
2163
2372
  case "running": return t("bash.running");
2164
2373
  case "error": return t("bash.failed");
2165
2374
  case "stopped": return t("bash.stopped");
@@ -2167,19 +2376,12 @@ window.__ModuleLoader__.load({
2167
2376
  }
2168
2377
  }
2169
2378
  /**
2170
- * Render expandable Bash output with an accessible lifecycle label.
2379
+ * Render expandable Bash output with an accessible lifecycle label. While the
2380
+ * call is preparing the row shows the description streamed so far and cannot expand.
2171
2381
  * @param props - tool call, Session sources, locale, and inspection callback.
2172
2382
  * @returns the Bash output row.
2173
2383
  */
2174
- const BashRow = (0, react.memo)(function BashRow(props) {
2175
- if (props.phase === "preparing") return (0, react_jsx_runtime.jsx)(PreparingToolRow, {
2176
- ...props,
2177
- icon: BASH_ICON,
2178
- title: props.t(toolTitleKey(props.toolName))
2179
- });
2180
- return (0, react_jsx_runtime.jsx)(StartedBashRow, { ...props });
2181
- });
2182
- const StartedBashRow = (0, react.memo)(function StartedBashRow({ toolName, block, sessionId, useSessions, inspect, useDisclosure, t }) {
2384
+ const BashRow = (0, react.memo)(function BashRow({ toolName, block, sessionId, useSessions, inspect, useDisclosure, t }) {
2183
2385
  const model = (0, react.useMemo)(() => toolRowModel(toolName, block), [toolName, block]);
2184
2386
  const cwd = useSessions((list) => list.byId[sessionId]?.cwd);
2185
2387
  const terminalModel = (0, react.useMemo)(() => terminalCardModel(block, cwd), [block, cwd]);
@@ -2199,7 +2401,7 @@ window.__ModuleLoader__.load({
2199
2401
  ]);
2200
2402
  const normalSummary = terminal?.description ?? model.summary;
2201
2403
  const settlementLine = state === "error" ? model.errorSummary ?? normalSummary : state === "stopped" ? t("bash.stopped") : null;
2202
- const running = state === "running";
2404
+ const running = state === "running" || state === "preparing";
2203
2405
  const toggleFromKeyboard = (0, react.useCallback)((event) => {
2204
2406
  if (!expandable || event.key !== "Enter" && event.key !== " ") return;
2205
2407
  event.preventDefault();
@@ -2310,26 +2512,33 @@ window.__ModuleLoader__.load({
2310
2512
  //#endregion
2311
2513
  //#region lib/types/client/tool/toolviews/file-mutation-row.js
2312
2514
  const FILE_MUTATION_ICON = (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconEditOutlineRegular, { size: 14 });
2515
+ const CONTENT_FIELDS = [
2516
+ "content",
2517
+ "old_string",
2518
+ "new_string"
2519
+ ];
2520
+ const KILOBYTE = 1024;
2521
+ /** Kilobytes of decoded input at every stage; null before any content field arrives. */
2522
+ function contentKilobytes(block) {
2523
+ const { args } = block;
2524
+ const open = CONTENT_FIELDS.find((key) => args.has(key) && !args.complete(key));
2525
+ const completed = CONTENT_FIELDS.reduce((total, key) => key !== open && args.complete(key) ? total + (args.stringLength(key, { step: KILOBYTE }) ?? 0) : total, 0);
2526
+ if (open === void 0) return CONTENT_FIELDS.some((key) => args.has(key)) ? Math.ceil(completed / KILOBYTE) : null;
2527
+ const chars = completed + (args.stringLength(open, {
2528
+ step: KILOBYTE,
2529
+ offset: completed
2530
+ }) ?? 0);
2531
+ return Math.ceil(chars / KILOBYTE);
2532
+ }
2313
2533
  /**
2314
- * Lets users expand an applied file diff and open the reported path.
2534
+ * Shows the path and decoded input size through preparation, execution, and
2535
+ * settlement, with the applied diff available once the call settles.
2315
2536
  */
2316
- function FileMutationRow(props) {
2317
- return props.phase === "preparing" ? (0, react_jsx_runtime.jsx)(PreparingFileMutationRow, { ...props }) : (0, react_jsx_runtime.jsx)(StartedFileMutationRow, { ...props });
2318
- }
2319
- function PreparingFileMutationRow({ toolName, useDisclosure, useToolCallArgumentsPartial, t }) {
2320
- const raw = useToolCallArgumentsPartial();
2321
- return (0, react_jsx_runtime.jsx)(PreparingToolRow, {
2322
- toolName,
2323
- useDisclosure,
2324
- icon: FILE_MUTATION_ICON,
2325
- title: t(toolTitleKey(toolName)),
2326
- t,
2327
- summary: t("tool.preparing.content", { kilobytes: Math.ceil(raw.length / 1024) })
2328
- });
2329
- }
2330
- function StartedFileMutationRow({ toolName, block, cwd, home, openFile, inspect, useDisclosure, t }) {
2537
+ function FileMutationRow({ toolName, block, cwd, home, openFile, inspect, useDisclosure, t }) {
2331
2538
  const model = toolRowModel(toolName, block, cwd, home);
2332
2539
  const diff = diffCardModel(block);
2540
+ const kilobytes = contentKilobytes(block);
2541
+ const size = kilobytes === null ? null : t("tool.preparing.content", { kilobytes });
2333
2542
  return (0, react_jsx_runtime.jsx)(ToolRow, {
2334
2543
  useDisclosure,
2335
2544
  t,
@@ -2338,6 +2547,7 @@ window.__ModuleLoader__.load({
2338
2547
  icon: FILE_MUTATION_ICON,
2339
2548
  title: t(model.titleKey),
2340
2549
  summary: model.summary,
2550
+ summarySuffix: size !== null && model.summary !== "" ? size : void 0,
2341
2551
  output: model.output,
2342
2552
  errorSummary: model.errorSummary,
2343
2553
  diff,
@@ -4307,8 +4517,7 @@ window.__ModuleLoader__.load({
4307
4517
  locale: CONVERSATION_NS,
4308
4518
  children: { "tool.call.toolview": {
4309
4519
  kind: "keyed",
4310
- scope: "session",
4311
- inject: { hooks: { toolCallArgumentsPartial: bindToolCallArgumentsPartial } }
4520
+ scope: "session"
4312
4521
  } },
4313
4522
  inject: toolInject
4314
4523
  }, ToolCallTree));