Skip to content

fix(promptinput): focus seeded prompts - #661

Open
Farhan (fkb032) wants to merge 1 commit into
mainfrom
agent/eng-612-focus-seeded-prompt
Open

fix(promptinput): focus seeded prompts#661
Farhan (fkb032) wants to merge 1 commit into
mainfrom
agent/eng-612-focus-seeded-prompt

Conversation

@fkb032

@fkb032 Farhan (fkb032) commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Route suggestion chips, Spotlight, trending prompts, Mac recommendations, and prompt history through one prompt-seeding path.
  • Reveal and focus the composer after seeding, place the caret at the end, and never auto-submit.
  • Preserve history-trigger focus restoration when the popover is dismissed without a selection.

Why

ENG-612 / #638: under the active evolve-prompt-suggestions multivariate feature flag, the trending variant can leave the composer off-screen while suggestion rows remain clickable. Previously those clicks only updated Zustand state, so they could look inert. Mac recommendations and prompt history also bypassed the shared helper.

This supersedes closed draft #641. The filesystem “edit with prompt” action navigates from another screen and is intentionally outside this in-place suggestion flow.

Fixes #638

Test Plan

  • bun -F native test:unit — 347 tests passed across 51 files
  • bunx tsc --noEmit -p apps/native/tsconfig.json
  • bunx oxlint on all four changed files — 0 warnings/errors
  • bunx oxfmt --check on all four changed files
  • bun -F native build
  • Real WKWebView smoke: an off-screen Mac recommendation revealed and focused the composer with the caret at the end and no submit; history selection retained composer focus; Escape restored trigger focus
  • git diff --check

Known repository baselines

Docs

  • No docs update needed

@linear-code

linear-code Bot commented Aug 15, 2026

Copy link
Copy Markdown

ENG-612

@github-actions

Copy link
Copy Markdown
Contributor

📋 PR Overview

Lines changed 217 (+179 / -38)
Files 0 added, 4 modified, 0 deleted
Draft / WIP no
Has Test Plan yes
Linear issue yes
No Test Plan Needed no
New UI components no
New Storybook stories no
New Rust modules no
New TS source files no
New tests no
package.json touched no
Cargo.toml touched no
Infra / CI touched no

🔬 Coverage

Report Lines Statements Functions Branches
apps/native/coverage/coverage-summary.json 36.1% 35.8% 31.3% 29.7%

Generated by 🚫 dangerJS against ba1dcb6

@darkmatter

darkmatter Bot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

🎨 Storybook preview

Open Storybook preview

Updated for ba1dcb6


⚠️ Detected UI changes (5)

These stories' HTML snapshots changed. I've added screenshots + links to the changed stories below. Review them carefully then accept the changes to regenerate baselines and include them in this PR:

Flows/Evolve › Playground

Flows/Evolve › Playground

Flows/Evolve › 1. Begin (idle)

Flows/Evolve › 1. Begin (idle)

Flows/Evolve › 2. Evolving (progress)

Flows/Evolve › 2. Evolving (progress)

Flows/Evolve › Evolving With Error Event

Flows/Evolve › Evolving With Error Event

Flows/Evolve › 3. Review (changes generated)

Flows/Evolve › 3. Review (changes generated)


Accept UI changes

  • Click here to accept these changes

Alternatively, you can run bun run test:update-snapshots locally to re-generate the baselines and then push the changes to this PR.

What does this do?

The screenshots above show UI changes detected by the Storybook
snapshot tests run on this PR. Each image is the rendered output of
a Storybook story from the code in this PR branch; the snapshot
test compared it against the committed baseline in
__snapshots__/ and flagged the difference.

Checking the box tells the darkmatter[bot] to regenerate the
baselines from this PR's current code and commit them directly to
this branch. The new baselines become the source of truth for
future runs — only accept after confirming the visual changes are
intentional.

Comparison baseline: the committed __snapshots__/ files on this
PR branch (carried forward from develop). Accept updates them in
place on this branch.

@prelint

prelint Bot commented Aug 15, 2026

Copy link
Copy Markdown

Ship it Prompt suggestions reveal and focus the composer before user submits

Product decisions in this change

Agree 1. All prompt suggestion surfaces share one seeding path, so the composer always reveals, receives focus, and positions the caret after any suggestion is selected.

Before this change, each surface called the global state action directly and stopped there. This meant a suggestion click on an off-screen composer updated state silently, with no visible feedback. A shared path ensures the user always knows their selection was received. The pattern is also correct for long-term maintenance: when seeding behavior needs to change again, one function controls all surfaces.

Agree 2. Selecting a suggestion seeds the composer but never submits the evolution, so users can review or edit before the agent starts.

In this product, an evolution edits system configuration. Auto-submit would start that process the moment a user taps a chip. The cost of an accidental evolution is high enough (time, build cycle, possible rollback) that requiring an explicit submit step is clearly right. The seeded text is a starting point, not a confirmed command.

Agree 3. After seeding, the caret lands at the end of the seeded text, not at the start.

Suggestions in this product are complete prompt sentences, not prefixes. A user who wants to refine the prompt is more likely to append context ("... but only for my user account") than to insert at the beginning. End placement also signals that the text is ready to submit as-is. This would need revisiting if the product adds partial-phrase chips designed to be completed.

Agree 4. The history popover returns focus to its trigger button when the user dismisses without selecting, and moves focus to the composer when the user does select.

This is the standard ARIA pattern for popovers. Focus returning to the element that opened the popover on Escape is what keyboard users expect. Redirecting focus to the composer after selection is correct because the next intended action is to review or submit the seeded text, not to interact with the history button again. The ref-based gate that distinguishes the two cases is the right mechanism.

Agree 5. Smooth scroll is replaced with instant scroll when the user's OS reports a preference for reduced motion.

This is a required accessibility behavior. The implementation reads the media query at call time inside the rAF callback, which means it picks up the live preference rather than a stale capture at component mount. The test that stubs matchMedia confirms the branch is exercised.

Agree 6. MacRecommendationChip and PromptHistoryBadge no longer own their seeding behavior and receive it as a callback from the parent composer.

These chips previously called a global action directly. That made seeding behavior impossible to extend from the parent and harder to test. Accepting a callback makes the parent the single source of truth for what "select a suggestion" means. The components remain simple presenters. The only cost is that they cannot be dropped into a new context without a parent that provides the callback, but that is not a realistic concern here since they are prompt-input-specific UI.

Agree with concerns 7. The "edit with prompt" filesystem action is intentionally excluded from this seeding unification.

The PR description gives a clear reason: that action navigates from another screen rather than operating in-place. The mechanics are genuinely different. However, users do not see those mechanics. A user who selects a filesystem file and picks "edit with prompt" has the same mental model as a user who picks a chip: they want the composer to be ready with their intent. If the filesystem path delivers a different focus or reveal experience, it will feel inconsistent. The current exclusion is defensible as a scoping decision, but the gap should be closed in a follow-up.

Open questions

  • Does the "edit with prompt" filesystem action currently reveal and focus the composer after navigating? If not, does the team plan to align it with the behavior introduced here?

  • Are there any suggestion surfaces not visible in this diff (for example, the Spotlight variant or the trending variant) that still call the global state action directly and bypass the shared seeding path?

  • When the composer is disabled because processing is already active, suggestion surfaces are presumably not shown. Is that suppression consistent across all surfaces, or can a user reach a chip while processing is running?

Recommendation

Ship it
Every decision in the PR is sound and consistent with good UX practice. The change fixes a real gap where suggestion clicks could appear inert, adds tests that cover the new behavior across every affected surface, and respects accessibility preferences. The one concern (filesystem action exclusion) is a known gap the team has already scoped out, not a regression introduced here.

Copy link
Copy Markdown
Contributor Author

Thanks — I checked each open question against the current branch:

  • Filesystem action: “Edit with a prompt” stores the seed and closes the Filesystem view. It does not use the shared seedPrompt path, focus the textarea, or scroll it into view. That remains a separate cross-screen path outside ENG-612; this PR covers the in-place suggestion controls.
  • Suggestion coverage: Spotlight, Trending (row selection and “Use”), starter chips, Mac recommendations, and prompt history all call the shared seedPrompt. The filesystem transition is the only production non-empty prompt writer outside PromptInput.
  • Processing state: During normal evolve, the overlay covers the controls and the textarea and history control are disabled. Rebuild also uses a full-content overlay. Some apply actions run from Begin, but the composer remains enabled, so suggestion seeding still reveals and focuses it normally. There is a brief cancellation wind-down where suggestions can be selected while the textarea remains disabled; on the cancellation path, the selected text is retained when processing clears and is not auto-submitted.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Suggestion chips feel dead when prompt is scrolled off-screen

2 participants