Conversation
WalkthroughThis PR introduces a new "Agent Work Orders" feature to the style guide, adding three new React components (AgentWorkOrderExample, StepHistoryCard, WorkflowStepButton) to visualize and manage workflow steps with human-in-the-loop checkpoints, plus modifications to SideNavigation for collapsibility and LayoutsTab integration. Changes
Sequence DiagramsequenceDiagram
actor User
participant LayoutsTab
participant AgentWorkOrderExample
participant WorkflowStepButton
participant StepHistoryCard
User->>LayoutsTab: Click "Agent Work Orders" tab
activate LayoutsTab
LayoutsTab->>AgentWorkOrderExample: render with mock work order data
deactivate LayoutsTab
activate AgentWorkOrderExample
AgentWorkOrderExample->>WorkflowStepButton: render step buttons for each workflow step
activate WorkflowStepButton
WorkflowStepButton-->>AgentWorkOrderExample: display with completion state & animations
deactivate WorkflowStepButton
User->>AgentWorkOrderExample: hover over step (shows + button)
AgentWorkOrderExample->>AgentWorkOrderExample: toggle human-in-the-loop checkpoint
User->>AgentWorkOrderExample: click to expand step history
rect rgba(100, 150, 200, 0.2)
note over AgentWorkOrderExample,StepHistoryCard: Expand History Section
AgentWorkOrderExample->>StepHistoryCard: render historical steps with expansion state
activate StepHistoryCard
end
User->>StepHistoryCard: click on human-in-loop step to expand
rect rgba(150, 100, 200, 0.2)
note over StepHistoryCard: Expanded View with Edit/Approve
StepHistoryCard->>StepHistoryCard: toggle between View & Edit modes
User->>StepHistoryCard: edit markdown content in textarea
StepHistoryCard->>StepHistoryCard: track unsaved changes
User->>StepHistoryCard: click Approve
StepHistoryCard->>StepHistoryCard: progress to next step
end
deactivate StepHistoryCard
deactivate AgentWorkOrderExample
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes The PR introduces three moderately complex components with Framer Motion animations, conditional rendering, and state management, alongside two straightforward file modifications. The components are cohesive but require separate reasoning for animation logic, markdown editing interactions, and state coordination across the workflow hierarchy. Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (10)
archon-ui-main/src/features/style-guide/shared/SideNavigation.tsx (3)
23-36: Add nav semantics and wire up collapse state for a11yWrap as a
, expose aria-expanded on the toggle, and link it via aria-controls for screen readers.Apply:
- <div className={cn("flex-shrink-0 transition-all duration-300", isCollapsed ? "w-12" : "w-32")}> + <nav + id="style-guide-sidenav" + aria-label="Style guide sections" + className={cn("flex-shrink-0 transition-all duration-300", isCollapsed ? "w-12" : "w-32")} + > ... - <Button + <Button variant="ghost" size="sm" - onClick={() => setIsCollapsed(!isCollapsed)} + onClick={() => setIsCollapsed(!isCollapsed)} className="px-2 py-1 h-auto text-gray-500 hover:text-gray-700 dark:hover:text-gray-300" - aria-label={isCollapsed ? "Expand navigation" : "Collapse navigation"} + aria-label={isCollapsed ? "Expand navigation" : "Collapse navigation"} + aria-controls="style-guide-sidenav" + aria-expanded={!isCollapsed} > ... - </div> + </nav>
40-56: Mark the active section with aria-currentImprove SR navigation.
- <button + <button key={section.id} type="button" onClick={() => onSectionClick(section.id)} title={isCollapsed ? section.label : undefined} + aria-current={isActive ? "page" : undefined} className={cn(
20-31: Persist collapsed state across sessionsRemember user preference via localStorage. Non-breaking and improves UX.
- const [isCollapsed, setIsCollapsed] = useState(false); + const [isCollapsed, setIsCollapsed] = useState<boolean>(() => { + try { + return localStorage.getItem("styleguide.sidenavCollapsed") === "1"; + } catch { + return false; + } + }); ... - onClick={() => setIsCollapsed(!isCollapsed)} + onClick={() => + setIsCollapsed((prev) => { + const next = !prev; + try { + localStorage.setItem("styleguide.sidenavCollapsed", next ? "1" : "0"); + } catch {} + return next; + }) + }archon-ui-main/src/features/style-guide/tabs/LayoutsTab.tsx (1)
1-4: Memoize sections to avoid unnecessary re-rendersCreate a stable sections array; cheaper reconciliations when state updates.
-import { Briefcase, Database, FileText, FolderKanban, Navigation, Settings } from "lucide-react"; -import { useState } from "react"; +import { Briefcase, Database, FileText, FolderKanban, Navigation, Settings } from "lucide-react"; +import { useMemo, useState } from "react"; ... - const sections: SideNavigationSection[] = [ - { id: "navigation", label: "Navigation", icon: <Navigation className="w-4 h-4" /> }, - { id: "projects", label: "Projects", icon: <FolderKanban className="w-4 h-4" /> }, - { id: "settings", label: "Settings", icon: <Settings className="w-4 h-4" /> }, - { id: "knowledge", label: "Knowledge", icon: <Database className="w-4 h-4" /> }, - { id: "document-browser", label: "Document Browser", icon: <FileText className="w-4 h-4" /> }, - { id: "agent-work-orders", label: "Agent Work Orders", icon: <Briefcase className="w-4 h-4" /> }, - ]; + const sections: SideNavigationSection[] = useMemo( + () => [ + { id: "navigation", label: "Navigation", icon: <Navigation className="w-4 h-4" /> }, + { id: "projects", label: "Projects", icon: <FolderKanban className="w-4 h-4" /> }, + { id: "settings", label: "Settings", icon: <Settings className="w-4 h-4" /> }, + { id: "knowledge", label: "Knowledge", icon: <Database className="w-4 h-4" /> }, + { id: "document-browser", label: "Document Browser", icon: <FileText className="w-4 h-4" /> }, + { id: "agent-work-orders", label: "Agent Work Orders", icon: <Briefcase className="w-4 h-4" /> }, + ], + [], + );Also applies to: 14-21
archon-ui-main/src/features/style-guide/layouts/AgentWorkOrderExample.tsx (3)
154-159: Expose hover-only plus button to keyboard usersReveal the control on focus, not just hover, for accessibility.
- <div + <div className="relative flex-shrink-0" style={{ width: "80px", height: "50px" }} - onMouseEnter={() => setHoveredStepIndex(index)} - onMouseLeave={() => setHoveredStepIndex(null)} + tabIndex={0} + onMouseEnter={() => setHoveredStepIndex(index)} + onMouseLeave={() => setHoveredStepIndex(null)} + onFocus={() => setHoveredStepIndex(index)} + onBlur={() => setHoveredStepIndex(null)} >Additionally consider using the shared Button primitive for the absolute Plus/User buttons to inherit focus-visible ring styles.
Also applies to: 192-209
305-307: Compute “Steps Completed” dynamicallyAvoid hard-coded “2 / 2”; reflect actual progress.
- <p className="text-2xl font-bold text-gray-900 dark:text-white mt-0.5">2 / 2</p> + <p className="text-2xl font-bold text-gray-900 dark:text-white mt-0.5"> + {MOCK_WORK_ORDER.workflow.currentStep} / {MOCK_WORK_ORDER.workflow.steps.length} + </p>
120-137: Minor: Details toggle should announce region relationshipAdd aria-controls to reference the collapsible details container for better SR context.
- <Button + <Button variant="ghost" size="sm" onClick={() => setShowDetails(!showDetails)} className="text-cyan-600 dark:text-cyan-400 hover:bg-cyan-500/10" aria-label={showDetails ? "Hide details" : "Show details"} + aria-controls="awo-details" + aria-expanded={showDetails} >And set id on the motion div:
- <motion.div + <motion.div + id="awo-details"archon-ui-main/src/features/style-guide/layouts/components/StepHistoryCard.tsx (2)
79-94: Link toggle to collapsible region with aria-controls/idImproves SR navigation for the animated panel.
export const StepHistoryCard = ({ step, isExpanded, onToggle, document }: StepHistoryCardProps) => { const [isEditingDocument, setIsEditingDocument] = useState(false); const [editedContent, setEditedContent] = useState(""); const [hasChanges, setHasChanges] = useState(false); + const contentId = `step-content-${step.id}`; ... - <Button + <Button variant="ghost" size="sm" onClick={onToggle} className={cn( "px-2 transition-colors", step.isHumanInLoop ? "text-orange-500 hover:text-orange-600 dark:hover:text-orange-400" : "text-cyan-500 hover:text-cyan-600 dark:hover:text-cyan-400", )} aria-label={isExpanded ? "Collapse step" : "Expand step"} aria-expanded={isExpanded} + aria-controls={contentId} > ... - <motion.div + <motion.div + id={contentId} initial={{ height: 0, opacity: 0 }}Also applies to: 100-116
9-27: Expose an onApprove callback; keep console log for demoMakes the component reusable beyond the style guide.
interface StepHistoryCardProps { step: { id: string; ... }; isExpanded: boolean; onToggle: () => void; + onApprove?: (args: { stepId: string; content: string }) => void; document?: { ... export const StepHistoryCard = ({ step, isExpanded, onToggle, document }: StepHistoryCardProps) => { ... - const handleApproveAndContinue = () => { - console.log("Approved and continuing to next step"); + const handleApproveAndContinue = () => { + console.log("Approved and continuing to next step"); + // Notify parent if provided + // eslint-disable-next-line @typescript-eslint/no-unused-expressions + (typeof onToggle === "function"); // keep tree-shaking happy if not used + // eslint-disable-next-line @typescript-eslint/no-unused-expressions + // @ts-expect-error optional prop may be undefined + onApprove?.({ stepId: step.id, content: editedContent }); setHasChanges(false); setIsEditingDocument(false); };Also applies to: 47-51, 238-255
archon-ui-main/src/features/style-guide/layouts/components/WorkflowStepButton.tsx (1)
13-22: Hoist color map and tighten typesAvoid re-allocating the map per render and align types.
-// Helper function to get color hex values for animations -const getColorValue = (color: string) => { +type ColorKey = "cyan" | "green" | "blue" | "purple"; +// Helper function to get color hex values for animations +const getColorValue = (color: ColorKey) => { const colorValues = { purple: "rgb(168,85,247)", green: "rgb(34,197,94)", blue: "rgb(59,130,246)", cyan: "rgb(34,211,238)", }; - return colorValues[color as keyof typeof colorValues] || colorValues.blue; + return colorValues[color]; }; + +const COLOR_MAP: Record<ColorKey, { + border: string; glow: string; glowHover: string; fill: string; innerGlow: string; +}> = { + purple: { + border: "border-purple-400", + glow: "shadow-[0_0_15px_rgba(168,85,247,0.8)]", + glowHover: "hover:shadow-[0_0_25px_rgba(168,85,247,1)]", + fill: "bg-purple-400", + innerGlow: "shadow-[inset_0_0_10px_rgba(168,85,247,0.8)]", + }, + green: { + border: "border-green-400", + glow: "shadow-[0_0_15px_rgba(34,197,94,0.8)]", + glowHover: "hover:shadow-[0_0_25px_rgba(34,197,94,1)]", + fill: "bg-green-400", + innerGlow: "shadow-[inset_0_0_10px_rgba(34,197,94,0.8)]", + }, + blue: { + border: "border-blue-400", + glow: "shadow-[0_0_15px_rgba(59,130,246,0.8)]", + glowHover: "hover:shadow-[0_0_25px_rgba(59,130,246,1)]", + fill: "bg-blue-400", + innerGlow: "shadow-[inset_0_0_10px_rgba(59,130,246,0.8)]", + }, + cyan: { + border: "border-cyan-400", + glow: "shadow-[0_0_15px_rgba(34,211,238,0.8)]", + glowHover: "hover:shadow-[0_0_25px_rgba(34,211,238,1)]", + fill: "bg-cyan-400", + innerGlow: "shadow-[inset_0_0_10px_rgba(34,211,238,0.8)]", + }, +}; ... - const colorMap = { - purple: { ... }, - green: { ... }, - blue: { ... }, - cyan: { ... }, - }; - - const styles = colorMap[color]; + const styles = COLOR_MAP[color];Also applies to: 32-64, 63-67
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
archon-ui-main/src/features/style-guide/layouts/AgentWorkOrderExample.tsx(1 hunks)archon-ui-main/src/features/style-guide/layouts/components/StepHistoryCard.tsx(1 hunks)archon-ui-main/src/features/style-guide/layouts/components/WorkflowStepButton.tsx(1 hunks)archon-ui-main/src/features/style-guide/shared/SideNavigation.tsx(2 hunks)archon-ui-main/src/features/style-guide/tabs/LayoutsTab.tsx(3 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
archon-ui-main/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
archon-ui-main/src/**/*.{ts,tsx}: Frontend TypeScript must use strict mode with no implicit any
Use TanStack Query for all data fetching; avoid prop drilling
Use database values directly in the frontend; avoid mapping layers between BE and FE typesUse TanStack Query for all data fetching; avoid WebSockets in the frontend (use smart HTTP polling)
Files:
archon-ui-main/src/features/style-guide/shared/SideNavigation.tsxarchon-ui-main/src/features/style-guide/tabs/LayoutsTab.tsxarchon-ui-main/src/features/style-guide/layouts/components/StepHistoryCard.tsxarchon-ui-main/src/features/style-guide/layouts/AgentWorkOrderExample.tsxarchon-ui-main/src/features/style-guide/layouts/components/WorkflowStepButton.tsx
archon-ui-main/src/features/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use Biome in features: 120 character line length, double quotes, and trailing commas
archon-ui-main/src/features/**/*.{ts,tsx}: Biome formatting in features: 120-character line length, double quotes, and trailing commas
Do not construct Tailwind classes dynamically
Use database enum/string values directly in the frontend (no mapping layer); maintain end-to-end type safety
Files:
archon-ui-main/src/features/style-guide/shared/SideNavigation.tsxarchon-ui-main/src/features/style-guide/tabs/LayoutsTab.tsxarchon-ui-main/src/features/style-guide/layouts/components/StepHistoryCard.tsxarchon-ui-main/src/features/style-guide/layouts/AgentWorkOrderExample.tsxarchon-ui-main/src/features/style-guide/layouts/components/WorkflowStepButton.tsx
archon-ui-main/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
archon-ui-main/**/*.{ts,tsx}: TypeScript: strict mode; no implicit any
Never return null to indicate failure in the frontend; throw an error with details
Files:
archon-ui-main/src/features/style-guide/shared/SideNavigation.tsxarchon-ui-main/src/features/style-guide/tabs/LayoutsTab.tsxarchon-ui-main/src/features/style-guide/layouts/components/StepHistoryCard.tsxarchon-ui-main/src/features/style-guide/layouts/AgentWorkOrderExample.tsxarchon-ui-main/src/features/style-guide/layouts/components/WorkflowStepButton.tsx
**/*.{ts,tsx,py}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx,py}: Do not include keywords SIMPLIFIED, ENHANCED, LEGACY, CHANGED, or REMOVED in code comments
Code comments should describe functionality and reasoning only; do not mention beta status or global rules
Files:
archon-ui-main/src/features/style-guide/shared/SideNavigation.tsxarchon-ui-main/src/features/style-guide/tabs/LayoutsTab.tsxarchon-ui-main/src/features/style-guide/layouts/components/StepHistoryCard.tsxarchon-ui-main/src/features/style-guide/layouts/AgentWorkOrderExample.tsxarchon-ui-main/src/features/style-guide/layouts/components/WorkflowStepButton.tsx
archon-ui-main/src/features/**/components/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use Radix UI primitives from src/features/ui/primitives/ in feature components
Files:
archon-ui-main/src/features/style-guide/layouts/components/StepHistoryCard.tsxarchon-ui-main/src/features/style-guide/layouts/components/WorkflowStepButton.tsx
🧬 Code graph analysis (4)
archon-ui-main/src/features/style-guide/shared/SideNavigation.tsx (2)
archon-ui-main/src/features/ui/primitives/styles.ts (1)
cn(605-607)archon-ui-main/src/features/ui/primitives/button.tsx (1)
Button(11-130)
archon-ui-main/src/features/style-guide/tabs/LayoutsTab.tsx (1)
archon-ui-main/src/features/style-guide/layouts/AgentWorkOrderExample.tsx (1)
AgentWorkOrderExample(76-332)
archon-ui-main/src/features/style-guide/layouts/components/StepHistoryCard.tsx (3)
archon-ui-main/src/features/ui/primitives/card.tsx (1)
Card(23-136)archon-ui-main/src/features/ui/primitives/button.tsx (1)
Button(11-130)archon-ui-main/src/features/ui/primitives/styles.ts (1)
cn(605-607)
archon-ui-main/src/features/style-guide/layouts/AgentWorkOrderExample.tsx (6)
archon-ui-main/src/features/ui/primitives/card.tsx (1)
Card(23-136)archon-ui-main/src/features/ui/primitives/button.tsx (1)
Button(11-130)archon-ui-main/src/features/style-guide/layouts/components/WorkflowStepButton.tsx (1)
WorkflowStepButton(24-170)archon-ui-main/src/features/ui/primitives/styles.ts (1)
cn(605-607)archon-ui-main/src/features/ui/primitives/tooltip.tsx (4)
TooltipProvider(6-6)Tooltip(9-9)TooltipTrigger(12-12)TooltipContent(15-50)archon-ui-main/src/features/style-guide/layouts/components/StepHistoryCard.tsx (1)
StepHistoryCard(29-265)
🔇 Additional comments (2)
archon-ui-main/src/features/style-guide/layouts/AgentWorkOrderExample.tsx (1)
1-331: Review comment is incorrect; orange edgeColor is fully supported.The
edgeColorsobject inarchon-ui-main/src/features/ui/primitives/styles.tsincludes a complete "orange" mapping with solid, gradient, border, and bg properties. The Card component's type definition explicitly accepts "orange" as a validedgeColoroption. StepHistoryCard correctly usesedgeColor={step.isHumanInLoop ? "orange" : "blue"}and will not encounter any runtime errors. No fixes or mapping additions are needed.Likely an incorrect or invalid review comment.
archon-ui-main/src/features/style-guide/layouts/components/StepHistoryCard.tsx (1)
54-61: No issues found—Card edgeColor supports "orange"The Card component at
archon-ui-main/src/features/ui/primitives/card.tsxexplicitly includes"orange"in its edgeColor type definition (line 17), and the corresponding style definitions are fully defined inglassCard.edgeColorsinstyles.ts(lines 177–181). The usage in StepHistoryCard.tsx is correct and will not crash.Likely an incorrect or invalid review comment.
* fix(web): pass project cwd to workflow discovery so project-specific workflows appear WorkflowList and WorkflowInvoker both called listWorkflows() without cwd, so the server always fell back to the first codebase. Add project-scoped cwd to both query functions and include project ID in the React Query key so the cache invalidates on project switch. Closes #818 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(web): use cwd (not project ID) in workflow query key for correct refetch timing The initial fix used localProjectId in the React Query key, but codebases load asynchronously — when the component mounts with a project selected, cwd is undefined until codebases resolve. Since the project ID doesn't change when codebases load, no refetch fires. Using cwd directly in the key ensures the refetch triggers when the actual path becomes available. Closes #818 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(web): pass project cwd to workflow discovery so project-specific workflows appear WorkflowList and WorkflowInvoker both called listWorkflows() without cwd, so the server always fell back to the first codebase. Add project-scoped cwd to both query functions and include project ID in the React Query key so the cache invalidates on project switch. Closes coleam00#818 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(web): use cwd (not project ID) in workflow query key for correct refetch timing The initial fix used localProjectId in the React Query key, but codebases load asynchronously — when the component mounts with a project selected, cwd is undefined until codebases resolve. Since the project ID doesn't change when codebases load, no refetch fires. Using cwd directly in the key ensures the refetch triggers when the actual path becomes available. Closes coleam00#818 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(web): pass project cwd to workflow discovery so project-specific workflows appear WorkflowList and WorkflowInvoker both called listWorkflows() without cwd, so the server always fell back to the first codebase. Add project-scoped cwd to both query functions and include project ID in the React Query key so the cache invalidates on project switch. Closes coleam00#818 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(web): use cwd (not project ID) in workflow query key for correct refetch timing The initial fix used localProjectId in the React Query key, but codebases load asynchronously — when the component mounts with a project selected, cwd is undefined until codebases resolve. Since the project ID doesn't change when codebases load, no refetch fires. Using cwd directly in the key ensures the refetch triggers when the actual path becomes available. Closes coleam00#818 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Pull Request
Summary
Added Agent Work Orders layout example to the Style Guide, featuring an interactive workflow progress visualization with human-in-the-loop checkpoints, collapsible step history, and integrated document editing.
Changes Made
AgentWorkOrderExample.tsxlayout component in style guide with workflow progress bar, step history, and document editorWorkflowStepButton.tsxcomponent - checkmark-based step indicators adapted from PowerButtonStepHistoryCard.tsxcomponent - collapsible cards with embedded document editing for human-in-loop stepsLayoutsTab.tsxto integrate Agent Work Orders section with Briefcase iconSideNavigation.tsxfor better full-screen viewingType of Change
Affected Services
Testing
Test Evidence
Checklist
Breaking Changes
None - This is a new additive feature in the style guide with no impact on existing functionality.
Additional Notes
Features Implemented
Workflow Progress Bar:
Step History:
Document Editor:
Side Navigation Enhancement:
Design Decisions
grid-cols-1 md:grid-cols-2for mobile supportUI Consistency Review
Conducted automated UI consistency review against
PRPs/ai_docs/UI_STANDARDS.md:PRPs/reviews/ui-consistency-review-agent-work-orders.mdDependencies
All dependencies already exist:
Screenshots
See style guide at: http://localhost:3737/style-guide → Layouts tab → Agent Work Orders
Files Changed
New Files:
archon-ui-main/src/features/style-guide/layouts/AgentWorkOrderExample.tsx(329 lines)archon-ui-main/src/features/style-guide/layouts/components/WorkflowStepButton.tsx(171 lines)archon-ui-main/src/features/style-guide/layouts/components/StepHistoryCard.tsx(266 lines)Modified Files:
archon-ui-main/src/features/style-guide/tabs/LayoutsTab.tsx(added Agent Work Orders section)archon-ui-main/src/features/style-guide/shared/SideNavigation.tsx(added collapse functionality)Total: 3 new files, 2 modified files, ~766 lines of new code
Summary by CodeRabbit
Release Notes