mirror of
https://github.com/alkimake/paperclip.git
synced 2026-06-17 19:20:39 +09:00
feat(ui): collapsible system_group block in transcript view
Batch consecutive system events into a single collapsible group instead of rendering each as a separate warn-toned block. Shows count in header, expands on click.
This commit is contained in:
parent
c757a07708
commit
199a2178cf
1 changed files with 57 additions and 7 deletions
|
|
@ -93,6 +93,12 @@ type TranscriptBlock =
|
||||||
endTs?: string;
|
endTs?: string;
|
||||||
lines: Array<{ ts: string; text: string }>;
|
lines: Array<{ ts: string; text: string }>;
|
||||||
}
|
}
|
||||||
|
| {
|
||||||
|
type: "system_group";
|
||||||
|
ts: string;
|
||||||
|
endTs?: string;
|
||||||
|
lines: Array<{ ts: string; text: string }>;
|
||||||
|
}
|
||||||
| {
|
| {
|
||||||
type: "stdout";
|
type: "stdout";
|
||||||
ts: string;
|
ts: string;
|
||||||
|
|
@ -558,13 +564,19 @@ export function normalizeTranscript(entries: TranscriptEntry[], streaming: boole
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
blocks.push({
|
// Batch consecutive system events into a single collapsible group
|
||||||
type: "event",
|
const prev = blocks[blocks.length - 1];
|
||||||
ts: entry.ts,
|
if (prev && prev.type === "system_group") {
|
||||||
label: "system",
|
prev.lines.push({ ts: entry.ts, text: entry.text });
|
||||||
tone: "warn",
|
prev.endTs = entry.ts;
|
||||||
text: entry.text,
|
} else {
|
||||||
});
|
blocks.push({
|
||||||
|
type: "system_group",
|
||||||
|
ts: entry.ts,
|
||||||
|
endTs: entry.ts,
|
||||||
|
lines: [{ ts: entry.ts, text: entry.text }],
|
||||||
|
});
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1260,6 +1272,43 @@ function TranscriptStderrGroup({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function TranscriptSystemGroup({
|
||||||
|
block,
|
||||||
|
density,
|
||||||
|
}: {
|
||||||
|
block: Extract<TranscriptBlock, { type: "system_group" }>;
|
||||||
|
density: TranscriptDensity;
|
||||||
|
}) {
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
return (
|
||||||
|
<div className="rounded-xl border border-blue-500/20 bg-blue-500/[0.04] p-2 text-blue-700 dark:text-blue-300">
|
||||||
|
<div
|
||||||
|
role="button"
|
||||||
|
tabIndex={0}
|
||||||
|
className="flex cursor-pointer items-center gap-2"
|
||||||
|
onClick={() => setOpen((v) => !v)}
|
||||||
|
onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); setOpen((v) => !v); } }}
|
||||||
|
>
|
||||||
|
<TerminalSquare className="h-3.5 w-3.5 shrink-0" />
|
||||||
|
<span className="text-[10px] font-semibold uppercase tracking-[0.14em]">
|
||||||
|
{block.lines.length} system {block.lines.length === 1 ? "message" : "messages"}
|
||||||
|
</span>
|
||||||
|
{open ? <ChevronDown className="h-3.5 w-3.5" /> : <ChevronRight className="h-3.5 w-3.5" />}
|
||||||
|
</div>
|
||||||
|
{open && (
|
||||||
|
<pre className="mt-2 overflow-x-auto whitespace-pre-wrap break-words font-mono text-[11px] text-blue-700/80 dark:text-blue-300/80 pl-5">
|
||||||
|
{block.lines.map((line, i) => (
|
||||||
|
<span key={`${line.ts}-${i}`}>
|
||||||
|
<span className="select-none text-blue-500/40 dark:text-blue-400/30">{i > 0 ? "\n" : ""}</span>
|
||||||
|
{line.text}
|
||||||
|
</span>
|
||||||
|
))}
|
||||||
|
</pre>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function TranscriptStdoutRow({
|
function TranscriptStdoutRow({
|
||||||
block,
|
block,
|
||||||
density,
|
density,
|
||||||
|
|
@ -1383,6 +1432,7 @@ export function RunTranscriptView({
|
||||||
{block.type === "tool_group" && <TranscriptToolGroup block={block} density={density} />}
|
{block.type === "tool_group" && <TranscriptToolGroup block={block} density={density} />}
|
||||||
{block.type === "diff_group" && <TranscriptDiffGroup block={block} density={density} />}
|
{block.type === "diff_group" && <TranscriptDiffGroup block={block} density={density} />}
|
||||||
{block.type === "stderr_group" && <TranscriptStderrGroup block={block} density={density} />}
|
{block.type === "stderr_group" && <TranscriptStderrGroup block={block} density={density} />}
|
||||||
|
{block.type === "system_group" && <TranscriptSystemGroup block={block} density={density} />}
|
||||||
{block.type === "stdout" && (
|
{block.type === "stdout" && (
|
||||||
<TranscriptStdoutRow block={block} density={density} collapseByDefault={collapseStdout} />
|
<TranscriptStdoutRow block={block} density={density} collapseByDefault={collapseStdout} />
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue