Skip to content

feat(sessions): reorder and edit queued messages in place#3242

Merged
charlesvien merged 16 commits into
mainfrom
posthog-code/queue-reorder-edit-in-place
Jul 15, 2026
Merged

feat(sessions): reorder and edit queued messages in place#3242
charlesvien merged 16 commits into
mainfrom
posthog-code/queue-reorder-edit-in-place

Conversation

@gantoine

@gantoine gantoine commented Jul 7, 2026

Copy link
Copy Markdown
Member

What

Two additions to the queued-messages dock (the follow-ups pinned above the composer while a turn is running):

  1. Drag to reorder — each queued card is now draggable. The queue drains in array order, so the order shown is the order the messages send. Uses the existing @dnd-kit/react sortable pattern (same as sidebar folders / browser tabs), with a PointerSensor movement threshold so the card's buttons still take clicks.
  2. Edit in place — the pencil now loads a queued message back into the composer for editing without removing it from the queue. Submitting the edit updates the message where it sits (same id, position, and queue timestamp) instead of appending a new one. If the message already drained or was discarded while being edited, it falls back to sending as a fresh message so nothing is lost. The card being edited is highlighted and gains a cancel (✕) affordance.

Previously the pencil ("return to editor") pulled the message out of the queue entirely; that hook (useReturnQueuedMessageToEditor) is replaced by useEditQueuedMessage / useCancelQueuedMessageEdit.

Screenshot 2026-07-08 at 4 45 37 PM

How

  • coremoveQueuedMessage and updateQueuedMessage store setters; SessionService.updateQueuedMessage mirrors the enqueue normalization (cloud recomputes transport display + raw payload via getCloudPromptTransport; local stores the serialized text).
  • uisessionViewStore tracks the active edit target per task (editingQueuedIdByTaskId); useSessionCallbacks.handleSendPrompt routes to updateQueuedMessage when an edit is in progress; QueuedMessagesDock wires the DragDropProvider + sortable cards and clears a stale edit target if the message leaves the queue.

Testing

  • pnpm --filter @posthog/core typecheck + @posthog/ui typecheck — clean
  • Biome lint — clean
  • New packages/core/src/sessions/sessionQueueEditing.test.ts (9 tests) for the store setters; updated QueuedMessagesDock.test.tsx
  • Full suites: core sessions 267 pass, UI sessions 348 pass

Not yet dogfooded in the running app — happy to do that next.


Created with PostHog Code

Let users drag queued follow-ups to reorder them (the queue drains in
array order, so the order shown is the order they send) and edit a
queued message in the composer without pulling it out of the queue.

- Add moveQueuedMessage and updateQueuedMessage store setters
- Add SessionService.updateQueuedMessage mirroring enqueue normalization
  (cloud recomputes transport display + raw payload; local stores text)
- Track the active edit target in sessionViewStore; the composer's next
  submit updates the message in place, falling back to a fresh send if
  it already drained or was discarded
- Make each queued card a dnd-kit drag handle; highlight the card being
  edited with a cancel affordance

Generated-By: PostHog Code
Task-Id: 96d2978d-909b-4bbf-a45b-44ede597a1b8
@trunk-io

trunk-io Bot commented Jul 7, 2026

Copy link
Copy Markdown

Merging to main in this repository is managed by Trunk.

  • To merge this pull request, check the box to the left or comment /trunk merge below.

After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown

React Doctor found 1 issue in 1 file · 1 warning.

1 warning

src/features/sessions/components/QueuedMessagesDock.tsx

Reviewed by React Doctor for commit a2291f9.

@gantoine gantoine added the build-installer Build a macOS installer for this PR label Jul 8, 2026
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown

🖥️ macOS test build (Apple Silicon)

A signed macOS build for this PR is ready to download and run.

⬇️ Open this run and download the code-macos-arm64 artifact (Apple Silicon / M-series).

Unzip it to get the .dmg, open it, and drag PostHog Code into Applications.

This build is signed but not notarized, so macOS quarantines it on download and Gatekeeper reports "PostHog Code is damaged and can't be opened". That is the missing notarization, not a corrupt file — clear the quarantine flag once and it launches:

xattr -dr com.apple.quarantine "/Applications/PostHog Code.app"

Then open PostHog Code normally. (Fully notarized, double-click-to-run builds ship only from the tagged release pipeline.)

Built from ec91f3d · rebuilds on each push while the build-installer label is present. Downloading requires being signed in to GitHub with repo access.

@charlesvien

Copy link
Copy Markdown
Member

hey @gantoine, what's the status of this one?

@gantoine

Copy link
Copy Markdown
Member Author

i'm still wresting with the UX a bit, namely around multiple stacked prompts executing as sa group and cutting off the edit (racing to save before the prompt is sent)

gantoine added 6 commits July 13, 2026 08:37
When a queued message is open for an in-place edit, it now acts as a
drain boundary: on turn end the messages queued before it still send,
but it and everything after stay queued until the edit is saved or
cancelled. Saving/cancelling while the agent is already idle re-drains
the now-unblocked queue.

The "which message is being edited" fact moves from the UI view store
into domain state (AgentSession.editingQueuedId) since it now gates the
send behavior, with a pure sendableQueuePrefixLength() helper. The
auto-drain paths pass stopAtEdited; cancel/recall still drain everything.

Generated-By: PostHog Code
Task-Id: 5cf31c6c-1ba0-4137-88c1-3a369f3acf36
Resolve QueuedMessageView conflict: keep main's font-medium text styling
and drop the obsolete fadeColor prop (main refactored the collapsed-fade
to a paint-only CSS mask, so the editing highlight no longer needs a
matching background color).

Generated-By: PostHog Code
Task-Id: 5cf31c6c-1ba0-4137-88c1-3a369f3acf36
While editing a queued message in place, Escape now abandons the edit
(clearing the hold and emptying the composer) instead of stopping the
running turn. Cancel-edit takes priority over stop-run, and the escape
hotkey is enabled whenever an edit is in progress — including while the
agent is idle.

Generated-By: PostHog Code
Task-Id: 5cf31c6c-1ba0-4137-88c1-3a369f3acf36
The editing (purple) state collapsed shorter than the default state
because its actions are all ghost icon buttons (fit-content height),
with no fixed-height Steer button to anchor the row. Pin the row to
min-h-6 so both states match. Also widen the action gap (gap-1 -> gap-2)
and add breathing room after the "Editing in composer" label.

Generated-By: PostHog Code
Task-Id: 5cf31c6c-1ba0-4137-88c1-3a369f3acf36
Previously the whole queue was merged into a single prompt when the turn
ended, so multiple queued messages landed in one turn. Drain just the
head message instead (max: 1) — when that turn completes, the existing
turn-end drain fires again for the next one, so the queue sends
sequentially. The in-place edit boundary still applies: the cutoff is
min(max, sendable-prefix). Cancel/recall paths still pull the whole
queue into the composer.

Generated-By: PostHog Code
Task-Id: 5cf31c6c-1ba0-4137-88c1-3a369f3acf36
The quality job's `biome ci` failed on organizeImports: the new export
sorts after `type SessionStatus` (case-sensitive S < s), not before.

Generated-By: PostHog Code
Task-Id: 5cf31c6c-1ba0-4137-88c1-3a369f3acf36
@gantoine gantoine marked this pull request as ready for review July 13, 2026 18:32
@greptile-apps

greptile-apps Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Reviews (1): Last reviewed commit: "fix(shared): sort sendableQueuePrefixLen..." | Re-trigger Greptile

Comment thread packages/ui/src/features/sessions/hooks/useSessionCallbacks.ts Outdated
Comment thread packages/ui/src/features/sessions/hooks/useEditQueuedMessage.ts Outdated
Comment thread packages/ui/src/features/sessions/components/QueuedMessagesDock.tsx

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds interactive queue management to the Sessions queued-messages dock: users can drag queued follow-ups to reorder send order, and can edit a queued message “in place” (without removing it) while the queue drain respects an edit hold boundary.

Changes:

  • Implement drag-to-reorder for queued messages using the existing @dnd-kit/react sortable pattern.
  • Implement in-place queued-message editing: mark an editingQueuedId, route composer submit to SessionService.updateQueuedMessage, and provide cancel/highlight UX.
  • Update core/shared queue semantics: add edit-boundary drain logic (sendableQueuePrefixLength, stopAtEdited, max) and add store setters + tests.

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/ui/src/features/sessions/sessionServiceHost.test.ts Adds tests/mocks covering edit-hold release behavior and updated dequeue options.
packages/ui/src/features/sessions/hooks/useSessionCallbacks.ts Routes composer submit to updateQueuedMessage when editing a queued item.
packages/ui/src/features/sessions/hooks/useReturnQueuedMessageToEditor.ts Removes the old “pull from queue back to editor” hook (replaced by in-place edit).
packages/ui/src/features/sessions/hooks/useEditQueuedMessage.ts New hooks to start/cancel in-place queued-message edits and restore content into composer.
packages/ui/src/features/sessions/components/SessionView.tsx Plumbs “editing queued” state into the composer to support Escape-to-cancel editing.
packages/ui/src/features/sessions/components/session-update/QueuedMessageView.tsx Updates queued-card UI: drag handle, edit/cancel affordances, and editing highlight state.
packages/ui/src/features/sessions/components/QueuedMessagesDock.tsx Adds sortable drag/drop wrapper, edit/cancel wiring, and stale-edit cleanup.
packages/ui/src/features/sessions/components/QueuedMessagesDock.test.tsx Updates mocks for new hooks/setters and drag support.
packages/ui/src/features/message-editor/components/PromptInput.tsx Adds Escape handling to cancel an in-progress queued-message edit.
packages/ui/src/features/message-editor/components/PromptInput.test.tsx Adds tests for Escape behavior when editing vs when a run is loading.
packages/shared/src/sessions.ts Adds editingQueuedId to AgentSession and introduces sendableQueuePrefixLength.
packages/shared/src/index.ts Re-exports sendableQueuePrefixLength.
packages/core/src/sessions/sessionStore.ts Adds moveQueuedMessage, updateQueuedMessage, edit-hold setters, and drain cutoff options.
packages/core/src/sessions/sessionService.ts Updates drain behavior (stop-at-edit, max=1) and adds edit-hold/update APIs.
packages/core/src/sessions/sessionQueueEditing.test.ts New unit tests for reorder/update/edit-hold and sequential drain behavior.
apps/web/vite.config.ts Adds @posthog/git/* aliasing to source for Rollup/Vite resolution parity.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/core/src/sessions/sessionService.ts
gantoine added 3 commits July 13, 2026 16:40
…edit

Cancelling a queued-message edit unconditionally set the composer to empty
content, wiping any draft the user had typed before clicking Edit. Snapshot
the composer content when the edit begins and restore it on cancel, falling
back to clearing only when there was no prior draft. The snapshot is
refreshed at each edit and taken (removed) on cancel, so it can never restore
stale content on a later edit.

Generated-By: PostHog Code
Task-Id: 5cf31c6c-1ba0-4137-88c1-3a369f3acf36
updateQueuedMessage awaited resolveCloudPrompt before writing to the store.
If the message drained during that await (a turn completed and sent it), the
store update became a no-op but the method still returned true, so the caller
treated the edit as saved and never fell back to sending it as a fresh
message -- losing the edit. Re-read fresh session state after the await and
return false if the target is no longer queued. Also read fresh state for the
edit-hold clear, since the pre-await snapshot may be stale.

Generated-By: PostHog Code
Task-Id: 5cf31c6c-1ba0-4137-88c1-3a369f3acf36
On a failed updateQueuedMessage the catch cleared editingQueuedId, which
releases the hold and can flush the queue when the run is idle — sending the
original, unedited message, the opposite of what the user intended. Keep the
hold on failure so the message stays queued and unsent, and restore the edited
text to the composer (unless the user already started typing) so they can retry
the save or cancel the edit explicitly.

Generated-By: PostHog Code
Task-Id: 5cf31c6c-1ba0-4137-88c1-3a369f3acf36
@gantoine gantoine requested review from a team and removed request for charlesvien July 14, 2026 13:48
@charlesvien charlesvien enabled auto-merge (squash) July 15, 2026 07:03
@charlesvien charlesvien merged commit 83a4cc7 into main Jul 15, 2026
27 checks passed
@charlesvien charlesvien deleted the posthog-code/queue-reorder-edit-in-place branch July 15, 2026 07:04
Gilbert09 added a commit that referenced this pull request Jul 15, 2026
Ports the desktop queued-messages improvements to the mobile app.

- Reorder queued messages with per-card move up/down controls.
- Edit a queued message in place: pull it into the composer while it stays
  in the queue, then save it back into position (or cancel unchanged).
- Drain boundary: while a message is being edited, only the messages queued
  before it auto-send when the turn ends; the edited message and everything
  after it stay queued until the edit is saved or cancelled.

Generated-By: PostHog Code
Task-Id: 8d0379e9-fb51-4ce7-9eb9-8f5b7a508bf0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build-installer Build a macOS installer for this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants