From f3fb4ecbeb71f38f6427ddcd15e6837133bca76b Mon Sep 17 00:00:00 2001 From: Felipe Cardoso Date: Thu, 1 Jan 2026 11:44:09 +0100 Subject: [PATCH] refactor(frontend): remove unused ActivityFeedPrototype code and documentation - Deleted `ActivityFeedPrototype` component and associated `README.md`. - Cleaned up related assets and mock data. - This component was no longer in use and has been deprecated. --- .../prototypes/activity-feed/README.md | 248 ---- .../prototypes/activity-feed/page.tsx | 830 ------------- .../prototypes/agent-configuration/README.md | 213 ---- .../prototypes/agent-configuration/page.tsx | 939 --------------- .../prototypes/issue-management/README.md | 246 ---- .../prototypes/issue-management/page.tsx | 958 --------------- .../prototypes/main-dashboard/README.md | 225 ---- .../prototypes/main-dashboard/page.tsx | 927 -------------- frontend/src/app/[locale]/prototypes/page.tsx | 218 ++-- .../prototypes/project-dashboard/README.md | 151 --- .../prototypes/project-dashboard/page.tsx | 586 --------- .../prototypes/project-wizard/README.md | 180 --- .../prototypes/project-wizard/page.tsx | 1063 ----------------- 13 files changed, 101 insertions(+), 6683 deletions(-) delete mode 100644 frontend/src/app/[locale]/prototypes/activity-feed/README.md delete mode 100644 frontend/src/app/[locale]/prototypes/activity-feed/page.tsx delete mode 100644 frontend/src/app/[locale]/prototypes/agent-configuration/README.md delete mode 100644 frontend/src/app/[locale]/prototypes/agent-configuration/page.tsx delete mode 100644 frontend/src/app/[locale]/prototypes/issue-management/README.md delete mode 100644 frontend/src/app/[locale]/prototypes/issue-management/page.tsx delete mode 100644 frontend/src/app/[locale]/prototypes/main-dashboard/README.md delete mode 100644 frontend/src/app/[locale]/prototypes/main-dashboard/page.tsx delete mode 100644 frontend/src/app/[locale]/prototypes/project-dashboard/README.md delete mode 100644 frontend/src/app/[locale]/prototypes/project-dashboard/page.tsx delete mode 100644 frontend/src/app/[locale]/prototypes/project-wizard/README.md delete mode 100644 frontend/src/app/[locale]/prototypes/project-wizard/page.tsx diff --git a/frontend/src/app/[locale]/prototypes/activity-feed/README.md b/frontend/src/app/[locale]/prototypes/activity-feed/README.md deleted file mode 100644 index 55c4eb1..0000000 --- a/frontend/src/app/[locale]/prototypes/activity-feed/README.md +++ /dev/null @@ -1,248 +0,0 @@ -# Real-time Activity Feed - Design Prototype - -## Overview -The Activity Feed provides a real-time view of all events happening across Syndarix projects. It displays agent status changes, messages, issue updates, sprint events, approval requests, and errors. This is the central hub for monitoring autonomous agent activity and responding to approval requests. - -## User Stories -- As a user, I want to see real-time updates from my projects so I stay informed -- As a user, I want to filter events by type, agent, or project to focus on what matters -- As a user, I want to quickly identify items requiring my action -- As a user, I want to expand events to see more details -- As a user, I want to approve or reject requests directly from the feed -- As a user, I want to know if I'm connected to the real-time stream -- As a user, I want to mark events as read to track what I've seen - -## Key Screens - -### Main Feed View - -**Header** -- Page title with description -- Action required count badge -- Mark all read button -- Real-time connection indicator - -**Search and Filters** -- Full-text search input -- Filter button (toggles filter panel) -- Refresh button - -**Filter Panel** (expandable) -- Event type checkboxes (with icons) -- Agent checkboxes -- "Action required only" toggle -- Clear all / Apply buttons - -**Event Groups** -- Grouped by time period: New, Earlier Today, Yesterday, This Week, Older -- Group header with count badge -- Separator line - -**Event Cards** -- Event type icon (colored) -- Title with New/Action Required badges -- Description text -- Metadata row (agent, project, type) -- Expand/collapse button -- Expanded details (conditional) -- Action buttons (for approval requests) - -## Event Types - -| Type | Icon | Color | Description | -|------|------|-------|-------------| -| Agent Status | Bot | Blue | Agent started, paused, resumed, stopped | -| Agent Message | MessageSquare | Purple | Agent communication, updates, questions | -| Issue Update | CircleDot | Green | Status change, assignment, creation | -| Sprint Event | Zap | Yellow | Standup, retrospective, planning | -| Approval Request | AlertCircle | Orange | Requires user action | -| Error | XCircle | Red | Agent or system errors | -| Milestone | CheckCircle | Emerald | Goals achieved, completions | - -## User Flow - -### Monitoring Activity -1. User lands on feed page -2. Feed shows real-time updates (newest first) -3. User scrolls through events -4. User clicks event to expand details -5. User navigates to related issue/PR if needed - -### Filtering Events -1. User clicks Filter button -2. Filter panel expands -3. User selects event types, agents, etc. -4. User clicks Apply -5. Feed updates to show matching events - -### Handling Approval Request -1. Approval request appears with orange badge -2. User reads request details -3. User clicks Approve or Request Changes -4. Event updates to show completed -5. Badge count decreases - -## Design Decisions - -### Card-Based Layout -- Each event is a distinct card -- Visual separation between events -- Expandable for more details -- Cards are self-contained - -### Time-Based Grouping -- Events grouped by time period -- Helps users orient in the timeline -- "New" group highlights unread items -- Clear visual hierarchy - -### Real-Time Indicator -- Pulsing green dot when connected -- Gray dot when disconnected -- Builds trust in data freshness -- Matches common patterns (Slack, Discord) - -### Action Required Emphasis -- Orange left border on cards -- Badge in header with count -- Cannot be missed -- Inline approval buttons - -### Expandable Details -- Keeps feed scannable -- Details available on demand -- Consistent expand/collapse pattern -- Metadata shown when expanded - -### Search and Filters -- Combined search and filter approach -- Quick search for specific events -- Structured filters for browsing -- Filter state indicator - -## States - -### Loading -- Skeleton cards while loading -- Connection indicator shows connecting - -### Empty -- No events: "Activity will appear here" message -- No matches: "Try adjusting filters" message - -### Disconnected -- Gray indicator -- Retry button available -- Last known data shown - -### Action Completed -- Card updates to remove action badge -- Success toast notification - -## Responsive Breakpoints - -### Desktop (lg: 1024px+) -- Centered content (max-w-3xl) -- Full filter panel inline -- Comfortable spacing - -### Tablet (md: 768px) -- Full-width content -- Filter panel still inline -- Slightly tighter spacing - -### Mobile (< 768px) -- Full-width cards -- Filter panel stacks vertically -- Touch-friendly buttons -- Simplified metadata row - -## Accessibility Notes -- Event type icons have text labels -- Color is not only indicator (badges, icons) -- Keyboard navigation for expand/collapse -- Screen reader announces new events -- Focus management on filter panel -- Live region for real-time updates - -## Components Used -- Card, CardContent -- Button (default, outline, ghost variants) -- Badge (default, secondary, outline, destructive variants) -- Input (search) -- Checkbox -- Label -- Separator -- Lucide icons - -## Event Data Structure - -```typescript -interface ActivityEvent { - id: string; - type: 'agent_status' | 'agent_message' | 'issue_update' | - 'sprint_event' | 'approval_request' | 'error' | 'milestone'; - title: string; - description: string; - timestamp: string; // ISO 8601 - agent: { - name: string; - avatar: string; - }; - project: string; - metadata: { - issueNumber?: number; - pullRequest?: number; - documentUrl?: string; - progress?: number; - summary?: { - agents: number; - inProgress: number; - blocked: number; - }; - importance?: 'low' | 'medium' | 'high'; - // ... other type-specific fields - }; - requiresAction: boolean; - isNew: boolean; -} -``` - -## Real-Time Implementation Notes - -For production, the feed should: -1. Connect via WebSocket or SSE -2. Handle reconnection gracefully -3. Queue events during disconnect -4. Merge with existing events on reconnect -5. Support pagination for history -6. Implement optimistic updates for actions - -## Questions for Review -1. Should events be grouped by time or show flat chronologically? -2. How many events should load initially? (Currently showing 10) -3. Should there be sound/browser notifications for urgent items? -4. Should users be able to "star" or save important events? -5. Should there be a compact view option? -6. Should events support threading/replies? - -## How to View -Navigate to: `/prototypes/activity-feed` - -Try the features: -1. Scroll through the event feed -2. Click events to expand details -3. Open the filter panel -4. Try the action buttons on approval requests -5. Use the search to filter events - -## Next Steps -After approval: -1. Implement WebSocket connection for real-time updates -2. Add browser notification support -3. Implement event pagination (infinite scroll) -4. Add optimistic updates for approve/dismiss -5. Implement notification sound settings -6. Add project-level filtering -7. Implement event archiving -8. Add keyboard shortcuts (j/k navigation) diff --git a/frontend/src/app/[locale]/prototypes/activity-feed/page.tsx b/frontend/src/app/[locale]/prototypes/activity-feed/page.tsx deleted file mode 100644 index 9add8cf..0000000 --- a/frontend/src/app/[locale]/prototypes/activity-feed/page.tsx +++ /dev/null @@ -1,830 +0,0 @@ -'use client'; - -import { useState, useEffect } from 'react'; -import { Card } from '@/components/ui/card'; -import { Button } from '@/components/ui/button'; -import { Badge } from '@/components/ui/badge'; -import { Input } from '@/components/ui/input'; -import { Label } from '@/components/ui/label'; -import { Checkbox } from '@/components/ui/checkbox'; -import { Separator } from '@/components/ui/separator'; -import { - Activity, - Bot, - MessageSquare, - CheckCircle2, - AlertCircle, - GitPullRequest, - CircleDot, - XCircle, - Zap, - Settings, - Filter, - Bell, - BellOff, - RefreshCw, - ChevronDown, - ChevronUp, - ExternalLink, - Search, -} from 'lucide-react'; - -// Event type configurations -const eventTypeConfig = { - agent_status: { - label: 'Agent Status', - icon: Bot, - color: 'text-blue-500', - bgColor: 'bg-blue-100 dark:bg-blue-900', - }, - agent_message: { - label: 'Agent Message', - icon: MessageSquare, - color: 'text-purple-500', - bgColor: 'bg-purple-100 dark:bg-purple-900', - }, - issue_update: { - label: 'Issue Update', - icon: CircleDot, - color: 'text-green-500', - bgColor: 'bg-green-100 dark:bg-green-900', - }, - sprint_event: { - label: 'Sprint Event', - icon: Zap, - color: 'text-yellow-500', - bgColor: 'bg-yellow-100 dark:bg-yellow-900', - }, - approval_request: { - label: 'Approval Request', - icon: AlertCircle, - color: 'text-orange-500', - bgColor: 'bg-orange-100 dark:bg-orange-900', - }, - error: { - label: 'Error', - icon: XCircle, - color: 'text-red-500', - bgColor: 'bg-red-100 dark:bg-red-900', - }, - milestone: { - label: 'Milestone', - icon: CheckCircle2, - color: 'text-emerald-500', - bgColor: 'bg-emerald-100 dark:bg-emerald-900', - }, -}; - -// Filter state type -type FilterState = { - types: string[]; - agents: string[]; - projects: string[]; - showActionRequired: boolean; -}; - -// Mock activity events -const mockEvents = [ - { - id: 'evt-001', - type: 'approval_request', - title: 'Approval Required: Architecture Decision', - description: 'Architect is requesting approval for the API design document for the checkout flow.', - timestamp: new Date(Date.now() - 1000 * 60 * 2).toISOString(), // 2 min ago - agent: { name: 'Architect', avatar: 'AR' }, - project: 'E-Commerce Platform', - metadata: { - documentUrl: '/docs/adr-015-checkout-api.md', - importance: 'high', - }, - requiresAction: true, - isNew: true, - }, - { - id: 'evt-002', - type: 'agent_message', - title: 'Implementation Update', - description: 'Completed JWT token generation and validation. Moving on to session management.', - timestamp: new Date(Date.now() - 1000 * 60 * 8).toISOString(), // 8 min ago - agent: { name: 'Backend Engineer', avatar: 'BE' }, - project: 'E-Commerce Platform', - metadata: { - issueNumber: 42, - progress: 65, - }, - requiresAction: false, - isNew: true, - }, - { - id: 'evt-003', - type: 'agent_status', - title: 'Agent Started Work', - description: 'Frontend Engineer has started working on the product catalog component.', - timestamp: new Date(Date.now() - 1000 * 60 * 15).toISOString(), // 15 min ago - agent: { name: 'Frontend Engineer', avatar: 'FE' }, - project: 'E-Commerce Platform', - metadata: { - previousStatus: 'idle', - newStatus: 'active', - issueNumber: 45, - }, - requiresAction: false, - isNew: true, - }, - { - id: 'evt-004', - type: 'issue_update', - title: 'Issue Status Changed', - description: 'Issue #38 "Implement user registration" moved from "In Progress" to "In Review".', - timestamp: new Date(Date.now() - 1000 * 60 * 25).toISOString(), // 25 min ago - agent: { name: 'Backend Engineer', avatar: 'BE' }, - project: 'E-Commerce Platform', - metadata: { - issueNumber: 38, - oldStatus: 'in_progress', - newStatus: 'in_review', - }, - requiresAction: false, - isNew: false, - }, - { - id: 'evt-005', - type: 'sprint_event', - title: 'Daily Standup Completed', - description: 'Sprint 3 daily standup: 4 agents reported, 8 issues in progress, 1 blocked.', - timestamp: new Date(Date.now() - 1000 * 60 * 60).toISOString(), // 1 hour ago - agent: { name: 'System', avatar: 'SY' }, - project: 'E-Commerce Platform', - metadata: { - sprintName: 'Sprint 3', - summary: { - agents: 4, - inProgress: 8, - blocked: 1, - }, - }, - requiresAction: false, - isNew: false, - }, - { - id: 'evt-006', - type: 'error', - title: 'Agent Error', - description: 'QA Engineer encountered an error while setting up the test framework. Retry attempted.', - timestamp: new Date(Date.now() - 1000 * 60 * 90).toISOString(), // 1.5 hours ago - agent: { name: 'QA Engineer', avatar: 'QA' }, - project: 'E-Commerce Platform', - metadata: { - errorType: 'configuration', - retryCount: 1, - resolved: false, - }, - requiresAction: true, - isNew: false, - }, - { - id: 'evt-007', - type: 'milestone', - title: 'Sprint Goal Achieved', - description: 'Authentication module completed! All acceptance criteria met.', - timestamp: new Date(Date.now() - 1000 * 60 * 120).toISOString(), // 2 hours ago - agent: { name: 'Product Owner', avatar: 'PO' }, - project: 'E-Commerce Platform', - metadata: { - milestone: 'Auth Module', - issuesCompleted: 5, - }, - requiresAction: false, - isNew: false, - }, - { - id: 'evt-008', - type: 'agent_status', - title: 'Agent Paused', - description: 'DevOps Engineer paused pending infrastructure approval.', - timestamp: new Date(Date.now() - 1000 * 60 * 180).toISOString(), // 3 hours ago - agent: { name: 'DevOps Engineer', avatar: 'DO' }, - project: 'E-Commerce Platform', - metadata: { - previousStatus: 'active', - newStatus: 'paused', - reason: 'Awaiting approval', - }, - requiresAction: false, - isNew: false, - }, - { - id: 'evt-009', - type: 'agent_message', - title: 'Code Review Comment', - description: 'Found potential security issue in password hashing. Recommending bcrypt with higher rounds.', - timestamp: new Date(Date.now() - 1000 * 60 * 240).toISOString(), // 4 hours ago - agent: { name: 'Architect', avatar: 'AR' }, - project: 'E-Commerce Platform', - metadata: { - issueNumber: 42, - pullRequest: 15, - }, - requiresAction: false, - isNew: false, - }, - { - id: 'evt-010', - type: 'issue_update', - title: 'Issue Created', - description: 'New issue created: "Add rate limiting to API endpoints" - assigned to Backend Engineer.', - timestamp: new Date(Date.now() - 1000 * 60 * 300).toISOString(), // 5 hours ago - agent: { name: 'Product Owner', avatar: 'PO' }, - project: 'E-Commerce Platform', - metadata: { - issueNumber: 50, - priority: 'medium', - }, - requiresAction: false, - isNew: false, - }, -]; - -// Format relative time -function formatRelativeTime(timestamp: string): string { - const now = new Date(); - const then = new Date(timestamp); - const diffMs = now.getTime() - then.getTime(); - const diffMins = Math.floor(diffMs / (1000 * 60)); - const diffHours = Math.floor(diffMs / (1000 * 60 * 60)); - const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24)); - - if (diffMins < 1) return 'Just now'; - if (diffMins < 60) return `${diffMins} min ago`; - if (diffHours < 24) return `${diffHours} hour${diffHours > 1 ? 's' : ''} ago`; - return `${diffDays} day${diffDays > 1 ? 's' : ''} ago`; -} - -// Group events by time period -function groupEventsByPeriod(events: typeof mockEvents) { - const now = new Date(); - const groups: { label: string; events: typeof mockEvents }[] = [ - { label: 'New', events: [] }, - { label: 'Earlier Today', events: [] }, - { label: 'Yesterday', events: [] }, - { label: 'This Week', events: [] }, - { label: 'Older', events: [] }, - ]; - - events.forEach((event) => { - const eventDate = new Date(event.timestamp); - const diffHours = (now.getTime() - eventDate.getTime()) / (1000 * 60 * 60); - const diffDays = diffHours / 24; - - if (event.isNew) { - groups[0].events.push(event); - } else if (diffHours < 24 && eventDate.getDate() === now.getDate()) { - groups[1].events.push(event); - } else if (diffDays < 2) { - groups[2].events.push(event); - } else if (diffDays < 7) { - groups[3].events.push(event); - } else { - groups[4].events.push(event); - } - }); - - return groups.filter((g) => g.events.length > 0); -} - -// Event card component -function EventCard({ - event, - expanded, - onToggle, - onApprove, - onDismiss, -}: { - event: (typeof mockEvents)[0]; - expanded: boolean; - onToggle: () => void; - onApprove: () => void; - onDismiss: () => void; -}) { - const config = eventTypeConfig[event.type as keyof typeof eventTypeConfig]; - const Icon = config.icon; - - return ( - -
-
- {/* Icon */} -
- -
- - {/* Content */} -
-
-
-
-

{event.title}

- {event.isNew && ( - - New - - )} - {event.requiresAction && ( - - Action Required - - )} -
-

- {event.description} -

-
-
- {formatRelativeTime(event.timestamp)} - -
-
- - {/* Metadata row */} -
-
- - {event.agent.name} -
-
- - {event.project} -
- - {config.label} - -
- - {/* Expanded details */} - {expanded && ( -
- {event.metadata.issueNumber && ( -
- - Issue #{event.metadata.issueNumber} - -
- )} - {event.metadata.pullRequest && ( -
- - PR #{event.metadata.pullRequest} - -
- )} - {event.metadata.documentUrl && ( - - )} - {event.metadata.summary && ( -
-
-

- {event.metadata.summary.agents} -

-

Agents

-
-
-

- {event.metadata.summary.inProgress} -

-

In Progress

-
-
-

- {event.metadata.summary.blocked} -

-

Blocked

-
-
- )} - {event.metadata.progress !== undefined && ( -
-
- Progress - {event.metadata.progress}% -
-
-
-
-
- )} -

- {new Date(event.timestamp).toLocaleString()} -

-
- )} - - {/* Action buttons for approval requests */} - {event.requiresAction && ( -
- - - -
- )} -
-
-
- - ); -} - -// Filter panel component -function FilterPanel({ - filters, - onFiltersChange, - onClose, -}: { - filters: FilterState; - onFiltersChange: (filters: FilterState) => void; - onClose: () => void; -}) { - const eventTypes = Object.entries(eventTypeConfig); - const agents = ['Backend Engineer', 'Frontend Engineer', 'Architect', 'Product Owner', 'QA Engineer', 'DevOps Engineer']; - const _projects = ['E-Commerce Platform', 'Mobile App', 'API Gateway']; - - const toggleType = (type: string) => { - const newTypes = filters.types.includes(type) - ? filters.types.filter((t) => t !== type) - : [...filters.types, type]; - onFiltersChange({ ...filters, types: newTypes }); - }; - - const toggleAgent = (agent: string) => { - const newAgents = filters.agents.includes(agent) - ? filters.agents.filter((a) => a !== agent) - : [...filters.agents, agent]; - onFiltersChange({ ...filters, agents: newAgents }); - }; - - return ( - -
- {/* Event Types */} -
- -
- {eventTypes.map(([key, config]) => { - const Icon = config.icon; - return ( -
- toggleType(key)} - /> - -
- ); - })} -
-
- - {/* Agents */} -
- -
- {agents.map((agent) => ( -
- toggleAgent(agent)} - /> - -
- ))} -
-
- - {/* Show action required only */} -
- - onFiltersChange({ ...filters, showActionRequired: checked as boolean }) - } - /> - -
- - {/* Actions */} -
- - -
-
-
- ); -} - -// Real-time indicator -function RealTimeIndicator({ connected }: { connected: boolean }) { - return ( -
- - - {connected ? 'Live' : 'Disconnected'} - -
- ); -} - -export default function ActivityFeedPrototype() { - const [events, setEvents] = useState(mockEvents); - const [expandedEvents, setExpandedEvents] = useState([]); - const [showFilters, setShowFilters] = useState(false); - const [filters, setFilters] = useState({ - types: [] as string[], - agents: [] as string[], - projects: [] as string[], - showActionRequired: false, - }); - const [searchQuery, setSearchQuery] = useState(''); - const [isConnected, setIsConnected] = useState(true); - const [notificationsEnabled, setNotificationsEnabled] = useState(true); - - // Simulate real-time updates - useEffect(() => { - const interval = setInterval(() => { - // Randomly toggle connection status for demo - if (Math.random() > 0.95) { - setIsConnected((prev) => !prev); - } - }, 5000); - - return () => clearInterval(interval); - }, []); - - // Filter events - const filteredEvents = events.filter((event) => { - const matchesSearch = - searchQuery === '' || - event.title.toLowerCase().includes(searchQuery.toLowerCase()) || - event.description.toLowerCase().includes(searchQuery.toLowerCase()); - const matchesType = - filters.types.length === 0 || filters.types.includes(event.type); - const matchesAgent = - filters.agents.length === 0 || filters.agents.includes(event.agent.name); - const matchesActionRequired = - !filters.showActionRequired || event.requiresAction; - return matchesSearch && matchesType && matchesAgent && matchesActionRequired; - }); - - const groupedEvents = groupEventsByPeriod(filteredEvents); - - const toggleExpanded = (eventId: string) => { - setExpandedEvents((prev) => - prev.includes(eventId) - ? prev.filter((id) => id !== eventId) - : [...prev, eventId] - ); - }; - - const handleApprove = (eventId: string) => { - setEvents((prev) => - prev.map((e) => - e.id === eventId ? { ...e, requiresAction: false, isNew: false } : e - ) - ); - }; - - const handleDismiss = (eventId: string) => { - // In real implementation, this would open a modal for feedback - console.log('Dismiss:', eventId); - }; - - const markAllRead = () => { - setEvents((prev) => prev.map((e) => ({ ...e, isNew: false }))); - }; - - const actionRequiredCount = events.filter((e) => e.requiresAction).length; - const newCount = events.filter((e) => e.isNew).length; - - return ( -
- {/* Navigation Bar */} - - -
-
- {/* Header */} -
-
-

Activity Feed

-

- Real-time updates from your projects -

-
-
- {actionRequiredCount > 0 && ( - - - {actionRequiredCount} pending - - )} - {newCount > 0 && ( - - )} -
-
- - {/* Search and Filters */} -
-
- - setSearchQuery(e.target.value)} - className="pl-9" - /> -
- - -
- - {/* Filter Panel */} - {showFilters && ( - setShowFilters(false)} - /> - )} - - {/* Event Groups */} -
- {groupedEvents.map((group) => ( -
-
-

- {group.label} -

- - {group.events.length} - - -
-
- {group.events.map((event) => ( - toggleExpanded(event.id)} - onApprove={() => handleApprove(event.id)} - onDismiss={() => handleDismiss(event.id)} - /> - ))} -
-
- ))} -
- - {filteredEvents.length === 0 && ( - - -

No activity found

-

- {searchQuery || filters.types.length > 0 - ? 'Try adjusting your search or filters' - : 'Activity will appear here as agents work on your projects'} -

-
- )} - - {/* Load More */} - {filteredEvents.length > 0 && ( -
- -
- )} -
-
-
- ); -} diff --git a/frontend/src/app/[locale]/prototypes/agent-configuration/README.md b/frontend/src/app/[locale]/prototypes/agent-configuration/README.md deleted file mode 100644 index 1960df3..0000000 --- a/frontend/src/app/[locale]/prototypes/agent-configuration/README.md +++ /dev/null @@ -1,213 +0,0 @@ -# Agent Configuration UI - Design Prototype - -## Overview -The Agent Configuration UI allows users to create, view, and manage Agent Types - the templates from which agent instances are spawned. This is a critical administrative interface for defining how AI agents behave, what models they use, and what permissions they have. - -## User Stories -- As an admin, I want to create new agent types so I can define specialized AI agents for my projects -- As an admin, I want to configure model selection and parameters to optimize agent performance -- As an admin, I want to define MCP permissions to control what tools agents can access -- As an admin, I want to craft personality prompts to shape agent behavior and communication style -- As an admin, I want to view all agent types and their status at a glance -- As an admin, I want to duplicate existing agent types as starting points for new ones - -## Key Screens - -### 1. Agent Type List View -- Grid layout of agent type cards -- Search functionality -- Status filter (Active, Draft, Inactive) -- Create new agent type button -- Card shows: name, description, expertise tags, model, instance count, status - -### 2. Agent Type Detail View -- Full configuration display (read-only) -- Description and expertise areas -- Model configuration (primary, failover, parameters) -- MCP permissions with scopes -- Personality prompt display -- Instance count and quick actions -- Duplicate, Edit, Delete buttons -- Danger zone for destructive actions - -### 3. Agent Type Editor View -- Tabbed interface for organized editing: - - **Basic Info**: Name, description, status, expertise areas - - **Model**: Primary/failover model selection, temperature, max tokens, top P - - **Permissions**: MCP server toggles with granular scope checkboxes - - **Personality**: Large textarea for personality prompt with character count - -## User Flow - -### Creating a New Agent Type -1. User clicks "Create Agent Type" from list view -2. Editor opens with blank form -3. User fills in basic info (name, description, expertise) -4. User selects model configuration -5. User enables MCP permissions and selects scopes -6. User writes personality prompt -7. User saves (creates as Draft or Active) - -### Editing an Existing Agent Type -1. User clicks agent type card in list -2. Detail view shows full configuration -3. User clicks "Edit" button -4. Editor opens with pre-filled data -5. User modifies settings across tabs -6. User saves changes - -### Duplicating an Agent Type -1. User opens detail view -2. User clicks "Duplicate" -3. Editor opens with copied data and new name -4. User modifies as needed -5. User saves as new agent type - -## Design Decisions - -### Three-View Architecture -- **List**: Overview and discovery -- **Detail**: Read-only inspection -- **Editor**: Focused editing experience -- Clear navigation between views with back button - -### Tabbed Editor -- Logical grouping of related settings -- Reduces cognitive load -- Allows focused work on one aspect at a time -- Icons on tabs for quick recognition - -### Card-Based List -- Visual grid layout for quick scanning -- Status badges for instant status recognition -- Expertise tags show capabilities at a glance -- Instance count indicates usage - -### MCP Permissions UI -- Checkbox for enabling/disabling each server -- Nested scopes only shown when server is enabled -- Clear visual distinction between enabled/disabled -- Granular control over what agents can access - -### Model Configuration -- Primary + failover model selection -- Common parameters exposed (temperature, max tokens, top P) -- Helpful descriptions for each parameter -- Sensible defaults pre-filled - -## States - -### Loading -- Skeleton cards in list view -- Skeleton placeholders in detail/editor views - -### Empty -- No agent types: "Create your first agent type" CTA -- No search results: "No agent types found" with suggestion - -### Error -- Failed to load: Error card with retry button -- Failed to save: Toast notification with error details - -### Validation -- Required fields highlighted -- Character limits enforced -- Model parameter ranges validated - -## Responsive Breakpoints - -### Desktop (lg: 1024px+) -- 3-column card grid in list view -- 2/3 + 1/3 split in detail view -- Full tab navigation visible - -### Tablet (md: 768px) -- 2-column card grid -- Stacked layout in detail view -- Compact tab labels - -### Mobile (< 768px) -- Single column card list -- Full-width cards -- Scrollable tab navigation -- Stacked form fields - -## Accessibility Notes -- Form labels properly associated with inputs -- Tab panel navigation is keyboard accessible -- Status badges have text (not just color) -- Focus management when navigating between views -- Screen reader announces view changes -- Textarea has proper aria-labels - -## Components Used -- Card, CardHeader, CardTitle, CardContent, CardDescription -- Button (default, outline, ghost, destructive variants) -- Badge (default, secondary, outline variants) -- Input, Textarea, Label -- Select, SelectContent, SelectItem, SelectTrigger, SelectValue -- Tabs, TabsList, TabsTrigger, TabsContent -- Checkbox -- Separator -- Lucide icons - -## Form Fields Reference - -### Basic Info -| Field | Type | Required | Validation | -|-------|------|----------|------------| -| Name | Text | Yes | 3-50 characters | -| Status | Select | Yes | active/draft/inactive | -| Description | Textarea | Yes | 10-500 characters | -| Expertise | Tags | No | Comma-separated | - -### Model Configuration -| Field | Type | Required | Validation | -|-------|------|----------|------------| -| Primary Model | Select | Yes | From available models | -| Failover Model | Select | No | From available models | -| Temperature | Number | Yes | 0.0 - 2.0 | -| Max Tokens | Number | Yes | 1024 - 32768 | -| Top P | Number | Yes | 0.0 - 1.0 | - -### MCP Permissions -| Server | Scopes | -|--------|--------| -| Gitea | read, write, issues, branches, prs | -| Knowledge Base | read, write | -| Filesystem | read, write | -| Slack | read, write | -| Jira | read, write, issues | - -### Personality Prompt -- Large textarea (15 rows) -- Character count display -- Template insertion button -- Preview functionality - -## Questions for Review -1. Should we add a "Test Agent" feature to try the personality prompt? -2. Is the tabbed editor the right approach or should all fields be on one page? -3. Should expertise be free-form tags or a predefined list? -4. Should model parameters have "presets" (conservative, balanced, creative)? -5. How should we handle versioning of agent types? -6. Should there be an approval workflow for activating agent types? - -## How to View -Navigate to: `/prototypes/agent-configuration` - -Click through the views: -1. Start on list view -2. Click any card to see detail view -3. Click "Edit" to see editor view -4. Click "Create Agent Type" to see editor in create mode - -## Next Steps -After approval: -1. Implement form validation with react-hook-form and zod -2. Connect to agent type CRUD API -3. Add real model list from API -4. Implement tag input component for expertise -5. Add personality prompt templates -6. Implement MCP permission verification -7. Add loading skeletons and error states diff --git a/frontend/src/app/[locale]/prototypes/agent-configuration/page.tsx b/frontend/src/app/[locale]/prototypes/agent-configuration/page.tsx deleted file mode 100644 index 4074df8..0000000 --- a/frontend/src/app/[locale]/prototypes/agent-configuration/page.tsx +++ /dev/null @@ -1,939 +0,0 @@ -'use client'; - -import { useState } from 'react'; -import { - Card, - CardContent, - CardDescription, - CardHeader, - CardTitle, -} from '@/components/ui/card'; -import { Button } from '@/components/ui/button'; -import { Badge } from '@/components/ui/badge'; -import { Input } from '@/components/ui/input'; -import { Label } from '@/components/ui/label'; -import { Textarea } from '@/components/ui/textarea'; -import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from '@/components/ui/select'; -import { Separator } from '@/components/ui/separator'; -import { Checkbox } from '@/components/ui/checkbox'; -import { - Bot, - Plus, - Search, - Settings, - ChevronRight, - ArrowLeft, - Copy, - Trash2, - Save, - Eye, - Edit, - Sliders, - Shield, - MessageSquare, - Cpu, - Zap, - Code, - FileText, - CheckCircle2, - AlertTriangle, -} from 'lucide-react'; - -// Mock data for agent types -const mockAgentTypes = [ - { - id: 'type-001', - name: 'Product Owner', - description: 'Manages product backlog, defines user stories, and prioritizes features', - expertise: ['Requirements', 'User Stories', 'Prioritization', 'Stakeholder Management'], - model: 'claude-opus-4-5-20251101', - status: 'active', - instanceCount: 3, - lastModified: '2025-01-20', - }, - { - id: 'type-002', - name: 'Software Architect', - description: 'Designs system architecture, makes technology decisions, and ensures scalability', - expertise: ['System Design', 'API Design', 'Database Architecture', 'Security'], - model: 'claude-opus-4-5-20251101', - status: 'active', - instanceCount: 2, - lastModified: '2025-01-18', - }, - { - id: 'type-003', - name: 'Backend Engineer', - description: 'Implements server-side logic, APIs, and database interactions', - expertise: ['Python', 'FastAPI', 'PostgreSQL', 'Redis', 'Testing'], - model: 'claude-sonnet-4-20250514', - status: 'active', - instanceCount: 5, - lastModified: '2025-01-22', - }, - { - id: 'type-004', - name: 'Frontend Engineer', - description: 'Builds user interfaces using modern React and Next.js', - expertise: ['React', 'Next.js', 'TypeScript', 'Tailwind CSS', 'Testing'], - model: 'claude-sonnet-4-20250514', - status: 'active', - instanceCount: 4, - lastModified: '2025-01-21', - }, - { - id: 'type-005', - name: 'QA Engineer', - description: 'Creates test plans, writes automated tests, and ensures quality', - expertise: ['Test Planning', 'E2E Testing', 'Unit Testing', 'Bug Reporting'], - model: 'claude-sonnet-4-20250514', - status: 'draft', - instanceCount: 0, - lastModified: '2025-01-19', - }, - { - id: 'type-006', - name: 'DevOps Engineer', - description: 'Manages infrastructure, CI/CD pipelines, and deployment processes', - expertise: ['Docker', 'Kubernetes', 'CI/CD', 'Monitoring', 'Security'], - model: 'claude-sonnet-4-20250514', - status: 'inactive', - instanceCount: 1, - lastModified: '2025-01-15', - }, -]; - -// Full agent type detail for editor -const mockAgentTypeDetail = { - id: 'type-002', - name: 'Software Architect', - description: 'Designs system architecture, makes technology decisions, and ensures scalability. Works closely with the Product Owner to understand requirements and with Engineers to implement solutions.', - expertise: ['System Design', 'API Design', 'Database Architecture', 'Security', 'Scalability'], - model: { - primary: 'claude-opus-4-5-20251101', - failover: 'claude-sonnet-4-20250514', - }, - parameters: { - temperature: 0.7, - maxTokens: 8192, - topP: 0.95, - }, - mcpPermissions: [ - { id: 'gitea', name: 'Gitea', enabled: true, scopes: ['read', 'write', 'issues'] }, - { id: 'knowledge', name: 'Knowledge Base', enabled: true, scopes: ['read', 'write'] }, - { id: 'filesystem', name: 'Filesystem', enabled: true, scopes: ['read', 'write'] }, - { id: 'slack', name: 'Slack', enabled: false, scopes: [] }, - { id: 'jira', name: 'Jira', enabled: false, scopes: [] }, - ], - personalityPrompt: `You are a Senior Software Architect with 15+ years of experience designing scalable, maintainable systems. Your approach is: - -1. **Pragmatic**: You favor proven solutions over cutting-edge unless there's a clear benefit -2. **Security-minded**: Security is a first-class concern, not an afterthought -3. **Documentation-focused**: You believe in architecture decision records (ADRs) -4. **Collaborative**: You seek input from engineers and stakeholders before making major decisions - -When designing systems: -- Start with requirements and constraints -- Consider scalability, maintainability, and operational concerns -- Document decisions and their rationale -- Provide clear guidance for implementation teams - -Your communication style is clear, structured, and respectful. You explain complex concepts simply and always justify your recommendations.`, - status: 'active', - instanceCount: 2, - createdAt: '2025-01-10', - lastModified: '2025-01-18', -}; - -// View states -type ViewState = 'list' | 'detail' | 'editor'; - -// Status badge for agent types -function AgentTypeStatusBadge({ status }: { status: string }) { - const variants: Record = { - active: { - label: 'Active', - className: 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200', - }, - draft: { - label: 'Draft', - className: 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200', - }, - inactive: { - label: 'Inactive', - className: 'bg-gray-100 text-gray-800 dark:bg-gray-800 dark:text-gray-200', - }, - }; - - const variant = variants[status] || variants.inactive; - - return ( - - {variant.label} - - ); -} - -// Agent Type List View -function AgentTypeListView({ - onSelect, - onCreate, -}: { - onSelect: (id: string) => void; - onCreate: () => void; -}) { - const [searchQuery, setSearchQuery] = useState(''); - const [statusFilter, setStatusFilter] = useState('all'); - - const filteredTypes = mockAgentTypes.filter((type) => { - const matchesSearch = - type.name.toLowerCase().includes(searchQuery.toLowerCase()) || - type.description.toLowerCase().includes(searchQuery.toLowerCase()); - const matchesStatus = statusFilter === 'all' || type.status === statusFilter; - return matchesSearch && matchesStatus; - }); - - return ( -
- {/* Header */} -
-
-

Agent Types

-

- Configure templates for spawning AI agent instances -

-
- -
- - {/* Filters */} -
-
- - setSearchQuery(e.target.value)} - className="pl-9" - /> -
- -
- - {/* Agent Type Grid */} -
- {filteredTypes.map((type) => ( - onSelect(type.id)} - > - -
-
- -
- -
- {type.name} - {type.description} -
- -
- {/* Expertise tags */} -
- {type.expertise.slice(0, 3).map((skill) => ( - - {skill} - - ))} - {type.expertise.length > 3 && ( - - +{type.expertise.length - 3} - - )} -
- - - - {/* Metadata */} -
-
- - {type.model.split('-').slice(1, 2).join(' ')} -
-
- - {type.instanceCount} instances -
-
-
-
-
- ))} -
- - {filteredTypes.length === 0 && ( -
- -

No agent types found

-

Try adjusting your search or filters

-
- )} -
- ); -} - -// Agent Type Detail View -function AgentTypeDetailView({ - onBack, - onEdit, -}: { - onBack: () => void; - onEdit: () => void; -}) { - const type = mockAgentTypeDetail; - - return ( -
- {/* Header */} -
- -
-
-

{type.name}

- -
-

Last modified: {type.lastModified}

-
-
- - -
-
- -
- {/* Main Content */} -
- {/* Description Card */} - - - - - Description - - - -

{type.description}

-
-
- - {/* Expertise Card */} - - - - - Expertise Areas - - - -
- {type.expertise.map((skill) => ( - - {skill} - - ))} -
-
-
- - {/* Personality Prompt Card */} - - - - - Personality Prompt - - - -
-                {type.personalityPrompt}
-              
-
-
- - {/* MCP Permissions Card */} - - - - - MCP Permissions - - - Model Context Protocol servers this agent can access - - - -
- {type.mcpPermissions.map((perm) => ( -
-
-
- {perm.enabled ? ( - - ) : ( - - )} -
-
-

{perm.name}

-

- {perm.enabled ? perm.scopes.join(', ') : 'Not enabled'} -

-
-
- - {perm.enabled ? 'Enabled' : 'Disabled'} - -
- ))} -
-
-
-
- - {/* Sidebar */} -
- {/* Model Configuration */} - - - - - Model Configuration - - - -
-

Primary Model

-

{type.model.primary}

-
-
-

Failover Model

-

{type.model.failover}

-
- -
-
- Temperature - {type.parameters.temperature} -
-
- Max Tokens - {type.parameters.maxTokens.toLocaleString()} -
-
- Top P - {type.parameters.topP} -
-
-
-
- - {/* Instance Stats */} - - - - - Instances - - - -
-

{type.instanceCount}

-

Active instances

-
- -
-
- - {/* Danger Zone */} - - - - - Danger Zone - - - - - - - -
-
-
- ); -} - -// Agent Type Editor View -function AgentTypeEditorView({ - onBack, - onSave, - isNew = false, -}: { - onBack: () => void; - onSave: () => void; - isNew?: boolean; -}) { - const [activeTab, setActiveTab] = useState('basic'); - - return ( -
- {/* Header */} -
- -
-

- {isNew ? 'Create Agent Type' : 'Edit Agent Type'} -

-

- {isNew - ? 'Define a new agent type template' - : 'Modify agent type configuration'} -

-
-
- - -
-
- - {/* Editor Tabs */} - - - - - Basic Info - - - - Model - - - - Permissions - - - - Personality - - - - {/* Basic Info Tab */} - - - - Basic Information - - Define the agent type name, description, and expertise areas - - - -
-
- - -
-
- - -
-
- -
- -