Direct messages between agents through the hub — architect↔agent and agent↔agent
questions, clarifications and pings that handoffs/memories don't cover. Built as
MCP tools so kimi + codex get it too (not Claude-only), plus REST + CLI.
- Message entity (MSG-NNNN): schema, counter, messages/ dir, messageService
(createMessage / listInbox / listMessages / markMessageRead).
- REST: POST /messages, GET /messages[?agent&unread], POST /messages/:id/read,
with SSE emit. fsWatch + statusRefresh wired ('message' events; status skips them).
- MCP: agenthub_message {from,to,text,taskId?} + agenthub_inbox {agent,unreadOnly?}.
agenthub_work now surfaces + drains unread messages and wakes on message events,
so an agent sees messages inside its work loop. (18 tools total.)
- CLI: `agenthub message <to> <text> --from <agent>` + `agenthub inbox --agent`.
watch stream shows "Message" events (architect-visible).
- Architect-visible by design: the hub stays the coordination point.
Bump 0.7.5 -> 0.8.0.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
22 lines
775 B
TypeScript
22 lines
775 B
TypeScript
import { createMessage, listInbox } from '../../core/services/messageService.js';
|
|
|
|
export function messageSend(
|
|
cwd: string,
|
|
opts: { from: string; to: string; text: string; taskId?: string },
|
|
): void {
|
|
const m = createMessage(cwd, opts);
|
|
console.log(`AgentHub: Message sent ${m.id} (${m.from} → ${m.to})`);
|
|
}
|
|
|
|
export function inboxList(cwd: string, opts: { agent: string; unreadOnly?: boolean }): void {
|
|
const msgs = listInbox(cwd, opts.agent, { unreadOnly: opts.unreadOnly });
|
|
if (msgs.length === 0) {
|
|
console.log(`No messages for ${opts.agent}.`);
|
|
return;
|
|
}
|
|
for (const m of msgs) {
|
|
const flag = m.status === 'unread' ? '●' : ' ';
|
|
console.log(`${flag} ${m.id} ${m.from} → ${m.to}${m.taskId ? ` [${m.taskId}]` : ''}: ${m.text}`);
|
|
}
|
|
}
|