Root cause of twitch + overlap: source.onmessage ran an unconditional full
board rerender (cardsEl.innerHTML=) on EVERY change event, and the enter
animation was on a global `.card` selector so it replayed on all cards each
rerender.
1+2) SSE onmessage now parses event.type and only rerenders the board on
type==='task' (message/ask/decision/memory/handoff/agent no longer
trigger a board rerender; budget still refreshes — it has its own
diff/throttle). renderBoard() rebuilt as a per-card diff-patch
(patchColumn/cardSig/cardNode): untouched cards are kept + reordered,
only new/changed cards are (re)built. Enter animation scoped to a
one-shot .card-new class. min-height added to the .card transition list
so the console-open growth is smooth. Open live consoles preserved
(reapplyConsoles unchanged; kept nodes retain their console DOM).
3) setMetric() pulses the .metric-card (.metric-flash + @keyframes metricFlash)
only when the value actually changes from a previously-seen value.
4) Donut center readout moved from a CSS top:66.7% div to SVG-native <text>
in viewBox coords (x=110, value y=102, label y=120) so it scales and sits
in the arc opening. .donut-value/.donut-label restyled with fill.
TSK-0154 politur: .cc-line.level-bridge .cc-text color.
tsc clean; vitest 36 files / 184 tests green. Visual points are Screenshot/
manual (no board.test.ts). No console regression.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- 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>
- work.ts: the CLI work loop now wakes on architect follow-up MESSAGES, not just
tasks. drainAgentMessages() surfaces + marks-read the agent's inbox; wired into
waitAndClaim (SSE message events) and as an upfront check in workAgent. reopen +
next-assign already wake via task events; a plain message no longer leaves the
re-armed loop dormant.
- mcp/server.ts: implementer agenthub_work LOOP reminder now explicitly instructs
re-arming after agenthub_task_review so the architect's approval/reopen/message
wakes it (waitForTask already wakes on task+message).
- tests: work.test.ts +message-wake +reopen-wake
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- routes PATCH /tasks/🆔 uniformly appendTaskLog + publishLog for every status
transition (claim/review/done/cancel/reopen) and on assign; best-effort, never
fails the mutation. No double-emission (log rides the 'log' channel; fsWatch
only watches .md so the .log append is not re-emitted).
- MCP agenthub_task_log tool + remoteClient.appendTaskLog + CLI 'task log <id>
--text [--agent][--level]'
- agenthub_work LOOP reminder: 'Report meaningful progress with agenthub_task_log'
- taskDetail: Live Console panel — historic lines via readTaskLog + live tail via
the named task-log SSE event filtered to this task id
- tests: +taskLog-live.test.ts (PATCH->one log event, no double change, historic
render, POST /log, remoteClient)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Board-v3 (TSK-0099, codex, architect-reviewed 7/7):
- kanban columns fill viewport height, scroll inside the column (no page scroll)
- padding/margin between task cards
- bar-chart HTML-escape bug fixed (est marker inserted raw, not esc())
- half-donut center text centered
- task detail opens in a modal (title/description/activity, empty sections hidden)
instead of navigating to /tasks
- header-jitter on page switch fixed via scrollbar-gutter: stable
- SSE connection-leak/freeze fixed (EventSource closed on pagehide/beforeunload)
Animated KPI icons (architect):
- vendored lottie-web player + Lottie card icons under assets/, served via a
path-traversal-guarded /card-assets/* route (offline-safe, no CDN)
- state-driven: loop-while-active (open/in_progress/review), pulse-on-change
(active/done/agents); light KPI card bg so the black-line icons read clearly
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QMN96FH9rJDY2bZnEBdPfA
- The pulse is now one dash with an effectively infinite gap, animated
origin→target→off with fill:forwards — no wrap-around second bar and no
snap-back to origin when it arrives (fixes the ghost bar). Slower, ease-in-out
so it eases out of the origin card and into the target's last branch.
- Real delegation/review pulses now originate at the ARCHITECT (the root's
single child), not the CEO above it — so a task assigned to an agent no longer
visibly starts from the CEO. Cuts a 3-edge cascade to 2 for a PO-level agent.
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>
Reflects the org move (CI/CD + Strategist now report to the architect, not the
CEO): architect coordinates them directly, and the demo flow adds a closing
'architect → CEO final report' step. The CEO is only touched at the very end.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Move the arrival/completion glow onto a dedicated ::after overlay animated by
opacity only, so it no longer collides with the node's box-shadow transition
— the card stays put on done (transform verified identity throughout).
- A pulse now lights only its FINAL destination; waypoint nodes it merely passes
through (e.g. the CEO on an architect→strategist peer handoff) are no longer
flashed as 'involved'.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The badge chip already says Active/Review, so the status line now shows just
the task id + relative time (e.g. 'TSK-0059 · 2h') instead of repeating it.
- Active card: a green highlight sweeps along the border left→right while the
task runs (masked gradient ::before), signalling live work.
- Status chip: white background (green/amber text), Paperclip-style.
- Slower, more readable animation (edge 1500ms, stagger 680ms, longer flow gaps).
- Arrival and task-completion are now soft glow fades with NO transform, so the
card no longer twitches on done; a dedicated doneFade plays when a task the
agent held goes done/cancelled.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- 'Active'/'Review' badge is now a floating pill straddling the card's top-right
edge (light green / amber) instead of an inline tag — keeps the card uncluttered.
- Move info + rename buttons out of the text row into an absolute top-right
cluster so short names (Chahine, backyard, CI/CD) fit without truncating;
smaller name font (12px); slightly wider node (182px) + matching grid.
- Rename is discoverable: a pencil appears on node hover (still double-click too).
Role labels for org-only / function nodes come from config.org 'role' (CEO,
Product Owner, CI/CD, Strategist, Release) so they no longer show 'Implementer'.
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>
Compact the tree so upper levels stay close together:
- a parent with >4 leaf children now lays them out in a square-ish grid
(cols = ceil(sqrt(n))) instead of one wide row; connectors drop from a fixed
bus Y so the elbows stay clean across grid rows;
- a 'Fit' toolbar button scales the whole chart to the viewport width via CSS
zoom (reflows, so scroll shrinks) and toggles back to 100%.
Cuts the rebreak org width ~2400px→~1830px, and Fit shows the entire tree at once.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Match the Paperclip look: connectors are now right-angle elbows (parent → shared
horizontal bus → drop to each child) instead of bezier curves; siblings share a
bus Y so it reads as a clean org chart. The traveling pulse follows the elbow
path. Role/model line truncates with ellipsis inside the card (no more text
spilling past the edge); nodes clip overflow. Slightly more compact nodes/gaps.
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>
The green pulse now visualises real task flow instead of looping randomly:
- delegation (task → in_progress/reassigned) fires a green pulse architect→agent
and the agent card turns 'active' (green ring + badge);
- review submission (→ review) fires an amber pulse agent→architect and the
card enters the 'reviewing' state.
Pulses are one-shot, created per transition (SSE-driven, deduped against a
baseline snapshot) and removed on arrival, which lights the destination node.
At rest only the connectors breathe faintly. Active state recoloured green to
match the pulse. Verified: delegation→down+active, review→up+reviewing.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Rebuild /team as a real org chart: architect at the root, workers below,
with an SVG connector layer whose edges carry a traveling green pulse
(getTotalLength + WAAPI stroke-dash motion) that flows from the architect
down each edge and lights up the node it reaches (onArrive → .arrive glow),
looping. Live busy state (SSE) keeps working agents lit blue; edges + nodes
re-layout on resize. Node cards restyled (icon box + name + role·model +
status). Kept data-agent / agent-card / claimed markers for the live sync.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Browsers were caching /board and /team, so a stale page kept showing old
markup and didn't reflect live task/agent state (looked like the pre-redesign
team page + tasks appearing unclaimed though the server had them claimed).
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>
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>
codex built the dashboard redesign (TSK-0032): KPI metric cards, half-donut status
distribution, recent-activity feed, /decisions page, /archive page, task-detail
handoffs. Architect follow-up: the KPI cards were oversized (stretched to the side
panel height) — reworked to a compact full-width top row (auto-fit, fixed ~84px
height, label over value, small status-colored icon) per the user's reference.
Committed together to lock TSK-0032 in before TSK-0030 (realtime) touches the same files.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>
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>
Architect implementation of the reopened TSK-0028 (option B). The team page now
reads config.agents (the roster) as the source of truth instead of inferring
role/identity from tasks:
- one fixed role per agent (fixes "codex in architect+implementer+tester")
- implementers grouped by provider with official Simple Icons brand logos
(Anthropic / OpenAI / Moonshot) + the model behind each agent (Opus 4.8,
Sonnet 4.6, GPT-5 Codex, Kimi K2)
- demo/throwaway agents gone (not in the roster)
- architect tier (claude) on top, implementer provider columns, tester tier
(ahmed); free/busy + live timer from in-progress tasks
- ui-shared: providerLogo()/providerMeta() with verified brand SVG paths
Bump 0.7.4 -> 0.7.5.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
One command, no hand-editing: `agenthub mcp install` writes/merges a project
.mcp.json (the standard config Claude Code and other .mcp.json-aware clients
auto-discover) with the hub URL filled in — so those agents register
automatically. Prints the global-config snippet for Codex/Kimi as fallback.
`--print` is a dry run. Bump 0.7.3 -> 0.7.4.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Removes the registration friction: `agenthub mcp install` prints ready-to-paste
MCP config for Claude Code, Codex and Kimi, with the hub URL filled in from the
project config. `agenthub mcp` (no action) still starts the stdio server, so the
MCP-client spawn command is unchanged. Bump 0.7.2 -> 0.7.3.
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>
Solid-collaboration foundation: agents invoke STRUCTURED tools instead of
shelling out to the CLI — so a tool can't be narrated away, hallucinated as
"doesn't exist", or mistyped. Confirmed working for Claude / Codex / Kimi
(all speak MCP).
- src/mcp/server.ts: `agenthub mcp` starts a stdio MCP server exposing 16
tools (work, task_list/show/create/assign/claim/review/reopen/done,
memory_add/search, handoff_read/create, decision_create, hello, status).
Thin layer over the SAME core: proxies through the REST API (remoteClient)
when a hub is configured — so board, SSE, status auto-refresh and CLI keep
working unchanged — else local services. agenthub_work blocks on SSE until
a task addressed to the agent is claimable, then returns it + its handoff.
- `agenthub mcp` command; excluded from the update-notify (stdio purity).
- Verified: initialize + tools/list (16) + tools/call (status, task_list)
proxy to the live hub.
Does NOT change the dormant-agent reality (agents still loop agenthub_work);
it makes every interaction reliable. Bump 0.6.1 -> 0.7.0.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>