dashboard: fan out op-send when recipient is *

This commit is contained in:
müde 2026-05-17 11:09:20 +02:00
parent 6ce85bd6f2
commit 9703753a4c
2 changed files with 15 additions and 3 deletions

View file

@ -1028,7 +1028,12 @@
// The broker uses the literal recipient `manager` for the // The broker uses the literal recipient `manager` for the
// manager's inbox, not the container name `hm1nd`. Swap on // manager's inbox, not the container name `hm1nd`. Swap on
// suggestion so `@manager` Just Works. // suggestion so `@manager` Just Works.
return s.containers.map((c) => (c.is_manager ? 'manager' : c.name)); const names = s.containers.map((c) => (c.is_manager ? 'manager' : c.name));
// `*` fans out the message to every registered agent (server-side
// broadcast_send). Surface it as a suggestion so operators can
// type `@*` from the dashboard the same way the manager does.
names.unshift('*');
return names;
} }
function autosize() { function autosize() {
input.style.height = 'auto'; input.style.height = 'auto';
@ -1037,7 +1042,7 @@
/// Parse "@name body…" — return {to, body} when the input opens /// Parse "@name body…" — return {to, body} when the input opens
/// with a known @-mention, otherwise null. /// with a known @-mention, otherwise null.
function parseAddressed(raw) { function parseAddressed(raw) {
const m = raw.match(/^@([\w-]+)\s+([\s\S]+)$/); const m = raw.match(/^@([\w*-]+)\s+([\s\S]+)$/);
if (!m) return null; if (!m) return null;
return { to: m[1], body: m[2] }; return { to: m[1], body: m[2] };
} }

View file

@ -1054,7 +1054,14 @@ async fn post_op_send(State(state): State<AppState>, Form(form): Form<OpSendForm
if body.is_empty() { if body.is_empty() {
return error_response("op-send: `body` required"); return error_response("op-send: `body` required");
} }
if let Err(e) = state.coord.broker.send(&hive_sh4re::Message { if to == "*" {
let errors = state
.coord
.broadcast_send(hive_sh4re::OPERATOR_RECIPIENT, &body);
if !errors.is_empty() {
return error_response(&format!("op-send broadcast partial fail: {}", errors.join("; ")));
}
} else if let Err(e) = state.coord.broker.send(&hive_sh4re::Message {
from: hive_sh4re::OPERATOR_RECIPIENT.to_owned(), from: hive_sh4re::OPERATOR_RECIPIENT.to_owned(),
to: to.clone(), to: to.clone(),
body, body,