feat(chat): add Send button to agent composers (mobile fix)

Soft keyboards have no reliable Enter-to-send, so chat was unsendable on
mobile browsers. Add an optional themed Send button wired through
wireAgentChat (Enter-to-send kept for desktop), applied to the Companion
rail, Yerin, and Little Blue composers. Blackflame-styled, flex-row layout.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
root
2026-06-05 08:25:05 +10:00
parent 3c028fed5a
commit c2569cad76
5 changed files with 31 additions and 11 deletions

View File

@@ -82,6 +82,7 @@ async function renderActions(panel, toastHost) {
export async function render(main) {
const log = el('div', { class: 'rail-log lb-log' });
const input = el('textarea', { class: 'rail-input', rows: 1, placeholder: 'Tell Little Blue whats wrong…' });
const sendBtn = el('button', { class: 'rail-send', type: 'button', title: 'Send', 'aria-label': 'Send' }, '➤');
const actionsPanel = el('div', { class: 'lb-actions' });
const toastHost = el('div', { class: 'lb-toasts' });
mount(main,
@@ -89,10 +90,10 @@ export async function render(main) {
el('p', { class: 'view-sub' }, 'She keeps the lab alive. Safe fixes run on her word; risky ones wait for yours.'),
toastHost,
el('div', { class: 'lb-grid' },
el('div', { class: 'lb-chat' }, log, el('div', { class: 'rail-inputwrap' }, input)),
el('div', { class: 'lb-chat' }, log, el('div', { class: 'rail-inputwrap' }, input, sendBtn)),
actionsPanel));
const chat = wireAgentChat({
logEl: log, inputEl: input,
logEl: log, inputEl: input, sendBtnEl: sendBtn,
historyUrl: '/api/little-blue', turnUrl: '/api/little-blue/turn',
agentName: 'Little Blue', showDrafts: false, toolLabels: BLUE_LABELS
});

View File

@@ -12,12 +12,13 @@ const YERIN_LABELS = {
export async function render(main) {
const log = el('div', { class: 'rail-log sentinel-log' });
const input = el('textarea', { class: 'rail-input', rows: 1, placeholder: 'Ask Yerin about the Voids security…' });
const sendBtn = el('button', { class: 'rail-send', type: 'button', title: 'Send', 'aria-label': 'Send' }, '➤');
mount(main, el('div', { class: 'yerin-view' },
el('h1', { class: 'view-h1' }, '◆ Yerin'),
el('p', { class: 'view-sub' }, 'Sage of the Endless Sword — read-only security & observability. She watches, reports, and warns; she never acts.'),
el('div', { class: 'sentinel-chat' }, log, el('div', { class: 'rail-inputwrap' }, input))));
el('div', { class: 'sentinel-chat' }, log, el('div', { class: 'rail-inputwrap' }, input, sendBtn))));
const chat = wireAgentChat({
logEl: log, inputEl: input,
logEl: log, inputEl: input, sendBtnEl: sendBtn,
historyUrl: '/api/security/yerin', turnUrl: '/api/security/yerin/turn',
agentName: 'Yerin', showDrafts: false, toolLabels: YERIN_LABELS
});