- core/index.ts: the FTS5 'search' table has no UNIQUE on id, so INSERT OR
REPLACE appended a new row every update and the search JOIN returned an id
N times. Now delete-then-insert by id -> exactly one FTS row per entity.
- taskService.claimTask: race-guarded — only an OPEN task can be claimed;
same-agent re-claim is an idempotent no-op; a task claimed by another agent or
past open is refused. getTask+updateTask are sync, so within the single-thread
event loop the read-check-write is effectively atomic (first claim wins).
- routes.ts (spec 'nicht brechen'): PATCH in_progress surfaces a lost/non-open
claim as a clean 400 instead of 500, so the board drag reverts gracefully and
a second agent can't clobber the first's claim.
- tests: +coreCorrectness.test.ts (no FTS dup after updates; concurrent claims
-> one wins; idempotent re-claim; refuse non-open) + server.test.ts route guard
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add an org service + CLI: parse a fenced ```agenthub-org YAML block from
CLAUDE.md (or AGENTS.md), validate it (one root, resolvable parents, unique
ids) and write it to .agenthub/agenthub.config.json. So the human-readable doc
drives /team: edit the block, run `agenthub org sync`, the chart adapts. Can be
wired into a post-commit hook to sync automatically when CLAUDE.md changes.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- OrgNode gains an optional 'role' field so org-only nodes (CEO, Product
Owners) show a role under their name; agents still fall back to their roster
role. Fixes the missing CEO label on the root.
- New 'Flow' button plays a choreographed delegation lifecycle as directional
pulses with step captions: claude defines → PO Native → agent → back to PO →
review at architect → CI/CD → ahmed test → back to architect (approve/push),
plus architect→strategist for some tasks. pulseBetween() walks any two nodes
via their lowest common ancestor, colouring each edge by its real direction
(down=green delegation, up=amber return), so the animation always shows the
direction.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the flat 2-tier team view with an arbitrary-depth org chart driven by
a new config.org hierarchy (OrgNodeSchema: id/label/title/agent/parentId).
Nodes render recursively (nested subtrees); SVG connectors are measured
parent→child; the event-driven pulse now travels the full path root→agent
(down = delegation/green, up = review/amber), lighting each node it passes.
Org-only nodes (a human CEO, product owners) sit in the tree without a linked
agent. Each node has an info button (its job description) and an inline-
editable name persisted via PATCH /org/:id. Live active/reviewing state is
rendered server-side and kept fresh over SSE. Compact layout + auto-centered
horizontal scroll. Falls back to a synthesised architect→workers tree when no
org is configured (keeps existing behaviour + tests).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Board (/board):
- Drag an AGENT chip onto a task card to (re)assign it (realtime-notified).
- Drag a task card to a column to change status; open→in_progress auto-assigns
from the title's "<agent>:" prefix — no manual agent picking.
- "+ New task" composer (agent dropdown removed; agent comes from the title).
- Live Cost & Budget panel.
Team (/team): live SSE sync of busy state + always-on ambient animation
(connector shimmer, idle glow) that brightens to a busy pulse when an agent
works. Org-chart hierarchy stays.
Token accounting: new budgetService/rosterService + GET /budget and /agents.
Real doneTokens + time-on-task estimate capped at 45 min/task (avoids the
wall-clock overcount that produced multi-million-token totals), blended
per-model EUR cost + optional budget bars. All estimates flagged "~".
Autostart: `agent setup` writes deterministic SessionStart hooks for Codex
(~/.codex/config.toml) and Kimi (~/.kimi-code/config.toml), not just Claude
Code. Verified: both auto-enter the agenthub_work loop.
Realtime architect review: agenthub_work is role-aware — architect/reviewer
blocks on SSE and wakes when a task hits review (no manual watcher re-arm).
mDNS: server advertises agenthub.local (bonjour-service) so the hub is
reachable in a browser on the LAN without an IP.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
codex reworked the board per the user's "keep it simple": /board now shows only
the compact KPI cards + the kanban (half-donut removed), with realtime SSE folded
in (TSK-0030). Recent Activity + Done Archive moved to a new /activity page; nav is
Board · Team · Activity · Decisions. team.ts / ui-shared.ts touched for nav + a
tier data-role hook. Tests green (133). The /team + /activity 500s seen on review
were a local better-sqlite3 ABI mismatch (native module rebuilt for Node 24), not a
code bug — all pages 200 after rebuild.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>
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>
Implementer onboarding now points at the MCP tools first (agenthub_work ->
implement -> agenthub_task_review -> loop), with the CLI as the fallback when
the MCP server isn't registered. Reflects the MCP pivot. Bump 0.7.1 -> 0.7.2.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds an optional `agents` roster to the project config: agent name -> role +
model + provider (kind). The team view can now show named agents (claude,
codex, kimi, windows-claude, backyard, mo, zied, …) with a FIXED role and the
model behind them, instead of inferring role/identity from whichever tasks an
agent happened to touch (which made one agent appear under several roles).
Bump 0.7.0 -> 0.7.1.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>
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>
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>
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>
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>
GAP A: extend PATCH /tasks/:id to support all five TaskStatus values
(open, in_progress, review, done, cancelled). Add reviewTask, cancelTask,
reopenTask helpers in taskService. Claim semantics preserved: in_progress
requires assignedTo. Board columns for review and cancelled now reachable
via the API.
GAP B: index fromRole/toRole/fromAgent/toAgent on handoff upsert. SQLite
migration guard adds columns to pre-existing DBs without data loss. Board
renderHandoffs shows "fromRole[@agent] → toRole[@agent]" via → arrow.
GET /handoffs now carries the routing fields in every index entry.
Tests: +14 (56 total, 21 files, all green). Covers every new status
transition, index field presence, board markup assertions, and a guard for
the claim-without-assignedTo 400.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>