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;