From e6e90495d4d74ea2438c7fec5aac49fd64d316a3 Mon Sep 17 00:00:00 2001 From: aiedwardyi <41576951+aiedwardyi@users.noreply.github.com> Date: Fri, 17 Jul 2026 20:11:46 +0900 Subject: [PATCH 1/4] feat: add live messages panel --- bridge.js | 25 ++++++++++ public/index.html | 118 ++++++++++++---------------------------------- src/daemon.js | 42 ++++++++++++++++- src/store.js | 49 +++++++++++++++++++ 4 files changed, 143 insertions(+), 91 deletions(-) diff --git a/bridge.js b/bridge.js index 2519d76..288ecdf 100644 --- a/bridge.js +++ b/bridge.js @@ -301,6 +301,20 @@ const tools = [ }, annotations: { readOnlyHint: false }, }, + { + name: 'send_message', + description: 'Post short progress updates, questions for the human, and final result summaries to the AgentLoop dashboard.', + inputSchema: { + type: 'object', + properties: { + text: { type: 'string', minLength: 1, maxLength: 2000 }, + kind: { type: 'string', enum: ['info', 'question', 'results'], default: 'info' }, + }, + required: ['text'], + additionalProperties: false, + }, + annotations: { readOnlyHint: false }, + }, ]; function daemonError(response) { @@ -350,6 +364,17 @@ async function callTool(params) { : toolFailure(daemonError(response)); } + if (name === 'send_message') { + const response = await daemonRequest('/api/message', { + text: args.text, + kind: args.kind, + }); + + return response.statusCode >= 200 && response.statusCode < 300 + ? toolResult(response.value) + : toolFailure(daemonError(response)); + } + return toolFailure(`Unknown tool: ${name}.`); } diff --git a/public/index.html b/public/index.html index cdbcb41..5d5017a 100644 --- a/public/index.html +++ b/public/index.html @@ -442,24 +442,25 @@ } .fchip:hover{color:var(--text)} .fchip.on{background:var(--accent-dim);border-color:var(--accent-soft);color:var(--accent)} -#msgList{max-height:380px;overflow-y:auto;display:flex;flex-direction:column;gap:6px;margin-bottom:10px;padding:2px} +#msgList{max-height:380px;overflow-y:auto;display:flex;flex-direction:column;gap:6px;margin-bottom:0;padding:2px} @media (min-width:1100px){ #msgList{max-height:none;height:0;flex:1 1 auto;min-height:240px} } .bubble{display:flex;gap:9px;min-width:0;position:relative} .bubble .avatar{width:7px;height:7px;border-radius:2px;flex:none;margin-top:9px;background:var(--muted)} -.bubble.r-planner .avatar{background:var(--accent)} -.bubble.r-worker .avatar{background:var(--info)} +.bubble.kind-question .avatar{background:var(--warn)} +.bubble.kind-results .avatar{background:var(--ok)} .bwrap{ flex:1;min-width:0;background:var(--hover); border:1px solid var(--line-soft);border-radius:6px;padding:7px 10px 8px; } .bubble.fresh .bwrap{border-color:var(--accent-soft);background:var(--accent-dim)} +.bubble.kind-question .bwrap{border-color:color-mix(in srgb,var(--warn) 42%,var(--line-soft));background:color-mix(in srgb,var(--warn) 10%,var(--hover))} .bmeta{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:2px;font-size:10.5px} -.bmeta .role{font:650 10px/1.6 var(--mono);letter-spacing:.08em;text-transform:uppercase} -.bubble.r-planner .role{color:var(--accent)} -.bubble.r-worker .role{color:var(--info)} -.bubble.r-system .role{color:var(--muted)} +.bmeta .kind{font:650 9.5px/1.6 var(--mono);letter-spacing:.08em;text-transform:uppercase;border-radius:4px;padding:0 6px} +.bmeta .kind-info{color:var(--muted);background:color-mix(in srgb,var(--muted) 12%,transparent)} +.bmeta .kind-question{color:var(--warn);background:color-mix(in srgb,var(--warn) 14%,transparent)} +.bmeta .kind-results{color:var(--ok);background:color-mix(in srgb,var(--ok) 14%,transparent)} .bmeta .rel{color:var(--muted);font-family:var(--mono);font-variant-numeric:tabular-nums} .newchip{ display:none;font:650 9.5px/1.5 var(--mono);letter-spacing:.08em;text-transform:uppercase; @@ -467,18 +468,7 @@ border-radius:4px;padding:0 6px; } .bubble.fresh .newchip{display:inline-flex} -.waittag{ - display:inline-flex;align-items:center;gap:5px; - font:650 9.5px/1.7 var(--mono);letter-spacing:.05em;text-transform:uppercase; - color:var(--warn);background:color-mix(in srgb,var(--warn) 13%,transparent); - border-radius:4px;padding:0 7px; -} -.waittag::before{content:"";width:4px;height:4px;border-radius:1px;background:currentColor} -.bubble.linked{cursor:pointer} -.bubble.linked:hover .bwrap{border-color:color-mix(in srgb,var(--warn) 40%,transparent)} .btext{white-space:pre-wrap;word-break:break-word;font-size:12.5px;line-height:1.55} -.composer{display:flex;gap:8px} -.composer input{flex:1} /* ================= events ================= */ #eventList{list-style:none;margin:0;padding:0;max-height:300px;overflow-y:auto} #eventList li{ @@ -572,11 +562,11 @@ [data-theme="atelier"] .wordmark em{font-style:italic} [data-theme="atelier"] .pill,[data-theme="atelier"] .btn,[data-theme="atelier"] .cancel, [data-theme="atelier"] .fchip,[data-theme="atelier"] .chip,[data-theme="atelier"] #pill, -[data-theme="atelier"] .waittag,[data-theme="atelier"] .newchip,[data-theme="atelier"] .count, +[data-theme="atelier"] .newchip,[data-theme="atelier"] .count, [data-theme="atelier"] .brandtag,[data-theme="atelier"] #themeBtn,[data-theme="atelier"] #dclose,[data-theme="atelier"] #nclose, [data-theme="atelier"] .act,[data-theme="atelier"] .seg,[data-theme="atelier"] .qm{border-radius:999px} [data-theme="atelier"] .pill i,[data-theme="atelier"] #pill .pdot,[data-theme="atelier"] .avatar, -[data-theme="atelier"] .act .livedot,[data-theme="atelier"] .waittag::before{border-radius:50%} +[data-theme="atelier"] .act .livedot{border-radius:50%} [data-theme="atelier"] input,[data-theme="atelier"] select,[data-theme="atelier"] textarea{border-radius:10px} [data-theme="atelier"] .run,[data-theme="atelier"] .blk,[data-theme="atelier"] .bwrap{border-radius:12px} [data-theme="atelier"] .rrow,[data-theme="atelier"] .qrow{border-radius:10px} @@ -696,10 +686,6 @@