diff --git a/packages/views/common/task-transcript/agent-transcript-dialog.tsx b/packages/views/common/task-transcript/agent-transcript-dialog.tsx
index 90116b73c..9f4bf9c08 100644
--- a/packages/views/common/task-transcript/agent-transcript-dialog.tsx
+++ b/packages/views/common/task-transcript/agent-transcript-dialog.tsx
@@ -436,7 +436,6 @@ export function AgentTranscriptDialog({
? elapsed
: null;
- const toolCount = items.filter((i) => i.type === "tool_use").length;
const copyTranscriptLabel = copied
? t(($) => $.transcript.copied)
: activeFilterKeys.length > 0
@@ -526,7 +525,9 @@ export function AgentTranscriptDialog({
const createdLabel = task.created_at ? formatRunTime(task.created_at) : null;
const startedLabel = task.started_at ? formatRunTime(task.started_at) : null;
const completedLabel = task.completed_at ? formatRunTime(task.completed_at) : null;
+ const hasTriggeredBy = !!task.attribution?.initiator;
const hasRunDetails =
+ hasTriggeredBy ||
!!runtimeInfo ||
!!task.relative_work_dir ||
!!createdLabel ||
@@ -561,13 +562,10 @@ export function AgentTranscriptDialog({
{agentName || agentInfo?.name || ""}
+ {/* Trigger mechanism (why this run exists). The accountable
+ human is audit metadata, not read-time context — it lives in
+ the ⓘ popover as "triggered by", not on this row. */}
{triggerLabel}
- {/* Accountable member (MUL-4302 §9): whose behalf this run is on. */}
-
@@ -585,6 +583,14 @@ export function AgentTranscriptDialog({
{t(($) => $.transcript.run_info)}
{items.length > 0 && (
@@ -837,44 +837,28 @@ interface SortDirectionToggleProps {
labels: { chronological: string; newestFirst: string; ariaLabel: string };
}
+// Sort is a two-state toggle, not a mode picker: one button showing the
+// current direction that flips on click. Shares the toolbar button chassis so
+// it reads as the same control family as density/filter/copy — no tab strip.
function SortDirectionToggle({ value, onChange, labels }: SortDirectionToggleProps) {
+ const isChronological = value === "chronological";
return (
-
onChange(isChronological ? "newest_first" : "chronological")}
aria-label={labels.ariaLabel}
- className="inline-flex shrink-0 items-center rounded border bg-muted/40 p-0.5 text-xs"
+ title={isChronological ? labels.chronological : labels.newestFirst}
+ className="flex shrink-0 items-center gap-1 rounded px-2 py-1 text-xs text-muted-foreground transition-colors hover:bg-accent hover:text-foreground"
>
-
onChange("chronological")}
- className={cn(
- "flex items-center gap-1 rounded px-1.5 py-0.5 transition-colors",
- value === "chronological"
- ? "bg-background text-foreground shadow-sm"
- : "text-muted-foreground hover:text-foreground",
- )}
- >
+ {isChronological ? (
- {labels.chronological}
-
-
onChange("newest_first")}
- className={cn(
- "flex items-center gap-1 rounded px-1.5 py-0.5 transition-colors",
- value === "newest_first"
- ? "bg-background text-foreground shadow-sm"
- : "text-muted-foreground hover:text-foreground",
- )}
- >
+ ) : (
- {labels.newestFirst}
-
-
+ )}
+
+ {isChronological ? labels.chronological : labels.newestFirst}
+
+
);
}
diff --git a/packages/views/common/task-transcript/trace-event-presenter.test.ts b/packages/views/common/task-transcript/trace-event-presenter.test.ts
index ecc5ca0b2..21d17266e 100644
--- a/packages/views/common/task-transcript/trace-event-presenter.test.ts
+++ b/packages/views/common/task-transcript/trace-event-presenter.test.ts
@@ -55,12 +55,16 @@ describe("traceToolArgSummary", () => {
});
describe("traceEventSummary", () => {
- it("takes the first non-empty line for agent text and tool output", () => {
+ it("takes the first non-empty line for agent text", () => {
expect(traceEventSummary({ type: "text", content: "\n\nFirst line\nrest" })).toBe(
"First line",
);
- expect(traceEventSummary({ type: "tool_result", output: "line one\nline two" })).toBe(
- "line one",
+ });
+
+ it("collapses pretty-printed JSON output to a content preview, not a lone bracket", () => {
+ const output = '[\n {\n "id": "694c",\n "title": "x"\n }\n]';
+ expect(traceEventSummary({ type: "tool_result", output })).toBe(
+ '[ { "id": "694c", "title": "x" } ]',
);
});
diff --git a/packages/views/common/task-transcript/trace-event-presenter.ts b/packages/views/common/task-transcript/trace-event-presenter.ts
index 99aa9b487..ce511b8e4 100644
--- a/packages/views/common/task-transcript/trace-event-presenter.ts
+++ b/packages/views/common/task-transcript/trace-event-presenter.ts
@@ -121,6 +121,15 @@ function firstLine(value: string | undefined): string {
return value?.split("\n").find((l) => l.trim().length > 0) ?? "";
}
+/**
+ * Collapse all whitespace runs to single spaces. Unlike firstLine this keeps
+ * content that spans lines, so a pretty-printed JSON result previews as
+ * `[ { "id": ... } ]` instead of a lone opening bracket.
+ */
+function collapseWhitespace(value: string | undefined): string {
+ return (value ?? "").replace(/\s+/g, " ").trim();
+}
+
/** One-line summary for the collapsed row — never contains a newline. */
export function traceEventSummary(event: TraceEvent): string {
switch (traceEventKind(event)) {
@@ -129,7 +138,7 @@ export function traceEventSummary(event: TraceEvent): string {
case "tool_use":
return traceToolArgSummary(event.input);
case "tool_result":
- return clip(firstLine(event.output), 200);
+ return clip(collapseWhitespace(event.output), 200);
default:
return firstLine(event.content ?? event.output);
}
diff --git a/packages/views/locales/en/agents.json b/packages/views/locales/en/agents.json
index 820ed4bfb..2c10e22ba 100644
--- a/packages/views/locales/en/agents.json
+++ b/packages/views/locales/en/agents.json
@@ -808,7 +808,8 @@
"details_created": "Created",
"details_started": "Started",
"details_completed": "Completed",
- "copy_workdir": "Copy working directory"
+ "copy_workdir": "Copy working directory",
+ "details_triggered_by": "Triggered by"
},
"task_failure": {
"agent_error": "Agent execution error",
diff --git a/packages/views/locales/ja/agents.json b/packages/views/locales/ja/agents.json
index 74219ce9a..deb1b8a52 100644
--- a/packages/views/locales/ja/agents.json
+++ b/packages/views/locales/ja/agents.json
@@ -688,7 +688,8 @@
"details_created": "作成",
"details_started": "開始",
"details_completed": "完了",
- "copy_workdir": "作業ディレクトリをコピー"
+ "copy_workdir": "作業ディレクトリをコピー",
+ "details_triggered_by": "トリガー"
},
"task_failure": {
"agent_error": "エージェント実行エラー",
diff --git a/packages/views/locales/ko/agents.json b/packages/views/locales/ko/agents.json
index c1244527f..2967ab92d 100644
--- a/packages/views/locales/ko/agents.json
+++ b/packages/views/locales/ko/agents.json
@@ -696,7 +696,8 @@
"details_created": "생성",
"details_started": "시작",
"details_completed": "완료",
- "copy_workdir": "작업 디렉터리 복사"
+ "copy_workdir": "작업 디렉터리 복사",
+ "details_triggered_by": "트리거한 사람"
},
"task_failure": {
"agent_error": "에이전트 실행 오류",
diff --git a/packages/views/locales/zh-Hans/agents.json b/packages/views/locales/zh-Hans/agents.json
index caaad72e1..8b9b4392a 100644
--- a/packages/views/locales/zh-Hans/agents.json
+++ b/packages/views/locales/zh-Hans/agents.json
@@ -792,7 +792,8 @@
"details_created": "创建",
"details_started": "开始",
"details_completed": "完成",
- "copy_workdir": "复制工作目录"
+ "copy_workdir": "复制工作目录",
+ "details_triggered_by": "触发人"
},
"task_failure": {
"agent_error": "智能体执行出错",