Let Vitest schedule independent projects in parallel while keeping each stateful integration project single-worker, and complete the human review Inbox fixture.
Add heartbeat_enabled persistence and enforce a 1 hour minimum heartbeat interval.
Keep webhook triggers active when scheduled heartbeat is disabled, and expose the toggle through the UI and CLI.
- Remove right padding from chat drawer body so scrollbar sits flush
against the drawer edge; add pr-3 inside viewport for content clearance
- Suppress horizontal scrollbar with overflow-x-hidden on viewport
- Remove redundant ChevronRight arrow from ToolShell (each tool has its
own icon); fix truncate+break-words conflict by dropping truncate
- Rename tool registration from "Task" to "Agent" to match actual Claude
API tool name — the custom TaskToolUI was never matching before
- Display subagent_type as label (e.g. CLEAN-CODE-REVIEWER) instead of
generic "task:" prefix; fall back to "agent" when no type is specified
- Add Agent tool call examples to MockChatPage for dev preview
- Add 36 unit tests for ToolShell, parseMcpToolName, langFromPath, and
agent label derivation
Unify the app into a single Worker deployment:
- Move functions/api/ → server/, add worker/index.ts entry point
- Merge relay-worker DO (TunnelRelay) into the main worker
- Replace Pages Functions with @cloudflare/vite-plugin build
- Integrate share SSR (OG meta injection) into Hono routes
- Remove dayjs dep from shared (native Date suffices)
- Simplify dev to single `vite dev`, deploy via CF Git integration
- Delete packages/relay-worker/ and Pages-specific _routes.json
Prettier's aggressive line-splitting (printWidth 100, single quotes) didn't
match the project's existing compact code style. Switch to Biome which
provides formatting + linting in one tool with better chain-call handling.
- Remove prettier, add @biomejs/biome
- Configure biome: double quotes, lineWidth 150, recommended lint rules
- Update lefthook pre-commit to use `biome check`
- Full codebase format pass with new config
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add CI workflow: build, type check, test with coverage on PRs and master
- Configure vitest coverage (v8 provider) scoped to source directories
- PR coverage report via vitest-coverage-report-action
- Coverage badge via GitHub Pages (no external services needed)
- Update CLAUDE.md with post-write workflow and testing conventions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Integration tests revealed three issues with the agent-auth bridge:
- BA adapter silently ignores custom IDs without forceAllowId: true
- Agent JWT requires typ: "agent+jwt" in protected header
- Agent JWT requires aud claim matching the server URL
Adds integration test suite (miniflare + real D1) covering the full
agent-auth flow: machine/host creation, agent registration in both
tables, JWT verification, and rejection of invalid/unsigned tokens.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: Agent Kanban v2 — agent observatory, dependencies, SSE streaming
Transform the board from a task tracker into an agent observatory with
real-time visibility, platform-driven assignment, and dependency-aware
task coordination.
- Agent entity: status tracking (idle/working/offline), GET /api/agents
- Task dependencies: depends_on with cycle detection, blocked computation
- Task origin: created_from for subtask tracking
- Assign/Release: POST /api/tasks/:id/assign and /release endpoints
- Stale detection: auto-release after 2h, write-on-read in board fetch
- SSE streaming: GET /api/tasks/:id/stream with polling fallback
- CLI: task assign/release, agent list, --parent/--depends-on flags
- UI: ActivityLog, AssignDropdown, AgentProfile, SubtaskList, blocked badges
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(review): address 5 review findings from pre-landing review
- Narrow SSE auth bypass to exact path pattern (was too broad)
- Fix SSE reconnection: resolve log ID to timestamp for since filtering
- Compute blocked status in getBoard() so kanban view shows blocked badges
- Remove dead code in useSSE polling fallback
- Rename fetch→load in useAgents to avoid shadowing global
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: bootstrap test framework (vitest)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* test: enum completeness coverage for v2 actions and agent statuses
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: bump version and changelog (v1.2.0)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs: sync CLAUDE.md with v1.2.0 patterns
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>