Commit graph

180 commits

Author SHA1 Message Date
Brad Groux
279221ee38 ci: add GitHub Actions CI pipeline 2026-01-28 17:12:18 -06:00
Brad Groux
190942b154 feat: add request ID middleware for request tracing 2026-01-28 17:11:15 -06:00
Brad Groux
14d60d28eb perf: lazy-load dashboard and split vendor chunks to reduce main bundle by 69% 2026-01-28 17:10:40 -06:00
Brad Groux
ccff6e78c8 fix(security): sanitize Content-Disposition header for attachments 2026-01-28 17:09:38 -06:00
Brad Groux
c8970f0631 fix(security): use timing-safe comparison for recovery keys 2026-01-28 17:08:26 -06:00
Brad Groux
1a9d406e5f fix(security): redact plaintext credentials from task data and audit doc 2026-01-28 17:06:59 -06:00
Brad Groux
b6fadfaa4c docs: add security, performance, and quality audit reports 2026-01-28 16:59:09 -06:00
Brad Groux
615b9b03b4 feat(security): replace custom rate limiter with express-rate-limit
- Swap hand-rolled Map-based rate limiter for battle-tested express-rate-limit
- Built-in MemoryStore handles TTL cleanup automatically (no memory leaks)
- Uses sliding window counter algorithm instead of fixed window
- Emits both IETF draft-7 (RateLimit-*) and legacy (X-RateLimit-*) headers
- Remove duplicate inline rate limiter from settings.ts, use shared strictRateLimit middleware
- Redis not warranted for single-instance local dev tool
2026-01-28 12:22:34 -06:00
Brad Groux
62b26a6f3a fix: add missing route imports in server index.ts (server crash fix) 2026-01-28 12:20:06 -06:00
Brad Groux
99cd20c5a4 perf: add in-memory task caching with file watchers 2026-01-28 12:18:41 -06:00
Brad Groux
7d3a9c404c perf: cache config in memory with write invalidation 2026-01-28 12:14:41 -06:00
Brad Groux
db74b427ef fix(security): add server-side MIME type validation for uploads 2026-01-28 12:14:22 -06:00
Brad Groux
8ec03eb3c9 fix(security): sanitize Markdown to prevent stored XSS 2026-01-28 12:14:12 -06:00
Brad Groux
6793b23310 perf: reduce polling when WebSocket connected 2026-01-28 12:13:48 -06:00
Brad Groux
06df2e2050 fix(security): validate Origin header for WebSocket connections 2026-01-28 12:11:53 -06:00
Brad Groux
d77f5dfa17 feat(security): implement JWT secret rotation mechanism 2026-01-28 12:09:20 -06:00
Brad Groux
9d0f5cae47 feat(perf): add gzip response compression middleware 2026-01-28 12:09:05 -06:00
Brad Groux
12c9f4ed65 feat(deploy): add production Dockerfile with multi-stage build 2026-01-28 12:08:14 -06:00
Brad Groux
5e4f3ec6b9 fix(security): move JWT secret to env var, update .env.example 2026-01-28 12:07:11 -06:00
Brad Groux
9fcb39d0ca feat(security): add CSP headers with Helmet 2026-01-28 12:05:43 -06:00
Brad Groux
5aa31115ae fix(security): remove .env from git, add .env.example 2026-01-28 12:05:17 -06:00
Brad Groux
0c42d0b125 Populate token telemetry for all 192 closed/archived tasks
- Added run.started, run.tokens, run.completed events for every completed task
- Token estimates based on time tracked and task complexity
- Metrics tab now displays agent run data for all historical tasks
- Added create-review-tasks.sh script
- Updated activity and status history
2026-01-28 11:49:14 -06:00
Brad Groux
7dcc78a325 docs: add comprehensive code review findings
Full review covering security, performance, architecture, standards,
testing, and deployment readiness. Created sprint tasks for all findings.
2026-01-28 11:24:47 -06:00
Brad Groux
3f10c45ab2 feat: add task-level metrics to Metrics tab
Shows time tracked, task age, time to close, subtask progress, and other
always-available metrics computed client-side from the Task object.
Agent run telemetry section remains below for tasks with run data.
2026-01-28 11:19:28 -06:00
Brad Groux
ec0466b2dc fix: prevent server refetch from overwriting active typing in task panel
The sync useEffect in useDebouncedSave blindly reset localTask to the
server value on every refetch, wiping out in-flight user input. Now uses
a ref-tracked dirty field set to merge server data while preserving
locally modified fields. Also stabilizes the mutate ref to prevent
debounce timer resets on re-renders.
2026-01-28 11:12:41 -06:00
Brad Groux
228fe0b6f8 fix: add dotenv to load .env file at server startup
- Added dotenv package to server dependencies
- Import dotenv/config at top of server/src/index.ts
- Fixes AUTH_REQUIRED errors when using API keys and localhost bypass

Resolves issue where VERITAS_AUTH_LOCALHOST_BYPASS and VERITAS_ADMIN_KEY
environment variables were not being loaded from .env file.
2026-01-28 10:31:07 -06:00
Brad Groux
887cfc9a7e feat(auth): Complete authentication sprint
- UserMenu: Session indicator with lock icon, expiry display, logout (Cmd+Shift+L)
- SecurityTab: Change password form with strength indicator, danger zone
- Header: Integrated UserMenu with security settings link
- SettingsDialog: Added Security tab with lazy loading, defaultTab prop
- useAuth: Fixed setup() to not refresh status before showing recovery key

Completes: US-d-eQbD, US-fCAsJx
2026-01-28 09:44:31 -06:00
Brad Groux
858669defb feat(US-1006,US-1012): Add metrics export and sprint velocity tracking
US-1006: Add metrics export functionality
- Export button on dashboard with JSON/CSV formats
- Export telemetry service endpoint
- Filter by time period and project

US-1012: Add sprint velocity tracking
- GET /api/metrics/velocity endpoint
- Bar chart with tasks completed per sprint
- Rolling 3-sprint average line overlay
- Velocity trend indicator (accelerating/steady/slowing)
- Task type breakdown on hover
- Current sprint progress vs average
2026-01-28 08:24:32 -06:00
Brad Groux
8a9416b7cc feat(US-1305): Add status history to activity sidebar
- Added daily summary card showing active/idle time and utilization %
- Added Status History tab with today's status transitions
- Display previous/new status with duration of each state
- Mini progress bar for visual time breakdown
- Backend was already complete (status-history-service logs all status changes)
2026-01-28 08:14:55 -06:00
Brad Groux
b53ef09dcd feat(dashboard): add refresh indicator during data fetch
- Show spinning RefreshCw icon and 'Refreshing...' text during fetch
- Expose isFetching state from useMetrics hook
- Dashboard already has all required metrics features:
  - Run count from real telemetry data
  - Success rate with color coding (green/yellow/red)
  - Token usage with input/output/cache breakdown
  - Duration with avg/p50/p95 percentiles
  - Trend indicators (↑/↓) comparing to previous period
  - Auto-refresh every 30 seconds
  - Graceful empty state when no data

Closes US-1405
2026-01-28 08:13:55 -06:00
Brad Groux
fdf5ff187d feat(dashboard): refresh metrics cards with real telemetry data
- Add cacheTokens tracking to backend metrics service
- Add trend comparison (↑/↓) vs previous period for all metrics
- Fix success rate color thresholds (green <10%, yellow 10-25%, red >25%)
- Show cache tokens in Token Usage card when available
- Add graceful 'no data' display when no runs recorded
- Auto-refresh already at 30s via useMetrics hook
- Update TokensDrillDown to show cache breakdown per agent

US-1405
2026-01-28 08:12:05 -06:00
Brad Groux
538e67fc49 fix(dashboard): improve TrendIndicator direction logic
- Separate direction (improvement/decline) from actual value change
- Always show green for 'up' direction (improvement)
- Arrow direction now based on actual value change
2026-01-28 08:11:50 -06:00
Brad Groux
df4274254f feat(US-1011): Add cost budget tracking
- Add BudgetSettings to FeatureSettings (token/cost limits, warning threshold)
- Add budget metrics API endpoint with monthly projections
- Create BudgetCard dashboard component with progress bars and status
- Add budget settings to Settings > Data tab
- Calculate burn rate (tokens/day average) and projected monthly usage
- Color coding: green (<60%), yellow (60-80%), red (>80%)
- Warning when projected usage exceeds budget limit

Features:
- Monthly token limit setting
- Monthly cost limit setting (USD)
- Warning threshold configuration
- Used/Budget progress bar with color indicators
- Projected end-of-month usage
- Daily burn rate display
2026-01-28 08:11:01 -06:00
Brad Groux
b2fe2e4b63 feat(US-1305): Add status history timeline to dashboard
- Create StatusTimeline component showing daily activity bar
- Add useStatusHistory hook for fetching status data
- Display active/idle time summary with transitions count
- Show recent status change history with timestamps
- Integrate into Dashboard below Agent Operations section
2026-01-28 08:10:55 -06:00
Brad Groux
71200bca36 feat(US-1010): Add daily digest feature
- Add digest service for 24h activity aggregation
- Add GET /api/digest/daily endpoint (JSON and Teams format)
- Add GET /api/digest/daily/preview for testing
- Add scripts/daily-digest.sh for cron scheduling
- Skip empty digests when no activity

Content includes:
- Tasks completed/created/in-progress counts
- Agent runs with success rate by agent
- Token usage by agent
- Top accomplishments (recently done tasks)
- Failed runs and blocked items
2026-01-28 08:08:06 -06:00
Brad Groux
44461f3daf feat(US-1007): Add historical trends charts to dashboard
- Add getTrends endpoint to metrics-service with daily aggregation
- Add /api/metrics/trends route for 7d/30d trend data
- Create TrendsCharts component with 4 chart types:
  - Runs per day (bar chart)
  - Success rate over time (line chart)
  - Token usage trend (stacked area chart)
  - Average run duration trend (line chart)
- Add useTrends hook with auto-refresh
- Integrate charts into Dashboard below metrics cards
- Add 7-day/30-day period toggle
- Responsive design for narrow screens
- Charts use recharts library
2026-01-28 08:05:02 -06:00
Brad Groux
fbb6aed001 feat(US-1005): Add dashboard drill-down views
- Make dashboard metric cards clickable
- Add DrillDownPanel component for slide-out panel
- Add TasksDrillDown for filtered task list view
- Add ErrorsDrillDown for failed runs list with task links
- Add TokensDrillDown with per-agent breakdown
- Add DurationDrillDown with per-agent breakdown
- Add /api/metrics/failed-runs endpoint
- Add useFailedRuns, useTokenMetrics, useDurationMetrics hooks
- Back navigation to return to dashboard
2026-01-28 08:03:13 -06:00
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