diff --git a/package.json b/package.json index c2396ac..80b1b99 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/cli/commands/watch.ts b/src/cli/commands/watch.ts index a5eceae..6c06ed8 100644 --- a/src/cli/commands/watch.ts +++ b/src/cli/commands/watch.ts @@ -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 diff --git a/src/cli/index.ts b/src/cli/index.ts index 50f1a81..28854d1 100644 --- a/src/cli/index.ts +++ b/src/cli/index.ts @@ -117,7 +117,7 @@ async function runRemote(serverUrl: string, fn: () => Promise): Promise', 'AgentHub server URL (env: AGENTHUB_SERVER)'); program diff --git a/src/core/templates.ts b/src/core/templates.ts index 447a354..8bf72f6 100644 --- a/src/core/templates.ts +++ b/src/core/templates.ts @@ -59,6 +59,10 @@ claims it, and returns the task + its handoff. Then: then \`agenthub task review \` + \`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. `; diff --git a/src/server/routes.ts b/src/server/routes.ts index bf05508..eb6d3ef 100644 --- a/src/server/routes.ts +++ b/src/server/routes.ts @@ -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 ". + 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');