@@ -17,20 +17,21 @@ interface AnnotationSidebarProps {
1717}
1818
1919export function AnnotationSidebar ( { onPreview, onSubmit, collapseButton } : AnnotationSidebarProps ) {
20- const { isReadOnly, selectedRevision, currentRevision, revisions } = useContext ( RevisionContext ) ;
20+ const { isReadOnly, selectedRevision, currentRevision, revisions, agentWatching } = useContext ( RevisionContext ) ;
2121 const sessionId = useContext ( SessionContext ) ;
22- const isCurrentButSubmitted = isReadOnly && selectedRevision === currentRevision ;
2322 const selectedRevInfo = revisions . find ( ( r ) => r . revision === selectedRevision ) ;
23+ const isCurrentButSubmitted = isReadOnly && selectedRevision === currentRevision ;
24+ const feedbackConsumed = ! ! selectedRevInfo ?. feedbackConsumed ;
2425 const roundLabel = selectedRevInfo ?. label || `Round ${ selectedRevision } ` ;
2526
2627 if ( isReadOnly ) {
27- return < ReadOnlyAnnotationSidebar sessionId = { sessionId } revision = { selectedRevision } label = { roundLabel } waitingForUpdate = { isCurrentButSubmitted } collapseButton = { collapseButton } /> ;
28+ return < ReadOnlyAnnotationSidebar sessionId = { sessionId } revision = { selectedRevision } label = { roundLabel } waitingForUpdate = { isCurrentButSubmitted } feedbackConsumed = { feedbackConsumed } agentWatching = { agentWatching } collapseButton = { collapseButton } /> ;
2829 }
2930
30- return < AnnotationSidebarInner onPreview = { onPreview } onSubmit = { onSubmit } collapseButton = { collapseButton } /> ;
31+ return < AnnotationSidebarInner onPreview = { onPreview } onSubmit = { onSubmit } agentWatching = { agentWatching } collapseButton = { collapseButton } /> ;
3132}
3233
33- function FeedbackDisplay ( { sessionId, revision, label, waitingForUpdate, collapseButton } : { sessionId : string ; revision : number ; label : string ; waitingForUpdate ?: boolean ; collapseButton ?: React . ReactNode } ) {
34+ function FeedbackDisplay ( { sessionId, revision, label, waitingForUpdate, feedbackConsumed , agentWatching , collapseButton } : { sessionId : string ; revision : number ; label : string ; waitingForUpdate ?: boolean ; feedbackConsumed ?: boolean ; agentWatching ?: boolean ; collapseButton ?: React . ReactNode } ) {
3435 const [ feedback , setFeedback ] = useState < string | null > ( null ) ;
3536 const [ loading , setLoading ] = useState ( true ) ;
3637
@@ -51,12 +52,7 @@ function FeedbackDisplay({ sessionId, revision, label, waitingForUpdate, collaps
5152 { collapseButton }
5253 </ div >
5354
54- { waitingForUpdate && (
55- < div className = "mx-4 mb-3 px-3 py-2.5 rounded-lg bg-accent-green-muted flex items-center gap-2 flex-shrink-0" >
56- < span className = "w-2 h-2 rounded-full bg-accent-green animate-pulse" />
57- < span className = "text-[12px] font-body text-accent-green" > Waiting for next revision...</ span >
58- </ div >
59- ) }
55+ { waitingForUpdate && < WaitingBanner feedbackConsumed = { feedbackConsumed } agentWatching = { agentWatching } /> }
6056
6157 < div className = "flex-1 overflow-y-auto px-4" >
6258 { loading ? (
@@ -71,17 +67,42 @@ function FeedbackDisplay({ sessionId, revision, label, waitingForUpdate, collaps
7167 ) ;
7268}
7369
70+ function WaitingBanner ( { feedbackConsumed, agentWatching } : { feedbackConsumed ?: boolean ; agentWatching ?: boolean } ) {
71+ if ( feedbackConsumed ) {
72+ return (
73+ < div className = "mx-4 mb-3 px-3 py-2.5 rounded-lg bg-accent-green-muted flex items-center gap-2 flex-shrink-0" >
74+ < span className = "w-2 h-2 rounded-full bg-accent-green animate-pulse" />
75+ < span className = "text-[12px] font-body text-accent-green" > Feedback received — waiting for next revision...</ span >
76+ </ div >
77+ ) ;
78+ }
79+ if ( agentWatching ) {
80+ return (
81+ < div className = "mx-4 mb-3 px-3 py-2.5 rounded-lg bg-accent-blue-muted flex items-center gap-2 flex-shrink-0" >
82+ < span className = "w-2 h-2 rounded-full bg-accent-blue animate-pulse" />
83+ < span className = "text-[12px] font-body text-accent-blue" > Waiting for agent to pick up feedback...</ span >
84+ </ div >
85+ ) ;
86+ }
87+ return (
88+ < div className = "mx-4 mb-3 px-3 py-2.5 rounded-lg bg-accent-amber-muted flex items-center gap-2 flex-shrink-0" >
89+ < span className = "w-2 h-2 rounded-full bg-accent-amber" />
90+ < span className = "text-[12px] font-body text-accent-amber" > Agent disconnected — tell Claude to check feedback</ span >
91+ </ div >
92+ ) ;
93+ }
94+
7495type ReadOnlyTab = "feedback" | "annotations" ;
7596
76- function ReadOnlyAnnotationSidebar ( { sessionId, revision, label, waitingForUpdate, collapseButton } : { sessionId : string ; revision : number ; label : string ; waitingForUpdate ?: boolean ; collapseButton ?: React . ReactNode } ) {
97+ function ReadOnlyAnnotationSidebar ( { sessionId, revision, label, waitingForUpdate, feedbackConsumed , agentWatching , collapseButton } : { sessionId : string ; revision : number ; label : string ; waitingForUpdate ?: boolean ; feedbackConsumed ?: boolean ; agentWatching ?: boolean ; collapseButton ?: React . ReactNode } ) {
7798 const { annotations, generalNote, activeAnnotationId, setActiveAnnotationId } = useAnnotations ( ) ;
7899 const { setActiveView } = useContext ( ActiveViewContext ) ;
79100 const hasAnnotations = annotations . length > 0 || generalNote . trim ( ) . length > 0 ;
80101 const [ activeTab , setActiveTab ] = useState < ReadOnlyTab > ( "feedback" ) ;
81102
82103 // If no annotations in localStorage, just show feedback
83104 if ( ! hasAnnotations ) {
84- return < FeedbackDisplay sessionId = { sessionId } revision = { revision } label = { label } waitingForUpdate = { waitingForUpdate } collapseButton = { collapseButton } /> ;
105+ return < FeedbackDisplay sessionId = { sessionId } revision = { revision } label = { label } waitingForUpdate = { waitingForUpdate } feedbackConsumed = { feedbackConsumed } agentWatching = { agentWatching } collapseButton = { collapseButton } /> ;
85106 }
86107
87108 return (
@@ -114,12 +135,7 @@ function ReadOnlyAnnotationSidebar({ sessionId, revision, label, waitingForUpdat
114135 { collapseButton }
115136 </ div >
116137
117- { waitingForUpdate && (
118- < div className = "mx-4 mb-3 px-3 py-2.5 rounded-lg bg-accent-green-muted flex items-center gap-2 flex-shrink-0" >
119- < span className = "w-2 h-2 rounded-full bg-accent-green animate-pulse" />
120- < span className = "text-[12px] font-body text-accent-green" > Waiting for next revision...</ span >
121- </ div >
122- ) }
138+ { waitingForUpdate && < WaitingBanner feedbackConsumed = { feedbackConsumed } agentWatching = { agentWatching } /> }
123139
124140 { activeTab === "feedback" ? (
125141 < FeedbackDisplayContent sessionId = { sessionId } revision = { revision } />
@@ -287,7 +303,7 @@ function ReadOnlyAnnotationList({ annotations, generalNote, activeAnnotationId,
287303 ) ;
288304}
289305
290- function AnnotationSidebarInner ( { onPreview, onSubmit, collapseButton } : AnnotationSidebarProps ) {
306+ function AnnotationSidebarInner ( { onPreview, onSubmit, agentWatching , collapseButton } : AnnotationSidebarProps & { agentWatching : boolean } ) {
291307 const {
292308 annotations, updateAnnotation, removeAnnotation,
293309 addAnnotationImage, removeAnnotationImage,
@@ -422,6 +438,10 @@ function AnnotationSidebarInner({ onPreview, onSubmit, collapseButton }: Annotat
422438 { annotations . length > 0 && (
423439 < span className = "inline-flex items-center justify-center min-w-[18px] h-[18px] px-1 rounded-full bg-border-subtle text-[10px] font-medium text-text-secondary" > { annotations . length } </ span >
424440 ) }
441+ < span
442+ className = { `w-1.5 h-1.5 rounded-full flex-shrink-0 ${ agentWatching ? "bg-accent-green" : "bg-accent-amber" } ` }
443+ title = { agentWatching ? "Agent connected" : "Agent disconnected" }
444+ />
425445 </ span >
426446 { collapseButton }
427447 </ div >
0 commit comments