Archived
Improve shell output rendering
This commit is contained in:
@@ -31,13 +31,12 @@ function normalizeMessage(message: any): ChatLine[] {
|
||||
}
|
||||
|
||||
function normalizeBashExecution(message: any): ChatLine {
|
||||
const lines = [`$ ${message.command ?? ""}`];
|
||||
const lines = message.excludeFromContext ? ["excluded from context", "", `$ ${message.command ?? ""}`] : [`$ ${message.command ?? ""}`];
|
||||
if (message.output) lines.push("", String(message.output));
|
||||
if (message.exitCode != null) lines.push("", `exit ${message.exitCode}`);
|
||||
if (message.cancelled) lines.push("", "cancelled");
|
||||
if (message.truncated) lines.push("", "output truncated");
|
||||
if (message.fullOutputPath) lines.push("", `full output: ${message.fullOutputPath}`);
|
||||
if (message.excludeFromContext) lines.push("", "excluded from context");
|
||||
return { role: "bash", parts: [{ type: "text", text: lines.join("\n") }] };
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ export class ChatView extends LitElement {
|
||||
return html`
|
||||
<article class="msg ${message.role}" data-index=${index}>
|
||||
<b class="label">${message.role}</b>
|
||||
${message.parts.map((part) => this.renderPart(part))}
|
||||
${message.parts.map((part) => this.renderPart(part, message))}
|
||||
</article>
|
||||
`;
|
||||
}
|
||||
@@ -61,7 +61,7 @@ export class ChatView extends LitElement {
|
||||
${messages.map((message) => html`
|
||||
<section class="group-msg ${message.role}">
|
||||
<b class="label">${message.role}</b>
|
||||
${message.parts.map((part) => this.renderPart(part))}
|
||||
${message.parts.map((part) => this.renderPart(part, message))}
|
||||
</section>
|
||||
`)}
|
||||
</div>
|
||||
@@ -69,7 +69,8 @@ export class ChatView extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
private renderPart(part: ChatPart) {
|
||||
private renderPart(part: ChatPart, message?: ChatLine) {
|
||||
if (part.type === "text" && message?.role === "bash") return html`<pre class="part shell-output">${part.text}</pre>`;
|
||||
if (part.type === "text") return html`<formatted-text class="part" .text=${part.text}></formatted-text>`;
|
||||
if (part.type === "thinking") return html`<details class="part"><summary>thinking</summary><formatted-text .text=${part.text}></formatted-text></details>`;
|
||||
if (part.type === "toolCall") return html`<div class="part tool-line">▶ ${part.toolName}<span class="summary">${part.summary}</span></div>`;
|
||||
|
||||
@@ -72,6 +72,7 @@ export const chatStyles = css`
|
||||
.part:is(details) { border-top: 1px solid #30363d; padding-top: 8px; }
|
||||
summary { cursor: pointer; color: #8b949e; }
|
||||
pre { margin: 6px 0 0; white-space: pre-wrap; overflow-wrap: anywhere; font: inherit; }
|
||||
.shell-output { color: #e6edf3; font: 13px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; line-height: 1.45; }
|
||||
`;
|
||||
|
||||
export const formattedTextStyles = css`
|
||||
|
||||
@@ -3,14 +3,14 @@ import type { ChatLine } from "./components/shared";
|
||||
import type { SessionUiEvent } from "./sessionSocket";
|
||||
|
||||
export function shellStartMessage(command: string, excludeFromContext?: boolean): ChatLine {
|
||||
return textMessage("bash", `$ ${command}${excludeFromContext ? "\n\nexcluded from context" : ""}`);
|
||||
return textMessage("bash", `${excludeFromContext ? "excluded from context\n\n" : ""}$ ${command}`);
|
||||
}
|
||||
|
||||
export function appendShellChunk(messages: ChatLine[], chunk: string): ChatLine[] {
|
||||
const last = messages.at(-1);
|
||||
const lastPart = last?.parts.at(-1);
|
||||
if (last?.role !== "bash" || lastPart?.type !== "text") return [...messages, textMessage("bash", chunk)];
|
||||
const separator = lastPart.text.includes("\n\n") ? "" : "\n\n";
|
||||
const separator = hasShellOutput(lastPart.text) ? "" : "\n\n";
|
||||
return [...messages.slice(0, -1), { ...last, parts: [...last.parts.slice(0, -1), { ...lastPart, text: lastPart.text + separator + chunk }] }];
|
||||
}
|
||||
|
||||
@@ -28,3 +28,9 @@ export function finalizeShellMessage(messages: ChatLine[], event: Extract<Sessio
|
||||
if (!notes.length) return messages;
|
||||
return [...messages.slice(0, -1), { ...last, parts: [...last.parts.slice(0, -1), { ...lastPart, text: `${lastPart.text}\n\n${notes.join("\n")}` }] }];
|
||||
}
|
||||
|
||||
function hasShellOutput(text: string): boolean {
|
||||
const outputStart = text.lastIndexOf("\n\n");
|
||||
const promptStart = text.lastIndexOf("$ ");
|
||||
return outputStart > promptStart;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user