Skip to content

feat(sidebar): surface unread tasks with an exclamation icon#2682

Open
MattPua wants to merge 2 commits into
mainfrom
posthog-code/unread-task-exclamation-icon
Open

feat(sidebar): surface unread tasks with an exclamation icon#2682
MattPua wants to merge 2 commits into
mainfrom
posthog-code/unread-task-exclamation-icon

Conversation

@MattPua

@MattPua MattPua commented Jun 15, 2026

Copy link
Copy Markdown
Member

Problem

  • Agent finishes task → not obvious in task list what needs attention / what's unseen
  • Read/unread plumbing already existed (lastViewedAt/lastActivityAt, markActivity on turn-complete, markAsViewed on open) but didn't surface:
    • Masked — in TaskIcon, unread sat below cloud/PR icons → on finish, cloud/PR icon won, unread never showed
    • Too subtle — when shown, tiny 8px green dot
    • Stale — off-screen completion wrote timestamp to backend but never updated react-query cache (getAllTaskTimestamps, staleTime 30s) → isUnread stuck false until next focus/reconnect refetch

Change

CleanShot.2026-06-15.at.14.04.48.mp4
  • Promote unread above cloud/PR/diff/suspended in TaskIcon, render as amber WarningCircle ❗ ("Unread — new activity")
  • Imperative markActivity/markViewed now invalidate timestamps query after mutate → unread shows instant on off-screen completion
  • Open task → markAsViewed clears isUnread → normal status icon returns (marked read on view)
  • Live states (generating / needs-permission) still win — not "finished and unseen"
  • Shared by sidebar list, command palette, canvas channel list (all via TaskIcon) → consistent everywhere

Activity → read/unread lifecycle

markActivity only fires for a live session (local agent, or cloud while watched). Unwatched-cloud completion has no markActivity — it rides server updated_at + the 30s task-list poll instead.

stateDiagram-v2
    [*] --> Unviewed
    Unviewed --> Read: markAsViewed (open)
    Read --> Unread: markActivity (local / watched-cloud finish)
    Read --> Unread: server updated_at + poll (unwatched cloud, ≤30s)
    Unread --> Read: markAsViewed (open)
    note right of Unread
        markActivity path: invalidate timestamps
        query → sidebar recomputes isUnread instantly
    end note
Loading

TaskIcon priority (after)

flowchart TD
    A[task state] --> B{needsPermission?}
    B -->|yes| P[HandPalm]
    B -->|no| C{isGenerating?}
    C -->|yes| G[spinner]
    C -->|no| D{isUnread?}
    D -->|yes| U["amber WarningCircle ❗"]
    D -->|no| E{terminal cloud?}
    E -->|yes| CL[cloud status]
    E -->|no| F{isSuspended?}
    F -->|yes| S[Pause]
    F -->|no| H{PR / diff?}
    H -->|yes| PR[PR / branch]
    H -->|no| Z[pinned / Slack / chat]
Loading

Note

  • isUnread only true once viewed at least once (lastViewedAt != null) → tasks never opened (e.g. Slack) won't flag til first open. Lower-noise default; easy to flip.
  • Currently-focused task stays read (continuously re-marked viewed) — exclamation is for tasks you've opened then navigated away from.

Testing

  • biome lint clean on changed files
  • Remaining package typecheck errors = pre-existing unbuilt-dist build-order noise, unrelated

Created with PostHog Code

When an agent finished a task, the cloud/PR status icon hid the unread
signal, so it wasn't clear which finished tasks still needed attention.

Promote the unread state above the cloud/PR/diff/suspended icons in
TaskIcon and render it as an amber WarningCircle exclamation. Opening the
task clears `isUnread` (via the existing markAsViewed flow), so the normal
status icon returns automatically — i.e. it's marked read on view. Live
states (generating, needs-permission) still take precedence.

Shared by the sidebar task list, command palette, and canvas channel
list, which all render through TaskIcon.

Generated-By: PostHog Code
Task-Id: 524c2fa0-2175-4cbc-bf2e-ab68ef366fae
@github-actions

github-actions Bot commented Jun 15, 2026

Copy link
Copy Markdown

React Doctor found no issues in the changed files. 🎉

Reviewed by React Doctor for commit c0fff88.

@greptile-apps

greptile-apps Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Reviews (1): Last reviewed commit: "fix(sidebar): surface unread tasks with ..." | Re-trigger Greptile

@MattPua MattPua changed the title fix(sidebar): surface unread tasks with an exclamation icon feat(sidebar): surface unread tasks with an exclamation icon Jun 15, 2026
The imperative markActivity/markViewed writes persisted timestamps to the
backend but never updated the react-query cache, so the sidebar's
getAllTaskTimestamps query (staleTime 30s) kept computing isUnread=false
until a later focus/reconnect refetch. Invalidate that query after the
mutation so the unread exclamation appears the moment a task finishes,
even when it isn't open.

Generated-By: PostHog Code
Task-Id: 2347fc39-cc4b-4c29-b9db-70e39074d83a
@MattPua MattPua force-pushed the posthog-code/unread-task-exclamation-icon branch from 3d1c63b to c0fff88 Compare June 15, 2026 18:03
@MattPua MattPua marked this pull request as ready for review June 15, 2026 18:06
@MattPua MattPua requested a review from jonathanlab June 15, 2026 18:07
@greptile-apps

greptile-apps Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Reviews (2): Last reviewed commit: "fix(sidebar): refresh unread state when ..." | Re-trigger Greptile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant