From 738b6d592e0c8e6a6e1869afcc41d987cc61beb3 Mon Sep 17 00:00:00 2001 From: Brett Chien Date: Sun, 13 Sep 2026 21:09:59 +0800 Subject: [PATCH] feat(console): show "agent is responding" above the chat input MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The existing "agent is responding…" label only lived in the chat-head pill at the top of the panel — easy to miss above a long scrolled transcript, and not where the user's eyes are once they've hit send. Add a small status line, with the existing spinner, right above the input box in both the management console and per-agent consoles, shown only while a turn is in flight. 🤖 Generated with Claude Code --- console/index.html | 2 ++ console/src/agentConsole.ts | 5 +++-- console/src/chatPanel.ts | 7 +++++++ console/src/main.ts | 5 ++++- console/src/styles.css | 9 +++++++++ 5 files changed, 25 insertions(+), 3 deletions(-) diff --git a/console/index.html b/console/index.html index 6b11d2a..d7eea71 100644 --- a/console/index.html +++ b/console/index.html @@ -62,6 +62,7 @@ disconnected
+
@@ -225,6 +226,7 @@ disconnected
+
diff --git a/console/src/agentConsole.ts b/console/src/agentConsole.ts index 69b4c08..8c0b5ff 100644 --- a/console/src/agentConsole.ts +++ b/console/src/agentConsole.ts @@ -53,6 +53,7 @@ export function initAgentConsole(cfg: AgentConsoleConfig): AgentConsole { const send = document.getElementById("ac-chat-send") as HTMLButtonElement | null; const stop = document.getElementById("ac-chat-stop") as HTMLButtonElement | null; const conn = document.getElementById("ac-chat-conn"); + const status = document.getElementById("ac-chat-status"); const noop: AgentConsole = { refresh: async () => {}, @@ -141,9 +142,9 @@ export function initAgentConsole(cfg: AgentConsoleConfig): AgentConsole { // Optimistic "connecting" until the first `remote-status` (or ready in mock). renderHeader(cfg.mock ? "connected" : "connecting"); renderList(); - if (log && form && text && send && stop && conn) { + if (log && form && text && send && stop && conn && status) { panel = createChatPanel( - { log, form, text, send, stop, conn }, + { log, form, text, send, stop, conn, status }, { agent: name, source: cfg.source, diff --git a/console/src/chatPanel.ts b/console/src/chatPanel.ts index c2180fa..5ba9065 100644 --- a/console/src/chatPanel.ts +++ b/console/src/chatPanel.ts @@ -34,6 +34,12 @@ export interface ChatPanelElements { send: HTMLButtonElement; stop: HTMLButtonElement; conn: HTMLElement; + // A fixed line above the input box, shown only while a turn is in flight — + // unlike `conn` (which also carries the not-ready/connected states and can + // scroll out of view above a long transcript), this sits right where the + // user is about to type, so "is it still working?" never requires a glance + // up top or a scroll through the log. + status: HTMLElement; } export interface ChatPanelOptions { @@ -113,6 +119,7 @@ export function createChatPanel( els.conn.textContent = label; els.conn.classList.toggle("is-connected", r && !turnActive); els.conn.classList.toggle("is-error", false); + els.status.hidden = !turnActive; } // Enqueue a prompt and try to release it. `flush` is the single choke point diff --git a/console/src/main.ts b/console/src/main.ts index e828bb3..cada376 100644 --- a/console/src/main.ts +++ b/console/src/main.ts @@ -70,6 +70,7 @@ const chatTextEl = document.getElementById("chat-text") as HTMLTextAreaElement | const chatSendEl = document.getElementById("chat-send") as HTMLButtonElement | null; const chatStopEl = document.getElementById("chat-stop") as HTMLButtonElement | null; const chatConnEl = document.getElementById("chat-conn"); +const chatStatusEl = document.getElementById("chat-status"); const source = defaultSource(); // The Debug drawer (ADR #83 Part D / slice 6, 7.6): Activity/MCP/Config @@ -813,7 +814,8 @@ function buildManagementPanel(): void { !chatTextEl || !chatSendEl || !chatStopEl || - !chatConnEl + !chatConnEl || + !chatStatusEl ) return; managementPanel = createChatPanel( @@ -824,6 +826,7 @@ function buildManagementPanel(): void { send: chatSendEl, stop: chatStopEl, conn: chatConnEl, + status: chatStatusEl, }, { source, mock: isMock(), note }, ); diff --git a/console/src/styles.css b/console/src/styles.css index 214bb1e..f224917 100644 --- a/console/src/styles.css +++ b/console/src/styles.css @@ -1139,6 +1139,15 @@ button.act:disabled { font-size: 11px; color: var(--warn); } +.chat-status { + font-size: 12px; + color: var(--muted); + margin-top: 8px; +} +.chat-status .chat-spinner { + margin-left: 0; + margin-right: 6px; +} .chat-input { display: flex; gap: 8px;