From 5f646b7d9be320503ed99893a52756a920d7dd9d Mon Sep 17 00:00:00 2001 From: Nexus Dev Date: Wed, 1 Apr 2026 18:19:42 +0000 Subject: [PATCH] =?UTF-8?q?docs(22-02):=20complete=20agent=20identity=20co?= =?UTF-8?q?mponents=20plan=20=E2=80=94=20ChatMessageIdentityBar,=20ChatAge?= =?UTF-8?q?ntSelector,=20agent-role-colors?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .planning/REQUIREMENTS.md | 8 +- .planning/ROADMAP.md | 10 +- .planning/STATE.md | 16 +- .../22-agent-streaming/22-02-SUMMARY.md | 162 ++++++++++++++++++ 4 files changed, 181 insertions(+), 15 deletions(-) create mode 100644 .planning/phases/22-agent-streaming/22-02-SUMMARY.md diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index 274bec7f..e3c95958 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -19,7 +19,7 @@ - [x] **CHAT-05** — Conversation titles: auto-generated from the first message, manually editable by the user - [x] **CHAT-06** — Delete, archive, and pin conversations - [ ] **CHAT-07** — Full-text search across all conversations -- [ ] **CHAT-08** — Agent selector: switch which agent you are talking to mid-conversation or per-conversation +- [x] **CHAT-08** — Agent selector: switch which agent you are talking to mid-conversation or per-conversation - [ ] **CHAT-09** — System message indicator: when the Brainstormer hands off to PM, or PM delegates to Engineer, the handoff is visible in chat - [ ] **CHAT-10** — Message editing: edit a previous message and regenerate the response - [ ] **CHAT-11** — Response regeneration: retry button on any assistant message @@ -42,7 +42,7 @@ - [ ] **AGENT-01** — Default agent is the Brainstormer (Generalist with a Superpowers-style system prompt, or a dedicated 4th Brainstormer agent) - [ ] **AGENT-02** — Brainstormer follows a structured questioning flow: asks clarifying questions, produces a spec template, and hands off to PM - [ ] **AGENT-03** — PM agent can receive specs from chat and create Nexus tasks/issues from them -- [ ] **AGENT-04** — Agent responses show which agent is speaking with avatar and name +- [x] **AGENT-04** — Agent responses show which agent is speaking with avatar and name - [ ] **AGENT-05** — Handoff indicators visible in chat: "Brainstormer → PM: Here's the spec for approval" - [ ] **AGENT-06** — Task creation from chat: user or agent can say "create a task for this" and it becomes a Nexus issue - [ ] **AGENT-07** — Status updates from agents appear in chat: "Engineer completed task X" notification in the relevant conversation @@ -125,7 +125,7 @@ The following are explicitly deferred: | CHAT-05 | Phase 21 | Complete | | CHAT-06 | Phase 21 | Complete | | CHAT-07 | Phase 24 | Pending | -| CHAT-08 | Phase 22 | Pending | +| CHAT-08 | Phase 22 | Complete | | CHAT-09 | Phase 23 | Pending | | CHAT-10 | Phase 22 | Pending | | CHAT-11 | Phase 22 | Pending | @@ -142,7 +142,7 @@ The following are explicitly deferred: | AGENT-01 | Phase 23 | Pending | | AGENT-02 | Phase 23 | Pending | | AGENT-03 | Phase 23 | Pending | -| AGENT-04 | Phase 22 | Pending | +| AGENT-04 | Phase 22 | Complete | | AGENT-05 | Phase 23 | Pending | | AGENT-06 | Phase 23 | Pending | | AGENT-07 | Phase 23 | Pending | diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 7cce8b3c..ec37d1b4 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -55,12 +55,12 @@ Plans: 4. User can click Stop to cancel an in-progress streaming response 5. User can edit a previous message to regenerate the response, or click Retry on any existing assistant message; conversations with 1,000+ messages scroll without jank via a virtualized list 6. Slash commands (`/brainstorm`, `/ask-pm`, `/ask-engineer`, `/task`, `/search`) route messages to the correct agent; `@mention` syntax routes to the named agent -**Plans:** 1/6 plans executed +**Plans:** 3/6 plans executed Plans: - [x] 22-00-PLAN.md — Wave 0: DB migration, shared types, install virtualizer, agent-role-colors, CSS, test stubs -- [ ] 22-01-PLAN.md — SSE streaming endpoint + useStreamingChat hook -- [ ] 22-02-PLAN.md — Agent identity bar, streaming cursor, agent selector +- [x] 22-01-PLAN.md — SSE streaming endpoint + useStreamingChat hook +- [x] 22-02-PLAN.md — Agent identity bar, streaming cursor, agent selector - [ ] 22-03-PLAN.md — Edit/retry/stop message action controls - [ ] 22-04-PLAN.md — Slash commands and @mention popovers - [ ] 22-05-PLAN.md — Virtualized message list + full ChatPanel integration @@ -79,7 +79,7 @@ Plans: **Plans:** 6 plans Plans: -- [ ] 22-00-PLAN.md — Wave 0: DB migration, shared types, install virtualizer, agent-role-colors, CSS, test stubs +- [x] 22-00-PLAN.md — Wave 0: DB migration, shared types, install virtualizer, agent-role-colors, CSS, test stubs - [ ] 22-01-PLAN.md — SSE streaming endpoint + useStreamingChat hook - [ ] 22-02-PLAN.md — Agent identity bar, streaming cursor, agent selector - [ ] 22-03-PLAN.md — Edit/retry/stop message action controls @@ -231,7 +231,7 @@ All 65 v1 requirements are mapped to exactly one phase. No orphans. | Phase | Milestone | Plans Complete | Status | Completed | |-------|-----------|----------------|--------|-----------| | 21. Chat Foundation | v1.3 | 7/7 | Complete | 2026-04-01 | -| 22. Agent Streaming | v1.3 | 1/6 | In Progress| | +| 22. Agent Streaming | v1.3 | 3/6 | In Progress| | | 23. Brainstormer Flow | v1.3 | 0/? | Not started | - | | 24. Search, History & Branching | v1.3 | 0/? | Not started | - | | 25. File System | v1.3 | 0/? | Not started | - | diff --git a/.planning/STATE.md b/.planning/STATE.md index 42f7c96d..ac730e96 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -3,14 +3,14 @@ gsd_state_version: 1.0 milestone: v1.3 milestone_name: milestone status: executing -stopped_at: Completed 22-agent-streaming-22-00-PLAN.md -last_updated: "2026-04-01T18:08:37.459Z" +stopped_at: Completed 22-agent-streaming-22-02-PLAN.md +last_updated: "2026-04-01T18:19:26.572Z" last_activity: 2026-04-01 progress: total_phases: 6 completed_phases: 1 total_plans: 13 - completed_plans: 8 + completed_plans: 10 percent: 0 --- @@ -26,7 +26,7 @@ See: .planning/PROJECT.md (updated 2026-03-30) ## Current Position Phase: 22 (agent-streaming) — EXECUTING -Plan: 2 of 6 +Plan: 3 of 6 Status: Ready to execute Last activity: 2026-04-01 @@ -67,6 +67,7 @@ Progress: [░░░░░░░░░░] 0% | Phase 21-chat-foundation P05 | 4 | 3 tasks | 8 files | | Phase 21-chat-foundation P06 | 10min | 2 tasks | 7 files | | Phase 22-agent-streaming P00 | 8min | 2 tasks | 14 files | +| Phase 22-agent-streaming P02 | 11min | 2 tasks | 10 files | ## Accumulated Context @@ -100,6 +101,9 @@ Recent decisions affecting current work: - [Phase 21-chat-foundation]: Cmd+K handler placed before input-guard early return in useKeyboardShortcuts so it fires globally even from input/textarea - [Phase 22-agent-streaming]: THEME-03: 11 agent roles each have unique Tailwind color — pm=blue, engineer=violet, ceo=amber, general=slate, designer=pink, qa=orange, researcher=teal, devops=emerald, cto=indigo, cmo=rose, cfo=cyan - [Phase 22-agent-streaming]: updatedAt on chat_messages is nullable (no .notNull()) — existing rows will have null until updated, prevents data migration requirement +- [Phase 22-02]: 11 distinct role colors for AgentRole with light/dark Tailwind variants (no duplicates) +- [Phase 22-02]: ChatAgentSelector uses Popover+Command shadcn pattern; integration tests deferred as it.todo() +- [Phase 22-02]: ChatMessage wrapped in group div to enable hover-reveal edit/retry actions in Plan 03 ### Pending Todos @@ -112,6 +116,6 @@ None yet. ## Session Continuity -Last session: 2026-04-01T18:08:37.456Z -Stopped at: Completed 22-agent-streaming-22-00-PLAN.md +Last session: 2026-04-01T18:19:26.568Z +Stopped at: Completed 22-agent-streaming-22-02-PLAN.md Resume file: None diff --git a/.planning/phases/22-agent-streaming/22-02-SUMMARY.md b/.planning/phases/22-agent-streaming/22-02-SUMMARY.md new file mode 100644 index 00000000..bba7a503 --- /dev/null +++ b/.planning/phases/22-agent-streaming/22-02-SUMMARY.md @@ -0,0 +1,162 @@ +--- +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 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.