feat(chat): reviews in the stream; quick prompts as chat messages - #1056
Merged
Conversation
Two things a user can see in an agent's Chat feed that were invisible there before. Reviews now render as a block in the stream, linking to the review itself. The entry is derived at read time from `reviews` — a fifth feed source alongside chat messages, status events, agent-to-agent messages and shared media — so a review's status and counts in the feed are always its current ones, with no second write path to keep in sync and no backfill for reviews that already exist. Ranked above the other sources so existing cursors keep their meaning; `cursorClause` gained an optional table alias, since the review source is the only one whose query joins. The block is the Reviews sidebar's own collapsed row, extracted as `ReviewSummaryBlock`: the sidebar renders it with a chevron and a date, the feed without either (the post it sits in is already stamped). Clicking it opens that review in the sidebar, through the same handler the Changes tab already used after submitting one. Quick phrases and shortcut pins now deliver as Chat messages when the surface is on: the same `sendUserMessage` the composer calls, so they get a user row, the envelope carrying its id, a post in the feed, and reply threading. A phrase pasted to be edited (`submit: false`) and a terminal session keep the pane path, as does everything with the flag off. These two clicks now honour the quiet gate, as a composed message does; the pin remains the trust boundary, and an undeliverable click still fails before any row is written. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
Two things a user can see in an agent's Chat feed that were invisible there before.
Reviews render in the stream
When a review is created against an agent's work, a block for it appears inline in that agent's Chat feed and links to the review.
The entry is derived at read time from
reviews— a fifth feed source alongside chat messages, status events, agent-to-agent messages and shared media — rather than written as a chat row. So the block always shows the review's current status and counts, there is no second write path to keep in sync, and reviews that already exist show up with no backfill. A review that resolves updates its block in place.cursorClausegained an optional table alias: the review source is the only one whose query joins (agentsfor the reviewer's persona,review_feedback_itemsfor the counts), and barecreated_at/idwould be ambiguous there.review.created/review.updated/review_feedback.updatednow also invalidate the chat feed query.Visually it is the Reviews sidebar's collapsed row: that header was extracted as
ReviewSummaryBlockand both surfaces render it. The sidebar passesexpanded(chevron, sticky/pinned classes) and shows the date; the feed omits both — the post it sits in is already stamped. Clicking the block opens that review in the sidebar, expanded, through the same handler the Changes tab already used after submitting one.Quick phrases and shortcut pins deliver as Chat messages
With the Chat surface on,
POST /terminal/inject-phraseandPOST /terminal/inject-pin/:pinIdnow go throughChatService.sendUserMessage— the same call the composer makes — so a click gets a user row, the injection envelope carrying its id, a post in the feed, and reply threading back to it.The decision and delivery live in
apps/server/src/chat/user-prompt.tsbehind a narrow deps shape, stated once and reused at both call sites.submit: false) keeps the pane path — there is no message yet.Behaviour change worth noting: these two clicks now honour the quiet gate, as a composed chat message does, where they previously set
gate: false. The hold pill and "Send now" are visible in both Console and Chat.The pin remains the trust boundary — a disabled or non-shortcut pin is still refused — and an undeliverable click (agent not running) fails with 409 before any row is written, so the feed never shows a post that did not land.
Testing
pnpm run checkclean;pnpm run finalize:webbuilt.deliverUserPrompt's routing and fallback; chat-surface cases on the pin route asserting no phantom post on a failed delivery.Reviews
architecture-review— clean approval, no findings.frontend-ux-review— one finding, fixed and verified: the post header named the reviewer from the agents list (its agent name) while the block saidReview · {persona}, so one actor read as two names.reviewAuthornow prefers the server'sreviewerName, matching the other author helpers in that file.🤖 Generated with Claude Code