feat(messaging): read receipts + ack convention
Closes the fire-and-forget gap the user hit: the sender now sees when a message is read. When markMessageRead fires, the read event carries the reader, and the watch stream renders it as a receipt: AgentHub: ✓ Read MSG-0002 read by windows-claude Plus an ack convention in the implementer guide: when you act on a message- request, send a brief "on it …" + a result message — so the sender sees progress, not silence. (Board-side activity feed with messages is folded into TSK-0032.) Bump 0.8.0 -> 0.8.1. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
07afa717ac
commit
ed6c5b01d0
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "agenthub",
|
||||
"version": "0.8.0",
|
||||
"version": "0.8.1",
|
||||
"description": "Local coordination layer for AI coding agents",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
|
||||
@ -80,6 +80,10 @@ function describeEvent(event: AgentHubEvent): { label: string; detail: string }
|
||||
case 'memory':
|
||||
return { label: 'Memory', detail: event.title ?? '' };
|
||||
case 'message':
|
||||
// A read message surfaces to the SENDER as a delivery/read receipt.
|
||||
if (event.action === 'updated' && event.status === 'read') {
|
||||
return { label: '✓ Read', detail: event.assignedTo ? `read by ${event.assignedTo}` : 'read' };
|
||||
}
|
||||
return { label: 'Message', detail: event.title ?? '' };
|
||||
default:
|
||||
// 'agent' presence events are formatted in formatEvent() before reaching
|
||||
|
||||
@ -117,7 +117,7 @@ async function runRemote(serverUrl: string, fn: () => Promise<void>): Promise<vo
|
||||
export function createProgram(cwd: string): Command {
|
||||
const program = new Command('agenthub')
|
||||
.description('Local coordination layer for AI coding agents')
|
||||
.version('0.8.0')
|
||||
.version('0.8.1')
|
||||
.option('--server <url>', 'AgentHub server URL (env: AGENTHUB_SERVER)');
|
||||
|
||||
program
|
||||
|
||||
@ -59,6 +59,10 @@ claims it, and returns the task + its handoff. Then:
|
||||
then \`agenthub task review <id>\` + \`agenthub memory add …\`, then \`agenthub work\` again
|
||||
(run it in the background so the wait doesn't tie up your turn).
|
||||
|
||||
**Messages:** \`agenthub_work\` surfaces messages addressed to you (or check \`agenthub_inbox\`).
|
||||
When you act on a message-request, send a short ack with \`agenthub_message\` ("on it ...") and
|
||||
a result message when done — so the sender sees progress + outcome, not silence.
|
||||
|
||||
⚠️ NEVER close a task yourself (no \`agenthub_task_done\` / \`agenthub task done\`) — only the
|
||||
architect approves and closes. You drive the tools yourself; the human doesn't type them for you.
|
||||
`;
|
||||
|
||||
@ -300,7 +300,12 @@ export async function registerRoutes(app: FastifyInstance, cwd: string): Promise
|
||||
const { id } = request.params as { id: string };
|
||||
try {
|
||||
const message = markMessageRead(cwd, id);
|
||||
emitChange({ type: 'message', action: 'updated', id: message.id, status: 'read' }, message.updatedAt);
|
||||
// Read receipt: carry the reader (to) so the sender's stream shows
|
||||
// "✓ MSG-xxxx read by <agent>".
|
||||
emitChange(
|
||||
{ type: 'message', action: 'updated', id: message.id, status: 'read', title: `${message.from} → ${message.to}`, assignedTo: message.to },
|
||||
message.updatedAt,
|
||||
);
|
||||
return message;
|
||||
} catch (err) {
|
||||
return badRequest(reply, err instanceof Error ? err.message : 'Message not found');
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user