Repository navigation
feat(ui): first-run announcement for Ask this session and non-blocking reviews - #1690
Merged
Merged
Conversation
backnotprop
added a commit
that referenced
this pull request
Oct 4, 2026
… and never mid-work Review of #1690: - Only a session that is connected right now sees it: the capabilities answer lists the session-bridge provider and its status is not gone. Everything else (remote, --tailscale, Windows, the mod off, -p, Pi's event-API path, OpenCode 1, an older CLI, a gone session, other hosts) defers without writing the cookie. The setup lines are gone and the footer always says the session is connected. - It opens only before the reader's first pointer press, key press or focus into a text field, within 4 s of the initial load, and never over a focused text field (useFirstRunAnnouncementWindow). A late capabilities answer no longer pops it up mid-comment for the next Space or Enter to dismiss unread; it waits for a later load instead. - It gates on Ask AI being reachable on the surface (the plan editor's canUseAI, not taken over by the annotate agent terminal; code review's AI button), so 'Open Ask AI to try it' never points at nothing.
…me gate Announces 0.28.0's integrated sessions: Ask AI answered by the Claude Code, Pi or OpenCode session that opened Plannotator, and reviews that no longer hold that session. One cookie, plannotator-announce-ask-session-seen, for every surface, read through storage directly like the terminal-tools gate. Same shell as the terminal-tools announcement (portal, z-[100], Escape, Tab wrap, focus restore, backdrop dismiss, capture-phase keydown that swallows Mod+Enter). The copy names the host; the footer says the session is connected when the server offers the bridge and otherwise what gets it. The gate shows it only for those three origins, only once Ask AI is available, and never on the same load as a pending terminal-tools announcement.
…he first-run chain Both apps gate it behind every chain dialog (permission-mode setup included) and behind the terminal-tools announcement, which keeps its own load. Code review's destination spotlight, auto-viewed toast and history shortcut guard defer behind it too. Archive, shared and no-server sessions, the compact touch shell, other origins and PLANNOTATOR_AI=disabled suppress it without consuming the cookie.
1280x800, 35 s: mp4 (2.4 MB), webm (2.6 MB) and a poster jpg, served from https://plannotator.ai/assets/ once the marketing deploy syncs them. Recorded from a real Claude Code 2.1.289 session with the real plugin, mod and compiled CLI and the real review app; the model calls went to a scripted local stand-in for the Messages API.
… and never mid-work Review of #1690: - Only a session that is connected right now sees it: the capabilities answer lists the session-bridge provider and its status is not gone. Everything else (remote, --tailscale, Windows, the mod off, -p, Pi's event-API path, OpenCode 1, an older CLI, a gone session, other hosts) defers without writing the cookie. The setup lines are gone and the footer always says the session is connected. - It opens only before the reader's first pointer press, key press or focus into a text field, within 4 s of the initial load, and never over a focused text field (useFirstRunAnnouncementWindow). A late capabilities answer no longer pops it up mid-comment for the next Space or Enter to dismiss unread; it waits for a later load instead. - It gates on Ask AI being reachable on the surface (the plan editor's canUseAI, not taken over by the annotate agent terminal; code review's AI button), so 'Open Ask AI to try it' never points at nothing.
On raw-HTML and live-app annotate, pointer, key and focus events inside the iframe never reach the parent document, and the parent sees only the <iframe> as focused. The announcement window now treats a focused iframe at open time as working (skip this load), and closes on a window blur, counted only after a one-second startup grace so a viewer that focuses its own iframe while loading does not cost the reader the announcement.
A 'Learn more' link in the footer to https://docs.plannotator.ai/open-source/workflows/ask-this-session (goes live with the 0.28.0 release), opened in a new tab with noopener noreferrer. Got it stays the primary action and keeps focus; the link sits before it in Tab order. Like the terminal-tools announcement's outbound links, following it neither dismisses the announcement nor spends its cookie.
A 'Watch on X' action to https://x.com/plannotator/status/2106875215170899992, the same as the terminal-tools announcement's: X mark and label, outbound style, new tab with noopener noreferrer, and following it neither dismisses nor spends the cookie. The actions (Watch on X, Learn more, Got it) wrap as one right-aligned group so a narrow panel never splits them; Got it stays primary and focused. When the media cannot load, the frame offers the X post like the precedent. XMark is now exported from the terminal-tools dialog.
backnotprop
force-pushed
the
feat/announce-ask-session
branch
from
October 4, 2026 23:20
dc8aa97 to
ce3181b
Compare
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.
What
A one-time, video-first announcement for 0.28.0's integrated sessions, built exactly like the terminal-tools announcement (#1529):
Files:
packages/ui/components/AskSessionAnnouncementDialog.tsx,packages/ui/utils/askSessionAnnouncement.ts(one plain cookie,plannotator-announce-ask-session-seen, for every surface, read through storage directly for the same seeding reason as the precedent). Same shell: portal,z-[100], Escape, Tab wrap, focus restore, backdrop dismiss, and a capture-phase keydown that swallowsMod+Enterso a keystroke can't approve a plan or post a review behind it.data-ask-session-announcement-dialogfor tests.Copy: headline "Ask {Agent}, right from Plannotator" (the connected host), two sentences, and a footer that always reads "This session is connected. Open Ask AI to try it." A Watch on X link to https://x.com/plannotator/status/2106875215170899992, done exactly like the precedent's: X mark and label, outbound style, new tab with
noopener noreferrer, and it doesn't dismiss or spend the cookie. If the media can't load, the frame offers this link, like the precedent. A Learn more link to https://docs.plannotator.ai/open-source/workflows/ask-this-session, which goes live with the 0.28.0 release; until then it returns 404 on the live site and 200 on the docs preview. The link opens in a new tab. Like the precedent's outbound links, following it neither dismisses the announcement nor spends its cookie. Got it stays the primary action and keeps focus. Both links come before it in Tab order, and the three actions wrap as one right-aligned group, so a narrow panel never splits them.The footage: what is real
apps/marketing/public/assets/ask-this-session-demo.{mp4,webm}+ask-this-session-poster.jpg: 1280x800, 35 s, mp4 2.4 MB, webm 2.6 MB, poster 135 KB (the TUI/Herdr demos are 5.5 MB and 3.5 MB mp4). They load fromhttps://plannotator.ai/assets/like the precedent, after the marketing deploy that runs on push to main.--plugin-dir apps/hook) and the Claude Code mod in its default-on state. The CLI is the real compiled one from this branch. The review UI is the real built app./plannotator-reviewopens the review through the mod. The question is sent from the line-selection popover over the real pull bridge, arrives in Claude Code as "The plannotator plugin sent a message", and Claude Code runs a realReadtool call. The answer streams back into the Ask AI panel ("Ask this session · Claude Code" is visible). Then a comment is sent with Send Feedback, the tab shows "Feedback Sent", and the feedback arrives in Claude Code as a plugin turn.ANTHROPIC_BASE_URLpointed at a local stand-in for the Messages API that streams fixed text (plus theReadtool_use). No real model ran, and no account or credentials were used. Everything ran with a tempHOMEand a tempPLANNOTATOR_DATA_DIR.Who sees it, and why
/api/ai/capabilitieslists the session-bridge provider forclaude-code,pioropencode, and its status is notgone(connectedAskSessionAgent). Ask AI must also be reachable on the surface: the plan editor'scanUseAI, not taken over by the annotate agent terminal, or code review's AI button.--tailscale, Windows, the mod off,-p, Pi's event-API path, OpenCode 1, an older CLI);PLANNOTATOR_AI=disabled;useFirstRunAnnouncementWindow): it opens only before the reader's first pointer press, key press or focus into a text field, and within 4 s of the initial load. It never opens over a focused text field (such as a comment composer) or a focused iframe. On raw-HTML and live-app annotate, work inside the iframe never reaches the parent's listeners, so a windowblurafter a one-second startup grace also closes the window; the grace is there because the viewer may focus its own iframe while loading. Capabilities can answer late because of model discovery. If it does, the announcement misses that load and the cookie stays unwritten, rather than taking focus mid-comment and being dismissed unread by the next Space or Enter.askSessionAnnouncementPendingThisLoad), so a fresh browser sees terminal tools first and this one on a later load. Code review's destination spotlight, auto-viewed toast and history-shortcut guard defer behind it, the same way they defer behind terminal tools.Screenshots
Final footer (Watch on X, Learn more, Got it), from the real built review app with a connected Claude Code session:
The screenshots below are from earlier revisions of the footer. Everything above the footer is unchanged.
Real built apps (
bun run --cwd apps/review build && bun run build:hook, then the compiled CLI) in headless Chromium, fresh profile, DPR 2. Each session was started withPLANNOTATOR_ORIGINand the real pull-bridge env (all screenshots are connected sessions; the not-connected variant no longer exists). The video was not deployed yet, so the hosted URLs were served from the committed files. The images were committed in a temporary commit and removed in the next one.Real-app checks (compiled CLI, fresh profiles)
claude-agent-sdkonly): no dialog, cookie unset.gone(no host poll within 30 s): no dialog, cookie unset.Tests
packages/ui/utils/askSessionAnnouncement.test.ts: the cookie is read without writing; a different version doesn't count; it is never pending on the same load as terminal tools. Connected means a listed bridge that is not gone: ready, busy and blocked count; gone, missing, an unknown host and a provider row with no status don't. Each eligibility condition works on its own.packages/ui/hooks/useFirstRunAnnouncementWindow.test.tsx(DOM):packages/ui/components/AskSessionAnnouncementDialog.test.tsx(DOM): labelled modal with one completion action that gets focus; names each host; the footer is always the connected line; Watch on X and Learn more open in a new tab without dismissing, while Got it keeps focus and comes after both in Tab order; the media fallback offers the X post; hosted, muted, looping, autoplaying media; reduced motion; load-failure fallback; Got it, Escape and backdrop dismiss (a press inside the panel doesn't);Mod+Enterswallowed; Tab wrap and focus restore.packages/editor/App.askSessionAnnouncement.test.tsx(DOM, real App):Mod+Enterover it decides nothing.packages/review-editor/App.decisionControl.test.tsx: it takes the last turn,Mod+Enterposts nothing, and dismissing it writes the cookie. Separately, it never shares a load with terminal tools.DOM_TESTSin.github/workflows/test.yml.Results after the fixes:
bun run typecheckclean.bun test packages/ui packages/editor packages/review-editor: 1725 pass, 0 fail.DOM_TESTS=1 bun test packages/editor/App packages/review-editor/App packages/ui/utilsplus the three new DOM files and the terminal-tools dialog test: 1154 pass, 0 fail.bun test scripts/dom-test-allowlist.test.tspasses.bun run --cwd apps/review build && bun run build:hooksucceeds. Before the fixes, the fullbun testrun was 6000 pass, 0 fail.Docs: an AGENTS.md section next to the terminal-tools one, and a manual checklist in
tests/UI-TESTING.md.