Commit graph

143 commits

Author SHA1 Message Date
Brad Groux
dd4e90475b refactor(web): improve state management patterns
RF-24: Frontend state management improvements

1. useCreateTaskForm hook - Replaces 11 useState calls in CreateTaskDialog with useReducer:
   - Single source of truth for form state
   - Predictable state transitions via typed actions
   - Atomic state updates (e.g., applyTemplate updates multiple fields at once)
   - Computed canSubmit derives validity instead of storing it

2. Optimistic updates for task mutations:
   - useCreateTask: Immediately adds placeholder task to list, rolls back on error
   - useUpdateTask: Immediately applies changes to cache, rolls back on error
   - Both sync with server on settle to ensure consistency

3. usePolling hook - Shared polling patterns:
   - usePolling: Core hook with enable/disable, immediate, cleanup
   - useConditionalPolling: Start/stop based on condition
   - getConditionalRefetchInterval: For react-query refetchInterval

These patterns improve UI responsiveness and code maintainability.
2026-01-28 08:00:43 -06:00
Brad Groux
a424d0a7c5 refactor(RF-15): split Board and Settings god components
- Extract useBoardDragDrop hook from KanbanBoard (drag-drop logic)
- Extract BoardLoadingSkeleton component from KanbanBoard
- Extract useSortableList hook from ManagedListManager
- Extract SortableListItem component from ManagedListManager

Line count improvements:
- KanbanBoard.tsx: 329 → 210 lines (-36%)
- ManagedListManager.tsx: 372 → 128 lines (-66%)

All extracted components follow single-responsibility principle.
2026-01-28 07:59:17 -06:00
Brad Groux
76bf61e428 chore: update telemetry/notification data from US-1009 testing 2026-01-28 07:57:02 -06:00
Brad Groux
22509f1808 feat(web): add Task Metrics Panel (US-1002)
- Created useTaskMetrics hook to fetch and aggregate telemetry events for a task
- Built TaskMetricsPanel component with:
  - Summary cards for total runs, success rate, duration, tokens, cost
  - Last run status display
  - Expandable per-attempt breakdown with full details
- Integrated as new 'Metrics' tab in TaskDetailPanel
- Fetches via GET /api/telemetry/events/task/:taskId endpoint
2026-01-28 07:55:48 -06:00
Brad Groux
65e0c8b278 feat(US-1303): Add real-time WebSocket agent status hook
- Create useRealtimeAgentStatus hook with WebSocket subscription
- Subscribe to agent:status events as primary transport
- Fall back to polling every 10s when WebSocket disconnects
- Auto-reconnect on WebSocket disconnect (via useWebSocket)
- Stale detection marks agent as idle after 5+ min without updates
- Memoized return value to prevent unnecessary re-renders
- Full TypeScript types for AgentStatusData, SubAgent, AgentStatusState
- Maintain backwards compatibility with useGlobalAgentStatus (polling-only)
2026-01-28 07:42:00 -06:00
Brad Groux
fd742b92c2 RF-09: Extract business logic from routes to services
Created new services with reusable, testable business logic:
- notification-service.ts: persistence, formatting, notification generation
- summary-service.ts: task aggregation and memory formatting
- automation-service.ts: scheduling decisions and lifecycle management
- blocking-service.ts: dependency validation and circular detection

Refactored routes to be thin HTTP handlers:
- notifications.ts: 228 → 102 lines (55% smaller)
- summary.ts: 136 → 33 lines (76% smaller)
- automation.ts: 139 → 110 lines (21% smaller)
- tasks.ts: blocking logic extracted to service

All 112 tests pass. Routes now only handle request/response;
all business logic lives in services for better testability.
2026-01-28 07:41:16 -06:00
Brad Groux
9cbf6a77be feat(security): RF-03 server security hardening
- CORS: Configure allowed origins (env CORS_ORIGINS or localhost defaults)
- Rate Limiting: Add 100 req/min rate limiter to all API routes
- Request Size: Limit express.json() to 1MB
- Path Traversal: Validate attachment paths stay within allowed directories
- Prototype Pollution: Sanitize deepMergeDefaults to reject __proto__ keys

Security improvements:
- New middleware: server/src/middleware/rate-limit.ts
- Startup banner shows security settings
- Attachment service validates all path operations
- ConfigService rejects dangerous object keys
2026-01-28 07:41:11 -06:00
Brad Groux
38ec9a99ce feat(telemetry): Add POST /api/telemetry/events endpoint (US-1401)
- Add POST endpoint for ingesting run telemetry events
  - Accepts: run.started, run.completed, run.error, run.tokens
  - Zod validation with discriminated union schema
  - Stores events in date-partitioned NDJSON files
  - Returns 201 with generated id and timestamp

- Add WebSocket broadcast for telemetry events
  - New broadcastTelemetryEvent() in broadcast-service
  - Emits 'telemetry:event' messages to connected clients

- Update shared telemetry types for flexibility
  - RunStartedEvent, RunCompletedEvent, RunErrorEvent types
  - TokenTelemetryEvent with optional cacheTokens and cost fields
  - Change agent field from AgentType to string for external sources

- Update metrics-service to handle optional totalTokens
  - Calculate totalTokens from input+output when not provided
2026-01-28 07:40:35 -06:00
Brad Groux
564d2b4386 feat(server): Add Zod validation layer for request inputs (RF-07)
- Add reusable validation middleware (middleware/validate.ts)
  - Generic type-safe ValidatedRequest for typed access to validated data
  - ZodError → ValidationError transformation with details

- Add common validation schemas (schemas/common.ts)
  - TaskIdSchema with format validation (task_YYYYMMDD_XXXXXX)
  - Helper functions: positiveInt, optionalPositiveInt, nonEmptyString
  - TelemetryEventTypeSchema, MetricsPeriodSchema enums

- Add route-specific schemas:
  - diff-schemas.ts: DiffParamsSchema, DiffFileQuerySchema
  - preview-schemas.ts: PreviewParamsSchema, PreviewOutputQuerySchema
  - telemetry-schemas.ts: TelemetryEventsQuerySchema, TelemetryCountQuerySchema
  - metrics-schemas.ts: MetricsQuerySchema with period validation
  - conflicts-schemas.ts: ResolveConflictBodySchema, ContinueMergeBodySchema

- Update routes to use validation middleware:
  - diff.ts: Validate taskId params and file path query
  - preview.ts: Validate taskId and lines query (default 50, max 1000)
  - telemetry.ts: Validate event type filters with enum check
  - metrics.ts: Validate period enum (24h|7d|30d)
  - conflicts.ts: Validate taskId, path, and resolution body

- Update task-service.ts:
  - Wrap gray-matter parsing in try-catch to handle malformed frontmatter
  - Add TaskId format validation with warning log for invalid files
  - Filter out null values from failed task file parses

- Fix metrics-service.ts type compatibility with updated shared types
  - Change AgentType to string to match telemetry event types

Closes RF-07
2026-01-28 07:39:23 -06:00
Brad Groux
833ece2509 feat(web): add AgentStatusIndicator component (US-1302)
- Create AgentStatusIndicator with 5 states: idle, working, thinking, subagents, error
- Pulsing dot design with CSS animations (pulse, breathe, ripple, flash)
- Smooth color transitions between states
- Tooltip shows active task, duration, sub-agent count
- Accessible: aria-live for state changes
- Respects prefers-reduced-motion
- Add useGlobalAgentStatus hook polling /api/agent/status
- Integrate into Header component
2026-01-28 07:38:28 -06:00
Brad Groux
3efa474eb0 feat(server): Add authentication & authorization system
- Add auth middleware (server/src/middleware/auth.ts)
  - API key authentication via Bearer token, X-API-Key header, or query param
  - Role-based authorization (admin, agent, read-only)
  - Localhost bypass option for development
  - WebSocket connection authentication

- Update index.ts to integrate auth middleware
  - Apply authenticate middleware to all /api routes
  - Add /api/auth/status endpoint for diagnostics
  - Protect WebSocket connections with token validation
  - Display auth status in startup banner

- Add configuration via environment variables
  - VERITAS_AUTH_ENABLED (default: true)
  - VERITAS_AUTH_LOCALHOST_BYPASS (default: false)
  - VERITAS_ADMIN_KEY for admin access
  - VERITAS_API_KEYS for named keys with roles

- Add comprehensive security documentation (docs/security.md)
- Add .env.example with all auth configuration options

Closes RF-01
2026-01-28 07:37:44 -06:00
Brad Groux
cb87b2df52 feat(sprint-1500): status refactor review→blocked + blocked reason tracking
- Rename TaskStatus.review to TaskStatus.blocked across codebase
- Add migration service (auto-converts on startup, idempotent)
- Add blocked reason tracking (category + notes)
- Add blocked badges on Kanban cards
- Add dashboard breakdown by blocked category
- Add 30d metrics period, per-agent breakdown, streaming NDJSON
- Add 8 migration tests, all 112 tests passing
- Fix attachment test regex to allow hyphens in IDs

US-1501, US-1502, US-1503, US-1504, US-1505, US-1506, US-1507, US-1403
2026-01-28 07:30:05 -06:00
Brad Groux
c1ee77eb33 US-1502/1503/1504: Propagate review → blocked across entire codebase
Frontend (US-1502 & US-1503):
- KanbanBoard.tsx: Column id/title changed to 'blocked'/'Blocked'
- KanbanColumn.tsx: Color changed from amber-500 to red-500
- Dashboard.tsx: Metric card label/icon/color updated
- TaskMetadataSection.tsx: Status label updated
- useKeyboard.tsx: Keyboard shortcuts updated
- useTasks.ts: tasksByStatus keys updated

Backend (US-1504):
- automation.ts: Task status on completion changed
- notifications.ts: Status check updated
- summary.ts: Status filtering updated
- clawdbot-agent-service.ts: Success now sets 'done' instead of 'review'
- metrics-service.ts: Status keys updated
2026-01-28 06:51:28 -06:00
Brad Groux
3c2eb55ca8 US-1501: Rename TaskStatus review → blocked in shared types
- Updated TaskStatus union from 'review' to 'blocked' in shared/src/types/task.types.ts
- Updated Zod enum in server/src/routes/tasks.ts
- ReviewComment and ReviewState interfaces unchanged (still valid for code review)
2026-01-28 06:47:57 -06:00
Brad Groux
442e5c03cd RF-20: Frontend performance optimization — memoization for diff components
- Add memo + useMemo to DiffViewer, FileDiffView, DiffHunkView, FileTree
- Add useCallback for event handlers to prevent re-renders
- Fix unused typeIconName variable in TaskCard
- All diff viewer components now properly memoized to prevent unnecessary re-renders when comments change
2026-01-28 06:45:54 -06:00
Brad Groux
ada2e468a0 RF-12: Extract shared useWebSocket hook
- Created hooks/useWebSocket.ts with connection lifecycle, reconnection, typed messages
- Refactored useTaskSync.ts to use shared hook (80 → 35 lines)
- Refactored useAgent.ts to use shared hook (cleaner separation)
- Added useWebSocket to barrel export
2026-01-28 06:33:29 -06:00
Brad Groux
58bfae2c25 RF-22: Add ESLint with TypeScript and React plugins
- Added ESLint flat config (eslint.config.js)
- Added @typescript-eslint/parser and plugin
- Added eslint-plugin-react and react-hooks
- Fixed ActivityItem naming collision in ActivitySidebar.tsx
- 0 errors, 141 warnings (existing code issues to fix over time)
- Rules: no-explicit-any (warn), no-non-null-assertion (warn), react-hooks/rules-of-hooks (error)
2026-01-28 06:31:53 -06:00
Brad Groux
f598ec186b RF-25: Code cleanup - remove dead code, add hooks barrel export
- 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
2026-01-28 06:29:20 -06:00
Brad Groux
75cee87a3d fix: browser compatibility for shared api-client
- 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
2026-01-28 06:22:29 -06:00
Brad Groux
39eccf3556 feat: Sprint US-1200 Refactoring batch — 13 tasks complete
Completed refactors:
- RF-02: Fix dependency vulnerabilities (xlsx → exceljs, Hono updates)
- RF-05: Add React error boundaries (FeatureErrorBoundary wrapper)
- RF-06: Server error handling middleware (AppError classes, asyncHandler)
- RF-10: Split shared types.ts into domain modules (6 files)
- RF-11: Consolidate frontend API layer (hooks now use api.ts)
- RF-13: TaskConfigContext — eliminate prop drilling
- RF-14: Split god components (GitSection, TaskDetailPanel, CreateTaskDialog, DiffViewer)
- RF-16: Frontend accessibility (ARIA labels, sr-only text)
- RF-17: Modularize CLI (899 → commands/ structure)
- RF-18: Modularize MCP (843 → tools/ structure)
- RF-19: Create shared API client library
- RF-21: Server performance (batch loading, memory limits, timeouts, graceful shutdown)
- RF-23: Extract shared utilities (path, format, constants)

Stats: ~59 files changed, significant code reduction through modularization
2026-01-28 06:08:59 -06:00
Brad Groux
01e0e29eb9 docs: Sprint 1150 Settings Hardening documentation update
- Created comprehensive settings-architecture.md covering:
  - Component hierarchy and responsibilities
  - Data flow and state management
  - Security measures (XSS, path traversal, prototype pollution)
  - Accessibility features (WCAG 2.1 AA compliance)
  - Error handling strategy with boundaries
  - Performance optimizations (lazy loading, memoization)
  - Code organization patterns

- Updated CHANGELOG.md with Sprint 1150 entry (v0.9.0)
  - All 8 user stories documented
  - Security, accessibility, and performance highlights

- Updated README.md with Settings & Customization section

Sprint 1150 Code Quality Assessment:
✅ TypeScript: 0 compilation errors
✅ Architecture: Clean component extraction, no circular deps
✅ Security: Strict validation, sanitization, rate limiting
✅ Accessibility: WCAG 2.1 AA compliant
✅ Performance: Lazy loading, memoization, debouncing
✅ Error Handling: Isolated error boundaries per tab
⚠️  Tests: 161 failures in worktree directories (unrelated to Sprint 1150)
2026-01-28 04:24:23 -06:00
Brad Groux
c0b852cc6b feat(settings): Add WCAG 2.1 AA accessibility improvements (US-1156)
- 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
2026-01-28 04:08:51 -06:00
Brad Groux
0f43e4e750 feat(settings): Replace alert() calls with toast notifications (US-1158)
- 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
2026-01-28 04:05:05 -06:00
Brad Groux
0025dc5f47 chore: remove build artifacts from template-schema 2026-01-28 03:10:25 -06:00
Brad Groux
fa33c43368 US-1155: Settings performance — memoization & lazy loading 2026-01-28 03:09:02 -06:00
Brad Groux
38252d8860 US-1154: Add test coverage for settings features
- Fixed vitest config to exclude worktree directories
- Fixed existing test directory cleanup issues
- Added settings service tests
- Added template validation tests
- All tests passing
2026-01-28 03:05:52 -06:00
Brad Groux
030b501d2c US-1153: Harden template import validation & security
- Added Zod schema for full template structure validation
- Prototype pollution protection (reject __proto__, constructor, prototype keys)
- Size limits enforced (name 100 chars, description 500, subtasks 50, blueprint 20)
- Blueprint dependency validation (refIds must exist)
- Replaced alert() with toast notifications
2026-01-28 03:00:04 -06:00
Brad Groux
a4a8d1d765 US-1152: Add error boundaries to Settings dialog tabs
- Created SettingsErrorBoundary with friendly fallback + retry
- Each tab wrapped individually — one crash doesn't affect others
- Error details logged with tab context
2026-01-28 02:58:58 -06:00
Brad Groux
7afcb97c3c US-1151: Extract Settings tab components from monolith
- Extracted 7 tab components to components/settings/tabs/
- Extracted 5 shared components to components/settings/shared/
- SettingsDialog.tsx reduced from 1,481 to 279 lines
- Barrel exports via index.ts
- No functional changes
2026-01-28 02:56:39 -06:00
Brad Groux
32ba617731 feat(US-1110): Settings import/export & reset all
- Export Settings button: downloads feature settings as JSON with date filename
- Import Settings: file picker with validation, section-level filtering
- Reset All: double-confirmation dialog to restore defaults
- Per-section reset already available from US-1109
- Import validates top-level sections, warns about unknown keys
- All actions in settings sidebar footer
2026-01-28 02:36:11 -06:00
Brad Groux
fd30fac03f feat(US-1105..1108): Server-side settings sync for telemetry, attachments, agents
- 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
2026-01-28 02:35:07 -06:00
Brad Groux
4681aad9d7 feat(US-1103, US-1104): Sprint badges on task cards + task behavior settings wiring
- Add sprint badge rendering to TaskCard (indigo/zap icon)
- Wire sprints data: KanbanBoard → KanbanColumn → TaskCard
- Respect boardSettings.showSprintBadges toggle
- Wire task behavior settings in TaskDetailPanel:
  - Dependencies section hidden when enableDependencies=false
  - Time tracking hidden when enableTimeTracking=false
  - Comments hidden when enableComments=false
  - Attachments tab hidden when enableAttachments=false
  - Preview button hidden when enablePreview=false
2026-01-28 02:32:40 -06:00
Brad Groux
55b72a2c75 feat(US-1109): tabbed settings panel redesign
- 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
2026-01-28 02:19:45 -06:00
Brad Groux
f0c72717d3 feat(US-1101, US-1102): settings infrastructure + feature toggle hooks
- Added FeatureSettings types (Board, Tasks, Agents, Telemetry, Notifications, Archive)
- AppConfig.features field with backward-compatible defaults
- ConfigService auto-merges defaults for missing keys on load
- Deep merge utility for partial config updates
- GET/PATCH /api/settings/features endpoints
- useFeatureSettings, useFeatureSetting, useUpdateFeatureSettings hooks
- Debounced update helper for rapid toggle changes
- Optimistic updates with rollback on error
2026-01-28 02:16:23 -06:00
Brad Groux
0c12bacbf2 docs: Sprint 12-14 planning — LAN access, status indicator, metrics refactoring
Sprint US-1200 (6 stories): LAN access — Vite/Express binding, CORS,
  firewall, auto-detect URL, responsive audit
Sprint US-1300 (6 stories): Working indicator — status API, animated
  component, real-time hook, Veritas integration, history, header layout
Sprint US-1400 (7 stories): Metrics refactoring — telemetry ingestion,
  reporter, service refactor, task metrics, dashboard refresh, run badges,
  cost tracking

All three feature requests investigated, documented, tasks created with
subtasks, sprint docs written.
2026-01-28 02:06:58 -06:00
Brad Groux
785d60cbcd feat: real-time board updates via WebSocket broadcast + polling
- 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
2026-01-28 01:20:56 -06:00
Brad Groux
f7f1487b12 feat: archived task read-only view, restore, and pagination
- 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
2026-01-28 01:15:40 -06:00
Brad Groux
ce5eda58b1 feat: add drag-and-drop task reordering within columns
- 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
2026-01-28 01:08:21 -06:00
Brad Groux
8f8f4a9031 fix: stopTimer YAML crash — strip undefined values from timeTracking
- 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
2026-01-28 01:00:56 -06:00
Brad Groux
4a1b92b46c fix: remove duplicate ProjectConfig import in SettingsDialog 2026-01-28 00:37:38 -06:00
Brad Groux
2b5d07c1f1 Convert hardcoded sprints to managed list
- 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
2026-01-28 00:29:16 -06:00
Brad Groux
a8ec6f1406 milestone: Sprint US-900 complete — all 20 stories archived
Sprint 9 (US-900): 20 stories delivered
- US-901–US-910: Enhanced task template system
- US-911–US-916: Entity management (comments, attachments, types, projects, tags→removed)
- US-917: Sprint assignment field
- US-918: Subtask progress on Kanban cards
- US-919: Task type display on Kanban cards
- US-920: Auto-archive by sprint
- Fixed US-800 archived tasks project assignment (Sprint 8 → veritas-kanban)
2026-01-28 00:07:16 -06:00
Brad Groux
027bc22eb3 feat(US-920): Auto-archive by sprint instead of project
- Server: getArchiveSuggestions groups by sprint instead of project
- Server: archiveSprint replaces archiveProject
- Server: bulk-archive endpoint takes sprint instead of project
- Server: added 'sprint_archived' activity type
- Frontend: ArchiveSuggestionBanner shows sprint completion banners
- Frontend: SprintArchiveSuggestion replaces ProjectArchiveSuggestion
- Frontend: API layer + hooks updated (archiveSprint, bulkArchive)
- Removed dead ProjectArchiveSuggestion.tsx
2026-01-27 23:59:42 -06:00
Brad Groux
b353ec1b53 fix: add US-100 sprint to sprint picker 2026-01-27 23:47:28 -06:00
Brad Groux
4406aa8efd chore: assign sprints to all tasks (active + archived)
- 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
2026-01-27 23:38:39 -06:00
Brad Groux
331fd966a8 refactor: remove tags feature entirely, fix TS errors and path traversal sanitization
- Removed tag-service, TagPicker, useTags hook, tags routes, tags.json
- Stripped tag references from TaskCard, TaskDetailPanel, CreateTaskDialog,
  ApplyTemplateDialog, SettingsDialog, ArchiveSidebar, KanbanBoard/Column
- Removed tags from shared Task type and template types
- Fixed ManagedListManager prop types (Promise<void> → Promise<any>)
- Fixed unused imports in FilterBar, CreateTaskDialog, TaskDetailPanel
- Fixed unused generic param in UseManagedListOptions
- Fixed path traversal in attachment filename sanitization (collapse ..)
- All tests passing (62/62), full build clean
2026-01-27 23:33:15 -06:00
Brad Groux
e21dc2ec77 fix: black screen on task click + updated color palette
- 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
2026-01-27 22:49:44 -06:00
Brad Groux
e6ac8cfe6a fix: remove hide/show feature, allow deleting any managed list item
- 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
2026-01-27 22:35:06 -06:00
Brad Groux
d28cf29598 fix: infinite recursion in project/tag service init, ID mismatch in seed migration
- 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)
2026-01-27 22:30:53 -06:00
Brad Groux
93345980d6 fix(US-916): Use useTags hook for items in SettingsDialog
The useTagsManager hook only provides CRUD operations, not items. Need to call useTags() separately to get the items list.
2026-01-27 22:20:44 -06:00