diff --git a/src/client/src/api.ts b/src/client/src/api.ts index aaa46d3..2c76fe2 100644 --- a/src/client/src/api.ts +++ b/src/client/src/api.ts @@ -92,6 +92,7 @@ export const api = { commands: (sessionId: string) => request(`/api/sessions/${sessionId}/commands`), files: (cwd: string, query: string, kind?: FileSuggestion["kind"]) => request(`/api/files?cwd=${encodeURIComponent(cwd)}&q=${encodeURIComponent(query)}${kind ? `&kind=${encodeURIComponent(kind)}` : ""}`), prompt: (sessionId: string, text: string) => request<{ accepted: true }>(`/api/sessions/${sessionId}/prompt`, { method: "POST", body: JSON.stringify({ text }) }), + shell: (sessionId: string, text: string) => request<{ accepted: true }>(`/api/sessions/${sessionId}/shell`, { method: "POST", body: JSON.stringify({ text }) }), runCommand: (sessionId: string, text: string) => request(`/api/sessions/${sessionId}/commands/run`, { method: "POST", body: JSON.stringify({ text }) }), respondToCommand: (sessionId: string, requestId: string, value: string) => request(`/api/sessions/${sessionId}/commands/respond`, { method: "POST", body: JSON.stringify({ requestId, value }) }), stop: (sessionId: string) => request<{ stopped: true }>(`/api/sessions/${sessionId}/stop`, { method: "POST" }), diff --git a/src/client/src/chatMessages.ts b/src/client/src/chatMessages.ts index 5f2c86e..3e57ce7 100644 --- a/src/client/src/chatMessages.ts +++ b/src/client/src/chatMessages.ts @@ -21,6 +21,7 @@ export function appendText(messages: ChatLine[], role: ChatLine["role"], text: s } function normalizeMessage(message: any): ChatLine[] { + if (message?.role === "bashExecution") return [normalizeBashExecution(message)]; const role = normalizeRole(message?.role); const parts = normalizeContent(message?.content, message); if (role === "tool") return [{ role, parts }]; @@ -29,6 +30,17 @@ function normalizeMessage(message: any): ChatLine[] { return visible.length ? [{ role, parts: visible }] : []; } +function normalizeBashExecution(message: any): ChatLine { + const lines = [`$ ${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") }] }; +} + function normalizeRole(role: unknown): ChatLine["role"] { if (role === "assistant") return "assistant"; if (role === "user") return "user"; diff --git a/src/client/src/components/ChatView.ts b/src/client/src/components/ChatView.ts index bf5b939..1379d72 100644 --- a/src/client/src/components/ChatView.ts +++ b/src/client/src/components/ChatView.ts @@ -95,7 +95,7 @@ export class ChatView extends LitElement { } private isReadablePart(message: ChatLine, part: ChatPart): boolean { - return part.type === "text" && (message.role === "user" || message.role === "assistant" || message.role === "system"); + return part.type === "text" && (message.role === "user" || message.role === "assistant" || message.role === "system" || message.role === "bash"); } private groupSummary(messages: ChatLine[]): string { diff --git a/src/client/src/components/PromptEditor.ts b/src/client/src/components/PromptEditor.ts index 26a287a..1deb3f9 100644 --- a/src/client/src/components/PromptEditor.ts +++ b/src/client/src/components/PromptEditor.ts @@ -26,9 +26,14 @@ export class PromptEditor extends LitElement { this.selectedIndex = 0; } + protected updated(changed: PropertyValues) { + if (changed.has("draft") || changed.has("sessionId")) this.resizeTextarea(); + } + render() { + const shellMode = this.isShellMode(); return html` -