From 45070222d036a8474bfc7cfa29a9b3e4d6b717e1 Mon Sep 17 00:00:00 2001 From: chahinebrini Date: Sat, 27 Jun 2026 16:33:03 +0200 Subject: [PATCH] feat: zero-config auto-connect + agent presence (join-announce) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Agents now connect to the hub with no manual env/flag, and announce themselves on join — restoring the agreed onboarding flow. Auto-connect (resolveContext): - An initialized project WITHOUT a configured serverUrl now falls through to LAN auto-discovery (previously it went straight to local mode, so agents in an initialized repo never found the server). The discovered URL is persisted to the project config, so the next command is instant. - IP-change self-heal: when a configured server is unreachable, runRemote re-discovers the live server and updates the config so the next command reconnects automatically. Presence (join-announce): - POST /announce broadcasts an ephemeral 'agent/joined' event (not written to disk). New `agenthub hello --agent --role ` posts it; watchers print "AgentHub: joined ()". - AgentHubEvent extended with type 'agent' + actions 'joined'/'left'; formatEvent renders presence lines; remoteClient.announce() added. Tests: formatEvent agent lines + /announce SSE e2e. 109/109 green. Bump 0.1.2 -> 0.2.0 (CLI --version too). Co-Authored-By: Claude Opus 4.8 --- package.json | 2 +- src/cli/commands/watch.ts | 11 ++++++ src/cli/index.ts | 70 ++++++++++++++++++++++++++++++++++++--- src/cli/remoteClient.ts | 4 +++ src/server/events.ts | 5 +-- src/server/routes.ts | 16 +++++++++ tests/sse.test.ts | 53 +++++++++++++++++++++++++++++ 7 files changed, 153 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index afb6565..fa1e9df 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "agenthub", - "version": "0.1.2", + "version": "0.2.0", "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 7c89bd8..5ed1433 100644 --- a/src/cli/commands/watch.ts +++ b/src/cli/commands/watch.ts @@ -79,6 +79,10 @@ function describeEvent(event: AgentHubEvent): { label: string; detail: string } return { label: 'Decision', detail: event.title ?? '' }; case 'memory': return { label: 'Memory', detail: event.title ?? '' }; + default: + // 'agent' presence events are formatted in formatEvent() before reaching + // here; this fallback only satisfies exhaustiveness. + return { label: 'Event', detail: event.title ?? '' }; } } @@ -92,6 +96,13 @@ function describeEvent(event: AgentHubEvent): { label: string; detail: string } * agent's console (Claude / Codex / Kimi) regardless of surrounding output. */ export function formatEvent(event: AgentHubEvent): string { + // Presence events read more naturally as " joined ()" than the + // padded "