- Removed dead agent-service.ts (replaced by clawdbot-agent-service.ts)
- Moved AgentOutput type to clawdbot-agent-service.ts
- Added web/src/hooks/index.ts barrel export for cleaner imports
- Noted: useToast is correct shadcn pattern, not a reimplementation
- Noted: UI components are shadcn standard, no docs needed
- Noted: Monorepo scripts already complete
- Add typeof check for process.env to avoid ReferenceError in browser
- process.env only exists in Node.js, not browser environments
- Fixes white screen issue when loading web frontend
- Add aria-live regions to SaveIndicator for screen reader announcements
- Add Move Up/Down buttons to ManagedListManager for keyboard navigation
- Implement focus management: focus first tab on dialog open, focus content on tab switch
- Add comprehensive ARIA labels to all interactive elements (switches, buttons)
- Add aria-hidden to decorative icons
- Improve Switch accessibility with proper labels and aria-label attributes
- Add role=tabpanel and aria-controls for proper tab/tabpanel relationships
- Radix Dialog provides built-in focus trap functionality
- Add duration support to toast system
- Replace all 5 alert() calls in SettingsDialog with toasts
- Success toasts auto-dismiss after 3s
- Error/warning toasts persist until manually dismissed
- Consistent with ManageTab toast patterns
- Add syncSettingsToServices() to propagate feature settings to services
- Telemetry service reads enabled/retention/traces from feature settings
- Attachment service reads dynamic limits from task behavior settings
- Sync on startup from config file and on every PATCH /api/settings/features
- Add setLimits() to AttachmentService for runtime limit updates
- Vertical sidebar navigation with 7 tabs: General, Board, Tasks, Agents, Data, Notifications, Manage
- Toggle rows with Switch components + descriptive labels
- Number inputs with min/max validation and unit labels
- Auto-save with debounced 500ms updates + save indicator
- Reset to Defaults button per section with confirmation
- Mobile: tabs collapse to dropdown selector
- Keyboard navigation between tabs (arrow keys)
- Existing managed lists (task types, projects, sprints, templates) moved to Manage tab
- Add broadcast-service.ts that sends task:changed events to all
connected WebSocket clients on any task mutation
- Wire broadcasts into task routes (create, update, delete, archive,
restore, reorder)
- Add useTaskSync hook — connects to WS, listens for task:changed,
invalidates React Query cache for instant board updates
- Add polling fallback: refetchInterval=10s, staleTime=5s on useTasks
- Auto-reconnect WebSocket with 3s backoff on disconnect
Board now updates within seconds of any external change (API calls
from Clawdbot agents, CLI, etc.) without manual page refresh.
Fixes: task_20260128_Zk4oV0
- Add readOnly prop to TaskDetailPanel — shows archived badge,
displays all fields as non-editable text, hides delete/template buttons,
shows 'Restore to Board' button instead
- Wire up task click in ArchiveSidebar to open read-only detail panel
- Add pagination to archive list (25 per page with 'Load More' button)
- Show results count when filters reduce the list
- ArchiveSidebar now manages its own detail panel internally
Fixes: task_20260128_tDh8SO
- Add position field to Task type (shared/types.ts)
- Add POST /api/tasks/reorder endpoint to persist ordering
- Update task-service with reorderTasks() method
- Switch TaskCard from useDraggable to useSortable (@dnd-kit/sortable)
- Wrap KanbanColumn tasks in SortableContext with verticalListSortingStrategy
- Update KanbanBoard DnD handlers to support both within-column reorder
and cross-column status changes
- Sort tasks by position in useTasksByStatus hook
- Use closestCorners collision detection for better sortable support
Fixes: task_20260128_4qCzGr
- stopTimer() set activeEntryId: undefined which js-yaml cannot serialize
- Changed to omit activeEntryId when clearing (conditional spread)
- Same fix in deleteTimeEntry() for active entry deletion
- Added deepCleanUndefined() to taskToMarkdown() as defense-in-depth
- Imported TimeTracking type for explicit typing
Fixes: task_20260128_RrQUWH
- Added SprintConfig interface extending ManagedListItem in shared types
- Created SprintService with seed migration from existing tasks
- Added /api/sprints endpoints using managed list router pattern
- Implemented useSprints and useSprintsManager hooks
- Updated TaskDetailPanel and CreateTaskDialog to use dynamic sprint list
- Added sprint management UI to SettingsDialog
- Sprint IDs match existing task.sprint values for backward compatibility
- Reference counter prevents deletion of sprints with tasks
- US-700 series (archive): US-701 through US-711
- US-800 series (archive): US-801 through US-808
- US-900 series (active): US-901 through US-919
- Created US-917 (sprint assignment), US-918 (subtask count), US-919 (task type on cards)
- All three marked done with closing comments
- Fixed path traversal in attachment filename sanitization
- Fixed Radix Select crash: empty string value ('') not supported
Changed 'No project' SelectItem from value='' to value='__none__'
in both TaskDetailPanel and CreateTaskDialog
- Updated task type colors: removed Rose, added bright Pink (fuchsia),
darkened Blue (700), darkened Green (700), added Yellow, added Brown
- Removed isDefault protection from delete (any item can be deleted)
- Removed hide/show toggle button from ManagedListManager
- Delete still blocked if item has task references (with clear message)
- Cleaned up isHidden flags from task-types.json
- Simplified delete dialog messaging
- ProjectService.init() had infinite recursion: list() → init() → seed → list() → init()...
- TagService seed checked file existence (always true after super.init creates it)
- Seed migrations now use seedItem() with raw project/tag strings as IDs
so they match existing task.project and task.tags values
- Added seedItem() to ManagedListService base for custom-ID seeding
- Cleaned up task-types.json (removed duplicate, restored Research)
PHASE 1: US-915 ManagedListService Foundation
- Added ManagedListItem and ManagedListServiceOptions types to shared/src/types.ts
- Created ManagedListService<T> base class with full CRUD, reorder, and reference checking
- Created createManagedListRouter factory for generic Express routes
- Created useManagedList hook for React with TanStack Query integration
- Added managedList API helpers to web/src/lib/api.ts
- Created ManagedListManager React component with drag-to-reorder using @dnd-kit
PHASE 2: US-913 Custom Task Types
- Changed TaskType from union to string in shared types
- Added TaskTypeConfig interface extending ManagedListItem with icon and color
- Created TaskTypeService using ManagedListService with 4 built-in default types
- Registered task-types routes at /api/task-types
- Updated server validation in tasks.ts and templates.ts to accept dynamic types
- Created useTaskTypes hook with helper functions (getTypeIcon, getTypeLabel, etc.)
- Updated FilterBar to use dynamic task types
- Updated TaskCard to accept and use dynamic task types
- Updated KanbanBoard and KanbanColumn to fetch and pass task types
- Updated TaskDetailPanel to use dynamic task types
- Updated CreateTaskDialog to use dynamic task types
- Updated SettingsDialog template form to use dynamic task types
- Added Task Types management section to Settings with full CRUD and customization
- Added taskTypes API namespace to web/src/lib/api.ts
All UI components now render task types dynamically from .veritas-kanban/task-types.json
Icon and color customization available in Settings with 20+ Lucide icons and 10 colors
- Export all templates as JSON file
- Import templates from JSON file with duplicate detection
- template-io utility for file handling and validation
- Import/Export buttons in SettingsDialog templates section
- Duplicates skipped during import with notification
- Add agent field to template editor (preferred agent for code tasks)
- Agent selector in AddTemplateForm with all available agents
- Agent displayed in template list alongside other defaults
- Templates can specify preferred agent (claude-code, amp, copilot, gemini, veritas)