30 Commits

Author SHA1 Message Date
chahinebrini
722388cb00 feat(server): emit SSE for CLI/file writes via filesystem watcher (TSK-0006)
Closes the documented /events limitation: mutations made through the
local CLI (direct file + SQLite writes, no --server) bypassed the
in-process event bus and were invisible to SSE subscribers. A watcher
(e.g. a Windows client) was therefore NOT triggered when another agent
created a task via plain `agenthub task create`.

- src/server/fsWatch.ts: watch the entity dirs (tasks/handoffs/
  decisions/memory); on any .md change, parse the entity and emit the
  matching AgentHubEvent. Debounced per-file; self-creates dirs so it
  attaches even before the first write.
- src/server/events.ts: shared dedup cache (signature = type🆔stamp)
  + emitChange() so the REST path and the watcher deliver each change
  exactly once (no echo when REST writes the file the watcher sees).
- src/server/routes.ts: route emits go through emitChange(); update the
  stale limitation comment.
- src/server/index.ts: start/stop the watcher with the server lifecycle.
- tests/sse.test.ts: CLI-write -> SSE, CLI-update -> SSE, and REST
  dedup (exactly-once). 102/102 green.

Effect: a watcher is auto-triggered the instant any agent creates a
task, with or without --server. Bump 0.1.0 -> 0.1.1.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 15:43:33 +02:00
chahinebrini
9f3dc28030 fix(cli): memory add no longer prompts when --category is supplied (non-interactive agents)
Local-mode branch of 'memory add' omitted category when calling memoryAdd, so it always fell through to an interactive select() prompt — which throws in non-TTY agent contexts and breaks the reporting loop. Forward category; add tests for the non-interactive flag path.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:59:37 +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
b405b268a5 feat(board): fix gaps A+B — full task status transitions + handoff who→whom
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 &rarr; 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>
2026-06-25 23:41:54 +02:00
chahinebrini
d0e45230bc feat(server): add static Trello-like task board at GET /board
Serves a single self-contained HTML page (inline CSS+JS, no build step,
no framework, no npm deps) that polls /tasks, /handoffs and /decisions on
the same origin and renders a column board by task status
(open/in_progress/review/done/cancelled). Each card shows id, title, role
and assignedTo; small handoffs + decisions panels below; auto-refresh
every 4s with a connection indicator. Purely additive and read-only — the
CLI core path is untouched.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 23:35:28 +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
c073f9a213 fix(network-mode): wrap remote calls for errors, skip Content-Type on empty body, use program CLI in E2E 2026-06-25 13:21:10 +02:00
chahinebrini
efd0c7edfd test(e2e): add network mode end-to-end test; log actual server URL 2026-06-25 12:41:48 +02:00
chahinebrini
7eff25129f fix(server): 404/400 error handling and consistent delegate behavior; add server route tests 2026-06-25 12:40:11 +02:00
chahinebrini
fb3da93f59 feat(cli): add RemoteClient for network mode 2026-06-25 12:32:11 +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
4a8f5cbb8e feat(services): add task service module 2026-06-25 12:18:49 +02:00
chahinebrini
37ddaae043 fix(cli): handle missing status, clean imports, record delegated agent 2026-06-24 23:57:22 +02:00
chahinebrini
1197d85fdc test(e2e): add basic integration test 2026-06-24 23:47:12 +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
chahinebrini
830e7af0c7 feat(templates): add agent instruction templates 2026-06-24 23:37:54 +02:00
chahinebrini
421420040a feat(status): add status aggregation and latest.md generation 2026-06-24 23:36:58 +02:00
chahinebrini
2b9e409b8b feat(index): add sqlite index with fts5 search 2026-06-24 23:35:53 +02:00
chahinebrini
c5af4c7b6a feat(config): add config read/write and defaults 2026-06-24 23:33:27 +02:00
chahinebrini
57bb572bf5 feat(files): add markdown entity read/write 2026-06-24 23:32:14 +02:00
chahinebrini
dd27e8caba feat(counter): add sequential id generator 2026-06-24 23:31:14 +02:00
chahinebrini
b3dea07352 feat(paths): add agenthub path helpers 2026-06-24 23:30:15 +02:00
chahinebrini
2b5696de82 fix(schema): enforce 4-digit ids 2026-06-24 23:29:32 +02:00
chahinebrini
c00ec16c84 feat(schema): add zod schemas for all entities 2026-06-24 23:27:59 +02:00