Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion desktop/frontend/scripts/check-bundle-budget.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ const rawInitialBytes = [...initialJS, ...initialCSS, ...appShellCSS]
// The shared harness decision surface adds a bounded startup stylesheet
// payload. The session-runtime fence and current-base merge measure 2493.1 KiB
// locally; retain the smallest bounded cross-platform ceiling.
const rawInitialBudgetKiB = 2_494.3;
// The shell card command section (#9858) measures 2494.5 KiB raw on this base.
const rawInitialBudgetKiB = 2_494.6;
assertBudget("initial raw JavaScript and CSS", rawInitialBytes, rawInitialBudgetKiB * 1024);
assertBudget("largest initial JavaScript chunk raw", largestInitialJSRaw, 1_000 * 1024);
Original file line number Diff line number Diff line change
Expand Up @@ -398,5 +398,44 @@ console.log("\ntool card shell execution");
await ui.cleanup();
}

// ── Command section: expanded shell card shows the full command (#9858) ──
{
const longCommand =
"git status && git diff --stat && docker system df -v && kubectl get pods -A -o wide | grep -v kube-system | head -80 && echo LONG_COMMAND_TAIL_MARKER_DONE";
let s = reducer(initialState, { type: "event", e: { kind: "turn_started" } });
s = reducer(s, {
type: "event",
e: {
kind: "tool_dispatch",
tool: { id: "cmd-vis", name: "bash", args: JSON.stringify({ command: longCommand }), readOnly: false },
},
});
s = reducer(s, {
type: "event",
e: {
kind: "tool_result",
tool: { id: "cmd-vis", name: "bash", readOnly: false, output: "done", durationMs: 5 },
},
});
const item = s.items.find((it): it is ToolItem => it.kind === "tool" && it.id === "cmd-vis");
ok(!!item, "command section: tool item created");
// The reducer archives tool payloads for memory efficiency; un-archiving
// here keeps this test focused on the command-section render (lazy full-data
// loading needs a live bridge and is exercised in the desktop app).
if (item) (item as any).dataArchived = false;
const ui = await renderCard(item!);
await ui.expand();
const section = document.querySelector(".tool__command");
ok(!!section, "command section: .tool__command rendered after expand");
const text = section?.textContent ?? "";
ok(text.includes("LONG_COMMAND_TAIL_MARKER_DONE"), "command section: full command tail visible (not truncated)");
const label = document.querySelector(".tool__command-label")?.textContent ?? "";
ok(label.length > 0, "command section: label rendered");
// Collapsed header keeps its glanceable subject row (CSS ellipsis is visual
// and not assertable in jsdom); the command section lives in the body.
ok(!!document.querySelector(".tool__subject"), "command section: header subject row retained");
await ui.cleanup();
}

console.log(`\n${passed} passed, ${failed} failed, ${passed + failed} total`);
if (failed > 0) process.exit(1);
7 changes: 7 additions & 0 deletions desktop/frontend/src/components/ToolCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,13 @@ export const ToolCard = memo(function ToolCard({ item, subcalls, tabId, displayN
</div>
)}

{isShellCard && subject && (
<div className="tool__command">
<div className="tool__command-label">{t("tool.command")}</div>
<CodeViewer value={subject} language="bash" maxHeight={180} />
</div>
)}

{shellPreview && (
<>
<CodeViewer value={showAll ? shellOutput! : shellPreview.preview} maxHeight={showAll ? 480 : 260} />
Expand Down
1 change: 1 addition & 0 deletions desktop/frontend/src/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3317,6 +3317,7 @@ export const en = {
"tool.error": "error",
"tool.receivingArgs": "receiving arguments ↓ {chars}…",
"tool.errorReceiptMismatch": "verification command has no matching successful receipt",
"tool.command": "Command",
"tool.truncated": "output truncated",
"tool.showAllLines": "show all {n} lines",
"tool.showErrorDetails": "show error details",
Expand Down
1 change: 1 addition & 0 deletions desktop/frontend/src/locales/zh-TW.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2369,6 +2369,7 @@ export const zhTW: Record<DictKey, string> = {
"tool.error": "錯誤",
"tool.receivingArgs": "接收參數中 ↓ {chars}…",
"tool.errorReceiptMismatch": "證據命令沒有匹配的成功執行記錄",
"tool.command": "命令",
"tool.truncated": "輸出已截斷",
"tool.showAllLines": "顯示全部 {n} 行",
"tool.showErrorDetails": "顯示錯誤詳情",
Expand Down
1 change: 1 addition & 0 deletions desktop/frontend/src/locales/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3320,6 +3320,7 @@ export const zh: Record<DictKey, string> = {
"tool.error": "错误",
"tool.receivingArgs": "接收参数中 ↓ {chars}…",
"tool.errorReceiptMismatch": "证据命令没有匹配的成功执行记录",
"tool.command": "命令",
"tool.truncated": "输出已截断",
"tool.showAllLines": "显示全部 {n} 行",
"tool.showErrorDetails": "显示错误详情",
Expand Down
11 changes: 11 additions & 0 deletions desktop/frontend/src/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -5054,6 +5054,17 @@ button.reasoning-summary:focus-visible {
color: var(--accent);
background: color-mix(in srgb, var(--fg) 6%, transparent);
}
.tool__command {
display: flex;
flex-direction: column;
gap: 4px;
}

.tool__command-label {
color: var(--fg-faint);
font-size: var(--text-sm);
}

.tool__search-summary {
display: flex;
flex-direction: column;
Expand Down
Loading