@deepseek-ai/dsh-client-ui-chat 0.1.7-alpha.2 → 0.1.7-rc.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/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-chat/README.md
5
- README.md: 1aa7d71b3f932a7a14ef6d23e9ace7eda444fc3b
6
- README.zh.md: 2239234448e1e00fd395634de39a96c2a80a35f7
5
+ README.md: f6924e91b24d6da9bae7722734dd8c7455145abf
6
+ README.zh.md: 0834d1f556a0757dd40fd5d0cdd7fb28c3f8516b
package/README.md CHANGED
@@ -8,7 +8,7 @@ English | [中文](README.zh.md)
8
8
 
9
9
  ## Summary
10
10
 
11
- Use this package to render a browser chat from recorded Session conversations, including historical images, localized actions, and restored scroll position. Work-details modes control reasoning previews and fold eligible completed-turn process rows without hiding final answers. Local transcript and steering submissions appear immediately, remain in their original surface, and disappear atomically when authoritative Session records arrive, while queued submissions stay outside Chat. The package does not assemble or modify model requests.
11
+ Use this package to render a browser chat from recorded Session conversations, including historical images, localized actions, and restored scroll position. Work-details modes control reasoning previews and process visibility without hiding final answers; Verbose keeps completed-turn process rows visible. Local transcript and steering submissions appear immediately, remain in their original surface, and disappear atomically when authoritative Session records arrive, while queued submissions stay outside Chat. The package does not assemble or modify model requests.
12
12
 
13
13
  File-mention providers receive the viewed Session ID with the closing-turn owner, so links into inherited history can address the fork itself.
14
14
 
@@ -33,6 +33,8 @@ File-mention providers receive the viewed Session ID with the closing-turn owner
33
33
 
34
34
  Chat supplies file and HTTP(S) navigation through one `MarkdownDelegateProvider` around its node list. Assistant Markdown file links open in the right Sidebar after the message settles, including references to unmodified files. Relative paths resolve in the viewed Session's workspace; absolute paths retain the same Session's filesystem access. `#L24` and `#L24-L30` navigate to the first specified line and reuse an existing file tab. Missing files show the preview's error state.
35
35
 
36
+ Standalone Markdown images show contained previews and open the shared image lightbox; local paths resolve against the viewed workspace after settlement. Image file links keep their sidebar activation and show a thumbnail after hover dwell or keyboard focus. Escape dismisses the thumbnail. Failed images retain a localized status and their description; no duplicate-image filtering is applied.
37
+
36
38
  Settings → General → Open chat links in selects the destination for ordinary clicks on Chat HTTP(S) links: In-App Sidebar (default) opens a new right-Sidebar Browser tab, while Default Browser opens an external tab. The setting is shown only while the Sidebar Browser is available. If the Sidebar Browser is not registered, both choices use the external browser; modified clicks retain native behavior. The `ui-chat.linkOpening` preference persists on loopback browsers and stays process-local when settings cannot persist writes. Sent file references and skills confirmed by the message’s logged invocation also open in the right Sidebar. File paths use the viewed Session; skill names resolve through its current input-trigger source. Both use the prose file-link dotted underline on hover or focus. Sessions, directories, and command labels remain non-navigating references.
37
39
 
38
40
  <a id="system-prompt-row"></a>
@@ -76,7 +78,7 @@ During uninterrupted following, local transcript and steering echoes remain moun
76
78
 
77
79
  When Chat ends with an open Turn control and that Turn has no visible input, the first local transcript echo precedes the control. Other echoes remain at the flow tail. The control and echoes share one keyed list, so arrival of the control preserves the echo's mounted identity. Durable inputs replace their matching echoes in the same render.
78
80
 
79
- Work-details modes control process-group display and reasoning previews; eligible completed Turns fold their process without hiding the final answer. The [business-rule reference](src/client/conversation-nodes/README.md#display-modes) contains the mode table, title behavior, whole-Turn eligibility, clocks, and disclosure resets.
81
+ Work-details modes control process-group display and reasoning previews. Compact, Standard, and Detailed fold eligible completed Turns without hiding the final answer; Verbose retains the duration/status header without a collapse action and shows historical process rows directly. The [business-rule reference](src/client/conversation-nodes/README.md#display-modes) contains the mode table, title behavior, whole-Turn eligibility, clocks, and disclosure resets.
80
82
 
81
83
  -----
82
84
 
@@ -85,7 +87,9 @@ Work-details modes control process-group display and reasoning previews; eligibl
85
87
 
86
88
  Chat registers its process Group Definition through `uiConversation.groups`. React renders the mixed `node`/`group` root sequence through stable Group and Node seats; group headers subscribe to data separately from member arrays. Settled group titles remain independent of the live-detail preference; only running titles update when that preference changes. [Process-group business rules](src/client/conversation-nodes/README.md#process-grouping) define segmentation and activity summaries.
87
89
 
88
- `groupPart` selects reasoning or response in the Assistant renderer without copying Node payloads. Each part has a distinct DOM anchor for reading-position restoration; Turn navigation addresses the original Node key and lands on its first visible part. Group sources, member parents, and keys survive display-mode changes and newly loaded prefixes that extend an intact group. The source Node Store remains the only Node-data owner, and a replaced Builder rebinds keyed subscriptions without remounting seats. Mode changes retain size observers and reuse the Turn-state selector.
90
+ `groupPart` selects reasoning or response in the Assistant renderer without copying Node payloads. A Tool node owns its preparing, dispatched, and result stages under one callId. Each part has a distinct DOM anchor for reading-position restoration; Turn navigation addresses the original Node key and lands on its first visible part. Group sources, member parents, and keys survive display-mode changes and newly loaded prefixes that extend an intact group. The source Node Store remains the only Node-data owner, and a replaced Builder rebinds keyed subscriptions without remounting seats. Mode changes retain size observers and reuse the Turn-state selector.
91
+
92
+ Live tool deltas share reasoning's frame-batched publication; durable calls and results publish immediately. Repeated named deltas retain the Tool node and its data when the projected call, anchor, location, and visibility are unchanged.
89
93
 
90
94
  The process group uses a stable `div` layout box, a scroll body, and an uncapped content box that reports growth inside the body. Business styles must adapt spacing within and across groups, including hidden or empty members and the answer-spacing exception. CSS variables do not belong in the Group Definition.
91
95
 
package/README.zh.md CHANGED
@@ -8,7 +8,7 @@ kind: "package-reference"
8
8
 
9
9
  ## 概述
10
10
 
11
- 使用本包可在浏览器中渲染已记录的 Session 对话,包括历史图片、本地化操作和滚动位置恢复。工作过程展示模式控制思考预览,并收起符合条件的已完成轮次过程行,不隐藏最终答案。本地 transcript(文本记录)与 steering(中途引导)提交会立即显示并保留在原区域,在权威会话记录到达时原子地消失,而排队中的提交始终不进入 Chat。本包不组装或修改模型请求。
11
+ 使用本包可在浏览器中渲染已记录的 Session 对话,包括历史图片、本地化操作和滚动位置恢复。工作步骤展示模式控制思考预览与过程显隐,不隐藏最终答案;完全展开模式保持已完成轮次的过程行可见。本地 transcript(文本记录)与 steering(中途引导)提交会立即显示并保留在原区域,在权威会话记录到达时原子地消失,而排队中的提交始终不进入 Chat。本包不组装或修改模型请求。
12
12
 
13
13
  文件提及提供方同时接收当前查看的会话 ID 与收尾轮次的属主信息,因此继承历史中的链接可以指向 fork 自身。
14
14
 
@@ -33,12 +33,14 @@ kind: "package-reference"
33
33
 
34
34
  Chat 在节点列表外通过一个 `MarkdownDelegateProvider` 提供文件及 HTTP(S) 导航。Assistant Markdown 文件链接在消息落定后可于右侧栏打开,包括未修改文件的引用。相对路径基于当前查看的 Session 工作区解析;绝对路径仍使用同一 Session 的文件系统访问。`#L24` 和 `#L24-L30` 定位到指定起始行,并复用现有文件标签。文件缺失时显示预览错误状态。
35
35
 
36
+ 独立的 Markdown 图片以内嵌预览显示,点击打开共享图片浮层;本地路径在消息落定后基于当前查看的工作区解析。图片文件链接保持点击打开侧栏,鼠标停留或键盘聚焦时显示缩略图,Esc 关闭缩略图。图片加载失败时保留本地化状态与图片说明;不执行重复图片过滤。
37
+
36
38
  设置 → 通用设置 → 网页链接默认打开方式控制普通点击 Chat HTTP(S) 链接时的目标:「应用内侧边栏」(默认)打开新的右侧 Sidebar Browser tab,「默认浏览器」打开外部标签页。该设置项仅在 Sidebar Browser 可用时显示。若 Sidebar Browser 未注册,两种选择均使用外部浏览器;带修饰键的点击保留原生行为。`ui-chat.linkOpening` 偏好在回环地址浏览器中持久化,设置无法持久化写入时仅在当前进程内生效。已发送的文件引用及消息日志确认调用的 skill 也可在右侧栏打开预览。文件路径使用当前查看的 Session;skill 名称由该 Session 当前的输入触发源解析。两者悬停或聚焦时均使用正文文件链接的虚线下划线。会话、目录和命令标签仍只作为引用展示。
37
39
 
38
40
  <a id="system-prompt-row"></a>
39
41
  ## Chat 隐藏的行
40
42
 
41
- Chat 在所有工作过程展示模式下都不显示系统提示词行、普通上下文注入和 `permission` 命令行。该过滤不改变已记录的 Session 事件或 Trajectory 查看能力。非人工轮次触发仍作为独立通知显示,其他命令行仍保留在 Chat 中。
43
+ Chat 在所有工作步骤展示模式下都不显示系统提示词行、普通上下文注入和 `permission` 命令行。该过滤不改变已记录的 Session 事件或 Trajectory 查看能力。非人工轮次触发仍作为独立通知显示,其他命令行仍保留在 Chat 中。
42
44
 
43
45
  Assistant 尝试结束且没有可见消息时,Chat 隐藏已发布的 Node,不移除其 key。同一 Step 的重试再次产生可见内容时,复用该 key。已加载窗口缺少 Step 起点时也遵循此规则。
44
46
 
@@ -76,7 +78,7 @@ Assistant 尝试结束且没有可见消息时,Chat 隐藏已发布的 Node,
76
78
 
77
79
  Chat 末尾为进行中的 Turn 控制行,且该轮尚无可见输入时,第一条本地 transcript 回显显示在控制行前。其他回显保留在正文末尾。控制行与回显共用一个 keyed 列表,因此控制行到达时不会重新挂载回显。持久输入在同一次渲染中替换匹配的回显。
78
80
 
79
- 工作过程展示模式控制过程组显示与推理预览;符合条件的已完成轮次折叠过程,但不隐藏最终答案。[业务规则明细](src/client/conversation-nodes/README.zh.md#display-modes) 统一说明模式表、组头行为、整轮折叠资格、时钟与开合重置。
81
+ 工作步骤展示模式控制过程组显示与推理预览。简洁、标准、详细模式收起符合条件的已完成轮次,不隐藏最终答案;完全展开模式保留时长或状态抬头,但不支持收起,历史过程行直接显示。[业务规则明细](src/client/conversation-nodes/README.zh.md#display-modes) 统一说明模式表、组头行为、整轮折叠资格、时钟与开合重置。
80
82
 
81
83
  -----
82
84
 
@@ -85,7 +87,9 @@ Chat 末尾为进行中的 Turn 控制行,且该轮尚无可见输入时,第
85
87
 
86
88
  Chat 通过 `uiConversation.groups` 注册过程 Group Definition。React 通过稳定的 Group 与 Node 容器渲染混合 `node`/`group` 根序列,组头数据与成员数组分别订阅。已结束组的标题独立于实时详情偏好,只有运行中的标题在该偏好变化时更新。[过程分组业务规则](src/client/conversation-nodes/README.zh.md#process-grouping) 定义切分方式与活动摘要。
87
89
 
88
- `groupPart` 在 Assistant 渲染器中选择推理或回复,不复制 Node 载荷。每个部分有独立的 DOM 锚点用于恢复阅读位置;轮次导航使用原 Node key,落到它的第一个可见部分。展示模式切换以及为完整旧组补入更早成员时,保留组来源、成员父级及 key。原 Node Store 仍是唯一节点数据所有者,替换 Builder 时重新绑定按键订阅,不重挂载容器。模式变化保留尺寸观察器,并复用整轮状态选择器。
90
+ `groupPart` 在 Assistant 渲染器中选择推理或回复,不复制 Node 载荷。同一个 callId 的准备、派发与结果阶段由 Tool 节点自己拥有。每个部分有独立的 DOM 锚点用于恢复阅读位置;轮次导航使用原 Node key,落到它的第一个可见部分。展示模式切换以及为完整旧组补入更早成员时,保留组来源、成员父级及 key。原 Node Store 仍是唯一节点数据所有者,替换 Builder 时重新绑定按键订阅,不重挂载容器。模式变化保留尺寸观察器,并复用整轮状态选择器。
91
+
92
+ 实时工具 delta 与推理共用按帧合并的发布节奏;持久调用和结果立即发布。重复具名 delta 在投影调用、锚点、位置及可见性均未变化时保留 Tool 节点及其数据引用。
89
93
 
90
94
  过程组使用稳定的 `div` 布局盒子、滚动正文及不限高的内容盒子,后者报告正文内部的内容增长。业务样式必须适配组内及组边界间距,处理隐藏或空成员以及回答前的间距特例。CSS 变量不属于 Group Definition。
91
95
 
package/lib/client.js CHANGED
@@ -76,6 +76,18 @@ window.__ModuleLoader__.load({
76
76
  return path.startsWith("/") || isWindowsStylePath(path);
77
77
  }
78
78
  /**
79
+ * Resolve a Workspace-relative path into the Host-facing spelling used by path operations.
80
+ * @param cwd - Session Workspace root, when known.
81
+ * @param path - Absolute or Workspace-relative path.
82
+ * @returns an absolute path when a Workspace root is available, otherwise the original path.
83
+ */
84
+ function resolveWorkspacePath(cwd, path) {
85
+ if (isAbsoluteWorkspacePath(path)) return path;
86
+ if (cwd === void 0 || cwd === "") return path;
87
+ const separator = isWindowsStylePath(cwd) && cwd.includes("\\") ? "\\" : "/";
88
+ return `${cwd.replace(/[/\\]+$/, "")}${separator}${path.replace(/^[/\\]+/, "")}`;
89
+ }
90
+ /**
79
91
  * The address for a path as a caller holds it: a relative path, or an absolute
80
92
  * path inside the Session's workspace, becomes a `session`-scoped address; an
81
93
  * absolute path outside it, or one whose workspace root is unknown, keeps its
@@ -93,6 +105,16 @@ window.__ModuleLoader__.load({
93
105
  if (root !== "" && normalized.startsWith(`${root}/`)) return sessionFileAddress(sessionId, normalized.slice(root.length + 1));
94
106
  return sessionFileAddress(sessionId, normalized);
95
107
  }
108
+ /**
109
+ * Address a decoded absolute file path through the authenticated file route.
110
+ * @param base - HTTP(S) application base, including its deployment prefix.
111
+ * @param path - Native file path; URL escapes in authored Markdown must already be decoded.
112
+ * @returns File URL, or undefined for unsupported transports and non-absolute paths.
113
+ */
114
+ function fileMediaUrl(base, path) {
115
+ if (!/^https?:/u.test(base) || !isAbsoluteWorkspacePath(path) || /^[/\\]{2}/u.test(path) || /[\u0000-\u001f\u007f]/u.test(path)) return void 0;
116
+ return new URL(`api/file?path=${encodeURIComponent(path)}`, base).href;
117
+ }
96
118
  //#endregion
97
119
  //#region lib/types/client/contract/snapshot.js
98
120
  const EMPTY_LIST$1 = [];
@@ -161,7 +183,7 @@ window.__ModuleLoader__.load({
161
183
  return useChat((snapshot) => {
162
184
  for (const node of snapshot.nodes.values()) {
163
185
  const root = node.kind === "tool-call" ? node.data.root : void 0;
164
- if (root !== void 0 && root.callId === callId && !("kind" in root)) return commandOf(root);
186
+ if (root !== void 0 && root.callId === callId && !("kind" in root) && root.phase === "start") return commandOf(root);
165
187
  }
166
188
  }) ?? null;
167
189
  }
@@ -1661,7 +1683,7 @@ window.__ModuleLoader__.load({
1661
1683
  processPresentation?.hasExternalProcess,
1662
1684
  setOpen
1663
1685
  ]);
1664
- const controllerInactive = routedNode?.kind === "turn-process" && !foldable;
1686
+ const controllerInactive = routedNode?.kind === "turn-process" && foldCompleted && !foldable;
1665
1687
  const compactAnswer = processAnswer && foldable && processPresentation.compactAnswer && !processOpen;
1666
1688
  const processHidden = controllerInactive || foldable && processMember && !processOpen;
1667
1689
  const wrapperRef = useSearchableHidden(processHidden, (0, react.useCallback)(() => {
@@ -2143,8 +2165,10 @@ window.__ModuleLoader__.load({
2143
2165
  const PROCESS_ICONS = {
2144
2166
  thinking: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconThinkOutlineRegular, {}),
2145
2167
  read: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconBrowseOutlineRegular, { size: 14 }),
2168
+ readImage: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconBrowseOutlineRegular, { size: 14 }),
2146
2169
  search: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSearchOutlineRegular, { size: 14 }),
2147
2170
  edit: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconEditOutlineRegular, { size: 14 }),
2171
+ write: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconEditOutlineRegular, { size: 14 }),
2148
2172
  commands: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconApiOutlineRegular, {}),
2149
2173
  code: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCodeOutlineRegular, { size: 14 }),
2150
2174
  webSearch: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconGlobeOutlineRegular, {}),
@@ -2155,7 +2179,7 @@ window.__ModuleLoader__.load({
2155
2179
  tools: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSparkleRegular, { size: 14 })
2156
2180
  };
2157
2181
  function sameLiveProcessTitle(left, right) {
2158
- return left.activity === right.activity && left.detail === right.detail;
2182
+ return left.activity === right.activity && left.detail === right.detail && left.preparing === right.preparing;
2159
2183
  }
2160
2184
  function useStableLiveProcessTitle(desired, active) {
2161
2185
  const [displayed, setDisplayed] = (0, react.useState)(desired);
@@ -2183,7 +2207,8 @@ window.__ModuleLoader__.load({
2183
2207
  }, [
2184
2208
  active,
2185
2209
  desired.activity,
2186
- desired.detail
2210
+ desired.detail,
2211
+ desired.preparing
2187
2212
  ]);
2188
2213
  return active ? displayed : desired;
2189
2214
  }
@@ -2200,10 +2225,11 @@ window.__ModuleLoader__.load({
2200
2225
  const detailed = usePresentation((policy) => data?.closed === false && policy.liveProcessDetail);
2201
2226
  const live = useStableLiveProcessTitle({
2202
2227
  activity: data?.summary.running ?? "thinking",
2203
- detail: data?.summary.runningDetail ?? ""
2228
+ detail: data?.summary.runningDetail ?? "",
2229
+ preparing: data?.summary.preparing === true
2204
2230
  }, data !== void 0 && !data.closed);
2205
2231
  if (data === void 0) return null;
2206
- const label = data.closed ? processTitle(data.summary, t) : t(`message.stepProcess.${live.activity}`);
2232
+ const label = data.closed ? processTitle(data.summary, t) : live.preparing ? t(`message.stepProcess.prepare.${live.activity === "thinking" ? "tools" : live.activity}`) : t(`message.stepProcess.${live.activity}`);
2207
2233
  const detail = detailed && !data.closed ? live.detail : "";
2208
2234
  const title = detail === "" ? label : `${label}${t("message.turnProcess.separator")}${detail}`;
2209
2235
  const activity = data.closed ? data.summary.counts[0]?.kind ?? "thinking" : live.activity;
@@ -2249,7 +2275,7 @@ window.__ModuleLoader__.load({
2249
2275
  const location = node?.location;
2250
2276
  return location?.kind === "turn" || location?.kind === "step" ? location.turn : void 0;
2251
2277
  });
2252
- const grouped = props.usePresentation((policy) => turnLocation?.status !== "open" || policy.stepGrouping !== "none");
2278
+ const grouped = props.usePresentation((policy) => policy.stepGrouping === "collapsed" || policy.stepGrouping === "history" && turnLocation?.status !== "open");
2253
2279
  const reason = turnLocation?.end?.data.reason.kind;
2254
2280
  const alwaysOpen = presentation?.turnClosed === false || presentation?.hasInterleavedInput === true || reason === "aborted" || reason === "error";
2255
2281
  const spec = presentation?.spec;
@@ -5006,6 +5032,16 @@ window.__ModuleLoader__.load({
5006
5032
  const railItems = (0, react.useMemo)(() => mergeTurnRailItems(turnNavigationItems, turnOutline), [turnNavigationItems, turnOutline]);
5007
5033
  const inbox = useProjection("inbox");
5008
5034
  const cwd = useSessions((s) => s.byId[sessionId]?.cwd);
5035
+ const fileImages = (0, react.useMemo)(() => ({
5036
+ resolve: (path) => fileMediaUrl(document.baseURI, resolveWorkspacePath(cwd, path)),
5037
+ labels: {
5038
+ open: t("image.open"),
5039
+ loading: t("image.loading"),
5040
+ failed: t("image.failed"),
5041
+ dialog: t("image.dialog"),
5042
+ close: t("image.close")
5043
+ }
5044
+ }), [cwd, t]);
5009
5045
  const running = useSession((s) => s.running);
5010
5046
  const openState = useSession((s) => s.openState);
5011
5047
  const openError = useSession((s) => s.openError);
@@ -5131,6 +5167,7 @@ window.__ModuleLoader__.load({
5131
5167
  (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.MarkdownDelegateProvider, {
5132
5168
  openExternalLink,
5133
5169
  openFile: requestOpenFile,
5170
+ fileImages,
5134
5171
  children: (0, react_jsx_runtime.jsx)(ChatNodeList, {
5135
5172
  entries,
5136
5173
  pendingInputs,
@@ -5211,25 +5248,42 @@ window.__ModuleLoader__.load({
5211
5248
  const zh = {
5212
5249
  "message.stepProcess.thinking": "正在分析请求",
5213
5250
  "message.stepProcess.read": "正在读取文件",
5251
+ "message.stepProcess.readImage": "正在读取图片",
5252
+ "message.stepProcess.write": "正在写入文件",
5214
5253
  "message.stepProcess.search": "正在搜索代码",
5215
5254
  "message.stepProcess.edit": "正在编辑文件",
5216
5255
  "message.stepProcess.commands": "正在运行命令",
5217
5256
  "message.stepProcess.code": "正在运行代码",
5218
5257
  "message.stepProcess.webSearch": "正在搜索网页",
5219
5258
  "message.stepProcess.webFetch": "正在访问网页",
5220
- "message.stepProcess.subagents": "正在协调子任务",
5259
+ "message.stepProcess.subagents": "正在协调子智能体",
5221
5260
  "message.stepProcess.plan": "正在更新计划",
5222
5261
  "message.stepProcess.questions": "等待你的操作",
5223
5262
  "message.stepProcess.tools": "正在调用工具",
5263
+ "message.stepProcess.prepare.read": "准备读取文件",
5264
+ "message.stepProcess.prepare.readImage": "准备读取图片",
5265
+ "message.stepProcess.prepare.write": "准备写入文件",
5266
+ "message.stepProcess.prepare.search": "准备搜索代码",
5267
+ "message.stepProcess.prepare.edit": "准备编辑文件",
5268
+ "message.stepProcess.prepare.commands": "准备运行命令",
5269
+ "message.stepProcess.prepare.code": "准备运行代码",
5270
+ "message.stepProcess.prepare.webSearch": "准备搜索网页",
5271
+ "message.stepProcess.prepare.webFetch": "准备访问网页",
5272
+ "message.stepProcess.prepare.subagents": "准备协调子智能体",
5273
+ "message.stepProcess.prepare.plan": "准备更新计划",
5274
+ "message.stepProcess.prepare.questions": "准备提问",
5275
+ "message.stepProcess.prepare.tools": "准备调用工具",
5224
5276
  "message.stepProcess.done.thinking": "已完成分析",
5225
5277
  "message.stepProcess.done.read": "已读取文件",
5278
+ "message.stepProcess.done.readImage": "已读取图片",
5279
+ "message.stepProcess.done.write": "已写入文件",
5226
5280
  "message.stepProcess.done.search": "已搜索代码",
5227
5281
  "message.stepProcess.done.edit": "修改了文件",
5228
5282
  "message.stepProcess.done.commands": "执行了命令",
5229
5283
  "message.stepProcess.done.code": "运行了代码",
5230
5284
  "message.stepProcess.done.webSearch": "已搜索网页",
5231
5285
  "message.stepProcess.done.webFetch": "已访问网页",
5232
- "message.stepProcess.done.subagents": "已协调子任务",
5286
+ "message.stepProcess.done.subagents": "已协调子智能体",
5233
5287
  "message.stepProcess.done.plan": "更新了计划",
5234
5288
  "message.stepProcess.done.questions": "向用户提出了问题",
5235
5289
  "message.stepProcess.done.tools": "已调用工具",
@@ -5253,6 +5307,11 @@ window.__ModuleLoader__.load({
5253
5307
  "message.turnProcess.took": "用时 {duration}",
5254
5308
  "message.turnProcess.failed": "处理失败",
5255
5309
  "view.chat": "对话",
5310
+ "image.open": "查看大图",
5311
+ "image.loading": "加载图片…",
5312
+ "image.failed": "图片无法预览",
5313
+ "image.dialog": "图片预览",
5314
+ "image.close": "关闭图片预览",
5256
5315
  "number.groupSeparator": ",",
5257
5316
  "duration.compactSeconds": "{seconds}秒",
5258
5317
  "duration.compactMinutes": "{minutes}分{seconds}秒",
@@ -5282,11 +5341,12 @@ window.__ModuleLoader__.load({
5282
5341
  "settings.links.description": "对话中网页链接的打开位置",
5283
5342
  "settings.links.sidebar": "应用内侧边栏",
5284
5343
  "settings.links.newTab": "默认浏览器",
5285
- "settings.transcript.title": "工作过程展示",
5286
- "settings.transcript.description": "控制轮次和步骤的默认展开方式",
5344
+ "settings.transcript.title": "工作步骤展示",
5345
+ "settings.transcript.description": "选择希望看到多少工具调用细节",
5287
5346
  "settings.transcript.compact": "简洁",
5347
+ "settings.transcript.standard": "标准",
5288
5348
  "settings.transcript.detailed": "详细",
5289
- "settings.transcript.expanded": "完全展开",
5349
+ "settings.transcript.verbose": "完全展开",
5290
5350
  "fileOpen.title": "无法打开文件",
5291
5351
  "fileOpen.unknown": "无法打开此文件",
5292
5352
  "message.extraBlock": "附加内容块",
@@ -5365,6 +5425,8 @@ window.__ModuleLoader__.load({
5365
5425
  const en = {
5366
5426
  "message.stepProcess.thinking": "Analyzing the request",
5367
5427
  "message.stepProcess.read": "Reading files",
5428
+ "message.stepProcess.readImage": "Reading images",
5429
+ "message.stepProcess.write": "Writing files",
5368
5430
  "message.stepProcess.search": "Searching code",
5369
5431
  "message.stepProcess.edit": "Editing files",
5370
5432
  "message.stepProcess.commands": "Running commands",
@@ -5375,8 +5437,23 @@ window.__ModuleLoader__.load({
5375
5437
  "message.stepProcess.plan": "Updating the plan",
5376
5438
  "message.stepProcess.questions": "Waiting for your action",
5377
5439
  "message.stepProcess.tools": "Calling tools",
5440
+ "message.stepProcess.prepare.read": "Preparing to read files",
5441
+ "message.stepProcess.prepare.readImage": "Preparing to read images",
5442
+ "message.stepProcess.prepare.write": "Preparing to write files",
5443
+ "message.stepProcess.prepare.search": "Preparing to search code",
5444
+ "message.stepProcess.prepare.edit": "Preparing to edit files",
5445
+ "message.stepProcess.prepare.commands": "Preparing to run commands",
5446
+ "message.stepProcess.prepare.code": "Preparing to run code",
5447
+ "message.stepProcess.prepare.webSearch": "Preparing to search the web",
5448
+ "message.stepProcess.prepare.webFetch": "Preparing to visit web pages",
5449
+ "message.stepProcess.prepare.subagents": "Preparing to coordinate subagents",
5450
+ "message.stepProcess.prepare.plan": "Preparing to update the plan",
5451
+ "message.stepProcess.prepare.questions": "Preparing questions",
5452
+ "message.stepProcess.prepare.tools": "Preparing tool calls",
5378
5453
  "message.stepProcess.done.thinking": "Analysis completed",
5379
5454
  "message.stepProcess.done.read": "Read files",
5455
+ "message.stepProcess.done.readImage": "Read images",
5456
+ "message.stepProcess.done.write": "Wrote files",
5380
5457
  "message.stepProcess.done.search": "Searched code",
5381
5458
  "message.stepProcess.done.edit": "Edited files",
5382
5459
  "message.stepProcess.done.commands": "Ran commands",
@@ -5407,6 +5484,11 @@ window.__ModuleLoader__.load({
5407
5484
  "message.turnProcess.took": "Took {duration}",
5408
5485
  "message.turnProcess.failed": "Failed",
5409
5486
  "view.chat": "Chat",
5487
+ "image.open": "View full image",
5488
+ "image.loading": "Loading image…",
5489
+ "image.failed": "Image preview unavailable",
5490
+ "image.dialog": "Image preview",
5491
+ "image.close": "Close image preview",
5410
5492
  "number.groupSeparator": ",",
5411
5493
  "duration.compactSeconds": "{seconds}s",
5412
5494
  "duration.compactMinutes": "{minutes}m{seconds}s",
@@ -5437,10 +5519,11 @@ window.__ModuleLoader__.load({
5437
5519
  "settings.links.sidebar": "In-App Sidebar",
5438
5520
  "settings.links.newTab": "Default Browser",
5439
5521
  "settings.transcript.title": "Work details",
5440
- "settings.transcript.description": "Controls how turns and steps expand by default",
5522
+ "settings.transcript.description": "Choose how much detail to show for tool calls",
5441
5523
  "settings.transcript.compact": "Compact",
5524
+ "settings.transcript.standard": "Standard",
5442
5525
  "settings.transcript.detailed": "Detailed",
5443
- "settings.transcript.expanded": "Expanded",
5526
+ "settings.transcript.verbose": "Verbose",
5444
5527
  "fileOpen.title": "Couldn’t open file",
5445
5528
  "fileOpen.unknown": "Couldn’t open this file",
5446
5529
  "message.extraBlock": "Extra content block",
@@ -5663,16 +5746,23 @@ window.__ModuleLoader__.load({
5663
5746
  //#endregion
5664
5747
  //#region lib/types/client/chat/AssistantMarkdown.js
5665
5748
  /**
5666
- * Resolve an authored POSIX image path against the document's file API.
5749
+ * Standalone fallback for image destinations (query/fragment suffixes are ignored).
5750
+ * Chat fileImages resolves decoded file references against cwd; pathImages also
5751
+ * serves this component outside that provider and accepts legacy image URL suffixes.
5752
+ * Resolve an authored absolute image path against the document's file API.
5667
5753
  * @param base - canonical `document.baseURI` at render time.
5668
- * @param value - authored markdown destination.
5754
+ * @param value - authored Markdown destination; URL escapes are decoded once.
5669
5755
  * @returns an absolute HTTP(S) file-API URL, or undefined for unsupported
5670
5756
  * protocols and non-local paths.
5671
5757
  */
5672
5758
  function localPathMediaUrl(base, value) {
5673
- if (!value.startsWith("/") || value.startsWith("//")) return void 0;
5674
- if (!base.startsWith("http:") && !base.startsWith("https:")) return void 0;
5675
- return new URL(`api/file?path=${encodeURIComponent(value)}`, base).href;
5759
+ let path;
5760
+ try {
5761
+ path = decodeURIComponent(value.split(/[?#]/u)[0] ?? "");
5762
+ } catch {
5763
+ return;
5764
+ }
5765
+ return fileMediaUrl(base, path);
5676
5766
  }
5677
5767
  /** Reasoning block as the Think variant summary row (figma 39:28304). */
5678
5768
  const AssistantMarkdown = (0, react.memo)(function AssistantMarkdown({ blocks, streaming, interrupted, renderMessageImages, groupPart, useDisclosure, reasoningHidden = false, usePresentation, revealProcess, mentions, t }) {
@@ -6011,10 +6101,10 @@ window.__ModuleLoader__.load({
6011
6101
  /** Turn-level process disclosure controller. */
6012
6102
  const TurnProcessNodeView = (0, react.memo)(function TurnProcessNodeView({ node, turnProcess, t }) {
6013
6103
  if (turnProcess === void 0) throw new Error("turn-process node requires Turn process owner state");
6014
- const open = turnProcess.open;
6104
+ const open = !turnProcess.foldable || turnProcess.open;
6015
6105
  const turn = node.location.kind === "turn" || node.location.kind === "step" ? node.location.turn : void 0;
6016
6106
  const [now, setNow] = (0, react.useState)(Date.now);
6017
- const ticking = turnProcess.foldable && turn?.status === "open";
6107
+ const ticking = turn?.status === "open" && turn.start !== void 0;
6018
6108
  (0, react.useEffect)(() => {
6019
6109
  if (!ticking) return;
6020
6110
  setNow(Date.now());
@@ -6025,11 +6115,11 @@ window.__ModuleLoader__.load({
6025
6115
  clearInterval(timer);
6026
6116
  };
6027
6117
  }, [ticking]);
6028
- if (!turnProcess.foldable) return null;
6029
- const canCollapse = turnProcess.hasContent && !turnProcessAlwaysOpen(node);
6030
- const running = turn?.status === "open";
6031
- const reason = turn?.end?.data.reason.kind;
6032
- const elapsedMs = turn?.start === void 0 ? void 0 : Math.max(1e3, (turn.end?.time ?? now) - turn.start.time);
6118
+ if (turn?.start === void 0 && turn?.status !== "closed") return null;
6119
+ const canCollapse = turnProcess.foldable && turnProcess.hasContent && !turnProcessAlwaysOpen(node);
6120
+ const running = turn.status === "open";
6121
+ const reason = turn.end?.data.reason.kind;
6122
+ const elapsedMs = turn.start === void 0 ? void 0 : Math.max(1e3, (turn.end?.time ?? now) - turn.start.time);
6033
6123
  const duration = elapsedMs === void 0 ? void 0 : running ? formatLiveRunDuration(elapsedMs, t) : formatRunDuration(elapsedMs, t);
6034
6124
  const label = running ? duration === void 0 ? t("chat.deepDiving") : t("message.turnProcess.deepDivingFor", { duration }) : reason === "aborted" ? t("message.stopped") : reason === "error" ? t("message.turnProcess.failed") : duration === void 0 ? t("message.turnProcess.worked") : t("message.turnProcess.took", { duration });
6035
6125
  const announcement = running ? t("chat.deepDiving") : reason === "aborted" ? t("message.stopped") : reason === "error" ? t("message.turnProcess.failed") : t("message.turnProcess.worked");
@@ -7397,7 +7487,7 @@ window.__ModuleLoader__.load({
7397
7487
  const blocks = settled?.blocks ?? compactBlocks(state.blocks);
7398
7488
  const visible = settled === void 0 ? state.visibleBlocks > 0 : hasVisibleContent(blocks);
7399
7489
  const status = settled?.interrupted === true ? "interrupted" : settled === void 0 ? "running" : "settled";
7400
- const anchorSeq = settled?.seq ?? state.firstVisibleSeq ?? context.matches[0]?.event.seq ?? 0;
7490
+ const anchorSeq = (settled?.interrupted === true ? settled.seq : state.firstVisibleSeq ?? settled?.seq) ?? context.matches[0]?.event.seq ?? 0;
7401
7491
  const time = settled?.time ?? state.firstVisibleTime ?? context.matches[0]?.event.time ?? 0;
7402
7492
  return {
7403
7493
  anchorSeq,
@@ -7476,7 +7566,7 @@ window.__ModuleLoader__.load({
7476
7566
  const settled = data.finalNode;
7477
7567
  const visible = settled === void 0 ? state.visibleBlocks > 0 : hasVisibleContent(data.blocks);
7478
7568
  if (settled === void 0 && !visible && current == null) return null;
7479
- return chatNode(context, "assistant-step", settled?.seq ?? state.firstVisibleSeq ?? context.matches[0]?.event.seq ?? 0, data, { visibility: settled?.interrupted === true || visible ? "visible" : "hidden" });
7569
+ return chatNode(context, "assistant-step", (settled?.interrupted === true ? settled.seq : state.firstVisibleSeq ?? settled?.seq) ?? context.matches[0]?.event.seq ?? 0, data, { visibility: settled?.interrupted === true || visible ? "visible" : "hidden" });
7480
7570
  }
7481
7571
  };
7482
7572
  /**
@@ -9137,6 +9227,7 @@ window.__ModuleLoader__.load({
9137
9227
  role: "start"
9138
9228
  } : null,
9139
9229
  start: (_context, match, reader) => {
9230
+ if (match.event.type === "assistant/live-chunk") throw new Error("system-message requires a durable event");
9140
9231
  return inspect(reader.previous("system-message")?.state, match.event);
9141
9232
  },
9142
9233
  update: (context) => context.state,
@@ -9301,8 +9392,23 @@ window.__ModuleLoader__.load({
9301
9392
  return JSON.stringify(value);
9302
9393
  }
9303
9394
  function rootCall(match) {
9395
+ const event = match.event;
9396
+ if (event.type === "assistant/live-chunk") {
9397
+ const chunk = event.data.chunk;
9398
+ if (chunk.type !== "tool-call-delta" || !chunk.name) throw new Error("tool preparation requires a named call delta");
9399
+ return {
9400
+ phase: "preparing",
9401
+ callId: String(chunk.id),
9402
+ name: chunk.name,
9403
+ turn: event.data.turn,
9404
+ step: event.data.step,
9405
+ time: event.time,
9406
+ subCalls: []
9407
+ };
9408
+ }
9304
9409
  if (match.event.type !== "tool/call") throw new Error("tool-call start requires tool/call");
9305
9410
  return {
9411
+ phase: "start",
9306
9412
  callId: String(match.event.data.callId),
9307
9413
  name: match.event.data.name,
9308
9414
  argsRaw: match.event.data.arguments,
@@ -9334,6 +9440,7 @@ window.__ModuleLoader__.load({
9334
9440
  }
9335
9441
  function childCall(match, data) {
9336
9442
  return {
9443
+ phase: "start",
9337
9444
  callId: data.subCallId,
9338
9445
  parentCallId: data.parentCallId,
9339
9446
  name: data.name,
@@ -9429,6 +9536,7 @@ window.__ModuleLoader__.load({
9429
9536
  };
9430
9537
  }
9431
9538
  function projectBlock(block, state, interruptedAt, visited = /* @__PURE__ */ new Set(), depth = 1) {
9539
+ if (!("kind" in block) && block.phase === "preparing") return block;
9432
9540
  if (visited.has(block.callId) || depth > MAX_DEPTH) return {
9433
9541
  ...block,
9434
9542
  subCalls: []
@@ -9490,11 +9598,18 @@ window.__ModuleLoader__.load({
9490
9598
  for (const candidate of context.matches) state = updateDispatch(state, candidate);
9491
9599
  return state;
9492
9600
  }
9493
- /** Root Tool lifecycle and nested PTC dispatch Definition. */
9601
+ /** Root Tool preparation, dispatch, result, and nested PTC calls. */
9494
9602
  const toolDefinition = {
9495
9603
  kind: "tool-call",
9496
9604
  target: "chat",
9497
9605
  match: (event) => {
9606
+ if (event.type === "assistant/live-chunk") {
9607
+ const chunk = event.data.chunk;
9608
+ return chunk.type === "tool-call-delta" && chunk.name ? {
9609
+ id: String(chunk.id),
9610
+ role: "start"
9611
+ } : null;
9612
+ }
9498
9613
  if (event.type === "tool/call") return {
9499
9614
  id: String(event.data.callId),
9500
9615
  role: "start"
@@ -9518,8 +9633,13 @@ window.__ModuleLoader__.load({
9518
9633
  parents: /* @__PURE__ */ new Map()
9519
9634
  }),
9520
9635
  update: (context, match) => {
9636
+ if (match.event.type === "tool/call") return {
9637
+ ...context.state,
9638
+ root: rootCall(match)
9639
+ };
9521
9640
  if (match.event.type === "tool/result") {
9522
- const result = rootResult(match, "kind" in context.state.root ? void 0 : context.state.root);
9641
+ const root = context.state.root;
9642
+ const result = rootResult(match, !("kind" in root) && root.phase === "start" ? root : void 0);
9523
9643
  return result === void 0 ? context.state : {
9524
9644
  ...context.state,
9525
9645
  root: result
@@ -9527,11 +9647,25 @@ window.__ModuleLoader__.load({
9527
9647
  }
9528
9648
  return updateDispatch(context.state, match);
9529
9649
  },
9650
+ publication: (match) => match.event.type === "assistant/live-chunk" ? "animation-frame" : "immediate",
9530
9651
  buildViewNode: (context) => {
9652
+ const current = context.current.get("chat");
9531
9653
  const state = context.state ?? fallbackState$2(context);
9532
- if (state === void 0) return null;
9533
- const projected = projectBlock(state.root, state, interruption(context));
9534
- return chatNode(context, "tool-call", context.start?.event.seq ?? ("kind" in state.root ? state.root.seq : context.matches[0]?.event.seq ?? 0), { root: projected });
9654
+ if (state === void 0) return current == null ? null : current.visibility === "hidden" ? current : {
9655
+ ...current,
9656
+ visibility: "hidden"
9657
+ };
9658
+ const interruptedAt = interruption(context);
9659
+ const projected = projectBlock(state.root, state, interruptedAt);
9660
+ const anchor = context.start?.event.seq ?? ("kind" in state.root ? state.root.seq : context.matches[0]?.event.seq ?? 0);
9661
+ const visibility = !("kind" in projected) && projected.phase === "preparing" && interruptedAt !== void 0 ? "hidden" : "visible";
9662
+ const location = contextLocation(context);
9663
+ const data = current?.data.root === projected ? current.data : { root: projected };
9664
+ if (current?.data === data && current.anchorSeq === anchor && current.visibility === visibility && current.location === location) return current;
9665
+ return chatNode(context, "tool-call", anchor, data, {
9666
+ visibility,
9667
+ location
9668
+ });
9535
9669
  }
9536
9670
  };
9537
9671
  /**
@@ -10219,19 +10353,11 @@ window.__ModuleLoader__.load({
10219
10353
  //#endregion
10220
10354
  //#region lib/types/client/conversation-nodes/process-activity.js
10221
10355
  function activity(name) {
10222
- if ([
10223
- "read",
10224
- "read_image",
10225
- "list_mcp_resources",
10226
- "list_mcp_resource_templates",
10227
- "read_mcp_resource"
10228
- ].includes(name)) return "read";
10356
+ if (name === "read") return "read";
10357
+ if (name === "read_image") return "readImage";
10229
10358
  if (name === "grep" || name === "glob" || name.endsWith("_inspect")) return "search";
10230
- if ([
10231
- "write",
10232
- "edit",
10233
- "apply_patch"
10234
- ].includes(name)) return "edit";
10359
+ if (name === "write") return "write";
10360
+ if (name === "edit" || name === "apply_patch") return "edit";
10235
10361
  if ([
10236
10362
  "bash",
10237
10363
  "pwsh",
@@ -10333,6 +10459,7 @@ window.__ModuleLoader__.load({
10333
10459
  let running;
10334
10460
  let runningDetail = "";
10335
10461
  let runningTime = -Infinity;
10462
+ let preparing;
10336
10463
  const visit = (tool) => {
10337
10464
  if (seen.has(tool.callId)) return;
10338
10465
  seen.add(tool.callId);
@@ -10341,7 +10468,8 @@ window.__ModuleLoader__.load({
10341
10468
  const kind = activity(call.name);
10342
10469
  if (isRunningTool(tool) && tool.time >= runningTime) {
10343
10470
  running = kind;
10344
- runningDetail = liveToolDetail(tool.name, tool.argsRaw);
10471
+ preparing = tool.phase === "preparing";
10472
+ runningDetail = tool.phase === "preparing" ? kind === "tools" ? tool.name : "" : liveToolDetail(tool.name, tool.argsRaw);
10345
10473
  runningTime = tool.time;
10346
10474
  }
10347
10475
  counts.set(kind, (counts.get(kind) ?? 0) + 1);
@@ -10356,7 +10484,8 @@ window.__ModuleLoader__.load({
10356
10484
  count
10357
10485
  })).sort((a, b) => b.count - a.count),
10358
10486
  running,
10359
- runningDetail
10487
+ runningDetail,
10488
+ ...preparing ? { preparing: true } : {}
10360
10489
  };
10361
10490
  }
10362
10491
  //#endregion
@@ -10382,7 +10511,7 @@ window.__ModuleLoader__.load({
10382
10511
  return node.kind === "assistant-step" && hasAssistantReplyContent(node.data.blocks);
10383
10512
  }
10384
10513
  function sameSummary(left, right) {
10385
- return left.running === right.running && left.runningDetail === right.runningDetail && left.counts.length === right.counts.length && left.counts.every((value, index) => value.kind === right.counts[index]?.kind && value.count === right.counts[index].count);
10514
+ return left.running === right.running && left.runningDetail === right.runningDetail && left.preparing === right.preparing && left.counts.length === right.counts.length && left.counts.every((value, index) => value.kind === right.counts[index]?.kind && value.count === right.counts[index].count);
10386
10515
  }
10387
10516
  function sameMembers(left, right) {
10388
10517
  return left.length === right.length && left.every((value, index) => value.key === right[index]?.key && value.groupPart === right[index].groupPart);
@@ -10427,7 +10556,7 @@ window.__ModuleLoader__.load({
10427
10556
  const previous = this.snapshot.data;
10428
10557
  const activity = unchanged && previous.closed === closed ? previous.summary : processActivity(nodes);
10429
10558
  const summary = closed ? {
10430
- ...activity,
10559
+ counts: activity.counts,
10431
10560
  running: void 0,
10432
10561
  runningDetail: ""
10433
10562
  } : activity;
@@ -11605,18 +11734,25 @@ window.__ModuleLoader__.load({
11605
11734
  /** Work-details presentation modes a user can choose. */
11606
11735
  const TRANSCRIPT_VIEW_MODES = [
11607
11736
  "compact",
11737
+ "standard",
11608
11738
  "detailed",
11609
- "expanded"
11739
+ "verbose"
11610
11740
  ];
11611
11741
  /**
11612
- * Saved value from the two-mode generation of this setting. Read as `detailed`;
11742
+ * Saved value from the two-mode generation of this setting. Read as `standard`;
11613
11743
  * never offered as a choice and never written back.
11614
11744
  */
11615
11745
  const LEGACY_TRANSCRIPT_VIEW_MODE = "normal";
11616
- /** Every value the durable field accepts: current modes plus the legacy saved value. */
11617
- const TRANSCRIPT_VIEW_SETTING_VALUES = [...TRANSCRIPT_VIEW_MODES, LEGACY_TRANSCRIPT_VIEW_MODE];
11618
- /** Default preserves the compact process disclosure introduced by Chat. */
11619
- const DEFAULT_TRANSCRIPT_VIEW_MODE = "compact";
11746
+ /** Saved `expanded` values read as `detailed`, without being offered or written back. */
11747
+ const LEGACY_EXPANDED_TRANSCRIPT_VIEW_MODE = "expanded";
11748
+ /** Every value the durable field accepts: current modes plus legacy saved values. */
11749
+ const TRANSCRIPT_VIEW_SETTING_VALUES = [
11750
+ ...TRANSCRIPT_VIEW_MODES,
11751
+ LEGACY_TRANSCRIPT_VIEW_MODE,
11752
+ LEGACY_EXPANDED_TRANSCRIPT_VIEW_MODE
11753
+ ];
11754
+ /** Standard process summaries for users without an explicit preference. */
11755
+ const DEFAULT_TRANSCRIPT_VIEW_MODE = "standard";
11620
11756
  /** Performance and usage detail levels accepted by user settings. */
11621
11757
  const PERFORMANCE_USAGE_MODES = ["compact", "detailed"];
11622
11758
  /** Preserve detailed accounting for users without an explicit preference. */
@@ -11625,7 +11761,7 @@ window.__ModuleLoader__.load({
11625
11761
  const ChatSettingsFields = {
11626
11762
  linkOpening: Schema.union(["sidebar", "new-tab"]).default("sidebar"),
11627
11763
  performanceUsage: Schema.union([...PERFORMANCE_USAGE_MODES]).default(DEFAULT_PERFORMANCE_USAGE),
11628
- [TRANSCRIPT_VIEW_FIELD]: Schema.union([...TRANSCRIPT_VIEW_SETTING_VALUES]).default(DEFAULT_TRANSCRIPT_VIEW_MODE)
11764
+ [TRANSCRIPT_VIEW_FIELD]: Schema.union([...TRANSCRIPT_VIEW_SETTING_VALUES]).default(DEFAULT_TRANSCRIPT_VIEW_MODE).loose()
11629
11765
  };
11630
11766
  Schema.object(ChatSettingsFields);
11631
11767
  //#endregion
@@ -11704,8 +11840,9 @@ window.__ModuleLoader__.load({
11704
11840
  //#region lib/types/client/settings/TranscriptViewRow.js
11705
11841
  const LABELS = {
11706
11842
  compact: "settings.transcript.compact",
11843
+ standard: "settings.transcript.standard",
11707
11844
  detailed: "settings.transcript.detailed",
11708
- expanded: "settings.transcript.expanded"
11845
+ verbose: "settings.transcript.verbose"
11709
11846
  };
11710
11847
  /**
11711
11848
  * Render the work-details mode selector.
@@ -11735,7 +11872,7 @@ window.__ModuleLoader__.load({
11735
11872
  var TranscriptViewPolicy = class {
11736
11873
  host;
11737
11874
  unsubscribe;
11738
- /** Reactive current mode; defaults to Compact before Host settings arrive. */
11875
+ /** Reactive current mode; defaults to Standard before Host settings arrive. */
11739
11876
  mode = (0, _deepseek_ai_dsh_client_store.createSnapshotStore)(DEFAULT_TRANSCRIPT_VIEW_MODE);
11740
11877
  /**
11741
11878
  * @param host - durable Chat settings scope.
@@ -11753,7 +11890,7 @@ window.__ModuleLoader__.load({
11753
11890
  }
11754
11891
  /**
11755
11892
  * Publish and persist one explicit user choice.
11756
- * @param mode - Compact, Detailed, or Expanded work details.
11893
+ * @param mode - Compact, Standard, Detailed, or Verbose work details.
11757
11894
  */
11758
11895
  setMode(mode) {
11759
11896
  if (this.mode.getSnapshot() === mode) return;
@@ -11764,7 +11901,8 @@ window.__ModuleLoader__.load({
11764
11901
  adopt() {
11765
11902
  const section = this.host.getSnapshot().value;
11766
11903
  if (section === void 0) return;
11767
- const mode = section.transcriptView === "normal" ? "detailed" : section.transcriptView;
11904
+ const saved = section.transcriptView;
11905
+ const mode = saved === "normal" ? "standard" : saved === "expanded" ? "detailed" : saved;
11768
11906
  if (this.mode.getSnapshot() !== mode) this.mode.set(mode);
11769
11907
  }
11770
11908
  };
@@ -11783,19 +11921,26 @@ window.__ModuleLoader__.load({
11783
11921
  liveProcessDetail: false,
11784
11922
  settledReasoningPreview: false
11785
11923
  },
11786
- detailed: {
11787
- mode: "detailed",
11924
+ standard: {
11925
+ mode: "standard",
11788
11926
  foldCompletedTurns: true,
11789
11927
  stepGrouping: "collapsed",
11790
11928
  liveProcessDetail: true,
11791
11929
  settledReasoningPreview: true
11792
11930
  },
11793
- expanded: {
11794
- mode: "expanded",
11931
+ detailed: {
11932
+ mode: "detailed",
11795
11933
  foldCompletedTurns: true,
11796
- stepGrouping: "none",
11934
+ stepGrouping: "history",
11797
11935
  liveProcessDetail: true,
11798
11936
  settledReasoningPreview: true
11937
+ },
11938
+ verbose: {
11939
+ mode: "verbose",
11940
+ foldCompletedTurns: false,
11941
+ stepGrouping: "none",
11942
+ liveProcessDetail: false,
11943
+ settledReasoningPreview: true
11799
11944
  }
11800
11945
  };
11801
11946
  /**
package/lib/index.js CHANGED
@@ -8,18 +8,25 @@ const TRANSCRIPT_VIEW_FIELD = "transcriptView";
8
8
  /** Work-details presentation modes a user can choose. */
9
9
  const TRANSCRIPT_VIEW_MODES = [
10
10
  "compact",
11
+ "standard",
11
12
  "detailed",
12
- "expanded"
13
+ "verbose"
13
14
  ];
14
15
  /**
15
- * Saved value from the two-mode generation of this setting. Read as `detailed`;
16
+ * Saved value from the two-mode generation of this setting. Read as `standard`;
16
17
  * never offered as a choice and never written back.
17
18
  */
18
19
  const LEGACY_TRANSCRIPT_VIEW_MODE = "normal";
19
- /** Every value the durable field accepts: current modes plus the legacy saved value. */
20
- const TRANSCRIPT_VIEW_SETTING_VALUES = [...TRANSCRIPT_VIEW_MODES, LEGACY_TRANSCRIPT_VIEW_MODE];
21
- /** Default preserves the compact process disclosure introduced by Chat. */
22
- const DEFAULT_TRANSCRIPT_VIEW_MODE = "compact";
20
+ /** Saved `expanded` values read as `detailed`, without being offered or written back. */
21
+ const LEGACY_EXPANDED_TRANSCRIPT_VIEW_MODE = "expanded";
22
+ /** Every value the durable field accepts: current modes plus legacy saved values. */
23
+ const TRANSCRIPT_VIEW_SETTING_VALUES = [
24
+ ...TRANSCRIPT_VIEW_MODES,
25
+ LEGACY_TRANSCRIPT_VIEW_MODE,
26
+ LEGACY_EXPANDED_TRANSCRIPT_VIEW_MODE
27
+ ];
28
+ /** Standard process summaries for users without an explicit preference. */
29
+ const DEFAULT_TRANSCRIPT_VIEW_MODE = "standard";
23
30
  /** Performance and usage detail levels accepted by user settings. */
24
31
  const PERFORMANCE_USAGE_MODES = ["compact", "detailed"];
25
32
  /** Preserve detailed accounting for users without an explicit preference. */
@@ -28,7 +35,7 @@ const DEFAULT_PERFORMANCE_USAGE = "detailed";
28
35
  const ChatSettingsFields = {
29
36
  linkOpening: z.union(["sidebar", "new-tab"]).default("sidebar"),
30
37
  performanceUsage: z.union([...PERFORMANCE_USAGE_MODES]).default(DEFAULT_PERFORMANCE_USAGE),
31
- [TRANSCRIPT_VIEW_FIELD]: z.union([...TRANSCRIPT_VIEW_SETTING_VALUES]).default(DEFAULT_TRANSCRIPT_VIEW_MODE)
38
+ [TRANSCRIPT_VIEW_FIELD]: z.union([...TRANSCRIPT_VIEW_SETTING_VALUES]).default(DEFAULT_TRANSCRIPT_VIEW_MODE).loose()
32
39
  };
33
40
  z.object(ChatSettingsFields);
34
41
  //#endregion
@@ -48,4 +55,4 @@ function apply(ctx) {
48
55
  });
49
56
  }
50
57
  //#endregion
51
- export { CHAT_SETTINGS_NAMESPACE, Config, DEFAULT_TRANSCRIPT_VIEW_MODE, LEGACY_TRANSCRIPT_VIEW_MODE, TRANSCRIPT_VIEW_FIELD, TRANSCRIPT_VIEW_MODES, apply };
58
+ export { CHAT_SETTINGS_NAMESPACE, Config, DEFAULT_TRANSCRIPT_VIEW_MODE, LEGACY_EXPANDED_TRANSCRIPT_VIEW_MODE, LEGACY_TRANSCRIPT_VIEW_MODE, TRANSCRIPT_VIEW_FIELD, TRANSCRIPT_VIEW_MODES, apply };
@@ -5,15 +5,17 @@ export declare const CHAT_SETTINGS_NAMESPACE = "ui-chat";
5
5
  /** Field carrying the work-details presentation mode. */
6
6
  export declare const TRANSCRIPT_VIEW_FIELD = "transcriptView";
7
7
  /** Work-details presentation modes a user can choose. */
8
- export declare const TRANSCRIPT_VIEW_MODES: readonly ["compact", "detailed", "expanded"];
8
+ export declare const TRANSCRIPT_VIEW_MODES: readonly ["compact", "standard", "detailed", "verbose"];
9
9
  /** Work-details presentation mode. */
10
10
  export type TranscriptViewMode = typeof TRANSCRIPT_VIEW_MODES[number];
11
11
  /**
12
- * Saved value from the two-mode generation of this setting. Read as `detailed`;
12
+ * Saved value from the two-mode generation of this setting. Read as `standard`;
13
13
  * never offered as a choice and never written back.
14
14
  */
15
15
  export declare const LEGACY_TRANSCRIPT_VIEW_MODE = "normal";
16
- /** Default preserves the compact process disclosure introduced by Chat. */
16
+ /** Saved `expanded` values read as `detailed`, without being offered or written back. */
17
+ export declare const LEGACY_EXPANDED_TRANSCRIPT_VIEW_MODE = "expanded";
18
+ /** Standard process summaries for users without an explicit preference. */
17
19
  export declare const DEFAULT_TRANSCRIPT_VIEW_MODE: TranscriptViewMode;
18
20
  /** Performance and usage detail levels accepted by user settings. */
19
21
  export declare const PERFORMANCE_USAGE_MODES: readonly ["compact", "detailed"];
@@ -27,8 +29,8 @@ export type LinkOpening = 'sidebar' | 'new-tab';
27
29
  export declare const DEFAULT_LINK_OPENING: LinkOpening;
28
30
  /** Durable Chat section shared by the Host schema and browser scope. */
29
31
  export interface ChatSettings {
30
- /** Work-details preference; the legacy value is accepted only from existing saved settings. */
31
- transcriptView: TranscriptViewMode | typeof LEGACY_TRANSCRIPT_VIEW_MODE;
32
+ /** Work-details preference; legacy values are accepted only from existing saved settings. */
33
+ transcriptView: TranscriptViewMode | typeof LEGACY_TRANSCRIPT_VIEW_MODE | typeof LEGACY_EXPANDED_TRANSCRIPT_VIEW_MODE;
32
34
  /** Detail level for composer statistics and completed-Turn usage. */
33
35
  performanceUsage: PerformanceUsageMode;
34
36
  /** Default destination for Chat HTTP(S) links. */
@@ -38,16 +40,16 @@ export interface ChatSettings {
38
40
  export declare const ChatSettingsFields: {
39
41
  linkOpening: z<"sidebar" | "new-tab", "sidebar" | "new-tab", "defined">;
40
42
  performanceUsage: z<"compact" | "detailed", "compact" | "detailed", "defined">;
41
- transcriptView: z<"compact" | "detailed" | "expanded" | "normal", "compact" | "detailed" | "expanded" | "normal", "defined">;
43
+ transcriptView: z<"compact" | "standard" | "detailed" | "verbose" | "normal" | "expanded", "compact" | "standard" | "detailed" | "verbose" | "normal" | "expanded", "defined">;
42
44
  };
43
45
  /** Schema for shared configuration values. */
44
46
  export declare const ChatSettingsSchema: z<Schemastery.ObjectS<NoInfer<{
45
47
  linkOpening: z<"sidebar" | "new-tab", "sidebar" | "new-tab", "defined">;
46
48
  performanceUsage: z<"compact" | "detailed", "compact" | "detailed", "defined">;
47
- transcriptView: z<"compact" | "detailed" | "expanded" | "normal", "compact" | "detailed" | "expanded" | "normal", "defined">;
49
+ transcriptView: z<"compact" | "standard" | "detailed" | "verbose" | "normal" | "expanded", "compact" | "standard" | "detailed" | "verbose" | "normal" | "expanded", "defined">;
48
50
  }>>, Schemastery.ObjectT<NoInfer<{
49
51
  linkOpening: z<"sidebar" | "new-tab", "sidebar" | "new-tab", "defined">;
50
52
  performanceUsage: z<"compact" | "detailed", "compact" | "detailed", "defined">;
51
- transcriptView: z<"compact" | "detailed" | "expanded" | "normal", "compact" | "detailed" | "expanded" | "normal", "defined">;
53
+ transcriptView: z<"compact" | "standard" | "detailed" | "verbose" | "normal" | "expanded", "compact" | "standard" | "detailed" | "verbose" | "normal" | "expanded", "defined">;
52
54
  }>>, "plain">;
53
55
  //# sourceMappingURL=chat-settings.d.ts.map
@@ -2,9 +2,12 @@ import type { MarkdownFileMentions } from '@deepseek-ai/dsh-client-ui-primitives
2
2
  import type { ChatNodeOwnerProps, ChatViewSlotProps, UseDisclosure, UsePresentation } from '../contract/slots.ts';
3
3
  import type { AssistantBlock } from '../contract/snapshot.ts';
4
4
  /**
5
- * Resolve an authored POSIX image path against the document's file API.
5
+ * Standalone fallback for image destinations (query/fragment suffixes are ignored).
6
+ * Chat fileImages resolves decoded file references against cwd; pathImages also
7
+ * serves this component outside that provider and accepts legacy image URL suffixes.
8
+ * Resolve an authored absolute image path against the document's file API.
6
9
  * @param base - canonical `document.baseURI` at render time.
7
- * @param value - authored markdown destination.
10
+ * @param value - authored Markdown destination; URL escapes are decoded once.
8
11
  * @returns an absolute HTTP(S) file-API URL, or undefined for unsupported
9
12
  * protocols and non-local paths.
10
13
  */
@@ -1,5 +1,5 @@
1
1
  /** Business data for Chat process groups; source Nodes remain in the Chat store. */
2
- export type ProcessActivity = 'read' | 'search' | 'edit' | 'commands' | 'code' | 'webSearch' | 'webFetch' | 'subagents' | 'plan' | 'questions' | 'tools';
2
+ export type ProcessActivity = 'read' | 'readImage' | 'search' | 'write' | 'edit' | 'commands' | 'code' | 'webSearch' | 'webFetch' | 'subagents' | 'plan' | 'questions' | 'tools';
3
3
  /** Distinct-call category ranking and the current live task detail. */
4
4
  export interface ProcessActivitySummary {
5
5
  readonly counts: readonly {
@@ -8,6 +8,8 @@ export interface ProcessActivitySummary {
8
8
  }[];
9
9
  readonly running: ProcessActivity | undefined;
10
10
  readonly runningDetail: string;
11
+ /** Present only while the selected live activity has not reached tool/call. */
12
+ readonly preparing?: true;
11
13
  }
12
14
  /** Presentation facts for one group between independent replies or input. */
13
15
  export interface ProcessGroupData {
@@ -2,7 +2,7 @@ import type { ConversationNode, ConversationTimelineSnapshot, PartialAssistant,
2
2
  import type { ChatConversationViewNode, ChatNodeDataMap, ChatNodeKind } from './chat-nodes.ts';
3
3
  import type { ObservableSnapshot } from '@deepseek-ai/dsh-client-store';
4
4
  import type { TurnProcessSpec } from './turn-process.ts';
5
- export type { AssistantBlock, AssistantMessageNode, AssistantProviderMetadataView, AssistantRequestConfig, AssistantTiming, CommandNode, CompactionSummaryNode, ContextMessageNode, ConversationNode, ModelRetryNode, PartialAssistant, RunningToolCall, SteeringMessageNode, TodoItem, ToolCallBlock, ToolResultNode, TurnErrorNode, TurnMaxTokensNode, UnknownSurfaceNode, UserMessageNode, } from '@deepseek-ai/dsh-client-ui-conversation/client';
5
+ export type { AssistantBlock, AssistantMessageNode, AssistantProviderMetadataView, AssistantRequestConfig, AssistantTiming, CommandNode, CompactionSummaryNode, ContextMessageNode, ConversationNode, ModelRetryNode, PartialAssistant, PreparingToolCall, RunningToolCall, StartedToolCall, SteeringMessageNode, TodoItem, ToolCallBlock, ToolResultNode, TurnErrorNode, TurnMaxTokensNode, UnknownSurfaceNode, UserMessageNode, } from '@deepseek-ai/dsh-client-ui-conversation/client';
6
6
  /** Per-key observable used by one mounted Chat Node Seat. */
7
7
  export interface ChatNodeSource {
8
8
  /** @returns the current Node for this source's stable key. */
@@ -11,7 +11,7 @@ interface ToolState {
11
11
  readonly children: ReadonlyMap<string, readonly ToolCallBlock[]>;
12
12
  readonly parents: ReadonlyMap<string, string>;
13
13
  }
14
- /** Root Tool lifecycle and nested PTC dispatch Definition. */
14
+ /** Root Tool preparation, dispatch, result, and nested PTC calls. */
15
15
  export declare const toolDefinition: ConversationNodeDefinition<ToolState>;
16
16
  /**
17
17
  * Register the root Tool lifecycle and nested-subcall contribution.
@@ -12,7 +12,7 @@ export type {} from './conversation-nodes/turn-error.ts';
12
12
  export type {} from './conversation-nodes/turn-max-tokens.ts';
13
13
  export type {} from './conversation-nodes/turn-process.ts';
14
14
  export type {} from './conversation-nodes/turn-tail.ts';
15
- export type { AssistantBlock, AssistantMessageNode, AssistantProviderMetadataView, AssistantRequestConfig, AssistantTiming, ChatLocationNodeIndex, ChatNodeProcessSource, ChatNodeSource, ChatNodeStore, ChatSnapshot, ChatTurnNavigationIndex, ChatTurnProcessPresentation, CommandNode, CompactionSummaryNode, ContextMessageNode, ConversationNode, LegacyConversationSlice, ModelRetryNode, PartialAssistant, RunningToolCall, SteeringMessageNode, ToolCallBlock, ToolResultNode, TurnErrorNode, TurnMaxTokensNode, TurnNavigationItem, UnknownSurfaceNode, UserMessageNode, } from './contract/snapshot.ts';
15
+ export type { AssistantBlock, AssistantMessageNode, AssistantProviderMetadataView, AssistantRequestConfig, AssistantTiming, ChatLocationNodeIndex, ChatNodeProcessSource, ChatNodeSource, ChatNodeStore, ChatSnapshot, ChatTurnNavigationIndex, ChatTurnProcessPresentation, CommandNode, CompactionSummaryNode, ContextMessageNode, ConversationNode, LegacyConversationSlice, ModelRetryNode, PartialAssistant, PreparingToolCall, RunningToolCall, StartedToolCall, SteeringMessageNode, ToolCallBlock, ToolResultNode, TurnErrorNode, TurnMaxTokensNode, TurnNavigationItem, UnknownSurfaceNode, UserMessageNode, } from './contract/snapshot.ts';
16
16
  export type { AssistantChatData, ChatConversationViewNode, ChatNode, ChatNodeKind, FinalAssistantChatData, ManualCompactionChatData, RetryChatData, ToolChatData, TurnProcessChatData, TurnTailChatData, } from './contract/chat-nodes.ts';
17
17
  export type { ChatStoreState, ToolCallId, TurnProcessViewEntry } from './contract/store.ts';
18
18
  export type { TranscriptViewRowInjected, TranscriptViewRowProps } from './settings/TranscriptViewRow.tsx';
@@ -5,6 +5,8 @@ export declare const NS = "chat";
5
5
  export declare const zh: {
6
6
  'message.stepProcess.thinking': string;
7
7
  'message.stepProcess.read': string;
8
+ 'message.stepProcess.readImage': string;
9
+ 'message.stepProcess.write': string;
8
10
  'message.stepProcess.search': string;
9
11
  'message.stepProcess.edit': string;
10
12
  'message.stepProcess.commands': string;
@@ -15,8 +17,23 @@ export declare const zh: {
15
17
  'message.stepProcess.plan': string;
16
18
  'message.stepProcess.questions': string;
17
19
  'message.stepProcess.tools': string;
20
+ 'message.stepProcess.prepare.read': string;
21
+ 'message.stepProcess.prepare.readImage': string;
22
+ 'message.stepProcess.prepare.write': string;
23
+ 'message.stepProcess.prepare.search': string;
24
+ 'message.stepProcess.prepare.edit': string;
25
+ 'message.stepProcess.prepare.commands': string;
26
+ 'message.stepProcess.prepare.code': string;
27
+ 'message.stepProcess.prepare.webSearch': string;
28
+ 'message.stepProcess.prepare.webFetch': string;
29
+ 'message.stepProcess.prepare.subagents': string;
30
+ 'message.stepProcess.prepare.plan': string;
31
+ 'message.stepProcess.prepare.questions': string;
32
+ 'message.stepProcess.prepare.tools': string;
18
33
  'message.stepProcess.done.thinking': string;
19
34
  'message.stepProcess.done.read': string;
35
+ 'message.stepProcess.done.readImage': string;
36
+ 'message.stepProcess.done.write': string;
20
37
  'message.stepProcess.done.search': string;
21
38
  'message.stepProcess.done.edit': string;
22
39
  'message.stepProcess.done.commands': string;
@@ -47,6 +64,11 @@ export declare const zh: {
47
64
  'message.turnProcess.took': string;
48
65
  'message.turnProcess.failed': string;
49
66
  'view.chat': string;
67
+ 'image.open': string;
68
+ 'image.loading': string;
69
+ 'image.failed': string;
70
+ 'image.dialog': string;
71
+ 'image.close': string;
50
72
  'number.groupSeparator': string;
51
73
  'duration.compactSeconds': string;
52
74
  'duration.compactMinutes': string;
@@ -79,8 +101,9 @@ export declare const zh: {
79
101
  'settings.transcript.title': string;
80
102
  'settings.transcript.description': string;
81
103
  'settings.transcript.compact': string;
104
+ 'settings.transcript.standard': string;
82
105
  'settings.transcript.detailed': string;
83
- 'settings.transcript.expanded': string;
106
+ 'settings.transcript.verbose': string;
84
107
  'fileOpen.title': string;
85
108
  'fileOpen.unknown': string;
86
109
  'message.extraBlock': string;
@@ -161,6 +184,8 @@ export type ChatKey = keyof typeof zh;
161
184
  export declare const en: {
162
185
  'message.stepProcess.thinking': string;
163
186
  'message.stepProcess.read': string;
187
+ 'message.stepProcess.readImage': string;
188
+ 'message.stepProcess.write': string;
164
189
  'message.stepProcess.search': string;
165
190
  'message.stepProcess.edit': string;
166
191
  'message.stepProcess.commands': string;
@@ -171,8 +196,23 @@ export declare const en: {
171
196
  'message.stepProcess.plan': string;
172
197
  'message.stepProcess.questions': string;
173
198
  'message.stepProcess.tools': string;
199
+ 'message.stepProcess.prepare.read': string;
200
+ 'message.stepProcess.prepare.readImage': string;
201
+ 'message.stepProcess.prepare.write': string;
202
+ 'message.stepProcess.prepare.search': string;
203
+ 'message.stepProcess.prepare.edit': string;
204
+ 'message.stepProcess.prepare.commands': string;
205
+ 'message.stepProcess.prepare.code': string;
206
+ 'message.stepProcess.prepare.webSearch': string;
207
+ 'message.stepProcess.prepare.webFetch': string;
208
+ 'message.stepProcess.prepare.subagents': string;
209
+ 'message.stepProcess.prepare.plan': string;
210
+ 'message.stepProcess.prepare.questions': string;
211
+ 'message.stepProcess.prepare.tools': string;
174
212
  'message.stepProcess.done.thinking': string;
175
213
  'message.stepProcess.done.read': string;
214
+ 'message.stepProcess.done.readImage': string;
215
+ 'message.stepProcess.done.write': string;
176
216
  'message.stepProcess.done.search': string;
177
217
  'message.stepProcess.done.edit': string;
178
218
  'message.stepProcess.done.commands': string;
@@ -203,6 +243,11 @@ export declare const en: {
203
243
  'message.turnProcess.took': string;
204
244
  'message.turnProcess.failed': string;
205
245
  'view.chat': string;
246
+ 'image.open': string;
247
+ 'image.loading': string;
248
+ 'image.failed': string;
249
+ 'image.dialog': string;
250
+ 'image.close': string;
206
251
  'number.groupSeparator': string;
207
252
  'duration.compactSeconds': string;
208
253
  'duration.compactMinutes': string;
@@ -235,8 +280,9 @@ export declare const en: {
235
280
  'settings.transcript.title': string;
236
281
  'settings.transcript.description': string;
237
282
  'settings.transcript.compact': string;
283
+ 'settings.transcript.standard': string;
238
284
  'settings.transcript.detailed': string;
239
- 'settings.transcript.expanded': string;
285
+ 'settings.transcript.verbose': string;
240
286
  'fileOpen.title': string;
241
287
  'fileOpen.unknown': string;
242
288
  'message.extraBlock': string;
@@ -11,8 +11,8 @@ export interface ChatPresentationPolicy {
11
11
  readonly mode: TranscriptViewMode;
12
12
  /** Whether a normally completed Turn folds its process rows behind the whole-Turn control. */
13
13
  readonly foldCompletedTurns: boolean;
14
- /** Whether running Turns' secondary groups expose a collapsible header; historical groups always do. */
15
- readonly stepGrouping: 'collapsed' | 'none';
14
+ /** Collapsible group headers for all Turns, historical Turns only, or no Turns. */
15
+ readonly stepGrouping: 'collapsed' | 'history' | 'none';
16
16
  /** Show the running command, path, query, or reasoning detail in group titles. */
17
17
  readonly liveProcessDetail: boolean;
18
18
  /** Whether a settled reasoning row previews its first line beside the Think title. */
@@ -6,7 +6,7 @@ import { type ChatSettings, type TranscriptViewMode } from '../chat-settings.ts'
6
6
  export declare class TranscriptViewPolicy {
7
7
  private readonly host;
8
8
  private readonly unsubscribe;
9
- /** Reactive current mode; defaults to Compact before Host settings arrive. */
9
+ /** Reactive current mode; defaults to Standard before Host settings arrive. */
10
10
  readonly mode: SnapshotStore<TranscriptViewMode>;
11
11
  /**
12
12
  * @param host - durable Chat settings scope.
@@ -16,7 +16,7 @@ export declare class TranscriptViewPolicy {
16
16
  dispose(): void;
17
17
  /**
18
18
  * Publish and persist one explicit user choice.
19
- * @param mode - Compact, Detailed, or Expanded work details.
19
+ * @param mode - Compact, Standard, Detailed, or Verbose work details.
20
20
  */
21
21
  setMode(mode: TranscriptViewMode): void;
22
22
  /** Adopt the latest accepted Host section without writing it back. */
@@ -1,7 +1,7 @@
1
1
  import type { Volatile, Context } from '@deepseek-ai/cordis';
2
2
  import type { LinkOpening, TranscriptViewMode, PerformanceUsageMode } from './chat-settings.ts';
3
3
  import z from '@deepseek-ai/schemastery';
4
- export { CHAT_SETTINGS_NAMESPACE, DEFAULT_TRANSCRIPT_VIEW_MODE, LEGACY_TRANSCRIPT_VIEW_MODE, TRANSCRIPT_VIEW_FIELD, TRANSCRIPT_VIEW_MODES, type ChatSettings, type TranscriptViewMode, } from './chat-settings.ts';
4
+ export { CHAT_SETTINGS_NAMESPACE, DEFAULT_TRANSCRIPT_VIEW_MODE, LEGACY_TRANSCRIPT_VIEW_MODE, LEGACY_EXPANDED_TRANSCRIPT_VIEW_MODE, TRANSCRIPT_VIEW_FIELD, TRANSCRIPT_VIEW_MODES, type ChatSettings, type TranscriptViewMode, } from './chat-settings.ts';
5
5
  /** Runtime preferences projected to the browser. */
6
6
  export interface Config {
7
7
  /** Completed turn transcript presentation. */
@@ -13,11 +13,11 @@ export interface Config {
13
13
  }
14
14
  /** Live preferences projected to the browser. */
15
15
  export declare const Config: z<Schemastery.ObjectS<NoInfer<{
16
- transcriptView: z<"compact" | "detailed" | "expanded" | "normal", "compact" | "detailed" | "expanded" | "normal", "volatile-defined">;
16
+ transcriptView: z<"compact" | "standard" | "detailed" | "verbose" | "normal" | "expanded", "compact" | "standard" | "detailed" | "verbose" | "normal" | "expanded", "volatile-defined">;
17
17
  performanceUsage: z<"compact" | "detailed", "compact" | "detailed", "volatile-defined">;
18
18
  linkOpening: z<"sidebar" | "new-tab", "sidebar" | "new-tab", "volatile-defined">;
19
19
  }>>, Schemastery.ObjectT<NoInfer<{
20
- transcriptView: z<"compact" | "detailed" | "expanded" | "normal", "compact" | "detailed" | "expanded" | "normal", "volatile-defined">;
20
+ transcriptView: z<"compact" | "standard" | "detailed" | "verbose" | "normal" | "expanded", "compact" | "standard" | "detailed" | "verbose" | "normal" | "expanded", "volatile-defined">;
21
21
  performanceUsage: z<"compact" | "detailed", "compact" | "detailed", "volatile-defined">;
22
22
  linkOpening: z<"sidebar" | "new-tab", "sidebar" | "new-tab", "volatile-defined">;
23
23
  }>>, "plain">;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-client-ui-chat",
3
3
  "description": "Chat Conversation target, node definitions, renderers, and details surface",
4
- "version": "0.1.7-alpha.2",
4
+ "version": "0.1.7-rc.1",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -54,41 +54,41 @@
54
54
  "react": "^18.2.0",
55
55
  "react-dom": "^18.2.0",
56
56
  "@deepseek-ai/cordis": "~4.0.4",
57
- "@deepseek-ai/dsh-agent": "0.1.7-alpha.2",
58
- "@deepseek-ai/dsh-api-remotes": "0.1.7-alpha.2",
59
- "@deepseek-ai/dsh-api-workspace-controller": "0.1.7-alpha.2",
60
- "@deepseek-ai/dsh-api-session-controller": "0.1.7-alpha.2",
61
- "@deepseek-ai/dsh-attachment": "0.1.7-alpha.2",
62
- "@deepseek-ai/dsh-brand": "0.1.7-alpha.2",
63
- "@deepseek-ai/dsh-api-workspace-files": "0.1.7-alpha.2",
64
- "@deepseek-ai/dsh-client-locale": "0.1.7-alpha.2",
65
- "@deepseek-ai/dsh-client-store": "0.1.7-alpha.2",
66
- "@deepseek-ai/dsh-client-ui-approval": "0.1.7-alpha.2",
67
- "@deepseek-ai/dsh-client-ui-conversation": "0.1.7-alpha.2",
68
- "@deepseek-ai/dsh-client-ui-layout": "0.1.7-alpha.2",
69
- "@deepseek-ai/dsh-client-ui-primitives": "0.1.7-alpha.2",
70
- "@deepseek-ai/dsh-client-ui-renderer": "0.1.7-alpha.2",
71
- "@deepseek-ai/dsh-client-ui-session": "0.1.7-alpha.2",
72
- "@deepseek-ai/dsh-client-ui-settings": "0.1.7-alpha.2",
73
- "@deepseek-ai/dsh-client-ui-sidebar-browser": "0.1.7-alpha.2",
74
- "@deepseek-ai/dsh-client-ui-sidebar-documentpreview": "0.1.7-alpha.2",
75
- "@deepseek-ai/dsh-client-ui-slots": "0.1.7-alpha.2",
76
- "@deepseek-ai/dsh-client-ui-workspace": "0.1.7-alpha.2",
77
- "@deepseek-ai/dsh-commands": "0.1.7-alpha.2",
78
- "@deepseek-ai/dsh-compaction": "0.1.7-alpha.2",
79
- "@deepseek-ai/dsh-llm": "0.1.7-alpha.2",
80
- "@deepseek-ai/dsh-client-ui-input-trigger": "0.1.7-alpha.2",
81
- "@deepseek-ai/dsh-session-stats": "0.1.7-alpha.2",
82
- "@deepseek-ai/dsh-session-turn-outline": "0.1.7-alpha.2",
83
- "@deepseek-ai/dsh-subagent": "0.1.7-alpha.2",
84
- "@deepseek-ai/dsh-token-meter": "0.1.7-alpha.2",
85
- "@deepseek-ai/dsh-tools": "0.1.7-alpha.2",
86
- "@deepseek-ai/dsh-session": "0.1.7-alpha.2",
87
- "@deepseek-ai/dsh-util-workspace-path": "0.1.7-alpha.2",
88
- "@deepseek-ai/dsh-llm-retry": "0.1.7-alpha.2",
89
- "@deepseek-ai/dsh-client-ui-sidebar-right": "0.1.7-alpha.2",
90
- "@deepseek-ai/dsh-util-values": "0.1.7-alpha.2",
91
- "@deepseek-ai/dsh-settings": "0.1.7-alpha.2"
57
+ "@deepseek-ai/dsh-agent": "0.1.7-rc.1",
58
+ "@deepseek-ai/dsh-api-remotes": "0.1.7-rc.1",
59
+ "@deepseek-ai/dsh-api-workspace-controller": "0.1.7-rc.1",
60
+ "@deepseek-ai/dsh-api-session-controller": "0.1.7-rc.1",
61
+ "@deepseek-ai/dsh-attachment": "0.1.7-rc.1",
62
+ "@deepseek-ai/dsh-brand": "0.1.7-rc.1",
63
+ "@deepseek-ai/dsh-client-locale": "0.1.7-rc.1",
64
+ "@deepseek-ai/dsh-client-store": "0.1.7-rc.1",
65
+ "@deepseek-ai/dsh-client-ui-approval": "0.1.7-rc.1",
66
+ "@deepseek-ai/dsh-client-ui-conversation": "0.1.7-rc.1",
67
+ "@deepseek-ai/dsh-client-ui-input-trigger": "0.1.7-rc.1",
68
+ "@deepseek-ai/dsh-client-ui-layout": "0.1.7-rc.1",
69
+ "@deepseek-ai/dsh-client-ui-renderer": "0.1.7-rc.1",
70
+ "@deepseek-ai/dsh-api-workspace-files": "0.1.7-rc.1",
71
+ "@deepseek-ai/dsh-client-ui-session": "0.1.7-rc.1",
72
+ "@deepseek-ai/dsh-client-ui-settings": "0.1.7-rc.1",
73
+ "@deepseek-ai/dsh-client-ui-sidebar-browser": "0.1.7-rc.1",
74
+ "@deepseek-ai/dsh-client-ui-primitives": "0.1.7-rc.1",
75
+ "@deepseek-ai/dsh-client-ui-slots": "0.1.7-rc.1",
76
+ "@deepseek-ai/dsh-client-ui-workspace": "0.1.7-rc.1",
77
+ "@deepseek-ai/dsh-client-ui-sidebar-documentpreview": "0.1.7-rc.1",
78
+ "@deepseek-ai/dsh-commands": "0.1.7-rc.1",
79
+ "@deepseek-ai/dsh-llm": "0.1.7-rc.1",
80
+ "@deepseek-ai/dsh-client-ui-sidebar-right": "0.1.7-rc.1",
81
+ "@deepseek-ai/dsh-session": "0.1.7-rc.1",
82
+ "@deepseek-ai/dsh-session-stats": "0.1.7-rc.1",
83
+ "@deepseek-ai/dsh-session-turn-outline": "0.1.7-rc.1",
84
+ "@deepseek-ai/dsh-subagent": "0.1.7-rc.1",
85
+ "@deepseek-ai/dsh-token-meter": "0.1.7-rc.1",
86
+ "@deepseek-ai/dsh-tools": "0.1.7-rc.1",
87
+ "@deepseek-ai/dsh-llm-retry": "0.1.7-rc.1",
88
+ "@deepseek-ai/dsh-util-workspace-path": "0.1.7-rc.1",
89
+ "@deepseek-ai/dsh-settings": "0.1.7-rc.1",
90
+ "@deepseek-ai/dsh-compaction": "0.1.7-rc.1",
91
+ "@deepseek-ai/dsh-util-values": "0.1.7-rc.1"
92
92
  },
93
93
  "dependencies": {
94
94
  "@deepseek-ai/schemastery": "~3.18.4"