@prettier-ai/dsh-client-ui-tool 0.1.2-alpha.1 → 0.1.2-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.i18n.yaml +2 -2
- package/README.md +1 -1
- package/README.zh.md +1 -1
- package/lib/client.js +54 -29
- package/lib/types/client/apply.d.ts +2 -1
- package/lib/types/client/contract/slots.d.ts +12 -7
- package/lib/types/client/index.d.ts +1 -1
- package/lib/types/client/tool/ToolCallTree.d.ts +1 -1
- package/lib/types/client/tool/ToolDetails.d.ts +1 -1
- package/lib/types/client/tool/components/ToolRow.d.ts +4 -4
- package/lib/types/client/tool/models/tool-call-model.d.ts +13 -6
- package/package.json +16 -26
package/README.i18n.yaml
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
3
|
# after editing either side, bring the other along and re-record with:
|
|
4
4
|
# pnpm run verify-translation-pairing --write packages/client/ui-tool/README.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: 895274748d8ee5b7bece16e5b76836966cc52663
|
|
6
|
+
README.zh.md: f4cf11cabdb94f45c9b11e7f7538ad5042a791e6
|
package/README.md
CHANGED
|
@@ -61,7 +61,7 @@ The package realizes one dispatch rule: atomic Tool views are keyed by wire Tool
|
|
|
61
61
|
|
|
62
62
|
### Details and cards
|
|
63
63
|
|
|
64
|
-
The package fills `conversation.details.tool` with `ToolDetails`. Row and Details renderers share one pure card model for each terminal, read, diff, search, and web card. These models validate raw call arguments, result content, failure state, persisted metadata, Code Dispatch `parentCallId`, and Session path facts. Unsupported or malformed inputs use flattened Tool result text. Card-specific limits and fallback rules remain in the owning [terminal](../../../.agents/notes/implemented/feature/2026-07-28-web-terminal-card.md), [diff](../../../.agents/notes/implemented/feature/2026-07-30-web-diff-card.md), [read](../../../.agents/notes/implemented/feature/2026-07-30-web-read-card-frontend.md), [search](../../../.agents/notes/implemented/feature/2026-07-30-web-search-card.md), [web](../../../.agents/notes/implemented/feature/2026-07-30-web-result-card-frontend.md), and [question](../../../.agents/notes/implemented/feature/2026-07-29-ask-question-web-presentation.md) notes.
|
|
64
|
+
The package fills `conversation.details.tool` with `ToolDetails`. Row and Details renderers share one pure card model for each terminal, read, diff, search, and web card. These models validate raw call arguments, result content, failure state, persisted metadata, Code Dispatch `parentCallId`, and Session path facts. Generic rows retain the original `argsRaw` reference and format their input body only while it is expanded; structured cards skip generic-body formatting. Unsupported or malformed inputs use flattened Tool result text. Card-specific limits and fallback rules remain in the owning [terminal](../../../.agents/notes/implemented/feature/2026-07-28-web-terminal-card.md), [diff](../../../.agents/notes/implemented/feature/2026-07-30-web-diff-card.md), [read](../../../.agents/notes/implemented/feature/2026-07-30-web-read-card-frontend.md), [search](../../../.agents/notes/implemented/feature/2026-07-30-web-search-card.md), [web](../../../.agents/notes/implemented/feature/2026-07-30-web-result-card-frontend.md), and [question](../../../.agents/notes/implemented/feature/2026-07-29-ask-question-web-presentation.md) notes.
|
|
65
65
|
|
|
66
66
|
</details>
|
|
67
67
|
|
package/README.zh.md
CHANGED
|
@@ -61,7 +61,7 @@ owner 载荷为 `ToolCallOwnerProps`:`callId`、`toolName`、冻结的 `block`
|
|
|
61
61
|
|
|
62
62
|
### 详情与卡片
|
|
63
63
|
|
|
64
|
-
本包通过 `ToolDetails` 填充 `conversation.details.tool`。行 renderer 与 Details renderer 分别为 terminal、read、diff、search 和 web 卡片复用同一个纯 card model。这些 model 校验原始调用参数、结果内容、失败状态、持久 metadata、Code Dispatch `parentCallId` 与 Session
|
|
64
|
+
本包通过 `ToolDetails` 填充 `conversation.details.tool`。行 renderer 与 Details renderer 分别为 terminal、read、diff、search 和 web 卡片复用同一个纯 card model。这些 model 校验原始调用参数、结果内容、失败状态、持久 metadata、Code Dispatch `parentCallId` 与 Session 路径事实。Generic row 保留原始 `argsRaw` 引用,只在展开期间格式化 input body;结构化卡片跳过 generic body 格式化。不受支持或格式错误的输入使用压平的工具结果文本。各类卡片的上限与 fallback 规则仍由对应的 [terminal](../../../.agents/notes/implemented/feature/2026-07-28-web-terminal-card.zh.md)、[diff](../../../.agents/notes/implemented/feature/2026-07-30-web-diff-card.zh.md)、[read](../../../.agents/notes/implemented/feature/2026-07-30-web-read-card-frontend.zh.md)、[search](../../../.agents/notes/implemented/feature/2026-07-30-web-search-card.zh.md)、[web](../../../.agents/notes/implemented/feature/2026-07-30-web-result-card-frontend.zh.md) 与 [question](../../../.agents/notes/implemented/feature/2026-07-29-ask-question-web-presentation.zh.md) 笔记负责。
|
|
65
65
|
|
|
66
66
|
</details>
|
|
67
67
|
|
package/lib/client.js
CHANGED
|
@@ -186,7 +186,13 @@ window.__ModuleLoader__.load({
|
|
|
186
186
|
const picked = pickString(parsed, FILE_PATH_KEYS);
|
|
187
187
|
return picked === void 0 ? void 0 : firstLine(picked);
|
|
188
188
|
}
|
|
189
|
-
|
|
189
|
+
/**
|
|
190
|
+
* Format one argument payload when its generic input body becomes visible.
|
|
191
|
+
* @param variant - row presentation selected for the Tool name.
|
|
192
|
+
* @param argsRaw - original argument JSON or incomplete raw text.
|
|
193
|
+
* @returns display body, or null for empty input.
|
|
194
|
+
*/
|
|
195
|
+
function formatToolBody(variant, argsRaw) {
|
|
190
196
|
if (argsRaw === "") return null;
|
|
191
197
|
const parsed = parseArgs(argsRaw);
|
|
192
198
|
if (parsed === void 0) return argsRaw;
|
|
@@ -214,12 +220,13 @@ window.__ModuleLoader__.load({
|
|
|
214
220
|
const summary = variant === "others" && toolName !== "" && toolTitleKey === void 0 ? `${toolName} · ${base}` : base;
|
|
215
221
|
const output = done ? resultText(block) || null : null;
|
|
216
222
|
const errorSummary = state === "error" && output !== null ? firstLine(output) : null;
|
|
223
|
+
const bodyRaw = argsRaw === "" ? null : argsRaw;
|
|
217
224
|
return {
|
|
218
225
|
variant,
|
|
219
226
|
titleKey: toolTitleKey ?? VARIANT_TITLE_KEYS[variant],
|
|
220
227
|
summary,
|
|
221
228
|
filePath: deriveFilePath(variant, argsRaw),
|
|
222
|
-
|
|
229
|
+
bodyRaw,
|
|
223
230
|
output,
|
|
224
231
|
errorSummary,
|
|
225
232
|
state
|
|
@@ -1035,7 +1042,7 @@ window.__ModuleLoader__.load({
|
|
|
1035
1042
|
}
|
|
1036
1043
|
//#endregion
|
|
1037
1044
|
//#region \0dsh-css:/home/runner/work/dsh-publisher/dsh-publisher/upstream/packages/client/ui-tool/src/client/tool/components/ToolRow.module.css.mjs
|
|
1038
|
-
const css$3 = ".RAJz1a_root{flex-direction:column;display:flex}.RAJz1a_row{position:relative;overflow:hidden}.RAJz1a_root[data-state=running] .RAJz1a_row:after{content:\"\";background:linear-gradient(90deg, transparent 0%, color-mix(in srgb, var(--dsw-alias-bg-base) 60%, transparent) 55%, transparent 100%);pointer-events:none;width:300px;animation:2.6s ease-out infinite RAJz1a_dsh-tool-row-sweep;position:absolute;top:0;bottom:0;left:0}@keyframes RAJz1a_dsh-tool-row-sweep{0%{left:-300px}90%,to{left:100%}}.RAJz1a_leading{flex-shrink:0}.RAJz1a_root[data-tool^=cordis_] .RAJz1a_leading,.RAJz1a_root[data-tool^=cordis_] .RAJz1a_title{color:var(--dsw-alias-state-business-primary)}.RAJz1a_root[data-tool^=cordis_] .RAJz1a_title{font-weight:500}.RAJz1a_root[data-tool^=cordis_] .RAJz1a_sep{background:var(--dsw-alias-state-business-primary)}.RAJz1a_chevron{color:var(--dsw-alias-label-secondary)}.RAJz1a_title{font-weight:400}.RAJz1a_sep{background:var(--dsw-alias-label-caption);border-radius:1px;flex:none;width:2px;height:2px;margin:0 8px}.RAJz1a_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;overflow:hidden}.RAJz1a_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}.RAJz1a_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;text-decoration-color:var(--dsw-alias-label-
|
|
1045
|
+
const css$3 = ".RAJz1a_root{flex-direction:column;display:flex}.RAJz1a_row{position:relative;overflow:hidden}.RAJz1a_root[data-state=running] .RAJz1a_row:after{content:\"\";background:linear-gradient(90deg, transparent 0%, color-mix(in srgb, var(--dsw-alias-bg-base) 60%, transparent) 55%, transparent 100%);pointer-events:none;width:300px;animation:2.6s ease-out infinite RAJz1a_dsh-tool-row-sweep;position:absolute;top:0;bottom:0;left:0}@keyframes RAJz1a_dsh-tool-row-sweep{0%{left:-300px}90%,to{left:100%}}.RAJz1a_leading{flex-shrink:0}.RAJz1a_root[data-tool^=cordis_] .RAJz1a_leading,.RAJz1a_root[data-tool^=cordis_] .RAJz1a_title{color:var(--dsw-alias-state-business-primary)}.RAJz1a_root[data-tool^=cordis_] .RAJz1a_title{font-weight:500}.RAJz1a_root[data-tool^=cordis_] .RAJz1a_sep{background:var(--dsw-alias-state-business-primary)}.RAJz1a_chevron{color:var(--dsw-alias-label-secondary)}.RAJz1a_title{font-weight:400}.RAJz1a_sep{background:var(--dsw-alias-label-caption);border-radius:1px;flex:none;width:2px;height:2px;margin:0 8px}.RAJz1a_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;overflow:hidden}.RAJz1a_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}.RAJz1a_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)}.RAJz1a_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;overflow:hidden}.RAJz1a_fileLink:hover{color:var(--dsw-alias-label-primary);text-decoration-color:currentColor}.RAJz1a_errorSummary{color:var(--dsw-alias-state-error-primary)}.RAJz1a_bodyWrap{flex-direction:column;display:flex}.RAJz1a_inspectButton{border:1px solid var(--dsw-alias-border-l2);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}.RAJz1a_root:hover .RAJz1a_inspectButton,.RAJz1a_inspectButton:focus-visible{opacity:1}.RAJz1a_inspectButton:hover{background:var(--dsw-alias-interactive-bg-hover-solid);color:var(--dsw-alias-label-primary)}.RAJz1a_bodyScroll{max-height:260px;overflow-y:auto}.RAJz1a_ioCard{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-markdown-code-block);font:var(--dsw-font-markdown-code-block-small);border-radius:12px;flex-direction:column;margin:4px 0 4px 4px;display:flex}.RAJz1a_ioSection{grid-template-columns:max-content 1fr;align-items:baseline;column-gap:14px;max-height:150px;padding:12px 16px;display:grid;overflow-y:auto}.RAJz1a_ioSection::-webkit-scrollbar-thumb{background-clip:padding-box;border:2px solid #0000;border-radius:6px}.RAJz1a_ioSection::-webkit-scrollbar-track{margin:6px 0}.RAJz1a_ioLabel{color:var(--dsw-alias-label-caption);align-self:start;position:sticky;top:0}.RAJz1a_ioDivider{background:var(--dsw-alias-border-l2);flex:none;height:1px}.RAJz1a_ioText{white-space:pre-wrap;word-break:break-word;min-width:0;color:var(--dsw-alias-label-secondary)}.RAJz1a_ioText[data-error]{color:var(--dsw-alias-state-error-primary)}.RAJz1a_codeBody,.RAJz1a_terminalBody,.RAJz1a_diffBody,.RAJz1a_readBody,.RAJz1a_searchBody,.RAJz1a_webBody{margin:4px 0 4px 4px}.RAJz1a_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}.RAJz1a_codeBody{--dsl-code-block-content-font:var(--dsw-font-markdown-code-block-small)}.RAJz1a_terminalBody{--dsl-terminal-font:var(--dsw-font-markdown-code-block-small);--dsl-terminal-line-height:18px;--dsl-terminal-output-max-height:224px;border:1px solid var(--dsw-alias-border-l1)}.RAJz1a_visuallyHidden{clip:rect(0 0 0 0);white-space:nowrap;width:1px;height:1px;position:absolute;overflow:hidden}";
|
|
1039
1046
|
const tagId$3 = "@prettier-ai/dsh-client-ui-tool/ToolRow.module.css";
|
|
1040
1047
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]") === null) {
|
|
1041
1048
|
const tag = document.createElement("style");
|
|
@@ -1050,6 +1057,7 @@ window.__ModuleLoader__.load({
|
|
|
1050
1057
|
"chevron": "RAJz1a_chevron",
|
|
1051
1058
|
"codeBody": "RAJz1a_codeBody",
|
|
1052
1059
|
"diffBody": "RAJz1a_diffBody",
|
|
1060
|
+
"diffStat": "RAJz1a_diffStat",
|
|
1053
1061
|
"dsh-tool-row-sweep": "RAJz1a_dsh-tool-row-sweep",
|
|
1054
1062
|
"errorSummary": "RAJz1a_errorSummary",
|
|
1055
1063
|
"fileLink": "RAJz1a_fileLink",
|
|
@@ -1094,7 +1102,7 @@ window.__ModuleLoader__.load({
|
|
|
1094
1102
|
default: return null;
|
|
1095
1103
|
}
|
|
1096
1104
|
}
|
|
1097
|
-
function ToolRow({ t, variant, toolName, icon, title, summary, summarySuffix,
|
|
1105
|
+
function ToolRow({ t, variant, toolName, icon, title, summary, summarySuffix, bodyRaw, output, askQuestion, errorSummary, terminal, diff, read, search, web, state, filePath, onOpenFile, inspect }) {
|
|
1098
1106
|
const [expanded, setExpanded] = (0, react.useState)(false);
|
|
1099
1107
|
const terminalLabels = (0, react.useMemo)(() => terminalBlockLabels(t), [t]);
|
|
1100
1108
|
const diffLabels = (0, react.useMemo)(() => diffBlockLabels(t), [t]);
|
|
@@ -1108,12 +1116,24 @@ window.__ModuleLoader__.load({
|
|
|
1108
1116
|
const webBody = web ?? null;
|
|
1109
1117
|
const askQuestionBody = askQuestion ?? null;
|
|
1110
1118
|
const outputText = output ?? null;
|
|
1111
|
-
const
|
|
1119
|
+
const card = askQuestionBody ?? terminalBody ?? diffBody ?? readBody ?? searchBody ?? webBody;
|
|
1120
|
+
const expandable = bodyRaw != null || outputText !== null || card !== null;
|
|
1112
1121
|
const open = expanded && expandable;
|
|
1122
|
+
const bodyText = (0, react.useMemo)(() => open && card === null && bodyRaw != null ? formatToolBody(variant, bodyRaw) : null, [
|
|
1123
|
+
bodyRaw,
|
|
1124
|
+
card,
|
|
1125
|
+
open,
|
|
1126
|
+
variant
|
|
1127
|
+
]);
|
|
1113
1128
|
const status = stateStatus$1(state, t);
|
|
1114
1129
|
const failureLine = state === "error" ? errorSummary ?? null : null;
|
|
1115
1130
|
const summaryText = failureLine ?? terminalBody?.description ?? summary;
|
|
1116
|
-
const
|
|
1131
|
+
const diffStat = (0, react.useMemo)(() => {
|
|
1132
|
+
if (diffBody === null) return null;
|
|
1133
|
+
const { added, removed } = (0, _prettier_ai_dsh_client_ui_primitives.diffTotals)(diffBody.card.diffs);
|
|
1134
|
+
return `+${added} -${removed}`;
|
|
1135
|
+
}, [diffBody]);
|
|
1136
|
+
const suffix = failureLine === null ? summarySuffix ?? diffStat : null;
|
|
1117
1137
|
const fileLink = filePath !== void 0 && onOpenFile !== void 0 && failureLine === null;
|
|
1118
1138
|
const toggleExpand = () => {
|
|
1119
1139
|
setExpanded((v) => !v);
|
|
@@ -1125,7 +1145,7 @@ window.__ModuleLoader__.load({
|
|
|
1125
1145
|
const fileLinkKeyDown = (event) => {
|
|
1126
1146
|
if (event.key === "Enter" || event.key === " ") event.stopPropagation();
|
|
1127
1147
|
};
|
|
1128
|
-
const cardBody = variant === "code" ? null :
|
|
1148
|
+
const cardBody = variant === "code" ? null : bodyText;
|
|
1129
1149
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
1130
1150
|
className: ToolRow_module_css_default.root,
|
|
1131
1151
|
"data-variant": variant,
|
|
@@ -1162,7 +1182,7 @@ window.__ModuleLoader__.load({
|
|
|
1162
1182
|
children: summaryText
|
|
1163
1183
|
}),
|
|
1164
1184
|
suffix !== null && (0, react_jsx_runtime.jsx)("span", {
|
|
1165
|
-
className: ToolRow_module_css_default.summarySuffix,
|
|
1185
|
+
className: clsx(ToolRow_module_css_default.summarySuffix, suffix === diffStat && ToolRow_module_css_default.diffStat),
|
|
1166
1186
|
children: suffix
|
|
1167
1187
|
})
|
|
1168
1188
|
] }),
|
|
@@ -1195,10 +1215,10 @@ window.__ModuleLoader__.load({
|
|
|
1195
1215
|
...webBody,
|
|
1196
1216
|
labels: webLabels,
|
|
1197
1217
|
className: ToolRow_module_css_default.webBody
|
|
1198
|
-
}) : (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [variant === "code" &&
|
|
1218
|
+
}) : (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [variant === "code" && bodyText !== null && (0, react_jsx_runtime.jsx)("div", {
|
|
1199
1219
|
className: ToolRow_module_css_default.bodyScroll,
|
|
1200
1220
|
children: (0, react_jsx_runtime.jsx)(_prettier_ai_dsh_client_ui_primitives.CodeBlock, {
|
|
1201
|
-
code:
|
|
1221
|
+
code: bodyText,
|
|
1202
1222
|
lang: "typescript",
|
|
1203
1223
|
copyLabel: t("copy"),
|
|
1204
1224
|
copiedLabel: t("copied"),
|
|
@@ -1271,7 +1291,7 @@ window.__ModuleLoader__.load({
|
|
|
1271
1291
|
icon: VARIANT_ICONS[model.variant],
|
|
1272
1292
|
title: t(model.titleKey),
|
|
1273
1293
|
summary: model.summary,
|
|
1274
|
-
|
|
1294
|
+
bodyRaw: singleFile ? null : model.bodyRaw,
|
|
1275
1295
|
output: model.output,
|
|
1276
1296
|
errorSummary: model.errorSummary,
|
|
1277
1297
|
terminal,
|
|
@@ -1376,8 +1396,8 @@ window.__ModuleLoader__.load({
|
|
|
1376
1396
|
* @param props - whole-Tool owner data and the Tool-owned child-slot share.
|
|
1377
1397
|
* @returns the Tool call tree.
|
|
1378
1398
|
*/
|
|
1379
|
-
function ToolCallTree({ renderSlot, node, selectedCallId, cwd, openFile, inspectCall,
|
|
1380
|
-
const home =
|
|
1399
|
+
function ToolCallTree({ renderSlot, node, selectedCallId, cwd, openFile, inspectCall, useHostInfo, t }) {
|
|
1400
|
+
const home = useHostInfo((info) => info.home);
|
|
1381
1401
|
const block = node.data.root;
|
|
1382
1402
|
return (0, react_jsx_runtime.jsx)(ToolCallBranch, {
|
|
1383
1403
|
renderSlot,
|
|
@@ -1419,8 +1439,8 @@ window.__ModuleLoader__.load({
|
|
|
1419
1439
|
* @param props - selected call slice, workspace root, host home, and locale seat.
|
|
1420
1440
|
* @returns the details output body.
|
|
1421
1441
|
*/
|
|
1422
|
-
function ToolDetails({ block, cwd,
|
|
1423
|
-
const home =
|
|
1442
|
+
function ToolDetails({ block, cwd, useHostInfo, t }) {
|
|
1443
|
+
const home = useHostInfo((info) => info.home);
|
|
1424
1444
|
const terminalModel = terminalCardModel(block, cwd);
|
|
1425
1445
|
if (terminalModel !== null) {
|
|
1426
1446
|
const terminal = localizeTerminalCardModel(terminalModel, t);
|
|
@@ -1616,7 +1636,7 @@ window.__ModuleLoader__.load({
|
|
|
1616
1636
|
icon: (0, react_jsx_runtime.jsx)(_prettier_ai_dsh_client_ui_primitives.IconQuestionOutline14, {}),
|
|
1617
1637
|
title: t("ask.rowTitle"),
|
|
1618
1638
|
summary,
|
|
1619
|
-
|
|
1639
|
+
bodyRaw: transcript === null ? model.bodyRaw : null,
|
|
1620
1640
|
output: transcript === null ? model.output : null,
|
|
1621
1641
|
askQuestion: transcript,
|
|
1622
1642
|
state,
|
|
@@ -1694,9 +1714,15 @@ window.__ModuleLoader__.load({
|
|
|
1694
1714
|
const state = model.state === "ok" && terminalModel !== null && terminalFailed(terminalModel) ? "error" : model.state;
|
|
1695
1715
|
const status = stateStatus(state, t);
|
|
1696
1716
|
const [expanded, setExpanded] = (0, react.useState)(false);
|
|
1697
|
-
const genericBody = terminal === null && (model.state === "error" || isSettledPersistentShellCall(block)) && (model.
|
|
1717
|
+
const genericBody = terminal === null && (model.state === "error" || isSettledPersistentShellCall(block)) && (model.bodyRaw !== null || model.output !== null);
|
|
1698
1718
|
const expandable = terminal !== null || genericBody;
|
|
1699
1719
|
const open = expanded && expandable;
|
|
1720
|
+
const body = (0, react.useMemo)(() => open && genericBody && model.bodyRaw !== null ? formatToolBody(model.variant, model.bodyRaw) : null, [
|
|
1721
|
+
genericBody,
|
|
1722
|
+
model.bodyRaw,
|
|
1723
|
+
model.variant,
|
|
1724
|
+
open
|
|
1725
|
+
]);
|
|
1700
1726
|
const failureLine = model.state === "error" ? model.errorSummary : null;
|
|
1701
1727
|
const toggleExpand = () => {
|
|
1702
1728
|
setExpanded((v) => !v);
|
|
@@ -1755,17 +1781,17 @@ window.__ModuleLoader__.load({
|
|
|
1755
1781
|
}) : (0, react_jsx_runtime.jsxs)("div", {
|
|
1756
1782
|
className: bash_sample_module_css_default.ioCard,
|
|
1757
1783
|
children: [
|
|
1758
|
-
|
|
1784
|
+
body !== null && (0, react_jsx_runtime.jsxs)("div", {
|
|
1759
1785
|
className: bash_sample_module_css_default.ioSection,
|
|
1760
1786
|
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
1761
1787
|
className: bash_sample_module_css_default.ioLabel,
|
|
1762
1788
|
children: t("row.input")
|
|
1763
1789
|
}), (0, react_jsx_runtime.jsx)("span", {
|
|
1764
1790
|
className: bash_sample_module_css_default.ioText,
|
|
1765
|
-
children:
|
|
1791
|
+
children: body
|
|
1766
1792
|
})]
|
|
1767
1793
|
}),
|
|
1768
|
-
|
|
1794
|
+
body !== null && model.output !== null && (0, react_jsx_runtime.jsx)("span", {
|
|
1769
1795
|
className: bash_sample_module_css_default.ioDivider,
|
|
1770
1796
|
"aria-hidden": true
|
|
1771
1797
|
}),
|
|
@@ -1817,7 +1843,6 @@ window.__ModuleLoader__.load({
|
|
|
1817
1843
|
icon: (0, react_jsx_runtime.jsx)(_prettier_ai_dsh_client_ui_primitives.IconEditOutline16, { size: 14 }),
|
|
1818
1844
|
title: t(model.titleKey),
|
|
1819
1845
|
summary: model.summary,
|
|
1820
|
-
body: null,
|
|
1821
1846
|
output: model.output,
|
|
1822
1847
|
errorSummary: model.errorSummary,
|
|
1823
1848
|
diff,
|
|
@@ -1861,7 +1886,6 @@ window.__ModuleLoader__.load({
|
|
|
1861
1886
|
icon: (0, react_jsx_runtime.jsx)(_prettier_ai_dsh_client_ui_primitives.IconBrowseOutline16, { size: 14 }),
|
|
1862
1887
|
title: t(model.titleKey),
|
|
1863
1888
|
summary: model.summary,
|
|
1864
|
-
body: null,
|
|
1865
1889
|
output: model.output,
|
|
1866
1890
|
errorSummary: model.errorSummary,
|
|
1867
1891
|
read,
|
|
@@ -1900,7 +1924,6 @@ window.__ModuleLoader__.load({
|
|
|
1900
1924
|
icon: (0, react_jsx_runtime.jsx)(_prettier_ai_dsh_client_ui_primitives.IconSearchOutline16, { size: 14 }),
|
|
1901
1925
|
title: t(toolName === "grep" ? SEARCH_TITLE_KEYS.grep : toolName === "glob" ? SEARCH_TITLE_KEYS.glob : model.titleKey),
|
|
1902
1926
|
summary: model.summary,
|
|
1903
|
-
body: null,
|
|
1904
1927
|
output: model.output,
|
|
1905
1928
|
errorSummary: model.errorSummary,
|
|
1906
1929
|
search,
|
|
@@ -2003,7 +2026,7 @@ window.__ModuleLoader__.load({
|
|
|
2003
2026
|
title: t("todo.rowTitle"),
|
|
2004
2027
|
summary: summary.text,
|
|
2005
2028
|
summarySuffix: summary.extra > 0 ? `+${summary.extra}` : null,
|
|
2006
|
-
|
|
2029
|
+
bodyRaw: model.bodyRaw,
|
|
2007
2030
|
output: model.output,
|
|
2008
2031
|
errorSummary: model.errorSummary,
|
|
2009
2032
|
state: model.state,
|
|
@@ -2040,7 +2063,6 @@ window.__ModuleLoader__.load({
|
|
|
2040
2063
|
icon,
|
|
2041
2064
|
title: t(toolName === "web_search" ? WEB_TITLE_KEYS.web_search : toolName === "web_fetch" ? WEB_TITLE_KEYS.web_fetch : model.titleKey),
|
|
2042
2065
|
summary: model.summary,
|
|
2043
|
-
body: null,
|
|
2044
2066
|
output: model.output,
|
|
2045
2067
|
errorSummary: model.errorSummary,
|
|
2046
2068
|
web,
|
|
@@ -2069,15 +2091,18 @@ window.__ModuleLoader__.load({
|
|
|
2069
2091
|
};
|
|
2070
2092
|
//#endregion
|
|
2071
2093
|
//#region lib/types/client/apply.js
|
|
2072
|
-
/** Required services: the slot registry and the Host
|
|
2073
|
-
const inject = ["slots", "
|
|
2094
|
+
/** Required services: the slot registry and the Remote face carrying the Host home used for POSIX `~`. */
|
|
2095
|
+
const inject = ["slots", "remote"];
|
|
2074
2096
|
/**
|
|
2075
2097
|
* Mount the whole-Tool renderers and built-in atomic Tool registrations.
|
|
2076
2098
|
* @param ctx - Client root context.
|
|
2077
2099
|
*/
|
|
2078
2100
|
function apply(ctx) {
|
|
2079
|
-
const
|
|
2080
|
-
|
|
2101
|
+
const hostInfo = {
|
|
2102
|
+
getSnapshot: () => ctx.remote.$host,
|
|
2103
|
+
subscribe: (listener) => ctx.on("connection/reset", listener)
|
|
2104
|
+
};
|
|
2105
|
+
const toolInject = () => ({ hooks: { hostInfo } });
|
|
2081
2106
|
ctx.slots.inject("conversation.chat.node", () => ctx.slots.register({
|
|
2082
2107
|
name: "conversation.chat.node",
|
|
2083
2108
|
key: "tool-call",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
/** Register the Tool call tree, details renderer, and built-in atomic views. */
|
|
1
2
|
import type { Context as ClientContext } from '@prettier-ai/cordis';
|
|
2
|
-
/** Required services: the slot registry and the Host
|
|
3
|
+
/** Required services: the slot registry and the Remote face carrying the Host home used for POSIX `~`. */
|
|
3
4
|
export declare const inject: string[];
|
|
4
5
|
/**
|
|
5
6
|
* Mount the whole-Tool renderers and built-in atomic Tool registrations.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Tool UI slot declarations and their composed component props. */
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
2
|
+
import type { HostObservable, InjectFace, PropsLocale, PropsRenderSlots, PropsRuntime } from '@prettier-ai/dsh-client-ui-slots';
|
|
3
|
+
import type { RemoteHostFacts } from '@prettier-ai/dsh-api-remotes/client';
|
|
4
4
|
import type { ToolCallBlock } from '@prettier-ai/dsh-client-ui-chat/client';
|
|
5
5
|
declare module '@prettier-ai/dsh-client-ui-slots' {
|
|
6
6
|
interface SlotMap {
|
|
@@ -45,14 +45,19 @@ export interface ToolCallOwnerProps {
|
|
|
45
45
|
/** Full props of a registered atomic Tool view. */
|
|
46
46
|
export type ToolCallViewProps = PropsRuntime<'tool.call.toolview'>;
|
|
47
47
|
/** Injected Host description for POSIX home-path display. */
|
|
48
|
-
export type
|
|
48
|
+
export type ToolHostInfoInjected = {
|
|
49
49
|
hooks: {
|
|
50
|
-
/**
|
|
51
|
-
|
|
50
|
+
/**
|
|
51
|
+
* Fixed Host facts, reached through a hook rather than injected as values:
|
|
52
|
+
* the renderer memoizes an entry's inject result for the registration's
|
|
53
|
+
* lifetime, so facts read there would freeze at whatever the first render
|
|
54
|
+
* saw. Select the field the view needs (`info => info.home`).
|
|
55
|
+
*/
|
|
56
|
+
hostInfo: HostObservable<RemoteHostFacts>;
|
|
52
57
|
};
|
|
53
58
|
};
|
|
54
59
|
/** Full props of the Tool call-tree renderer registered as a `tool-call` Chat Node. */
|
|
55
|
-
export type ToolTreeProps = PropsRuntime<'conversation.chat.node', 'tool-call'> & PropsRenderSlots<'tool.call.toolview'> & PropsLocale<'conversation'> & InjectFace<
|
|
60
|
+
export type ToolTreeProps = PropsRuntime<'conversation.chat.node', 'tool-call'> & PropsRenderSlots<'tool.call.toolview'> & PropsLocale<'conversation'> & InjectFace<ToolHostInfoInjected>;
|
|
56
61
|
/** Full props of the selected Tool output renderer in the details panel. */
|
|
57
|
-
export type ToolDetailsProps = PropsRuntime<'conversation.details.tool'> & PropsLocale<'conversation'> & InjectFace<
|
|
62
|
+
export type ToolDetailsProps = PropsRuntime<'conversation.details.tool'> & PropsLocale<'conversation'> & InjectFace<ToolHostInfoInjected>;
|
|
58
63
|
//# sourceMappingURL=slots.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
/** Browser Tool plugin: whole-call composition and keyed atomic Tool views. */
|
|
2
2
|
export { apply, inject } from './apply.ts';
|
|
3
|
-
export type { ToolCallOwnerProps, ToolCallViewProps,
|
|
3
|
+
export type { ToolCallOwnerProps, ToolCallViewProps, ToolDetailsProps, ToolHostInfoInjected, ToolTreeProps, } from './contract/slots.ts';
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -5,5 +5,5 @@ import type { ToolTreeProps } from '../contract/slots.ts';
|
|
|
5
5
|
* @param props - whole-Tool owner data and the Tool-owned child-slot share.
|
|
6
6
|
* @returns the Tool call tree.
|
|
7
7
|
*/
|
|
8
|
-
export declare function ToolCallTree({ renderSlot, node, selectedCallId, cwd, openFile, inspectCall,
|
|
8
|
+
export declare function ToolCallTree({ renderSlot, node, selectedCallId, cwd, openFile, inspectCall, useHostInfo, t, }: ToolTreeProps): import("react").JSX.Element;
|
|
9
9
|
//# sourceMappingURL=ToolCallTree.d.ts.map
|
|
@@ -5,5 +5,5 @@ import type { ToolDetailsProps } from '../contract/slots.ts';
|
|
|
5
5
|
* @param props - selected call slice, workspace root, host home, and locale seat.
|
|
6
6
|
* @returns the details output body.
|
|
7
7
|
*/
|
|
8
|
-
export declare function ToolDetails({ block, cwd,
|
|
8
|
+
export declare function ToolDetails({ block, cwd, useHostInfo, t, }: Pick<ToolDetailsProps, 'block' | 'cwd' | 'useHostInfo' | 't'>): import("react").JSX.Element;
|
|
9
9
|
//# sourceMappingURL=ToolDetails.d.ts.map
|
|
@@ -5,7 +5,7 @@ import { type ReadCardModel } from '../models/read-card-model.ts';
|
|
|
5
5
|
import { type SearchCardModel } from '../models/search-card-model.ts';
|
|
6
6
|
import { type TerminalCardModel } from '../models/terminal-card-model.ts';
|
|
7
7
|
import type { AskQuestionCardModel } from '../models/ask-question-card-model.ts';
|
|
8
|
-
import type
|
|
8
|
+
import { type ToolRowState, type ToolRowVariant } from '../models/tool-call-model.ts';
|
|
9
9
|
import type { WebCardModelProps } from '../models/web-card-model.ts';
|
|
10
10
|
export interface ToolRowProps {
|
|
11
11
|
t: TranslateNS<'conversation'>;
|
|
@@ -23,8 +23,8 @@ export interface ToolRowProps {
|
|
|
23
23
|
* error row, whose collapsed summary is the failure line instead.
|
|
24
24
|
*/
|
|
25
25
|
summarySuffix?: string | null | undefined;
|
|
26
|
-
/**
|
|
27
|
-
|
|
26
|
+
/** Original argument JSON formatted only while the row is expanded. */
|
|
27
|
+
bodyRaw?: string | null | undefined;
|
|
28
28
|
/** Flattened result text for the expanded Output section; null/absent = no output section. */
|
|
29
29
|
output?: string | null | undefined;
|
|
30
30
|
/** Ask-user transcript card; card fields are mutually exclusive and replace text sections. */
|
|
@@ -51,5 +51,5 @@ export interface ToolRowProps {
|
|
|
51
51
|
*/
|
|
52
52
|
inspect?: (() => void) | undefined;
|
|
53
53
|
}
|
|
54
|
-
export declare function ToolRow({ t, variant, toolName, icon, title, summary, summarySuffix,
|
|
54
|
+
export declare function ToolRow({ t, variant, toolName, icon, title, summary, summarySuffix, bodyRaw, output, askQuestion, errorSummary, terminal, diff, read, search, web, state, filePath, onOpenFile, inspect, }: ToolRowProps): import("react").JSX.Element;
|
|
55
55
|
//# sourceMappingURL=ToolRow.d.ts.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Pure row-model derivation for tool summary rows: variant classification,
|
|
3
|
-
* one-line summary,
|
|
4
|
-
* frozen call slice. Input material comes from the call ARGUMENTS;
|
|
5
|
-
* error material from the settled result node. A supported terminal
|
|
6
|
-
* its expanded body from `terminalCardModel` instead.
|
|
3
|
+
* one-line summary, expansion-time body input, and flattened result output
|
|
4
|
+
* from the frozen call slice. Input material comes from the call ARGUMENTS;
|
|
5
|
+
* output and error material from the settled result node. A supported terminal
|
|
6
|
+
* call gets its expanded body from `terminalCardModel` instead.
|
|
7
7
|
*/
|
|
8
8
|
import type { ToolCallBlock, ToolResultNode } from '@prettier-ai/dsh-client-ui-chat/client';
|
|
9
9
|
import type { LocaleKeysOf } from '@prettier-ai/dsh-client-ui-slots';
|
|
@@ -40,8 +40,8 @@ export interface ToolRowModel {
|
|
|
40
40
|
* relative values against the session cwd before opening.
|
|
41
41
|
*/
|
|
42
42
|
filePath: string | undefined;
|
|
43
|
-
/**
|
|
44
|
-
|
|
43
|
+
/** Original argument JSON retained for expansion-time body formatting. */
|
|
44
|
+
bodyRaw: string | null;
|
|
45
45
|
/** Flattened result text ({@link resultText}); null while running or when the result carries no text. */
|
|
46
46
|
output: string | null;
|
|
47
47
|
/** First line of the result text on an error row; null for every other state. */
|
|
@@ -63,6 +63,13 @@ export declare function resultText(node: ToolResultNode): string;
|
|
|
63
63
|
* @returns the path relative to the workspace root, or unchanged when it is not rooted there.
|
|
64
64
|
*/
|
|
65
65
|
export declare function relativizeToCwd(text: string, cwd: string | undefined): string;
|
|
66
|
+
/**
|
|
67
|
+
* Format one argument payload when its generic input body becomes visible.
|
|
68
|
+
* @param variant - row presentation selected for the Tool name.
|
|
69
|
+
* @param argsRaw - original argument JSON or incomplete raw text.
|
|
70
|
+
* @returns display body, or null for empty input.
|
|
71
|
+
*/
|
|
72
|
+
export declare function formatToolBody(variant: ToolRowVariant, argsRaw: string): string | null;
|
|
66
73
|
/**
|
|
67
74
|
* Derive the full row model from a frozen call slice.
|
|
68
75
|
* @param toolName - wire tool name (dispatch-supplied; survives windowless results).
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prettier-ai/dsh-client-ui-tool",
|
|
3
3
|
"description": "Client Tool call-tree renderer and keyed per-tool presentation slot",
|
|
4
|
-
"version": "0.1.2-alpha.
|
|
4
|
+
"version": "0.1.2-alpha.3",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -45,37 +45,27 @@
|
|
|
45
45
|
"clsx": "^2.0.0"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
|
-
"@prettier-ai/cordis": "^4.0.
|
|
49
|
-
"@prettier-ai/dsh-client-connection": "^0.1.2-alpha.1",
|
|
50
|
-
"@prettier-ai/dsh-client-ui-conversation": "^0.1.2-alpha.1",
|
|
51
|
-
"@prettier-ai/dsh-invariants": "^0.1.2-alpha.1",
|
|
52
|
-
"@prettier-ai/dsh-api-workspace-controller": "^0.1.2-alpha.1",
|
|
53
|
-
"@prettier-ai/dsh-client-locale": "^0.1.2-alpha.1",
|
|
54
|
-
"@prettier-ai/dsh-client-ui-chat": "^0.1.2-alpha.1",
|
|
55
|
-
"@prettier-ai/dsh-api-remotes": "^0.1.2-alpha.1",
|
|
56
|
-
"@prettier-ai/dsh-client-ui-renderer": "^0.1.2-alpha.1",
|
|
57
|
-
"@prettier-ai/dsh-client-ui-session": "^0.1.2-alpha.1",
|
|
58
|
-
"@prettier-ai/dsh-util-workspace-path": "^0.1.2-alpha.1"
|
|
48
|
+
"@prettier-ai/cordis": "^4.0.2"
|
|
59
49
|
},
|
|
60
50
|
"devDependencies": {
|
|
61
51
|
"@testing-library/react": "^16.1.0",
|
|
62
52
|
"@types/react": "~18.3.1",
|
|
63
53
|
"react": "^18.2.0",
|
|
64
54
|
"react-dom": "^18.2.0",
|
|
65
|
-
"@prettier-ai/cordis": "^4.0.
|
|
66
|
-
"@prettier-ai/dsh-api-remotes": "^0.1.2-alpha.
|
|
67
|
-
"@prettier-ai/dsh-client-connection": "^0.1.2-alpha.
|
|
68
|
-
"@prettier-ai/dsh-client-locale": "^0.1.2-alpha.
|
|
69
|
-
"@prettier-ai/dsh-client-
|
|
70
|
-
"@prettier-ai/dsh-client-
|
|
71
|
-
"@prettier-ai/dsh-client-ui-primitives": "^0.1.2-alpha.
|
|
72
|
-
"@prettier-ai/dsh-
|
|
73
|
-
"@prettier-ai/dsh-
|
|
74
|
-
"@prettier-ai/dsh-
|
|
75
|
-
"@prettier-ai/dsh-client-ui-
|
|
76
|
-
"@prettier-ai/dsh-
|
|
77
|
-
"@prettier-ai/dsh-client-ui-chat": "^0.1.2-alpha.
|
|
78
|
-
"@prettier-ai/dsh-
|
|
55
|
+
"@prettier-ai/cordis": "^4.0.2",
|
|
56
|
+
"@prettier-ai/dsh-api-remotes": "^0.1.2-alpha.3",
|
|
57
|
+
"@prettier-ai/dsh-client-connection": "^0.1.2-alpha.3",
|
|
58
|
+
"@prettier-ai/dsh-client-locale": "^0.1.2-alpha.3",
|
|
59
|
+
"@prettier-ai/dsh-client-ui-conversation": "^0.1.2-alpha.3",
|
|
60
|
+
"@prettier-ai/dsh-client-test-runtime": "^0.1.2-alpha.3",
|
|
61
|
+
"@prettier-ai/dsh-client-ui-primitives": "^0.1.2-alpha.3",
|
|
62
|
+
"@prettier-ai/dsh-invariants": "^0.1.2-alpha.3",
|
|
63
|
+
"@prettier-ai/dsh-api-workspace-controller": "^0.1.2-alpha.3",
|
|
64
|
+
"@prettier-ai/dsh-client-ui-renderer": "^0.1.2-alpha.3",
|
|
65
|
+
"@prettier-ai/dsh-client-ui-session": "^0.1.2-alpha.3",
|
|
66
|
+
"@prettier-ai/dsh-util-workspace-path": "^0.1.2-alpha.3",
|
|
67
|
+
"@prettier-ai/dsh-client-ui-chat": "^0.1.2-alpha.3",
|
|
68
|
+
"@prettier-ai/dsh-client-ui-slots": "^0.1.2-alpha.3"
|
|
79
69
|
},
|
|
80
70
|
"files": [
|
|
81
71
|
"lib/index.js",
|