36 Commits

Author SHA1 Message Date
chahinebrini
996f988f11 feat(autostart): self-perpetuating work loop — stay reachable
The recurring "agent doesn't read messages in realtime / isn't triggered for the
next task" problem: agents weren't STAYING in the agenthub_work loop, so they went
dormant after each task. Two reinforcements:

- agenthub_work now ends every response with a LOOP directive: "the instant you
  finish, call agenthub_work again (in the background) so the next task/message
  reaches you in realtime — never end your turn without relaunching it."
- The auto-start hook-context now stresses the BACKGROUND loop + relaunch pattern,
  so a Claude Code session is woken on each event instead of blocking.

Layer 1 (auto-start) gets agents INTO the loop; this keeps them IN it. Honest
limit: turn-based agents still rely on obeying the relaunch nudge — there's no
100% always-on without a supervisor. Bump 0.9.0 -> 0.9.1.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 05:23:05 +02:00
chahinebrini
d00f2812f9 feat(autostart): agenthub agent setup — SessionStart hook enters the work loop
Closes the dormancy gap: an agent no longer needs to be told "call agenthub_work".
`agenthub agent setup --agent <name> --role <role>` writes a verified Claude Code
SessionStart hook (.claude/settings.json) whose command runs `agenthub hook-context`,
which prints the work-loop instruction injected into every new session — so the
agent claims tasks AND surfaces messages from the first turn, no manual trigger.

- agentSetup.ts: agentSetup() (idempotent hook write, project or --user scope) +
  hookContext() (the injected instruction).
- Honest limit (per Claude Code docs): SessionStart context is a strong nudge the
  model reads, not a hard directive; the guide reinforces it. Can't block startup.
- Codex/Kimi aren't Claude Code — their guide already nudges agenthub_work first.

Run once per agent machine. Bump 0.8.1 -> 0.9.0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 04:57:30 +02:00
chahinebrini
ed6c5b01d0 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>
2026-06-29 04:04:04 +02:00
chahinebrini
07afa717ac feat(messaging): agent messaging — agenthub_message / agenthub_inbox (cross-agent via MCP)
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>
2026-06-29 03:20:38 +02:00
chahinebrini
b5f75c6c65 fix(update): harden auto-update — fire agenthub update directly on tick
The old auto path checked `HEAD..origin/branch` right after kicking off a
background fetch, so it read a stale origin ref and only fired on the SECOND
invocation (and never if the agent sat in one long-running `work`).

Now: when AGENTHUB_AUTO_UPDATE is set, a throttled tick (≤1h) spawns
`agenthub update` directly in the background. update does its OWN fresh fetch
+ reset + build and no-ops when current — so it self-heals on the FIRST
invocation, no stale-ref lag. Notify-only path (no flag) unchanged.

Removed the now-unused cooldown const. 122/122 green. Bump 0.6.0 -> 0.6.1.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 00:29:59 +02:00
chahinebrini
78bbebf435 feat(task): agenthub task assign — architect addresses an open task to an agent
Closes the addressing gap that left a waiting `agenthub work` blocked: the
remaining Win tasks were titled "Win L2: …" / unassigned, so they matched
no agent and the daemon waited forever.

`agenthub task assign <id> --agent <name>` sets assignedTo WITHOUT claiming
(status stays open) and fires task/updated — so an agent's blocked `work`
re-checks, matches via assignedTo, and auto-claims it. The architect can now
route a specific open task to a specific agent and have its daemon pick it up.

- taskService.assignTask; PATCH /tasks/:id handles assignedTo-without-status;
  remoteClient.assignTask; CLI `task assign`.
- test: assign keeps status open + sets assignedTo; start/work then claims it
  via the assignedTo match. 122/122 green.

Bump 0.5.0 -> 0.6.0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 00:12:50 +02:00
chahinebrini
ec378131e4 feat(watch): --await-review — architect review-queue notifier
Closes the architect-side gap: the auto-claim daemon wakes implementers on
new tasks, but the architect had no signal when an implementer submitted.

`agenthub watch --await-review` exits (after printing) the moment a task
enters `review` — including any task already in review on connect (initial
check) — so the architect can run it in the background and be re-invoked by
the harness the instant a submission needs a verdict.

- watch.ts: awaitReview option, initial fetchReviewTasks() check + SSE exit
  on task→review.
- index.ts: --await-review flag.
- tests: returns immediately on already-pending review; exits on a review
  transition while watching. 121/121 green.

Bump 0.4.0 -> 0.5.0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 18:53:40 +02:00
chahinebrini
d2b26cc64c feat: agenthub work — auto-claim daemon (TSK-0018)
The missing autonomy step: an implementer no longer needs a human prompt
per task. `agenthub work --agent <name> --role <role>` announces, then:
  - claims an already-open task addressed to the agent immediately, or
  - blocks on the SSE stream until one appears (newly delegated OR
    reopened after review), then claims + prints it.

Loop: work → implement → `task review` → work. New/reopened tasks are
picked up automatically; run it in the background so the wait doesn't tie
up the turn.

- src/cli/commands/start.ts: extracted announceAgent / findAddressedOpenTask
  / claimAndPrintTask (shared by start + work); addressed-match now also
  covers assignedTo (reopened tasks coming back for rework).
- src/cli/commands/work.ts: wait-and-claim via /events, with a gap-close
  re-check after subscribing and an optional --timeout.
- index.ts: `agenthub work` command.
- templates: implementer guides lead with `work` (the autonomous loop),
  keep `start` as the one-shot.
- tests: immediate claim (local) + wait-then-claim (server SSE). 119/119.

Bump 0.3.1 -> 0.4.0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 18:18:47 +02:00
chahinebrini
7723360054 feat: agenthub start — one-command onboarding (no copy-paste prompts)
An agent runs ONE command and is working: it announces presence, claims
the open task addressed to it, and prints the task + its handoff + the
next step. Removes the per-agent kickoff copy-paste.

- src/cli/commands/start.ts: `agenthub start --agent <name> --role <role>`.
  "Addressed to <agent>" = task title starts with "<agent>:" OR a handoff
  has toAgent=<agent>. Claims it, prints task body + handoff + the review
  gate reminder. No addressed task → lists open role tasks to pick.
  Works on local + --server paths.
- templates: implementer guides (AGENTS/CODEX/KIMI.md) now lead with
  "On your first turn, RUN `agenthub start …` — do not just summarize",
  so a fresh session self-onboards from one trigger word.
- tests: start auto-claims the addressed task, ignores others, no-ops on
  empty queue; templates test updated for the new commands. 116/116 green.

Bump 0.2.2 -> 0.3.0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 17:15:25 +02:00
chahinebrini
b0973a878c feat(update): opt-in background auto-update (AGENTHUB_AUTO_UPDATE)
Set AGENTHUB_AUTO_UPDATE=1 and the install keeps itself current with no
manual `agenthub update` — ideal for the Windows client.

maybeNotifyUpdate now:
- auto mode: refreshes the behind-count hourly (vs 24h) and, when behind,
  spawns a detached `agenthub update` (fetch → reset → install → build)
  that doesn't block the current command; the next invocation runs the
  new version. A 10-min cooldown stamp prevents a second build spawning
  while one is in flight.
- otherwise: unchanged "run `agenthub update`" hint.

Safe to enable anywhere: `update` no-ops when current and refuses to
discard unpushed local commits, so the authoring machine is protected.
Cross-platform (no OS scheduler needed). Bump 0.2.1 -> 0.2.2.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 17:00:31 +02:00
chahinebrini
353c139796 feat: review-gate (task review/reopen) + autonomous role guides
Implements the architect-controlled workflow: implementers submit work
for review, only the architect closes tasks.

- CLI: `agenthub task review <id>` (implementer submits → status review)
  and `agenthub task reopen <id>` (architect re-triggers → status open).
  Server already supported both statuses; now exposed on local + --server
  paths, with remoteClient.reviewTask/reopenTask.
- templates: AGENTS.md + role guides rewritten so agents self-drive the
  CLI on open (hello → claim → implement → task review → wait), with the
  hard rule that ONLY the architect runs `task done`. Implementer guides
  (codex/kimi) never call done; architect guide documents done/reopen.
- tests: review/reopen SSE events + formatEvent "Task review"/"Task
  reopened" lines. 113/113 green.

Bump 0.2.0 -> 0.2.1.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 16:48:42 +02:00
chahinebrini
45070222d0 feat: zero-config auto-connect + agent presence (join-announce)
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 <name> --role <role>`
  posts it; watchers print "AgentHub: <agent> joined (<role>)".
- 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 <noreply@anthropic.com>
2026-06-27 16:33:03 +02:00
chahinebrini
ff79cbb639 feat(cli): brand all AgentHub console output with "AgentHub:" prefix
Every user-facing line — the watch stream and each command's success
line, on both the local and --server (remote) paths — now carries an
"AgentHub:" prefix so it's recognizable in any agent's console
(Claude / Codex / Kimi), independent of the board.

- watch: formatEvent rewritten to verb-based, branded lines
  ("AgentHub: Task received <id>  <title>  [status]",
   "AgentHub: Task done <id>  by <agent>", "AgentHub: Handoff …"),
  plus an "AgentHub: connected" line on stream start.
- task/handoff/decision/memory/delegate/init + server-listening lines
  branded on the local command path.
- cli/index.ts: same branding on the --server remote path (the path
  agents actually hit), so CLI line and SSE stream now match.
- tests: formatEvent assertions updated to the branded format
  (regex-tolerant of column padding). 106/106 green.

codex + kimi stay implementers by convention (role=implementer +
assignedTo) — no schema change. Bump 0.1.1 -> 0.1.2.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 16:09:15 +02:00
chahinebrini
9c749beacb feat(activity): per-task timeline endpoint, board expand, --task/--tokens/--duration/--by flags
GET /tasks/:id/activity returns a time-sorted ActivityItem[] assembled from existing data (task created, handoffs by taskId, memory by relatedTasks, current status). memory add + task done gain optional tokens/duration/by metadata surfaced in the timeline. Board cards expand inline to show the timeline. Index gains taskId + relatedTasks columns with migrations. 74 -> 97 tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 14:49:47 +02:00
chahinebrini
4e5e5ae6bb feat(realtime): SSE event channel + agenthub watch (TSK-0006 part 1)
- src/server/events.ts: in-process EventEmitter bus (AgentHubEventBus);
  singleton per server process, unlimited listeners for SSE fan-out.
- src/server/routes.ts: GET /events SSE endpoint — keepalive every 25 s,
  optional ?role= server-side filter, reply.hijack() for clean streaming;
  eventBus.publish() called on every successful mutating route (POST tasks/
  handoffs/decisions/memory, PATCH tasks/:id).
- src/cli/commands/watch.ts: SSE client using Node fetch + ReadableStream
  reader; exports parseSSEBuffer + formatEvent for testability; --once flag
  exits 0 after first event (turn-based agent use case); --role for client-
  side filtering (additive to server-side filter).
- src/cli/index.ts: register agenthub watch command via resolveContext.
- tests/sse.test.ts: 18 new tests (74 total, all green) — unit tests for
  parseSSEBuffer + formatEvent, integration tests for eventBus on each
  mutation type, E2E SSE stream + role-filter tests over real HTTP.

Limitation (documented): only REST mutations through the server emit events.
Local-CLI writes (direct file+SQLite) are invisible to subscribers — a
filesystem-watch increment is deferred to a later phase.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 00:16:16 +02:00
chahinebrini
074b75f909 feat(cli): add agenthub update self-updater + non-blocking update hint
agenthub update: fetch + reset install to origin/<branch> + reinstall + rebuild, so users never touch git or pnpm. Robust to a dirty working tree (the 'commit before pull' wall) by resetting to remote; guards unpushed local commits and refuses to discard them. Adds a daily, non-blocking update hint on startup (detached background fetch + instant local comparison, like gh/npm/brew) that never auto-applies. Tests for the non-git-install path.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 22:24:53 +02:00
chahinebrini
79f5c8afde feat(cli): single-instance guard, ambient discovery, graceful errors, cwd-robust
Make the network MVP simple to operate: server start refuses a second instance on a port already serving AgentHub (single source of truth, prevents discovery split-brain); commands auto-discover a LAN server when run outside any project so the CLI works from any directory with zero config; walk up to the nearest .agenthub project (cwd-robust) and serve the project root; replace raw stack traces with actionable messages; add tests for findProjectRoot and the single-instance guard.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 22:15:14 +02:00
chahinebrini
9b8d587e9d feat(discovery): auto-discover LAN server during init; zero-config network mode 2026-06-25 13:46:39 +02:00
chahinebrini
3ebd33c4be feat(cli): store serverUrl in config during init; auto-connect LAN clients 2026-06-25 13:33:12 +02:00
chahinebrini
c2e3b0298e feat(server): support --host for LAN binding and export buildApp 2026-06-25 12:33:04 +02:00
chahinebrini
a0af702344 fix(services): guard getters, use counter for memory, deduplicate listEntities 2026-06-25 12:30:14 +02:00
chahinebrini
908a89d772 feat(services): add delegate service and refactor CLI 2026-06-25 12:24:14 +02:00
chahinebrini
6708dde532 feat(services): add status service and refactor CLI 2026-06-25 12:23:57 +02:00
chahinebrini
e69e81135a feat(services): add memory service and refactor CLI 2026-06-25 12:23:45 +02:00
chahinebrini
fff8a61ad9 feat(services): add decision service and refactor CLI 2026-06-25 12:23:23 +02:00
chahinebrini
6c8ee37a08 feat(services): add handoff service and refactor CLI 2026-06-25 12:23:02 +02:00
chahinebrini
b4874afbe9 refactor(cli): use taskService in task command 2026-06-25 12:22:37 +02:00
chahinebrini
37ddaae043 fix(cli): handle missing status, clean imports, record delegated agent 2026-06-24 23:57:22 +02:00
chahinebrini
5adaaad216 feat(server): add optional fastify api 2026-06-24 23:45:20 +02:00
chahinebrini
7c20dd91d9 feat(cli): add status command 2026-06-24 23:44:14 +02:00
chahinebrini
d728c616d1 feat(cli): add delegate command with suggest/auto mode 2026-06-24 23:43:44 +02:00
chahinebrini
fed43e70ed feat(cli): add decision create/list commands 2026-06-24 23:43:02 +02:00
chahinebrini
0cc88603e1 feat(cli): add handoff create/read/list commands 2026-06-24 23:42:22 +02:00
chahinebrini
c4fbbbd865 feat(cli): add memory add/search/list commands 2026-06-24 23:41:34 +02:00
chahinebrini
be9161d7d1 feat(cli): add task create/list/show/claim/done commands 2026-06-24 23:40:23 +02:00
chahinebrini
cd6add215d feat(cli): add init command with agent instruction generation 2026-06-24 23:39:19 +02:00