162 lines
7.8 KiB
Markdown
162 lines
7.8 KiB
Markdown
---
|
|
phase: 22-agent-streaming
|
|
plan: "02"
|
|
subsystem: ui
|
|
tags: [react, agent-identity, streaming, tailwind, shadcn, tanstack-query]
|
|
|
|
# Dependency graph
|
|
requires:
|
|
- phase: 22-00
|
|
provides: agent-role-colors utility and test stubs (co-created here as prerequisite)
|
|
- phase: 21-chat-foundation
|
|
provides: ChatMarkdownMessage, ChatCodeBlock, agentsApi, chatApi base infrastructure
|
|
provides:
|
|
- ChatMessageIdentityBar component with agent icon, name, timestamp, and streaming dot
|
|
- ChatStreamingCursor component with animate-cursor-blink and aria-hidden
|
|
- Extended ChatMessage accepting agentName, agentIcon, agentRole, timestamp, isStreaming props
|
|
- ChatAgentSelector dropdown for per-conversation agent switching
|
|
- agent-role-colors.ts with 11 distinct role color classes (light + dark variants)
|
|
- chat.ts API client with updateConversation supporting agentId field
|
|
- shared types/chat.ts with ChatMessage and ChatConversation types
|
|
affects: [22-03, 22-04, 22-05, ChatPanel, ChatMessageList, useStreamingChat]
|
|
|
|
# Tech tracking
|
|
tech-stack:
|
|
added: []
|
|
patterns:
|
|
- "Agent identity bar pattern: icon + semibold name + muted timestamp above assistant messages"
|
|
- "Role-specific color map: Record<AgentRole, string> with light/dark Tailwind variants"
|
|
- "Streaming cursor: inline-block span with animate-cursor-blink, aria-hidden for a11y"
|
|
- "ChatMessage group wrapper: enables hover-reveal for edit/retry buttons in Plan 03"
|
|
- "ChatAgentSelector uses Popover+Command pattern from shadcn for agent selection"
|
|
|
|
key-files:
|
|
created:
|
|
- ui/src/components/ChatMessageIdentityBar.tsx
|
|
- ui/src/components/ChatStreamingCursor.tsx
|
|
- ui/src/components/ChatAgentSelector.tsx
|
|
- ui/src/components/ChatMessageIdentityBar.test.tsx
|
|
- ui/src/components/ChatAgentSelector.test.tsx
|
|
- ui/src/lib/agent-role-colors.ts
|
|
- ui/src/api/chat.ts
|
|
- packages/shared/src/types/chat.ts
|
|
modified:
|
|
- ui/src/components/ChatMessage.tsx (extended with identity props and group wrapper)
|
|
- packages/shared/src/index.ts (added chat type exports)
|
|
|
|
key-decisions:
|
|
- "Co-created agent-role-colors.ts as prerequisite (22-00 not yet executed by another agent)"
|
|
- "11 distinct role colors chosen: pm=blue, engineer=violet, ceo=amber, general=slate, designer=pink, qa=orange, researcher=teal, devops=emerald, cto=indigo, cmo=rose, cfo=cyan"
|
|
- "ChatAgentSelector uses full integration tests as it.todo() since QueryClientProvider mocking is deferred"
|
|
- "chat.ts API updateConversation extended with agentId field ahead of 22-01 server PR merge"
|
|
- "Created ChatCodeBlock and ChatMarkdownMessage as prerequisites from phase-21 base (not in this worktree)"
|
|
|
|
patterns-established:
|
|
- "Agent identity bar always above assistant message content, never for user messages"
|
|
- "ChatStreamingCursor appended after ChatMarkdownMessage during isStreaming=true"
|
|
- "agentName prop controls identity bar rendering — null/undefined suppresses the bar"
|
|
|
|
requirements-completed: [AGENT-04, CHAT-08, THEME-03]
|
|
|
|
# Metrics
|
|
duration: 11min
|
|
completed: 2026-04-01
|
|
---
|
|
|
|
# Phase 22 Plan 02: Agent Identity Components Summary
|
|
|
|
**Agent identity bar with role-specific colors (THEME-03), agent selector dropdown (CHAT-08), and streaming cursor for visible agent identity on every assistant message (AGENT-04)**
|
|
|
|
## Performance
|
|
|
|
- **Duration:** ~11 minutes
|
|
- **Started:** 2026-04-01T18:06:52Z
|
|
- **Completed:** 2026-04-01T18:17:48Z
|
|
- **Tasks:** 2/2
|
|
- **Files created:** 8 new files
|
|
- **Files modified:** 2 existing files
|
|
|
|
## Accomplishments
|
|
|
|
### Task 1: ChatMessageIdentityBar, ChatStreamingCursor, and extended ChatMessage
|
|
|
|
Created the three core identity components:
|
|
|
|
- **ChatMessageIdentityBar** (`h-4 w-4` icon, `text-[13px] font-semibold` name, `text-[11px]` timestamp, `animate-pulse` streaming dot)
|
|
- **ChatStreamingCursor** (`inline-block w-2 h-[1em] bg-foreground/70 animate-cursor-blink`, `aria-hidden="true"`)
|
|
- **ChatMessage** extended with `agentName`, `agentIcon`, `agentRole`, `timestamp`, `isStreaming` props; wrapped in `group` div for future hover actions
|
|
|
|
Created **agent-role-colors.ts** with 11 distinct roles (all with `dark:` variants, zero duplicate colors):
|
|
|
|
| Role | Light | Dark |
|
|
|------|-------|------|
|
|
| pm | text-blue-600 | text-blue-400 |
|
|
| engineer | text-violet-600 | text-violet-400 |
|
|
| ceo | text-amber-600 | text-amber-400 |
|
|
| general | text-slate-600 | text-slate-400 |
|
|
| designer | text-pink-600 | text-pink-400 |
|
|
| qa | text-orange-600 | text-orange-400 |
|
|
| researcher | text-teal-600 | text-teal-400 |
|
|
| devops | text-emerald-600 | text-emerald-400 |
|
|
| cto | text-indigo-600 | text-indigo-400 |
|
|
| cmo | text-rose-600 | text-rose-400 |
|
|
| cfo | text-cyan-600 | text-cyan-400 |
|
|
|
|
All 4 ChatMessageIdentityBar tests pass.
|
|
|
|
### Task 2: ChatAgentSelector component
|
|
|
|
Created **ChatAgentSelector** using `Popover` + `Command` shadcn components:
|
|
|
|
- Trigger shows active agent icon + name (max-w-[120px], truncated) + ChevronDown
|
|
- "Select agent" in `text-muted-foreground` when no agent selected
|
|
- Popover (200px wide) lists agents with icon, name, and role label
|
|
- "No agents configured" empty state via `CommandEmpty`
|
|
- Selection calls `onAgentChange` and PATCHes conversation via `chatApi.updateConversation`
|
|
- Role-specific colors from `agentRoleColors` applied to all agent icons
|
|
- Loading state shows `Skeleton` placeholder
|
|
- `aria-label="Active agent"` on trigger for accessibility
|
|
|
|
TypeScript compiles clean (`tsc --noEmit` passes).
|
|
|
|
## Deviations from Plan
|
|
|
|
### Auto-created prerequisites (Rule 2 - Missing critical functionality)
|
|
|
|
**1. [Rule 2 - Prerequisite] Created agent-role-colors.ts inline**
|
|
- **Found during:** Task 1 setup
|
|
- **Issue:** Plan 22-00 (which creates agent-role-colors.ts) had not been executed yet; 22-02 depends on it
|
|
- **Fix:** Created agent-role-colors.ts directly in this worktree with all 11 distinct colors
|
|
- **Files modified:** `ui/src/lib/agent-role-colors.ts`
|
|
- **Commit:** 91aa9d65
|
|
|
|
**2. [Rule 2 - Prerequisite] Created ChatMarkdownMessage and ChatCodeBlock**
|
|
- **Found during:** Task 1 setup
|
|
- **Issue:** Phase-21 ChatMarkdownMessage and ChatCodeBlock not present in this worktree (branched before phase-21)
|
|
- **Fix:** Created both files from phase-22 branch content
|
|
- **Files modified:** `ui/src/components/ChatMarkdownMessage.tsx`, `ui/src/components/ChatCodeBlock.tsx`
|
|
- **Commit:** 91aa9d65
|
|
|
|
**3. [Rule 2 - Prerequisite] Created shared types/chat.ts and chatApi**
|
|
- **Found during:** Task 2
|
|
- **Issue:** Phase-21 shared chat types and chat API client not present in this worktree
|
|
- **Fix:** Created `packages/shared/src/types/chat.ts` and `ui/src/api/chat.ts` with types needed for ChatAgentSelector
|
|
- **Note:** Added `agentId` to `updateConversation` type signature (expected from 22-01 server work)
|
|
- **Files modified:** `packages/shared/src/types/chat.ts`, `ui/src/api/chat.ts`, `packages/shared/src/index.ts`
|
|
- **Commit:** 471efdfd
|
|
|
|
**4. [Rule 3 - Blocking] Created node_modules symlinks for test execution**
|
|
- **Found during:** Task 1 verification
|
|
- **Issue:** Worktree has no `node_modules` (pnpm workspace links only in main repo); vitest failed to resolve React
|
|
- **Fix:** Created symlinks: `ui/node_modules -> /opt/nexus/ui/node_modules` package symlinks; `node_modules/.pnpm -> /opt/nexus/node_modules/.pnpm`
|
|
- **Not committed** (runtime infrastructure, not code)
|
|
|
|
## Known Stubs
|
|
|
|
- `ChatAgentSelector.test.tsx` has 5 `it.todo()` entries for full integration tests (rendering with QueryClientProvider mock). These are intentional — the export test confirms the component loads correctly. Full tests deferred to post-integration phase.
|
|
- `animate-cursor-blink` CSS animation assumed to exist in `ui/src/index.css` (created by plan 22-00 which runs in parallel). If not present, the cursor will display statically but without the blink animation.
|
|
|
|
## Self-Check: PASSED
|
|
|
|
All 7 created files confirmed to exist.
|
|
Commits 91aa9d65 (Task 1) and 471efdfd (Task 2) both verified in git log.
|