fix(desktop): spin the sidebar dot for starting cloud runs - #76341
Merged
Conversation
|
😎 This pull request was merged. |
Cloud queued means a sandbox is being claimed and the backend leaves that state on its own, so it earns the spinner (labelled "Starting"). A local queued run has nothing advancing its persisted status, so it keeps the still dot alongside in_progress runs whose claim outlives the work.
adamleithp
force-pushed
the
ux/task-icons-rework-nits
branch
from
August 1, 2026 11:29
68549a1 to
3018547
Compare
adamleithp
marked this pull request as ready for review
August 1, 2026 11:29
Contributor
|
Reviews (1): Last reviewed commit: "test(desktop): pin the starting spinner ..." | Re-trigger Greptile |
adboio
approved these changes
Aug 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Follow-up nits on top of PostHog/code#4008, which reworked the sidebar row status dots. That PR folded
queuedinto pending, so a cloud task waiting on a sandbox showed the same still yellow dot as a run that had simply never been closed out. Those are not the same fact to a reader. A sandbox being claimed is bounded motion the backend leaves on its own, and it should look like it.What the dot does
One node changes. A cloud run's first few seconds stop reading as "nothing is happening".
Cloud run, before:
flowchart LR A(["send"]) --> Q["queued<br/>● Pending"] Q --> S["streaming<br/>⠋ Working"] S --> P["in_progress, idle<br/>● Pending"] P --> D["PR opened<br/>○ All caught up"] classDef phBlue fill:#1d4aff,stroke:#1d4aff,color:#fff; classDef phYellow fill:#f9bd2b,stroke:#f9bd2b,color:#000; classDef phGray fill:#e5e7eb,stroke:#c7ccd1,color:#000; class A phYellow; class Q,P phGray; class S phBlue; class D phGray;Cloud run, after:
flowchart LR A(["send"]) --> Q["queued<br/>⠋ Starting"] Q --> S["streaming<br/>⠋ Working"] S --> P["in_progress, idle<br/>● Pending"] P --> D["PR opened<br/>○ All caught up"] classDef phBlue fill:#1d4aff,stroke:#1d4aff,color:#fff; classDef phYellow fill:#f9bd2b,stroke:#f9bd2b,color:#000; classDef phGray fill:#e5e7eb,stroke:#c7ccd1,color:#000; class A phYellow; class Q,S phBlue; class P,D phGray;Local run, unchanged:
flowchart LR A(["send"]) --> Q["queued<br/>● Pending"] Q --> S["streaming<br/>⠋ Working"] S --> P["never advances<br/>● Pending"] classDef phBlue fill:#1d4aff,stroke:#1d4aff,color:#fff; classDef phYellow fill:#f9bd2b,stroke:#f9bd2b,color:#000; classDef phGray fill:#e5e7eb,stroke:#c7ccd1,color:#000; class A phYellow; class Q,P phGray; class S phBlue;⠋spins,●is still and solid,○is hollow and quiet.Timings below are from a real cloud run in the dev app, polled once a second from the moment of send:
queued, sandbox being claimed. This is the new stateisPromptPendingin_progresswith nothing streamingEight seconds is long enough that the old still dot read as a click that did not register.
Changes
taskStatusVocabulary.ts:queuednow earns the spinner, labelled "Starting". The backend advances that state by itself, so the motion terminates.queueddoes not. Nothing writes a terminal status when a local agent goes idle, so a local run can sit atqueuedfor hours after the work is done. It keeps the still dot alongsidein_progressruns whose claim outlives the work.ChannelItemRow.test.tsx: two cases, the new starting state and its precedence over an existing PR.Note
The cloud-queued branch returns before the PR check, so a re-queued cloud run on a task that already has a PR spins rather than going quiet. That is deliberate. The PR rule exists because
in_progresslies (the workflow holds it while babysitting CI); cloudqueueddoes not lie, and a re-run genuinely is starting. The docblock now says the PR beats a status that merely claims work, not one that is visibly starting, and a test pins it.The changes originate on the PostHog/code branch
ux/task-icons-rework-nits(commit0edbe86). No PR was ever opened there, and PostHog/code main is frozen after the desktop import, so it is remade here. It only became portable once #76339 resyncedproducts/desktoptofc991d3, which brought PostHog/code#4008 and the file this edits into the monorepo.How did you test this code?
I (Claude) ran these from
products/desktop, on the rebased branch:pnpm install --frozen-lockfile, cleanpnpm --filter @posthog/ui test, 2499 tests across 301 files pass, including both newChannelItemRowcasespnpm --filter @posthog/ui typecheck, 3 errors, all pre-existing. I ran the same command on the base commit and got the identical 3 (CLOUD_STREAM_IDLE_TIMEOUT,MCP_GATEWAY_FLAG,@posthog/harness/extensions/posthog-provider/model-catalog). None are in files this PR touches.Then I drove the running dev app over CDP with agent-browser and started both a cloud run and a local run in a space, polling the row's accessible name once a second. The dot's accessible name is the exact
labelstringtaskDot()returns, so the snapshot reads the real value rather than a rendering of it. The cloud table above is that run. The local run sat at "Pending, no work in flight" from creation onward and never spun, which is the branch this change deliberately excludes.Raw polling output, cloud run
The two new tests assert that a cloud run at
queuedgets the spinner while a local run atqueueddoes not, and that the spinner survives an existing PR on the task. No existing test covered the workspace mode split (both used to fall through to the same still dot), and the two PR-precedence cases both usedin_progress, so nothing pinned the interaction between a starting run and a PR.Automatic notifications
Docs update
No user-facing docs cover the sidebar dot vocabulary.
🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Ported by Claude Code (Opus 5) using the repo's
/porting-code-prsskill, with/writing-code-commentsand/writing-testsfor the follow-up rounds. The skill's normal path isgh pr diffintogit am --directory=products/desktop/, but there was no source PR here, just a branch with one commit, so the patch came fromgit format-patchon the fetched branch instead.git am -3preserved the original authorship.The interesting part was the base. The skill is explicit that merged PostHog/code changes must arrive through the resync protocol in MIGRATION.md and must never be hand-ported, since that duplicates the diff. PostHog/code#4008 is merged and sat after what was then the pinned SHA, so the file this commit edits was absent from master and the port was blocked. I first built this stacked on the open resync PR, then found #76339 had already merged an hour earlier, so it was rebased straight onto master and the stack thrown away.
A review pass afterwards found the PR-precedence gap called out above, plus a docblock that claimed queued folds into working without qualifying it to cloud. Both are fixed in follow-up commits. The commit message was reworded from
nitsto conventional-commit format.