- Set task status to 'failed' on execution failure in engine executor
- Add failed indicator styling on TaskCard component
- Add POST /tasks/:id/retry API endpoint and client function
- Add retry button in TaskDetailModal for failed tasks
- Add tests for failed indicator, retry endpoint, and modal behavior
- Route now returns 404 only for ENOENT, 500 for transient errors
- store.getTask() retries once after 50ms on non-ENOENT failures
- Added route tests for success, 404, and 500 cases
- Updated vitest config to include src/**/*.test.* files
- Add rate limiting middleware to dashboard API endpoints
- Install lucide-react and replace emoji usage with Lucide icons across dashboard components
- Add rate limiter unit tests
- Document API rate limiting in README
- Refactor engine executor/triage and remove unused reviewer module
- Add maxWorktrees field to Settings interface with default of 4
- Enforce worktree limit in Scheduler.schedule() alongside maxConcurrent
- Wire setting through dashboard startup from persisted settings
- Include maxWorktrees in /api/config response
- Add Max Worktrees input to Settings Modal UI
- Backward compatible: existing configs without maxWorktrees use default
- Make Task.title optional and description required in types and TaskCreateInput
- Update CLI task create to prompt for description instead of title, with updated help text
- Update REST API and dashboard CreateTaskModal to require description instead of title
- Handle optional/missing title across TaskCard, TaskDetailModal, and engine components
- Add description validation in TaskStore and update generateSpecifiedPrompt
- Fix Vite alias to resolve @hai/core to types-only module (avoids Node.js deps in browser bundle)
- Add tsconfig.app.json for client-side typecheck
- Fix server.ts return type annotation
- Update imports to use @hai/core (resolved via Vite alias)
- Add base project files needed for workspace