Der Architekten-Message-Notifier (`watch --await-message claude`) feuerte bei
JEDER Nachricht — auch bei den Watchdog-Erinnerungen, die alle paar Minuten
eintreffen ("review waiting 5m/10m/15m…"). Real erlebt: dreimal hintereinander
geweckt worden, ohne dass etwas Neues passiert war. Ein Signal, das im Takt
seiner eigenen Erinnerungen feuert, entwertet sich selbst.
`--ignore-from <agents>` blendet Absender aus; message-Events tragen dafür
jetzt `from` (bisher nur im title). Armung des Architekten künftig mit
`--ignore-from agenthub` — echte Agenten-Post weckt weiterhin sofort, die
Watchdog-Erinnerungen sieht man beim Pollen ohnehin.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`dormantAgents` filterte auf `!inLoop`. `inLoop` ist aber immer false, solange
ein Agent einen Task AUSFÜHRT — dadurch meldete der Pulse jeden hart
arbeitenden Agenten als dormant. Live gesehen: codex mit 17 s altem Check-in
stand als dormant im Pulse. Genau das Signal, auf das sich der Architekt
verlassen soll, hätte ihn dazu gebracht, funktionierende Agenten anzustoßen.
Jetzt zwei getrennte Fälle:
- `loopExitReason` gesetzt → der Agent hat den Loop ausdrücklich verlassen
und hört nicht mehr zu: sofort melden (unverändert).
- kein Exit-Grund, aber Task in Arbeit → er führt aus; erst nach
DORMANT_AFTER_MS (5 min) ohne Check-in ist das mein Fall.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1) hookContext druckte einen eigenen, aelteren Text. Fuer Codex/Kimi ist der
Hook aber oft der EINZIGE Einstieg (sie starten automatisch) — dadurch
kannten auto-gestartete Agenten weder den Check-in-Kanal noch DEC-0035.
Aufgefallen, als codex ohne `agenthub start` losgelaufen ist. Beide Wege
nutzen jetzt agentBriefing().
2) `server start` prueft jetzt VOR dem Binden, ob hier ueberhaupt ein Projekt
liegt. Vorher band der Server erst den Port und starb dann beim Laden der
Config — der alte Hub war da schon gekillt, die Agenten liefen ins Leere.
Klassiker: aus dem Quellrepo statt aus dem Projekt gestartet (an einem Tag
dreimal passiert). Jetzt sofortiger, verstaendlicher Fehler.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Der Check-in prüfte nur `assignedTo`, `findAddressedOpenTask` dagegen
Titel-Präfix `<name>:`, Handoff-Empfänger UND `assignedTo`. Folge: `agenthub
start codex` meldete "AKTUELL: nichts offen", während TSK-0268 mit
`codex:`-Präfix offen lag — der Work-Loop hätte sie unmittelbar danach
geclaimt. Zwei Wahrheiten über dieselbe Frage.
Jetzt nutzt der Check-in dieselbe Adressierungslogik.
Tests: 293 → 295.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`delivered` heißt nur "einmal ausgeliefert", nicht "gelesen" — abgeschlossen
ist eine Nachricht erst mit read/acked. Der Check-in filterte aber auf
`unread` und ließ damit jede Nachricht fallen, die irgendwo schon einmal
aufgetaucht war (etwa beim Session-Start), ohne dass der Agent sie je
beantwortet hätte.
Real aufgefallen an einer Architekten-Korrektur an kimi: Status `delivered`,
im pending-Block unsichtbar — die Korrektur wäre still verlorengegangen.
Genau der Fehlermodus, gegen den der Kanal gebaut wurde.
Tests: 292 → 294.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Realer Fall heute: kimi stellte ASK-0004 um 16:43 und blockierte in
`agenthub_ask(wait:true)`. Der Wait läuft nach 300 s aus. Der Architekt
brauchte für die Architekturentscheidung 18 Minuten — danach war kimi
dormant, das korrekt emittierte `ask`-Event lief ins Leere, und ein Mensch
musste den Agenten wecken.
Dieselbe Taubheit wie in TSK-0274, nur an einer anderen Stelle: dormant =
unerreichbar. Deshalb wandert die Antwort jetzt in den pending-Block —
`resolvePending` liefert beantwortete eigene Fragen mit, sodass sie beim
nächsten Hub-Kontakt (task_log, checkin, start) ankommt, egal wie lange der
Architekt gebraucht hat.
Tests: 290 → 292.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Der Architekt kann prinzipiell nicht in agenthub_work blockieren (er ist die
interaktive Gegenstelle des Menschen). Sein Sessionstart ist deshalb ein
Lagebericht: Hub-Status, Board, wer woran arbeitet inkl. "kein Check-in seit",
wer auf Übernahme wartet, und eine ausdrückliche Warnung, wenn etwas auf sein
Review wartet. Dazu das rollenspezifische Briefing (pollen statt blockieren,
Approve ist sein Gate, Push gehört dem Menschen, "still" ≠ "tot").
BUGFIX dabei: Die Rolle wurde aus der LOKALEN Config gelesen und hing damit am
Startverzeichnis — das Quellrepo hat ein .agenthub OHNE Config, wodurch
loadConfig warf und die Auflösung stumm auf "implementer" zurückfiel. Der
Architekt bekam so das Implementer-Briefing und hätte sich einen Task
geclaimt. Jetzt kommt die Rolle vom Hub-Roster, wenn ein Hub erreichbar ist;
der lokale Weg greift nur noch ohne Server.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Der Mensch soll pro Session eine Zeile tippen, nicht einen Textblock
einfügen (CEO: „die Prompts sind mega lang"). `agenthub start codex` druckt
jetzt das verbindliche Briefing selbst — Loop-Pflicht, Taubheit während der
Arbeit, pending-Block als einziger Empfangsweg, DEC-0035 — und zeigt
anschließend, was gerade auf den Agenten wartet.
Kein zweites Kommando: das bestehende `start` (Onboarding: announce, Task
claimen, Handoff drucken) nimmt jetzt ein positionales Agent-Argument und
stellt das Briefing voran. `--agent` bleibt für Hooks/Skripte, `--no-briefing`
gibt das alte Verhalten.
Die Rolle kommt aus dem Roster (Architekt wird als solcher erkannt), sodass
`agenthub start <name>` für jeden Agenten ohne weitere Flags reicht.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
WURZEL: Ein Agent empfängt SSE-Events ausschließlich, solange er in
agenthub_work blockiert. Während er einen Task AUSFÜHRT, ist er vollständig
taub — kein Reopen, kein Cancel, keine Nachricht erreicht ihn. Ein echter
Interrupt in einen laufenden Agenten-Turn existiert nicht. Heartbeat,
Watchdog, Polling-Fallback und Presence-Tracking waren allesamt Umgehungen
dieser einen Tatsache; deshalb kam das Problem jede Session zurück.
LÖSUNG — der einzige reale Kanal: die Momente, in denen der Agent von sich
aus mit dem Hub spricht.
- checkinService.resolvePending(): zustandslos aus Tasks + Messages
abgeleitet, nichts, was ein Neustart verliert. Erkennt, dass dem Agenten
die Arbeit entzogen wurde (reopen/cancel/fremder Claim), und liefert
ungelesene Nachrichten + offene Zuweisungen mit.
- agenthub_task_log gibt den pending-Block zurück; der Tool-Text macht ihn
verbindlich (pending.interrupted ⇒ sofort aufhören, nicht einreichen).
- Neu: agenthub_checkin(agent, taskId) für lange Strecken ohne Log-Zeile,
plus GET /agents/:agent/pending.
- resolvePending degradiert auf reinen Namensvergleich, wenn keine Config da
ist — ein Check-in darf nie an Konfiguration scheitern.
DEC-0035: `review` bindet den Agenten wie `in_progress`. Vorher galt er in
der Sekunde des Einreichens als frei, griff sich die nächste Task, und ein
Reopen prallte danach am Ein-Task-Guard ab (so ging der Reopen von TSK-0218
verloren). Der Loop bleibt aktiv — wach warten, nichts Neues anfangen.
Außerdem: in_progress → open erlaubt, damit der Architekt eine festhängende
Arbeit überhaupt entziehen kann (vorher 400, Agent blieb dauerhaft blockiert).
SICHTBARKEIT: /health und /agent-health zeigen pro Agent pendingCount
(wartende Tasks) und deafForSec (wie lange ohne Check-in bei laufender
Arbeit). Ungelesene Nachrichten stehen separat — der dreistellige
Altbestand einzelner Agenten hätte das Signal sonst erschlagen.
Tests: 279 → 290. tests/singleClaim (b) auf den neuen Vertrag umgeschrieben
(+ (b2): ein Reopen gewinnt gegen die nächste Task).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Drei vom Architekten abgenommene Tasks, gebündelt als Checkpoint:
- TSK-0242: Agent-Alias-Mapping (kimi-ah → kimi kanonisiert, Rollen → preferredAgent),
reopenTask räumt claimedBy ab, fsWatch reindiziert direkte Datei-Edits,
work-Default 300s → 50s, task_list mit Limit.
- TSK-0245: zwei Agent-Klassen (dispatch loop|architect). Watchdog mahnt
architekt-getriebene Agenten nur noch EINMAL statt im Minutentakt;
`task dispatch` startet sie explizit, `task record` trägt extern
erledigte Arbeit mit origin=external nach.
- TSK-0249: Lifecycle wird serverseitig erzwungen (open→review scheitert mit
klarer Meldung), claimedBy/doneBy überleben bis done, Presence pro Agent,
Review-Watchdog, GET /architect/pulse (1.4 kB statt 34 kB, since-Cursor,
omitted statt stillem Abschneiden), unbekannter Agent → 400 statt 500.
Alle Punkte live am laufenden Hub nachgemessen, nicht aus Agenten-Logs übernommen.
Tests: 242 → 279 grün, tsc sauber.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- probe configured server URL (~1s) before remote commands; on failure
re-discover via LAN discovery, persist and use the resolved URL
- poll tryClaim/trySurfaceMessages every ~4s during the SSE wait in CLI
work and MCP waitForTask — a lost SSE frame costs seconds, never sleep
- work/MCP no longer auto-mark messages read: surfacing sets delivered,
explicit ack/read required; loops still wake only on unread (no spin)
- parseSSEBuffer accepts CRLF frame separators and joins multi data: lines
- bump version to 0.10.1 (package.json, CLI --version, MCP server)
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>